diff options
55 files changed, 1564 insertions, 508 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc7b2b55f3..2830e676f1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,11 +44,11 @@ variables: # these tags should be updated each time the list of packages is updated # changing these will force rebuilding the associated image # Note: these tags have no meaning and are not tied to a particular NM version - FEDORA_TAG: '2021-01-28.0-5ee9fa53946e' - UBUNTU_TAG: '2021-01-28.0-b172a9697407' - DEBIAN_TAG: '2021-01-28.0-b172a9697407' - CENTOS_TAG: '2021-01-28.0-5ee9fa53946e' - ALPINE_TAG: '2021-01-28.0-76f28d039de3' + FEDORA_TAG: '2021-01-28.0-204b637c4b94' + UBUNTU_TAG: '2021-01-28.0-397adbc67ac4' + DEBIAN_TAG: '2021-01-28.0-397adbc67ac4' + CENTOS_TAG: '2021-01-28.0-204b637c4b94' + ALPINE_TAG: '2021-01-28.0-35b8aa24ed67' FEDORA_EXEC: 'bash .gitlab-ci/fedora-install.sh' UBUNTU_EXEC: 'bash .gitlab-ci/debian-install.sh' @@ -890,7 +890,7 @@ pages: paths: - public only: - - master + - main dependencies: - t_fedora:33 needs: diff --git a/.gitlab-ci/ci.template b/.gitlab-ci/ci.template index f8f13395e4..8ee2c89541 100644 --- a/.gitlab-ci/ci.template +++ b/.gitlab-ci/ci.template @@ -213,7 +213,7 @@ pages: paths: - public only: - - master + - main dependencies: - t_{{pages_build.name}}:{{pages_build.version}} needs: @@ -8,5 +8,5 @@ For the detailed project history see git [2]. For notable changes between releases see the NEWS file [3]. [1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/blob/b25c227e078bc9e3a2e06b3f62bd2b727f50beee/ChangeLog -[2] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/commits/master -[3] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/blob/master/NEWS +[2] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/commits/main +[3] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/blob/main/NEWS diff --git a/Makefile.am b/Makefile.am index 81860efd65..02a01c19e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -127,6 +127,7 @@ 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/fundamental/.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 @@ -2304,6 +2305,8 @@ src_core_libnm_systemd_core_la_SOURCES = \ src/core/systemd/src/libsystemd-network/lldp-neighbor.h \ src/core/systemd/src/libsystemd-network/lldp-network.c \ src/core/systemd/src/libsystemd-network/lldp-network.h \ + src/core/systemd/src/libsystemd-network/network-common.c \ + src/core/systemd/src/libsystemd-network/network-common.h \ src/core/systemd/src/libsystemd-network/network-internal.c \ src/core/systemd/src/libsystemd-network/network-internal.h \ src/core/systemd/src/libsystemd-network/sd-dhcp-client.c \ @@ -2639,6 +2642,7 @@ src_core_libNetworkManagerTest_la_LIBADD = \ $(CODE_COVERAGE_LDFLAGS) \ $(GLIB_LIBS) \ $(LIBUDEV_LIBS) \ + $(PTHREAD_LIBS) \ $(NULL) $(src_core_libNetworkManagerTest_la_OBJECTS): $(src_libnm_core_public_mkenums_h) @@ -2665,7 +2669,7 @@ src_core_NetworkManager_all_sym_LDFLAGS = \ $(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)" + $(AM_V_GEN) LIBTOOL="$(LIBTOOL)" NM="$(NM)" "$(srcdir)/tools/create-exports-NetworkManager.sh" --called-from-build "$(srcdir)" CLEANFILES += src/core/NetworkManager.ver diff --git a/configure.ac b/configure.ac index 5126ed2f0f..59de44dfbf 100644 --- a/configure.ac +++ b/configure.ac @@ -1229,6 +1229,8 @@ 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') +AX_PTHREAD([,AC_MSG_ERROR([Threads are required for the NetworkManager tests])]) + if test -n "$PYTHON" ; then AM_PATH_PYTHON([], [], []) else diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec index 174535cc4d..20496c17f7 100644 --- a/contrib/fedora/rpm/NetworkManager.spec +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -304,7 +304,7 @@ Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release} # that the scripts that would parse the SPEC file naively would be unlikely # to fail. Refer to git log for the real date and commit number of last # synchronization: -# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/commits/master/src/systemd +# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/commits/main/src/ Provides: bundled(systemd) = 0 diff --git a/contrib/fedora/rpm/release.sh b/contrib/fedora/rpm/release.sh index c07a8c2846..9aa30dde33 100755 --- a/contrib/fedora/rpm/release.sh +++ b/contrib/fedora/rpm/release.sh @@ -6,18 +6,18 @@ # # There are 6 modes: # -# - "devel" : on master branch to tag a devel release (e.g. "1.25.2-dev"). -# - "rc1" : the first release candidate on "master" branch which branches off +# - "devel" : on main branch to tag a devel release (e.g. "1.25.2-dev"). +# - "rc1" : the first release candidate on "main" branch which branches off # a new "nm-1-X" branch (e.g. tag "1.26-rc1" (1.25.90) and branch -# off "nm-1-26"). On master this also bumps the version number +# off "nm-1-26"). On main this also bumps the version number # and creates a new devel release (e.g. "1.27.0-dev"). # - "rc" : further release candidates on RC branch (e.g. from "nm-1-26" branch # tag "1.26-rc2" with version number 1.25.91). # - "major" : on stable branch do a major release (e.g. on "nm-1-26" branch # release "1.26.0", followed by "1.26.1-dev"). # You should do a "major-post" release right a "major" release. -# - "major-post": after a "major" release, merge the release branch with master and -# do another devel snapshot on master (e.g. do "1.27.1-dev" release). +# - "major-post": after a "major" release, merge the release branch with main and +# do another devel snapshot on main (e.g. do "1.27.1-dev" release). # - "minor" : on a stable branch do a minor release (e.g. "1.26.4" on "nm-1-26" # branch and bump to "1.26.5-dev"). # @@ -34,7 +34,7 @@ # # * Your git repository needs a remote "origin" that points to the upstream git repository. # -# * All your (relevant) local branches (master and nm-1-*) must be up to date with their +# * All your (relevant) local branches (main and nm-1-*) must be up to date with their # remote tracking branches for origin. # # Run with --no-test to do the actual release. @@ -218,7 +218,7 @@ while [ "$#" -ge 1 ]; do DO_CLEANUP=0 ;; --allow-local-branches) - # by default, the script errors out if the relevant branch (master, nm-1-Y) are not the same + # by default, the script errors out if the relevant branch (main, nm-1-Y) are not the same # as the remote branch on origin. You should not do a release if you have local changes # that differ from upstream. Set this flag to override that check. ALLOW_LOCAL_BRANCHES=1 @@ -262,12 +262,12 @@ CUR_BRANCH="$(git rev-parse --abbrev-ref HEAD)" CUR_HEAD="$(git rev-parse HEAD)" TMP_BRANCH=release-branch -if [ "$CUR_BRANCH" = master ]; then - number_is_odd "${VERSION_ARR[1]}" || die "Unexpected version number on master. Should be an odd development version" +if [ "$CUR_BRANCH" = main ]; then + number_is_odd "${VERSION_ARR[1]}" || die "Unexpected version number on main. Should be an odd development version" [ "$RELEASE_MODE" = devel -o "$RELEASE_MODE" = rc1 -o "$RELEASE_MODE" = major-post ] || die "Unexpected branch name \"$CUR_BRANCH\" for \"$RELEASE_MODE\"" else re='^nm-[0-9]+-[0-9]+$' - [[ "$CUR_BRANCH" =~ $re ]] || die "Unexpected current branch $CUR_BRANCH. Should be master or nm-?-??" + [[ "$CUR_BRANCH" =~ $re ]] || die "Unexpected current branch $CUR_BRANCH. Should be main or nm-?-??" if number_is_odd "${VERSION_ARR[1]}"; then # we are on a release candiate branch. [ "$RELEASE_MODE" = rc -o "$RELEASE_MODE" = major ] || die "Unexpected branch name \"$CUR_BRANCH\" for \"$RELEASE_MODE\"" @@ -284,12 +284,12 @@ case "$RELEASE_MODE" in minor) number_is_even "${VERSION_ARR[1]}" && number_is_odd "${VERSION_ARR[2]}" || die "cannot do minor release on top of version $VERSION_STR" - [ "$CUR_BRANCH" != master ] || die "cannot do a minor release on master" + [ "$CUR_BRANCH" != main ] || die "cannot do a minor release on main" ;; devel) number_is_odd "${VERSION_ARR[1]}" || die "cannot do devel release on top of version $VERSION_STR" [ "$((${VERSION_ARR[2]} + 1))" -lt 90 ] || die "devel release must have a micro version smaller than 90 but current version is $VERSION_STR" - [ "$CUR_BRANCH" == master ] || die "devel release can only be on master" + [ "$CUR_BRANCH" == main ] || die "devel release can only be on main" ;; rc) number_is_odd "${VERSION_ARR[1]}" || die "cannot do rc release on top of version $VERSION_STR" @@ -300,7 +300,7 @@ case "$RELEASE_MODE" in rc1) number_is_odd "${VERSION_ARR[1]}" || die "cannot do rc release on top of version $VERSION_STR" [ "${VERSION_ARR[2]}" -lt 90 ] || die "rc release must have a micro version smaller than ${VERSION_ARR[0]}.${VERSION_ARR[1]}.90 but current version is $VERSION_STR" - [ "$CUR_BRANCH" == master ] || die "rc1 release can only be on master" + [ "$CUR_BRANCH" == main ] || die "rc1 release can only be on main" RELEASE_BRANCH="nm-${VERSION_ARR[0]}-$((${VERSION_ARR[1]} + 1))" ;; major) @@ -311,7 +311,7 @@ case "$RELEASE_MODE" in major-post) number_is_odd "${VERSION_ARR[1]}" || die "cannot do major-post release on top of version $VERSION_STR" [ "$((${VERSION_ARR[2]} + 1))" -lt 90 ] || die "major-post release must have a micro version smaller than 90 but current version is $VERSION_STR" - [ "$CUR_BRANCH" == master ] || die "major-post release can only be on master" + [ "$CUR_BRANCH" == main ] || die "major-post release can only be on main" ;; *) die "Release mode $RELEASE_MODE not yet implemented" @@ -326,7 +326,7 @@ if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then fi NEWER_BRANCHES=() -if [ "$CUR_BRANCH" != master ]; then +if [ "$CUR_BRANCH" != main ]; then i="${VERSION_ARR[1]}" while : ; do i=$((i + 2)) @@ -341,7 +341,7 @@ if [ "$CUR_BRANCH" != master ]; then fi NEWER_BRANCHES+=("refs/heads/$b") done - b=master + b=main if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then git_same_ref "$b" "refs/heads/$b" || die "branch $b is not a branch??" git_same_ref "$b" "refs/remotes/$ORIGIN/$b" || die "branch $b seems not up to date with refs/remotes/$ORIGIN/$b. Git pull or --allow-local-branches?" @@ -354,7 +354,7 @@ if [ -n "$RELEASE_BRANCH" ]; then fi if [ "$ALLOW_LOCAL_BRANCHES" != 1 ]; then - cmp <(git show origin/master:contrib/fedora/rpm/release.sh) "$BASH_SOURCE" || die "$BASH_SOURCE is not identical to \`git show origin/master:contrib/fedora/rpm/release.sh\`" + cmp <(git show origin/main:contrib/fedora/rpm/release.sh) "$BASH_SOURCE" || die "$BASH_SOURCE is not identical to \`git show origin/main:contrib/fedora/rpm/release.sh\`" fi if ! check_news "$RELEASE_MODE" "@{VERSION_ARR[@]}" ; then @@ -365,12 +365,12 @@ if ! check_news "$RELEASE_MODE" "@{VERSION_ARR[@]}" ; then fi if [ $FIND_BACKPORTS = 1 ]; then - git show "$ORIGIN/master:contrib/scripts/find-backports" > ./.git/nm-find-backports \ + git show "$ORIGIN/main:contrib/scripts/find-backports" > ./.git/nm-find-backports \ && chmod +x ./.git/nm-find-backports \ || die "cannot get contrib/scripts/find-backports" - TMP="$(./.git/nm-find-backports "$CUR_BRANCH" master "${NEWER_BRANCHES[@]}" 2>/dev/null)" || die "nm-find-backports failed" - test -z "$TMP" || die "nm-find-backports returned patches that need to be backported (ignore with --no-find-backports): ./.git/nm-find-backports \"$CUR_BRANCH\" master ${NEWER_BRANCHES[@]}" + TMP="$(./.git/nm-find-backports "$CUR_BRANCH" main "${NEWER_BRANCHES[@]}" 2>/dev/null)" || die "nm-find-backports failed" + test -z "$TMP" || die "nm-find-backports returned patches that need to be backported (ignore with --no-find-backports): ./.git/nm-find-backports \"$CUR_BRANCH\" main ${NEWER_BRANCHES[@]}" fi if [ $CHECK_GITLAB = 1 ]; then @@ -461,18 +461,18 @@ case "$RELEASE_MODE" in TAR_VERSION="$b" ;; major-post) - # We create a merge commit with the content of current "master", with two - # parent commits $THE_RELEASE and "master". But we want that the first parent + # We create a merge commit with the content of current "main", with two + # parent commits $THE_RELEASE and "main". But we want that the first parent # is the release, so that `git log --first-parent` follows the path with the # release candidates, and not the devel part during that time. Hence this # switcheroo here. git checkout -B "$TMP_BRANCH" "${VERSION_ARR[0]}.$((${VERSION_ARR[1]} - 1)).0" || die "merge0" - git merge -Xours --commit -m tmp master || die "merge1" + git merge -Xours --commit -m tmp main || die "merge1" git rm --cached -r . || die "merge2" - git checkout master -- . || die "merge3" + git checkout main -- . || die "merge3" b="${VERSION_ARR[0]}.${VERSION_ARR[1]}.$((${VERSION_ARR[2]} + 1))" git commit --amend -m tmp -a || die "failed to commit major version bump" - test x = "x$(git diff master HEAD)" || die "there is a diff after merge!" + test x = "x$(git diff main HEAD)" || die "there is a diff after merge!" set_version_number "${VERSION_ARR[0]}" "${VERSION_ARR[1]}" "$((${VERSION_ARR[2]} + 1))" git commit --amend -m "release: bump version to $b (development)" -a || die "failed to commit major version bump" diff --git a/contrib/scripts/checkpatch-feature-branch.sh b/contrib/scripts/checkpatch-feature-branch.sh index c46fcd4b5a..d6f72b2034 100755 --- a/contrib/scripts/checkpatch-feature-branch.sh +++ b/contrib/scripts/checkpatch-feature-branch.sh @@ -23,23 +23,23 @@ else git fetch origin "$(git rev-parse "$HEAD")" --no-tags --unshallow git fetch "$NM_UPSTREAM_REMOTE" \ --no-tags \ - "refs/heads/master:$BASE_REF/master" \ + "refs/heads/main:$BASE_REF/main" \ "refs/heads/nm-*:$BASE_REF/nm-*" \ || die "failure to fetch from https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git" fi # the argument is only a single ref (or the default "HEAD"). - # Find all commits that branch off one of the stable branches or master + # Find all commits that branch off one of the stable branches or main # and lead to $HEAD. These are the commits of the feature branch. - RANGES=( $(git show-ref | sed 's#^\(.*\) '"$BASE_REF/"'\(master\|nm-1-[0-9]\+\)$#\1..'"$HEAD"'#p' -n) ) + RANGES=( $(git show-ref | sed 's#^\(.*\) '"$BASE_REF/"'\(main\|nm-1-[0-9]\+\)$#\1..'"$HEAD"'#p' -n) ) [ "${#RANGES[@]}" != 0 ] || die "cannot detect git-ranges (HEAD is $(git rev-parse "$HEAD"))" REFS=( $(git log --reverse --format='%H' "${RANGES[@]}") ) if [ "${#REFS[@]}" == 0 ] ; then - # no refs detected. This means, $HEAD is already on master (or one of the + # no refs detected. This means, $HEAD is already on main (or one of the # stable nm-1-* branches. Just check the patch itself. REFS=( "$HEAD" ) fi diff --git a/contrib/scripts/find-backports b/contrib/scripts/find-backports index 7f1b8ab8dd..fcb903d584 100755 --- a/contrib/scripts/find-backports +++ b/contrib/scripts/find-backports @@ -247,11 +247,11 @@ if __name__ == "__main__": if not git_ref_exists(r): break ref_upstreams.append(r) - ref_upstreams.append("master") + ref_upstreams.append("main") if not ref_upstreams: if len(sys.argv) <= 2: - ref_upstreams = ["master"] + ref_upstreams = ["main"] else: ref_upstreams = list(sys.argv[2:]) diff --git a/contrib/scripts/nm-copr-build-nm-git-bundle.sh b/contrib/scripts/nm-copr-build-nm-git-bundle.sh index 4e47d164fb..c4281834bc 100755 --- a/contrib/scripts/nm-copr-build-nm-git-bundle.sh +++ b/contrib/scripts/nm-copr-build-nm-git-bundle.sh @@ -8,7 +8,7 @@ # downloading the entire upstream git repository of NetworkManager. # # This script is also used by [1] to generate the SRPM. -# [1] https://copr.fedorainfracloud.org/coprs/networkmanager/NetworkManager-master/package/nm-git-bundle/ +# [1] https://copr.fedorainfracloud.org/coprs/networkmanager/NetworkManager-main/package/nm-git-bundle/ set -ex @@ -22,7 +22,7 @@ git clone -n "$GIT_URL" pushd NetworkManager REFS=( - $(git branch -a | sed -n 's#^ *remotes/origin/\(master\|nm-1-[0-9]\+\)$#\1#p') + $(git branch -a | sed -n 's#^ *remotes/origin/\(main\|nm-1-[0-9]\+\)$#\1#p') ) unset R @@ -48,7 +48,7 @@ Release: $(date '+%H%M%S') Summary: git-bundle of NetworkManager upstream repository License: Public Domain -URL: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/tree/master/contrib/fedora/rpm/nm-git-bundle.spec +URL: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/tree/main/contrib/fedora/rpm/nm-git-bundle.spec %global GIT_URL 'https://github.com/NetworkManager/NetworkManager' #global GIT_URL 'https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git' diff --git a/contrib/scripts/nm-copr-build.sh b/contrib/scripts/nm-copr-build.sh index 29712b6f4a..7b02df815d 100755 --- a/contrib/scripts/nm-copr-build.sh +++ b/contrib/scripts/nm-copr-build.sh @@ -1,7 +1,7 @@ #!/bin/bash # environment variables: -# - GIT_REF: the ref that should be build. Can be "master" or a git sha. +# - GIT_REF: the ref that should be build. Can be "main" or a git sha. # - DEBUG: set to 1 to build "--with debug". # - NM_GIT_BUNDLE: set to a HTTP url where to fetch the nm-git-bundle-*.noarch.rpm # from. Set to empty to skip it. By default, it fetches the bundle from copr. @@ -36,7 +36,7 @@ get_nm_git_bundle() { if [ -n "${NM_GIT_BUNDLE+x}" ]; then return 0 fi - NM_GIT_BUNDLE='https://download.copr.fedorainfracloud.org/results/networkmanager/NetworkManager-master/fedora-33-x86_64/01999272-nm-git-bundle/nm-git-bundle-20210219-141432.noarch.rpm' + NM_GIT_BUNDLE='https://download.copr.fedorainfracloud.org/results/networkmanager/NetworkManager-main/fedora-34-x86_64/02112667-nm-git-bundle/nm-git-bundle-20210401-202836.noarch.rpm' fi mkdir nm-git-bundle pushd nm-git-bundle diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml index 5e554c2bf8..fad9552283 100644 --- a/docs/libnm/libnm-docs.xml +++ b/docs/libnm/libnm-docs.xml @@ -169,7 +169,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in In general, the C API documentation applies to the use GObject introspection from other languages, with the calling convention respecting the language's customs. Consult the source tree for - <ulink url="https://gitlab.freedesktop.org/NetworkManager/NetworkManager/tree/master/examples">some examples</ulink>. + <ulink url="https://gitlab.freedesktop.org/NetworkManager/NetworkManager/tree/main/examples">some examples</ulink>. </para> </simplesect> diff --git a/examples/C/glib/vpn-import-libnm.c b/examples/C/glib/vpn-import-libnm.c index 6a563bac2d..55ed5175c1 100644 --- a/examples/C/glib/vpn-import-libnm.c +++ b/examples/C/glib/vpn-import-libnm.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * The example shows how to import VPN connection from a file. + * * @author: Jagadeesh Kotra <jagadeesh@stdin.top> * * Compile with: @@ -9,66 +10,154 @@ #include <glib.h> #include <NetworkManager.h> -#include <stdlib.h> + +/*****************************************************************************/ + +static NMConnection * +vpn_connection_import(const char *filename) +{ + NMConnection *conn = NULL; + GSList * plugins; + GSList * iter; + + g_print("Try to import file \"%s\"...\n", filename); + + plugins = nm_vpn_plugin_info_list_load(); + + for (iter = plugins; iter; iter = iter->next) { + GError * error = NULL; + NMVpnPluginInfo * plugin = iter->data; + NMVpnEditorPlugin *editor; + const char * plugin_name = nm_vpn_plugin_info_get_name(plugin); + + g_print("plugin[%s]: trying import...\n", plugin_name); + + editor = nm_vpn_plugin_info_load_editor_plugin(plugin, &error); + if (error) { + g_print("plugin[%s]: error loading plugin: %s\n", plugin_name, error->message); + g_clear_error(&error); + continue; + } + + conn = nm_vpn_editor_plugin_import(editor, filename, &error); + if (error) { + g_print("plugin[%s]: error importing file: %s\n", plugin_name, error->message); + g_clear_error(&error); + continue; + } + + if (!nm_connection_normalize(conn, NULL, NULL, &error)) { + g_print("plugin[%s]: imported connection invalid: %s\n", plugin_name, error->message); + g_clear_error(&error); + g_clear_object(&conn); + continue; + } + + g_print("plugin[%s]: imported connection \"%s\" (%s)\n", + plugin_name, + nm_connection_get_id(conn), + nm_connection_get_uuid(conn)); + break; + } + g_slist_free_full(plugins, g_object_unref); + + if (!conn) { + g_print("Failure to import the file with any plugin\n"); + return NULL; + } + + return conn; +} + +/*****************************************************************************/ + +typedef struct { + GMainLoop * loop; + GError * error; + NMRemoteConnection *rconn; +} RequestData; static void -add_cb(NMClient *client, GAsyncResult *result, GMainLoop *loop) +add_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + RequestData *rdata = user_data; + + rdata->rconn = nm_client_add_connection_finish(NM_CLIENT(source), result, &rdata->error); + g_main_loop_quit(rdata->loop); +} + +static NMRemoteConnection * +connection_add(NMConnection *conn) { - GError *err = NULL; - nm_client_add_connection_finish(client, result, &err); - if (err != NULL) { - g_print("Error: %s\n", err->message); + GError * error = NULL; + NMClient * client; + RequestData rdata; + + g_print("Adding connection \"%s\" (%s)\n", + nm_connection_get_id(conn), + nm_connection_get_uuid(conn)); + + client = nm_client_new(NULL, &error); + if (!client) { + g_print("Failure to connect with NetworkManager: %s\n", error->message); + return NULL; + } + + g_print("Adding connection \"%s\" (%s)\n", + nm_connection_get_id(conn), + nm_connection_get_uuid(conn)); + + rdata = (RequestData){ + .loop = g_main_loop_new(NULL, FALSE), + .rconn = NULL, + .error = NULL, + }; + + nm_client_add_connection_async(client, conn, TRUE, NULL, add_cb, &rdata); + + g_main_loop_run(rdata.loop); + + g_clear_pointer(&rdata.loop, g_main_loop_unref); + + if (rdata.error != NULL) { + g_print("Error: %s\n", rdata.error->message); + g_clear_error(&rdata.error); } else { - g_print("Connection Added.\n"); + g_print("Connection successfully added: %s\n", nm_object_get_path(NM_OBJECT(rdata.rconn))); } - g_main_loop_quit(loop); + g_clear_object(&client); + + return rdata.rconn; } +/*****************************************************************************/ + 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; + NMRemoteConnection *rconn; + NMConnection * conn; + const char * filename; + gboolean success; if (argc < 2) { g_print("program takes exactly one(1) argument.\n"); - exit(1); + return 1; } - plugins = nm_vpn_plugin_info_list_load(); - g_assert(plugins != NULL); + filename = argv[1]; - 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; - } - } + conn = vpn_connection_import(filename); + if (!conn) + return 1; - g_slist_free_full(plugins, g_object_unref); - g_assert(conn != NULL); + rconn = connection_add(conn); - client = nm_client_new(NULL, NULL); + success = (rconn != NULL); - nm_client_add_connection_async(client, conn, TRUE, NULL, (GAsyncReadyCallback) add_cb, loop); - g_main_loop_run(loop); + g_clear_object(&conn); + g_clear_object(&rconn); - return 0; + return success ? 0 : 1; } diff --git a/m4/ax_lib_readline.m4 b/m4/ax_lib_readline.m4 index af32fdaff7..0d0822bce6 100644 --- a/m4/ax_lib_readline.m4 +++ b/m4/ax_lib_readline.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_lib_readline.html +# https://www.gnu.org/software/autoconf-archive/ax_lib_readline.html # =========================================================================== # # SYNOPSIS @@ -58,7 +58,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 6 +#serial 8 AU_ALIAS([VL_LIB_READLINE], [AX_LIB_READLINE]) AC_DEFUN([AX_LIB_READLINE], [ @@ -66,15 +66,14 @@ AC_DEFUN([AX_LIB_READLINE], [ ax_cv_lib_readline, [ ORIG_LIBS="$LIBS" for readline_lib in readline edit editline; do - # prefer ncurses since we use it for nmtui too - for termcap_lib in "" ncurses termcap curses; do + for termcap_lib in "" termcap curses ncurses; do if test -z "$termcap_lib"; then TRY_LIB="-l$readline_lib" else TRY_LIB="-l$readline_lib -l$termcap_lib" fi LIBS="$ORIG_LIBS $TRY_LIB" - AC_TRY_LINK_FUNC(readline, ax_cv_lib_readline="$TRY_LIB") + AC_LINK_IFELSE([AC_LANG_CALL([], [readline])], [ax_cv_lib_readline="$TRY_LIB"]) if test -n "$ax_cv_lib_readline"; then break fi @@ -83,39 +82,26 @@ AC_DEFUN([AX_LIB_READLINE], [ break fi done + if test -z "$ax_cv_lib_readline"; then + ax_cv_lib_readline="no" + fi LIBS="$ORIG_LIBS" ]) - if test -z "$ax_cv_lib_readline"; then - AC_MSG_ERROR([readline library with terminfo support is required (one of readline, edit, or editline, AND one of ncurses, curses, or termcap)]) + if test "$ax_cv_lib_readline" != "no"; then + LIBS="$LIBS $ax_cv_lib_readline" + AC_DEFINE(HAVE_LIBREADLINE, 1, + [Define if you have a readline compatible library]) + AC_CHECK_HEADERS(readline.h readline/readline.h) + AC_CACHE_CHECK([whether readline supports history], + ax_cv_lib_readline_history, [ + ax_cv_lib_readline_history="no" + AC_LINK_IFELSE([AC_LANG_CALL([], [add_history])], [ax_cv_lib_readline_history="yes"]) + ]) + if test "$ax_cv_lib_readline_history" = "yes"; then + AC_DEFINE(HAVE_READLINE_HISTORY, 1, + [Define if your readline library has \`add_history']) + AC_CHECK_HEADERS(history.h readline/history.h) + fi fi - - ORIG_LIBS="$LIBS" - LIBS="$LIBS $ax_cv_lib_readline" - AC_CHECK_HEADERS(readline.h readline/readline.h) - - # Check history - AC_CACHE_CHECK([whether readline supports history], - ax_cv_lib_readline_history, [ - ax_cv_lib_readline_history="no" - AC_TRY_LINK_FUNC(add_history, ax_cv_lib_readline_history="yes") - ]) - if test "$ax_cv_lib_readline_history" != "yes"; then - AC_MSG_ERROR(readline history support is required) - fi - AC_CHECK_HEADERS(history.h readline/history.h) - - # check rl_echo_signal_char() - AC_CACHE_CHECK([whether readline supports rl_echo_signal_char()], - ax_cv_lib_readline_echo_signal_char, [ - ax_cv_lib_readline_echo_signal_char="no" - AC_TRY_LINK_FUNC(rl_echo_signal_char, ax_cv_lib_readline_echo_signal_char="yes") - ]) - if test "$ax_cv_lib_readline_echo_signal_char" != "yes"; then - AC_MSG_ERROR(rl_echo_signal_char() is required (install readline6?)) - fi - - LIBS="$ORIG_LIBS" - READLINE_LIBS="$ax_cv_lib_readline" - AC_SUBST(READLINE_LIBS) ])dnl diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 new file mode 100644 index 0000000000..e5858e50c3 --- /dev/null +++ b/m4/ax_pthread.m4 @@ -0,0 +1,522 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 30 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_TARGET]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $target_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; +esac + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $target_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $target_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $target_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index 5e03b102b7..54de1e28e0 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -22,6 +22,7 @@ #include <libpsl.h> #endif +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "nm-dns-manager.h" @@ -83,13 +84,13 @@ typedef struct { GHashTable *configs_dict; CList configs_lst_head; - CList ip_configs_lst_head; + CList ip_config_lst_head; GVariant *config_variant; NMDnsConfigIPData *best_ip_config_4; NMDnsConfigIPData *best_ip_config_6; - bool ip_configs_lst_need_sort : 1; + bool ip_config_lst_need_sort : 1; bool configs_lst_need_sort : 1; @@ -266,9 +267,11 @@ _dns_config_ip_data_new(NMDnsConfigData * data, .ip_config_type = ip_config_type, }; c_list_link_tail(&data->data_lst_head, &ip_data->data_lst); - c_list_link_tail(&NM_DNS_MANAGER_GET_PRIVATE(data->self)->ip_configs_lst_head, + c_list_link_tail(&NM_DNS_MANAGER_GET_PRIVATE(data->self)->ip_config_lst_head, &ip_data->ip_config_lst); + /* We also need to set priv->ip_config_lst_need_sort, but the caller will do that! */ + g_signal_connect(ip_config, NM_IS_IP4_CONFIG(ip_config) ? "notify::" NM_IP4_CONFIG_DNS_PRIORITY : "notify::" NM_IP6_CONFIG_DNS_PRIORITY, @@ -325,7 +328,7 @@ _dns_config_data_free(NMDnsConfigData *data) } static int -_mgr_get_ip_configs_lst_cmp(const CList *a_lst, const CList *b_lst, const void *user_data) +_mgr_get_ip_config_lst_cmp(const CList *a_lst, const CList *b_lst, const void *user_data) { const NMDnsConfigIPData *a = c_list_entry(a_lst, NMDnsConfigIPData, ip_config_lst); const NMDnsConfigIPData *b = c_list_entry(b_lst, NMDnsConfigIPData, ip_config_lst); @@ -341,16 +344,16 @@ _mgr_get_ip_configs_lst_cmp(const CList *a_lst, const CList *b_lst, const void * } static CList * -_mgr_get_ip_configs_lst_head(NMDnsManager *self) +_mgr_get_ip_config_lst_head(NMDnsManager *self) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self); - if (G_UNLIKELY(priv->ip_configs_lst_need_sort)) { - priv->ip_configs_lst_need_sort = FALSE; - c_list_sort(&priv->ip_configs_lst_head, _mgr_get_ip_configs_lst_cmp, NULL); + if (G_UNLIKELY(priv->ip_config_lst_need_sort)) { + priv->ip_config_lst_need_sort = FALSE; + c_list_sort(&priv->ip_config_lst_head, _mgr_get_ip_config_lst_cmp, NULL); } - return &priv->ip_configs_lst_head; + return &priv->ip_config_lst_head; } static int @@ -1104,7 +1107,7 @@ update_resolv_conf(NMDnsManager * self, } static void -compute_hash(NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer[HASH_LEN]) +compute_hash(NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer[static HASH_LEN]) { nm_auto_free_checksum GChecksum *sum = NULL; NMDnsConfigIPData * ip_data; @@ -1119,7 +1122,7 @@ compute_hash(NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer[ /* FIXME(ip-config-checksum): this relies on the fact that an IP * configuration without DNS parameters gives a zero checksum. */ - head = _mgr_get_ip_configs_lst_head(self); + head = _mgr_get_ip_config_lst_head(self); c_list_for_each_entry (ip_data, head, ip_config_lst) nm_ip_config_hash(ip_data->ip_config, sum, TRUE); } @@ -1169,27 +1172,26 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) } static const char * -get_nameserver_list(const NMIPConfig *config, GString **str) +get_nameserver_list(const NMIPConfig *config, NMStrBuf *tmp_strbuf) { - guint num, i; char buf[NM_UTILS_INET_ADDRSTRLEN]; int addr_family; + guint num; + guint i; - if (*str) - g_string_truncate(*str, 0); - else - *str = g_string_sized_new(64); + nm_str_buf_reset(tmp_strbuf); addr_family = nm_ip_config_get_addr_family(config); num = nm_ip_config_get_num_nameservers(config); for (i = 0; i < num; i++) { nm_utils_inet_ntop(addr_family, nm_ip_config_get_nameserver(config, i), buf); if (i > 0) - g_string_append_c(*str, ' '); - g_string_append(*str, buf); + nm_str_buf_append_c(tmp_strbuf, ' '); + nm_str_buf_append(tmp_strbuf, buf); } - return (*str)->str; + nm_str_buf_maybe_expand(tmp_strbuf, 1, FALSE); + return nm_str_buf_get_str(tmp_strbuf); } static char ** @@ -1224,13 +1226,14 @@ _collect_resolv_conf_data(NMDnsManager * self, if (global_config) merge_global_dns_config(&rc, global_config); else { - nm_auto_free_gstring GString *tmp_gstring = NULL; - int prio, first_prio = 0; - const NMDnsConfigIPData * ip_data; - const CList * head; - gboolean is_first = TRUE; - - head = _mgr_get_ip_configs_lst_head(self); + nm_auto_str_buf NMStrBuf tmp_strbuf = NM_STR_BUF_INIT(0, FALSE); + int prio; + int first_prio = 0; + const NMDnsConfigIPData *ip_data; + const CList * head; + gboolean is_first = TRUE; + + head = _mgr_get_ip_config_lst_head(self); c_list_for_each_entry (ip_data, head, ip_config_lst) { gboolean skip = FALSE; @@ -1244,16 +1247,13 @@ _collect_resolv_conf_data(NMDnsManager * self, } else if (first_prio < 0 && first_prio != prio) skip = TRUE; - if (nm_ip_config_get_num_nameservers(ip_data->ip_config)) { - _LOGT( - "config: %8d %-7s v%c %-5d %s: %s", - prio, - _config_type_to_string(ip_data->ip_config_type), - nm_utils_addr_family_to_char(nm_ip_config_get_addr_family(ip_data->ip_config)), - ip_data->data->ifindex, - skip ? "<SKIP>" : "", - get_nameserver_list(ip_data->ip_config, &tmp_gstring)); - } + _LOGT("config: %8d %-7s v%c %-5d %s: %s", + prio, + _config_type_to_string(ip_data->ip_config_type), + nm_utils_addr_family_to_char(nm_ip_config_get_addr_family(ip_data->ip_config)), + ip_data->data->ifindex, + skip ? "<SKIP>" : "", + get_nameserver_list(ip_data->ip_config, &tmp_strbuf)); if (!skip) merge_one_ip_config(&rc, ip_data->data->ifindex, ip_data->ip_config); @@ -1394,7 +1394,7 @@ _mgr_configs_data_construct(NMDnsManager *self) CList * head; int prev_priority = G_MININT; - head = _mgr_get_ip_configs_lst_head(self); + head = _mgr_get_ip_config_lst_head(self); #if NM_MORE_ASSERTS /* we call _mgr_configs_data_clear() at the end of update. We @@ -1611,7 +1611,7 @@ _mgr_configs_data_clear(NMDnsManager *self) NMDnsConfigIPData *ip_data; CList * head; - head = _mgr_get_ip_configs_lst_head(self); + head = _mgr_get_ip_config_lst_head(self); c_list_for_each_entry (ip_data, head, ip_config_lst) { nm_clear_g_free(&ip_data->domains.search); nm_clear_pointer(&ip_data->domains.reverse, g_strfreev); @@ -1680,7 +1680,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, GError **error) if (priv->sd_resolve_plugin) { nm_dns_plugin_update(priv->sd_resolve_plugin, global_config, - _mgr_get_ip_configs_lst_head(self), + _mgr_get_ip_config_lst_head(self), priv->hostname, NULL); } @@ -1702,7 +1702,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, GError **error) _LOGD("update-dns: updating plugin %s", plugin_name); if (!nm_dns_plugin_update(plugin, global_config, - _mgr_get_ip_configs_lst_head(self), + _mgr_get_ip_config_lst_head(self), priv->hostname, &plugin_error)) { _LOGW("update-dns: plugin %s update failed: %s", plugin_name, plugin_error->message); @@ -1839,7 +1839,7 @@ _ip_config_dns_priority_changed(gpointer config, GParamSpec *pspec, NMDnsConfigI { _ASSERT_dns_config_ip_data(ip_data); - NM_DNS_MANAGER_GET_PRIVATE(ip_data->data->self)->ip_configs_lst_need_sort = TRUE; + NM_DNS_MANAGER_GET_PRIVATE(ip_data->data->self)->ip_config_lst_need_sort = TRUE; } gboolean @@ -1904,7 +1904,7 @@ nm_dns_manager_set_ip_config(NMDnsManager * self, else ip_data->ip_config_type = ip_config_type; - priv->ip_configs_lst_need_sort = TRUE; + priv->ip_config_lst_need_sort = TRUE; p_best = NM_IS_IP4_CONFIG(ip_config) ? &priv->best_ip_config_4 : &priv->best_ip_config_6; @@ -2440,7 +2440,7 @@ _get_config_variant(NMDnsManager *self) g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); - head = _mgr_get_ip_configs_lst_head(self); + head = _mgr_get_ip_config_lst_head(self); c_list_for_each_entry (ip_data, head, ip_config_lst) { const NMIPConfig *ip_config = ip_data->ip_config; GVariantBuilder entry_builder; @@ -2546,7 +2546,7 @@ nm_dns_manager_init(NMDnsManager *self) _LOGT("creating..."); c_list_init(&priv->configs_lst_head); - c_list_init(&priv->ip_configs_lst_head); + c_list_init(&priv->ip_config_lst_head); priv->config = g_object_ref(nm_config_get()); @@ -2587,7 +2587,7 @@ dispose(GObject *object) priv->best_ip_config_4 = NULL; priv->best_ip_config_6 = NULL; - c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_configs_lst_head, ip_config_lst) + c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_config_lst_head, ip_config_lst) _dns_config_ip_data_free(ip_data); nm_clear_pointer(&priv->configs_dict, g_hash_table_destroy); diff --git a/src/core/nm-audit-manager.c b/src/core/nm-audit-manager.c index a1d20fcb62..2ef5d86097 100644 --- a/src/core/nm-audit-manager.c +++ b/src/core/nm-audit-manager.c @@ -11,14 +11,18 @@ #include <libaudit.h> #endif +#define NM_VALUE_TYPE_DEFINE_FUNCTIONS + #include "libnm-core-aux-intern/nm-auth-subject.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-value-type.h" #include "nm-config.h" #include "nm-dbus-manager.h" #include "settings/nm-settings-connection.h" /*****************************************************************************/ -typedef enum { +typedef enum _nm_packed { BACKEND_LOG = (1 << 0), BACKEND_AUDITD = (1 << 1), _BACKEND_LAST, @@ -26,10 +30,11 @@ typedef enum { } AuditBackend; typedef struct { - const char * name; - GValue value; - gboolean need_encoding; - AuditBackend backends; + const char * name; + AuditBackend backends; + bool need_encoding; + NMValueType value_type; + NMValueTypUnion value; } AuditField; /*****************************************************************************/ @@ -85,66 +90,77 @@ _audit_field_init_string(AuditField * field, gboolean need_encoding, AuditBackend backends) { - field->name = name; - field->need_encoding = need_encoding; - field->backends = backends; - g_value_init(&field->value, G_TYPE_STRING); - g_value_set_static_string(&field->value, str); + *field = (AuditField){ + .name = name, + .need_encoding = need_encoding, + .backends = backends, + .value_type = NM_VALUE_TYPE_STRING, + .value.v_string = str, + }; } static void -_audit_field_init_uint(AuditField *field, const char *name, uint val, AuditBackend backends) +_audit_field_init_uint64(AuditField *field, const char *name, guint64 val, AuditBackend backends) { - field->name = name; - field->backends = backends; - g_value_init(&field->value, G_TYPE_UINT); - g_value_set_uint(&field->value, val); + *field = (AuditField){ + .name = name, + .backends = backends, + .value_type = NM_VALUE_TYPE_UINT64, + .value.v_uint64 = val, + }; } -static char * -build_message(GPtrArray *fields, AuditBackend backend) +static const char * +build_message(NMStrBuf *strbuf, AuditBackend backend, GPtrArray *fields) { - GString * string; - AuditField *field; - gboolean first = TRUE; - guint i; + guint i; - string = g_string_new(NULL); + if (strbuf->len == 0) { + /* preallocate a large buffer... */ + nm_str_buf_maybe_expand(strbuf, NM_UTILS_GET_NEXT_REALLOC_SIZE_232, FALSE); + } else + nm_str_buf_reset(strbuf); for (i = 0; i < fields->len; i++) { - field = fields->pdata[i]; + const AuditField *field = fields->pdata[i]; if (!NM_FLAGS_ANY(field->backends, backend)) continue; - if (first) - first = FALSE; - else - g_string_append_c(string, ' '); + nm_str_buf_append_required_delimiter(strbuf, ' '); - if (G_VALUE_HOLDS_STRING(&field->value)) { - const char *str = g_value_get_string(&field->value); + if (field->value_type == NM_VALUE_TYPE_STRING) { + const char *str = field->value.v_string; #if HAVE_LIBAUDIT if (backend == BACKEND_AUDITD) { if (field->need_encoding) { - char *value; + gs_free char *value = NULL; value = audit_encode_nv_string(field->name, str, 0); - g_string_append(string, value); - g_free(value); + nm_str_buf_append(strbuf, value); } else - g_string_append_printf(string, "%s=%s", field->name, str); + nm_str_buf_append_printf(strbuf, "%s=%s", field->name, str); continue; } #endif /* HAVE_LIBAUDIT */ - g_string_append_printf(string, "%s=\"%s\"", field->name, str); - } else if (G_VALUE_HOLDS_UINT(&field->value)) { - g_string_append_printf(string, "%s=%u", field->name, g_value_get_uint(&field->value)); - } else - g_assert_not_reached(); + + nm_str_buf_append_printf(strbuf, "%s=\"%s\"", field->name, str); + continue; + } + + if (field->value_type == NM_VALUE_TYPE_UINT64) { + nm_str_buf_append_printf(strbuf, + "%s=%" G_GUINT64_FORMAT, + field->name, + field->value.v_uint64); + continue; + } + + g_return_val_if_reached(NULL); } - return g_string_free(string, FALSE); + + return nm_str_buf_get_str(strbuf); } static void @@ -155,10 +171,10 @@ nm_audit_log(NMAuditManager *self, const char * func, gboolean success) { + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(0, FALSE); #if HAVE_LIBAUDIT NMAuditManagerPrivate *priv; #endif - char *msg; g_return_if_fail(NM_IS_AUDIT_MANAGER(self)); @@ -166,16 +182,29 @@ nm_audit_log(NMAuditManager *self, priv = NM_AUDIT_MANAGER_GET_PRIVATE(self); if (priv->auditd_fd >= 0) { - msg = build_message(fields, BACKEND_AUDITD); - audit_log_user_message(priv->auditd_fd, AUDIT_USYS_CONFIG, msg, NULL, NULL, NULL, success); - g_free(msg); + audit_log_user_message(priv->auditd_fd, + AUDIT_USYS_CONFIG, + build_message(&strbuf, BACKEND_AUDITD, fields), + NULL, + NULL, + NULL, + success); } #endif if (nm_logging_enabled(AUDIT_LOG_LEVEL, LOGD_AUDIT)) { - msg = build_message(fields, BACKEND_LOG); - _NMLOG(AUDIT_LOG_LEVEL, LOGD_AUDIT, "%s", msg); - g_free(msg); + _nm_log_full(file, + line, + func, + !(NM_THREAD_SAFE_ON_MAIN_THREAD), + AUDIT_LOG_LEVEL, + LOGD_AUDIT, + 0, + NULL, + NULL, + "%s%s", + _NMLOG_PREFIX_NAME ": ", + build_message(&strbuf, BACKEND_LOG, fields)); } } @@ -190,9 +219,13 @@ _audit_log_helper(NMAuditManager *self, gpointer subject_context, const char * reason) { - AuditField op_field = {}, pid_field = {}, uid_field = {}; - AuditField result_field = {}, reason_field = {}; - gulong pid, uid; + AuditField op_field; + AuditField pid_field; + AuditField uid_field; + AuditField result_field; + AuditField reason_field; + gulong pid; + gulong uid; NMAuthSubject * subject = NULL; gs_unref_object NMAuthSubject *subject_free = NULL; @@ -213,11 +246,11 @@ _audit_log_helper(NMAuditManager *self, pid = nm_auth_subject_get_unix_process_pid(subject); uid = nm_auth_subject_get_unix_process_uid(subject); if (pid != G_MAXULONG) { - _audit_field_init_uint(&pid_field, "pid", pid, BACKEND_ALL); + _audit_field_init_uint64(&pid_field, "pid", pid, BACKEND_ALL); g_ptr_array_add(fields, &pid_field); } if (uid != G_MAXULONG) { - _audit_field_init_uint(&uid_field, "uid", uid, BACKEND_ALL); + _audit_field_init_uint64(&uid_field, "uid", uid, BACKEND_ALL); g_ptr_array_add(fields, &uid_field); } } @@ -262,8 +295,10 @@ _nm_audit_manager_log_connection_op(NMAuditManager * self, gpointer subject_context, const char * reason) { - gs_unref_ptrarray GPtrArray *fields = NULL; - AuditField uuid_field = {}, name_field = {}, args_field = {}; + gs_unref_ptrarray GPtrArray *fields = NULL; + AuditField uuid_field; + AuditField name_field; + AuditField args_field; g_return_if_fail(op); @@ -304,8 +339,8 @@ _nm_audit_manager_log_generic_op(NMAuditManager *self, gpointer subject_context, const char * reason) { - gs_unref_ptrarray GPtrArray *fields = NULL; - AuditField arg_field = {}; + gs_unref_ptrarray GPtrArray *fields = NULL; + AuditField arg_field; g_return_if_fail(op); g_return_if_fail(arg); @@ -330,8 +365,10 @@ _nm_audit_manager_log_device_op(NMAuditManager *self, gpointer subject_context, const char * reason) { - gs_unref_ptrarray GPtrArray *fields = NULL; - AuditField interface_field = {}, ifindex_field = {}, args_field = {}; + gs_unref_ptrarray GPtrArray *fields = NULL; + AuditField interface_field; + AuditField ifindex_field; + AuditField args_field; int ifindex; g_return_if_fail(op); @@ -348,7 +385,7 @@ _nm_audit_manager_log_device_op(NMAuditManager *self, ifindex = nm_device_get_ip_ifindex(device); if (ifindex > 0) { - _audit_field_init_uint(&ifindex_field, "ifindex", ifindex, BACKEND_ALL); + _audit_field_init_uint64(&ifindex_field, "ifindex", ifindex, BACKEND_ALL); g_ptr_array_add(fields, &ifindex_field); } diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 68c315cbc3..1357dd4ae4 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -7100,6 +7100,85 @@ typedef struct { #define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied" +static const char * +_dbus_set_property_audit_log_get_args(NMDBusObject *obj, + const char * property_name, + GVariant * value, + char ** str_to_free) +{ + nm_assert(str_to_free && !*str_to_free); + + /* We assert here that the property is one of the few expected ones. + * + * Future properties should not made writable! Add a D-Bus method instead, + * they are more flexible (for example, you can set multiple properties at + * once). */ + + if (NM_IS_DEVICE(obj)) { + nm_assert(NM_IN_STRSET(property_name, + NM_DEVICE_MANAGED, + NM_DEVICE_AUTOCONNECT, + NM_DEVICE_STATISTICS_REFRESH_RATE_MS)); + return (*str_to_free = g_variant_print(value, FALSE)); + } + + nm_assert(NM_IS_MANAGER(obj)); + if (NM_IN_STRSET(property_name, + NM_MANAGER_WIRELESS_ENABLED, + NM_MANAGER_WWAN_ENABLED, + NM_MANAGER_WIMAX_ENABLED, + NM_MANAGER_CONNECTIVITY_CHECK_ENABLED)) { + return (*str_to_free = g_strdup_printf("%s:%s", + property_name, + g_variant_get_boolean(value) ? "on" : "off")); + } + if (NM_IN_STRSET(property_name, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) { + return NM_MANAGER_GLOBAL_DNS_CONFIGURATION; + } + + return nm_assert_unreachable_val("???"); +} + +/* this is a macro to catch the caller's line number. */ +#define _dbus_set_property_audit_log(obj, \ + audit_op, \ + auth_subject, \ + property_name, \ + value, \ + error_message) \ + G_STMT_START \ + { \ + NMDBusObject *const _obj = (obj); \ + const char *const _audit_op = (audit_op); \ + NMAuthSubject *const _auth_subject = (auth_subject); \ + const char *const _property_name = (property_name); \ + GVariant *const _value = (value); \ + const char *const _error_message = (error_message); \ + gs_free char * _args_to_free = NULL; \ + \ + if (NM_IS_DEVICE(_obj)) { \ + nm_audit_log_device_op(_audit_op, \ + NM_DEVICE(_obj), \ + !_error_message, \ + _dbus_set_property_audit_log_get_args(_obj, \ + _property_name, \ + _value, \ + &_args_to_free), \ + _auth_subject, \ + _error_message); \ + } else { \ + nm_audit_log_control_op(_audit_op, \ + _dbus_set_property_audit_log_get_args(_obj, \ + _property_name, \ + _value, \ + &_args_to_free), \ + !_error_message, \ + _auth_subject, \ + _error_message); \ + } \ + } \ + G_STMT_END + static void _dbus_set_property_auth_cb(NMAuthChain * chain, GDBusMethodInvocation *invocation, @@ -7157,11 +7236,13 @@ _dbus_set_property_auth_cb(NMAuthChain * chain, g_value_unset(&gvalue); out: - nm_audit_log_control_op(property_info->writable.audit_op, - property_info->property_name, - !error_message, - nm_auth_chain_get_subject(chain), - error_message); + _dbus_set_property_audit_log(obj, + property_info->writable.audit_op, + nm_auth_chain_get_subject(chain), + property_info->property_name, + value, + error_message); + if (error_message) g_dbus_method_invocation_return_dbus_error(invocation, error_name, error_message); else @@ -7185,10 +7266,27 @@ nm_manager_dbus_set_property_handle(NMDBusObject * obj, gs_unref_object NMAuthSubject *subject = NULL; DBusSetPropertyHandle * handle_data; + /* we only have writable properties on Device or Manager. In the future, + * we probably should not add new API with writable properties. Add + * methods instead. Systemd also avoids writable properties. */ + nm_assert(obj == (gpointer) self || NM_IS_DEVICE(obj)); + subject = nm_dbus_manager_new_auth_subject_from_context(invocation); if (!subject) { error_message = NM_UTILS_ERROR_MSG_REQ_UID_UKNOWN; - goto err; + + _dbus_set_property_audit_log(obj, + property_info->writable.audit_op, + NULL, + property_info->property_name, + value, + error_message); + + g_dbus_method_invocation_return_error_literal(invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_AUTH_FAILED, + error_message); + return; } handle_data = g_slice_new0(DBusSetPropertyHandle); @@ -7202,18 +7300,6 @@ nm_manager_dbus_set_property_handle(NMDBusObject * obj, chain = nm_auth_chain_new_subject(subject, invocation, _dbus_set_property_auth_cb, handle_data); c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain)); nm_auth_chain_add_call_unsafe(chain, property_info->writable.permission, TRUE); - return; - -err: - nm_audit_log_control_op(property_info->writable.audit_op, - property_info->property_name, - FALSE, - invocation, - error_message); - g_dbus_method_invocation_return_error_literal(invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_AUTH_FAILED, - error_message); } /*****************************************************************************/ diff --git a/src/core/systemd/meson.build b/src/core/systemd/meson.build index 4a90dfb591..fb1e812fa4 100644 --- a/src/core/systemd/meson.build +++ b/src/core/systemd/meson.build @@ -19,6 +19,7 @@ libnm_systemd_core = static_library( 'src/libsystemd-network/dhcp6-option.c', 'src/libsystemd-network/lldp-neighbor.c', 'src/libsystemd-network/lldp-network.c', + 'src/libsystemd-network/network-common.c', 'src/libsystemd-network/network-internal.c', 'src/libsystemd-network/sd-dhcp-client.c', 'src/libsystemd-network/sd-dhcp-lease.c', diff --git a/src/core/systemd/src/libsystemd-network/dhcp-internal.h b/src/core/systemd/src/libsystemd-network/dhcp-internal.h index 40e6b1f26f..c5c851c575 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp-internal.h +++ b/src/core/systemd/src/libsystemd-network/dhcp-internal.h @@ -12,6 +12,7 @@ #include "sd-dhcp-client.h" #include "dhcp-protocol.h" +#include "log-link.h" #include "socket-util.h" typedef struct sd_dhcp_option { @@ -65,5 +66,15 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui #define DHCP_CLIENT_DONT_DESTROY(client) \ _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) -#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) -#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) +#define log_dhcp_client_errno(client, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_dhcp_client_get_ifname(client), \ + LOG_DEBUG, _e, "DHCPv4 client: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_dhcp_client(client, fmt, ...) \ + log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/dhcp6-internal.h b/src/core/systemd/src/libsystemd-network/dhcp6-internal.h index 681c462315..274b14b056 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp6-internal.h +++ b/src/core/systemd/src/libsystemd-network/dhcp6-internal.h @@ -9,9 +9,11 @@ #include <netinet/in.h> #include "sd-event.h" +#include "sd-dhcp6-client.h" -#include "list.h" #include "hashmap.h" +#include "list.h" +#include "log-link.h" #include "macro.h" #include "sparse-endian.h" @@ -78,7 +80,7 @@ struct ia_ta { be32_t id; } _packed_; -struct DHCP6IA { +typedef struct DHCP6IA { uint16_t type; union { struct ia_na ia_na; @@ -87,12 +89,7 @@ struct DHCP6IA { }; LIST_HEAD(DHCP6Address, addresses); -}; - -typedef struct DHCP6IA DHCP6IA; - -#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) -#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__) +} DHCP6IA; int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, size_t optlen, const void *optval); @@ -105,7 +102,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen, uint8_t **optvalue); int dhcp6_option_parse_status(DHCP6Option *option, size_t len); -int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code); +int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code); int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, struct in6_addr **addrs, size_t count, size_t *allocated); @@ -121,3 +118,16 @@ const char *dhcp6_message_type_to_string(int s) _const_; int dhcp6_message_type_from_string(const char *s) _pure_; const char *dhcp6_message_status_to_string(int s) _const_; int dhcp6_message_status_from_string(const char *s) _pure_; + +#define log_dhcp6_client_errno(client, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_dhcp6_client_get_ifname(client), \ + LOG_DEBUG, _e, "DHCPv6 client: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_dhcp6_client(client, fmt, ...) \ + log_dhcp6_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/dhcp6-option.c b/src/core/systemd/src/libsystemd-network/dhcp6-option.c index c71ef6a521..d50ce3db28 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/core/systemd/src/libsystemd-network/dhcp6-option.c @@ -427,7 +427,7 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) { return be16toh(statusopt->status); } -static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { +static int dhcp6_option_parse_address(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option; DHCP6Address *addr; uint32_t lt_valid, lt_pref; @@ -439,23 +439,20 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t lt_valid = be32toh(addr_option->iaaddr.lifetime_valid); lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred); - if (lt_valid == 0 || lt_pref > lt_valid) { - log_dhcp6_client(client, - "Valid lifetime of an IA address is zero or " - "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, - lt_pref, lt_valid); - return -EINVAL; - } + if (lt_valid == 0 || lt_pref > lt_valid) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Valid lifetime of an IA address is zero or " + "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, + lt_pref, lt_valid); if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) { r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option)); if (r < 0) return r; - if (r > 0) { - log_dhcp6_client(client, "Non-zero status code '%s' for address is received", - dhcp6_message_status_to_string(r)); - return -EINVAL; - } + if (r > 0) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Non-zero status code '%s' for address is received", + dhcp6_message_status_to_string(r)); } addr = new0(DHCP6Address, 1); @@ -472,7 +469,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t return 0; } -static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { +static int dhcp6_option_parse_pdprefix(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option; DHCP6Address *prefix; uint32_t lt_valid, lt_pref; @@ -484,23 +481,20 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_ lt_valid = be32toh(pdprefix_option->iapdprefix.lifetime_valid); lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred); - if (lt_valid == 0 || lt_pref > lt_valid) { - log_dhcp6_client(client, - "Valid lifetieme of a PD prefix is zero or " - "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, - lt_pref, lt_valid); - return -EINVAL; - } + if (lt_valid == 0 || lt_pref > lt_valid) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Valid lifetieme of a PD prefix is zero or " + "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, + lt_pref, lt_valid); if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) { r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option)); if (r < 0) return r; - if (r > 0) { - log_dhcp6_client(client, "Non-zero status code '%s' for PD prefix is received", - dhcp6_message_status_to_string(r)); - return -EINVAL; - } + if (r > 0) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Non-zero status code '%s' for PD prefix is received", + dhcp6_message_status_to_string(r)); } prefix = new0(DHCP6Address, 1); @@ -517,7 +511,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_ return 0; } -int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) { +int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) { uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX; uint16_t iatype, optlen; size_t iaaddr_offset; @@ -543,10 +537,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat lt_t1 = be32toh(ia->ia_na.lifetime_t1); lt_t2 = be32toh(ia->ia_na.lifetime_t2); - if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { - log_dhcp6_client(client, "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2); - return -EINVAL; - } + if (lt_t1 > lt_t2) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", + lt_t1, lt_t2); break; @@ -561,10 +555,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat lt_t1 = be32toh(ia->ia_pd.lifetime_t1); lt_t2 = be32toh(ia->ia_pd.lifetime_t2); - if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { - log_dhcp6_client(client, "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2); - return -EINVAL; - } + if (lt_t1 > lt_t2) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", + lt_t1, lt_t2); break; @@ -596,12 +590,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat switch (opt) { case SD_DHCP6_OPTION_IAADDR: - if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) { - log_dhcp6_client(client, "IA Address option not in IA NA or TA option"); - return -EINVAL; - } + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA Address option not in IA NA or TA option"); - r = dhcp6_option_parse_address(option, ia, <_valid); + r = dhcp6_option_parse_address(client, option, ia, <_valid); if (r < 0 && r != -EINVAL) return r; if (r >= 0 && lt_valid < lt_min) @@ -611,12 +604,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat case SD_DHCP6_OPTION_IA_PD_PREFIX: - if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) { - log_dhcp6_client(client, "IA PD Prefix option not in IA PD option"); - return -EINVAL; - } + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA PD Prefix option not in IA PD option"); - r = dhcp6_option_parse_pdprefix(option, ia, <_valid); + r = dhcp6_option_parse_pdprefix(client, option, ia, <_valid); if (r < 0 && r != -EINVAL) return r; if (r >= 0 && lt_valid < lt_min) @@ -652,7 +644,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat switch(iatype) { case SD_DHCP6_OPTION_IA_NA: - if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2 && lt_min != UINT32_MAX) { + if (ia->ia_na.lifetime_t1 == 0 && ia->ia_na.lifetime_t2 == 0 && lt_min != UINT32_MAX) { lt_t1 = lt_min / 2; lt_t2 = lt_min / 10 * 8; ia->ia_na.lifetime_t1 = htobe32(lt_t1); @@ -665,7 +657,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat break; case SD_DHCP6_OPTION_IA_PD: - if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2 && lt_min != UINT32_MAX) { + if (ia->ia_pd.lifetime_t1 == 0 && ia->ia_pd.lifetime_t2 == 0 && lt_min != UINT32_MAX) { lt_t1 = lt_min / 2; lt_t2 = lt_min / 10 * 8; ia->ia_pd.lifetime_t1 = htobe32(lt_t1); diff --git a/src/core/systemd/src/libsystemd-network/lldp-internal.h b/src/core/systemd/src/libsystemd-network/lldp-internal.h index daedbb088f..f13555d35c 100644 --- a/src/core/systemd/src/libsystemd-network/lldp-internal.h +++ b/src/core/systemd/src/libsystemd-network/lldp-internal.h @@ -5,13 +5,14 @@ #include "sd-lldp.h" #include "hashmap.h" -#include "log.h" +#include "log-link.h" #include "prioq.h" struct sd_lldp { unsigned n_ref; int ifindex; + char *ifname; int fd; sd_event *event; @@ -32,8 +33,18 @@ struct sd_lldp { struct ether_addr filter_address; }; -#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) -#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__) - const char* lldp_event_to_string(sd_lldp_event_t e) _const_; sd_lldp_event_t lldp_event_from_string(const char *s) _pure_; + +#define log_lldp_errno(lldp, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_lldp_get_ifname(lldp), \ + LOG_DEBUG, _e, "LLDP: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_lldp(lldp, fmt, ...) \ + log_lldp_errno(lldp, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/lldp-neighbor.c b/src/core/systemd/src/libsystemd-network/lldp-neighbor.c index 58ff0e0fbc..1b2108d8b1 100644 --- a/src/core/systemd/src/libsystemd-network/lldp-neighbor.c +++ b/src/core/systemd/src/libsystemd-network/lldp-neighbor.c @@ -114,7 +114,7 @@ sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) { return n; } -static int parse_string(char **s, const void *q, size_t n) { +static int parse_string(sd_lldp *lldp, char **s, const void *q, size_t n) { const char *p = q; char *k; @@ -122,7 +122,7 @@ static int parse_string(char **s, const void *q, size_t n) { assert(p || n == 0); if (*s) { - log_lldp("Found duplicate string, ignoring field."); + log_lldp(lldp, "Found duplicate string, ignoring field."); return 0; } @@ -135,14 +135,14 @@ static int parse_string(char **s, const void *q, size_t n) { /* Look for inner NULs */ if (memchr(p, 0, n)) { - log_lldp("Found inner NUL in string, ignoring field."); + log_lldp(lldp, "Found inner NUL in string, ignoring field."); return 0; } /* Let's escape weird chars, for security reasons */ k = cescape_length(p, n); if (!k) - return -ENOMEM; + return log_oom_debug(); free(*s); *s = k; @@ -158,27 +158,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { assert(n); - if (n->raw_size < sizeof(struct ether_header)) { - log_lldp("Received truncated packet, ignoring."); - return -EBADMSG; - } + if (n->raw_size < sizeof(struct ether_header)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received truncated packet, ignoring."); memcpy(&h, LLDP_NEIGHBOR_RAW(n), sizeof(h)); - if (h.ether_type != htobe16(ETHERTYPE_LLDP)) { - log_lldp("Received packet with wrong type, ignoring."); - return -EBADMSG; - } + if (h.ether_type != htobe16(ETHERTYPE_LLDP)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received packet with wrong type, ignoring."); if (h.ether_dhost[0] != 0x01 || h.ether_dhost[1] != 0x80 || h.ether_dhost[2] != 0xc2 || h.ether_dhost[3] != 0x00 || h.ether_dhost[4] != 0x00 || - !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) { - log_lldp("Received packet with wrong destination address, ignoring."); - return -EBADMSG; - } + !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received packet with wrong destination address, ignoring."); memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr)); memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr)); @@ -190,27 +187,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { uint8_t type; uint16_t length; - if (left < 2) { - log_lldp("TLV lacks header, ignoring."); - return -EBADMSG; - } + if (left < 2) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TLV lacks header, ignoring."); type = p[0] >> 1; length = p[1] + (((uint16_t) (p[0] & 1)) << 8); p += 2, left -= 2; - if (left < length) { - log_lldp("TLV truncated, ignoring datagram."); - return -EBADMSG; - } + if (left < length) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TLV truncated, ignoring datagram."); switch (type) { case SD_LLDP_TYPE_END: - if (length != 0) { - log_lldp("End marker TLV not zero-sized, ignoring datagram."); - return -EBADMSG; - } + if (length != 0) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "End marker TLV not zero-sized, ignoring datagram."); /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0 * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */ @@ -218,98 +212,93 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { goto end_marker; case SD_LLDP_TYPE_CHASSIS_ID: - if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */ - log_lldp("Chassis ID field size out of range, ignoring datagram."); - return -EBADMSG; - } - if (n->id.chassis_id) { - log_lldp("Duplicate chassis ID field, ignoring datagram."); - return -EBADMSG; - } + if (length < 2 || length > 256) + /* includes the chassis subtype, hence one extra byte */ + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Chassis ID field size out of range, ignoring datagram."); + + if (n->id.chassis_id) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate chassis ID field, ignoring datagram."); n->id.chassis_id = memdup(p, length); if (!n->id.chassis_id) - return -ENOMEM; + return log_oom_debug(); n->id.chassis_id_size = length; break; case SD_LLDP_TYPE_PORT_ID: - if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */ - log_lldp("Port ID field size out of range, ignoring datagram."); - return -EBADMSG; - } - if (n->id.port_id) { - log_lldp("Duplicate port ID field, ignoring datagram."); - return -EBADMSG; - } + if (length < 2 || length > 256) + /* includes the port subtype, hence one extra byte */ + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Port ID field size out of range, ignoring datagram."); + + if (n->id.port_id) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate port ID field, ignoring datagram."); n->id.port_id = memdup(p, length); if (!n->id.port_id) - return -ENOMEM; + return log_oom_debug(); n->id.port_id_size = length; break; case SD_LLDP_TYPE_TTL: - if (length != 2) { - log_lldp("TTL field has wrong size, ignoring datagram."); - return -EBADMSG; - } + if (length != 2) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TTL field has wrong size, ignoring datagram."); - if (n->has_ttl) { - log_lldp("Duplicate TTL field, ignoring datagram."); - return -EBADMSG; - } + if (n->has_ttl) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate TTL field, ignoring datagram."); n->ttl = unaligned_read_be16(p); n->has_ttl = true; break; case SD_LLDP_TYPE_PORT_DESCRIPTION: - r = parse_string(&n->port_description, p, length); + r = parse_string(n->lldp, &n->port_description, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_NAME: - r = parse_string(&n->system_name, p, length); + r = parse_string(n->lldp, &n->system_name, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_DESCRIPTION: - r = parse_string(&n->system_description, p, length); + r = parse_string(n->lldp, &n->system_description, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_CAPABILITIES: if (length != 4) - log_lldp("System capabilities field has wrong size, ignoring."); - else { - n->system_capabilities = unaligned_read_be16(p); - n->enabled_capabilities = unaligned_read_be16(p + 2); - n->has_capabilities = true; - } + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "System capabilities field has wrong size."); + n->system_capabilities = unaligned_read_be16(p); + n->enabled_capabilities = unaligned_read_be16(p + 2); + n->has_capabilities = true; break; - case SD_LLDP_TYPE_PRIVATE: { + case SD_LLDP_TYPE_PRIVATE: if (length < 4) - log_lldp("Found private TLV that is too short, ignoring."); - else { - /* RFC 8520: MUD URL */ - if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 && - p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) { - r = parse_string(&n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1, - length - 1 - sizeof(SD_LLDP_OUI_MUD)); - if (r < 0) - return r; - } + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Found private TLV that is too short, ignoring."); + + /* RFC 8520: MUD URL */ + if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 && + p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) { + r = parse_string(n->lldp, &n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1, + length - 1 - sizeof(SD_LLDP_OUI_MUD)); + if (r < 0) + return r; } - } - break; } @@ -317,11 +306,9 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { } end_marker: - if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) { - log_lldp("One or more mandatory TLV missing in datagram. Ignoring."); - return -EBADMSG; - - } + if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "One or more mandatory TLV missing in datagram. Ignoring."); n->rindex = sizeof(struct ether_header); diff --git a/src/core/systemd/src/libsystemd-network/network-common.c b/src/core/systemd/src/libsystemd-network/network-common.c new file mode 100644 index 0000000000..b9494c154c --- /dev/null +++ b/src/core/systemd/src/libsystemd-network/network-common.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-core.h" + +#include "format-util.h" +#include "network-common.h" +#include "string-util.h" + +const char *get_ifname(int ifindex, char **ifname) { + char buf[IF_NAMESIZE + 1]; + + assert(ifname); + + /* This sets ifname only when it is not set yet. */ + + if (*ifname) + return *ifname; + + if (ifindex <= 0) + return NULL; + + if (!format_ifname(ifindex, buf)) + return NULL; + + return *ifname = strdup(buf); +} diff --git a/src/core/systemd/src/libsystemd-network/network-common.h b/src/core/systemd/src/libsystemd-network/network-common.h new file mode 100644 index 0000000000..76a6c4a989 --- /dev/null +++ b/src/core/systemd/src/libsystemd-network/network-common.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +const char *get_ifname(int ifindex, char **ifname); diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c index f9875e62a7..91ef7b2c41 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -26,6 +26,7 @@ #include "hostname-util.h" #include "io-util.h" #include "memory-util.h" +#include "network-common.h" #include "random-util.h" #include "set.h" #include "sort-util.h" @@ -78,6 +79,7 @@ struct sd_dhcp_client { int event_priority; sd_event_source *timeout_resend; int ifindex; + char *ifname; int fd; uint16_t port; union sockaddr_union link; @@ -284,6 +286,23 @@ int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) { return 0; } +int sd_dhcp_client_set_ifname(sd_dhcp_client *client, const char *ifname) { + assert_return(client, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&client->ifname, ifname); +} + +const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client) { + if (!client) + return NULL; + + return get_ifname(client->ifindex, &client->ifname); +} + int sd_dhcp_client_set_mac( sd_dhcp_client *client, const uint8_t *addr, @@ -2210,6 +2229,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) { client->user_class = strv_free(client->user_class); ordered_hashmap_free(client->extra_options); ordered_hashmap_free(client->vendor_options); + free(client->ifname); return mfree(client); } diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c index e6373dab18..240d1697a3 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -27,6 +27,7 @@ #include "hexdecoct.h" #include "hostname-util.h" #include "in-addr-util.h" +#include "network-common.h" #include "random-util.h" #include "socket-util.h" #include "string-table.h" @@ -53,6 +54,7 @@ struct sd_dhcp6_client { sd_event *event; int event_priority; int ifindex; + char *ifname; DHCP6Address hint_pd_prefix; struct in6_addr local_address; uint8_t mac_addr[MAX_MAC_ADDR_LEN]; @@ -171,6 +173,23 @@ int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) { return 0; } +int sd_dhcp6_client_set_ifname(sd_dhcp6_client *client, const char *ifname) { + assert_return(client, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&client->ifname, ifname); +} + +const char *sd_dhcp6_client_get_ifname(sd_dhcp6_client *client) { + if (!client) + return NULL; + + return get_ifname(client->ifindex, &client->ifname); +} + int sd_dhcp6_client_set_local_address( sd_dhcp6_client *client, const struct in6_addr *local_address) { @@ -1182,7 +1201,7 @@ static int client_parse_message( break; } - r = dhcp6_option_parse_ia(option, &lease->ia, &ia_na_status); + r = dhcp6_option_parse_ia(client, option, &lease->ia, &ia_na_status); if (r < 0 && r != -ENOMSG) return r; @@ -1215,7 +1234,7 @@ static int client_parse_message( break; } - r = dhcp6_option_parse_ia(option, &lease->pd, &ia_pd_status); + r = dhcp6_option_parse_ia(client, option, &lease->pd, &ia_pd_status); if (r < 0 && r != -ENOMSG) return r; @@ -1797,6 +1816,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { ordered_hashmap_free(client->extra_options); strv_free(client->user_class); strv_free(client->vendor_class); + free(client->ifname); return mfree(client); } diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c index 5792f6882d..d40fbbb727 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c @@ -208,7 +208,7 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) { lease->dns_count, &lease->dns_allocated); if (r < 0) - return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m"); + return r; lease->dns_count = r; @@ -323,19 +323,16 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) if (!optlen) return 0; - if (lease->ntp || lease->ntp_fqdn) { - log_dhcp6_client(client, "NTP information already provided"); + if (lease->ntp || lease->ntp_fqdn) + return -EEXIST; - return 0; - } - - log_dhcp6_client(client, "Using deprecated SNTP information"); + /* Using deprecated SNTP information */ r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp, lease->ntp_count, &lease->ntp_allocated); if (r < 0) - return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m"); + return r; lease->ntp_count = r; diff --git a/src/core/systemd/src/libsystemd-network/sd-lldp.c b/src/core/systemd/src/libsystemd-network/sd-lldp.c index 4e01652efc..09c2052f91 100644 --- a/src/core/systemd/src/libsystemd-network/sd-lldp.c +++ b/src/core/systemd/src/libsystemd-network/sd-lldp.c @@ -16,6 +16,7 @@ #include "lldp-neighbor.h" #include "lldp-network.h" #include "memory-util.h" +#include "network-common.h" #include "socket-util.h" #include "sort-util.h" #include "string-table.h" @@ -41,12 +42,10 @@ static void lldp_callback(sd_lldp *lldp, sd_lldp_event_t event, sd_lldp_neighbor assert(lldp); assert(event >= 0 && event < _SD_LLDP_EVENT_MAX); - if (!lldp->callback) { - log_lldp("Received '%s' event.", lldp_event_to_string(event)); - return; - } + if (!lldp->callback) + return (void) log_lldp(lldp, "Received '%s' event.", lldp_event_to_string(event)); - log_lldp("Invoking callback for '%s' event.", lldp_event_to_string(event)); + log_lldp(lldp, "Invoking callback for '%s' event.", lldp_event_to_string(event)); lldp->callback(lldp, event, n, lldp->userdata); } @@ -188,11 +187,11 @@ static int lldp_handle_datagram(sd_lldp *lldp, sd_lldp_neighbor *n) { r = lldp_add_neighbor(lldp, n); if (r < 0) { - log_lldp_errno(r, "Failed to add datagram. Ignoring."); + log_lldp_errno(lldp, r, "Failed to add datagram. Ignoring."); return 0; } - log_lldp("Successfully processed LLDP datagram."); + log_lldp(lldp, "Successfully processed LLDP datagram."); return 0; } @@ -206,8 +205,10 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v assert(lldp); space = next_datagram_size_fd(fd); - if (space < 0) - return log_lldp_errno(space, "Failed to determine datagram size to read: %m"); + if (space < 0) { + log_lldp_errno(lldp, space, "Failed to determine datagram size to read, ignoring: %m"); + return 0; + } n = lldp_neighbor_new(space); if (!n) @@ -218,12 +219,13 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v if (IN_SET(errno, EAGAIN, EINTR)) return 0; - return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); + log_lldp_errno(lldp, errno, "Failed to read LLDP datagram, ignoring: %m"); + return 0; } if ((size_t) length != n->raw_size) { - log_lldp("Packet size mismatch."); - return -EINVAL; + log_lldp(lldp, "Packet size mismatch, ignoring"); + return 0; } /* Try to get the timestamp of this packet if it is known */ @@ -269,7 +271,7 @@ _public_ int sd_lldp_start(sd_lldp *lldp) { (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io"); - log_lldp("Started LLDP client"); + log_lldp(lldp, "Started LLDP client"); return 1; fail: @@ -284,7 +286,7 @@ _public_ int sd_lldp_stop(sd_lldp *lldp) { if (lldp->fd < 0) return 0; - log_lldp("Stopping LLDP client"); + log_lldp(lldp, "Stopping LLDP client"); lldp_reset(lldp); lldp_flush_neighbors(lldp); @@ -345,6 +347,23 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) { return 0; } +int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname) { + assert_return(lldp, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&lldp->ifname, ifname); +} + +const char *sd_lldp_get_ifname(sd_lldp *lldp) { + if (!lldp) + return NULL; + + return get_ifname(lldp->ifindex, &lldp->ifname); +} + static sd_lldp* lldp_free(sd_lldp *lldp) { assert(lldp); @@ -356,6 +375,7 @@ static sd_lldp* lldp_free(sd_lldp *lldp) { hashmap_free(lldp->neighbor_by_id); prioq_free(lldp->neighbor_by_expiry); + free(lldp->ifname); return mfree(lldp); } @@ -400,12 +420,16 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) { int r; r = lldp_make_space(lldp, 0); - if (r < 0) - return log_lldp_errno(r, "Failed to make space: %m"); + if (r < 0) { + log_lldp_errno(lldp, r, "Failed to make space, ignoring: %m"); + return 0; + } r = lldp_start_timer(lldp, NULL); - if (r < 0) - return log_lldp_errno(r, "Failed to restart timer: %m"); + if (r < 0) { + log_lldp_errno(lldp, r, "Failed to restart timer, ignoring: %m"); + return 0; + } return 0; } diff --git a/src/core/systemd/src/systemd/sd-dhcp-client.h b/src/core/systemd/src/systemd/sd-dhcp-client.h index 822286919e..c784cbcb9a 100644 --- a/src/core/systemd/src/systemd/sd-dhcp-client.h +++ b/src/core/systemd/src/systemd/sd-dhcp-client.h @@ -125,6 +125,10 @@ int sd_dhcp_client_set_request_broadcast( int sd_dhcp_client_set_ifindex( sd_dhcp_client *client, int interface_index); +int sd_dhcp_client_set_ifname( + sd_dhcp_client *client, + const char *interface_name); +const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client); int sd_dhcp_client_set_mac( sd_dhcp_client *client, const uint8_t *addr, diff --git a/src/core/systemd/src/systemd/sd-dhcp6-client.h b/src/core/systemd/src/systemd/sd-dhcp6-client.h index 84e3170130..e02d67632a 100644 --- a/src/core/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/core/systemd/src/systemd/sd-dhcp6-client.h @@ -91,6 +91,10 @@ int sd_dhcp6_client_set_callback( int sd_dhcp6_client_set_ifindex( sd_dhcp6_client *client, int interface_index); +int sd_dhcp6_client_set_ifname( + sd_dhcp6_client *client, + const char *interface_name); +const char * sd_dhcp6_client_get_ifname(sd_dhcp6_client *client); int sd_dhcp6_client_set_local_address( sd_dhcp6_client *client, const struct in6_addr *local_address); diff --git a/src/core/systemd/src/systemd/sd-lldp.h b/src/core/systemd/src/systemd/sd-lldp.h index e48e29fbc0..64047ee817 100644 --- a/src/core/systemd/src/systemd/sd-lldp.h +++ b/src/core/systemd/src/systemd/sd-lldp.h @@ -147,6 +147,8 @@ sd_event *sd_lldp_get_event(sd_lldp *lldp); int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata); int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex); +int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname); +const char *sd_lldp_get_ifname(sd_lldp *lldp); /* Controls how much and what to store in the neighbors database */ int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n); diff --git a/src/core/systemd/src/systemd/sd-ndisc.h b/src/core/systemd/src/systemd/sd-ndisc.h index 49b127c018..6088def1b6 100644 --- a/src/core/systemd/src/systemd/sd-ndisc.h +++ b/src/core/systemd/src/systemd/sd-ndisc.h @@ -78,6 +78,8 @@ sd_event *sd_ndisc_get_event(sd_ndisc *nd); int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata); int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index); +int sd_ndisc_set_ifname(sd_ndisc *nd, const char *interface_name); +const char *sd_ndisc_get_ifname(sd_ndisc *nd); int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *ret); diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index dd5f7d4889..ee0d88a0db 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -1394,7 +1394,7 @@ nm_device_get_autoconnect(NMDevice *device) * 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. + * 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. **/ @@ -1408,7 +1408,7 @@ nm_device_set_autoconnect(NMDevice *device, gboolean autoconnect) _nm_client_set_property_sync_legacy(_nm_object_get_client(device), _nm_object_get_path(device), NM_DBUS_INTERFACE_DEVICE, - "AutoConnect", + "Autoconnect", "b", autoconnect); } diff --git a/src/libnm-glib-aux/nm-json-aux.h b/src/libnm-glib-aux/nm-json-aux.h index 99759a8d27..1a4b539524 100644 --- a/src/libnm-glib-aux/nm-json-aux.h +++ b/src/libnm-glib-aux/nm-json-aux.h @@ -33,6 +33,12 @@ nm_json_gstr_append_int64(GString *gstr, gint64 v) g_string_append_printf(gstr, "%" G_GINT64_FORMAT, v); } +static inline void +nm_json_gstr_append_uint64(GString *gstr, guint64 v) +{ + g_string_append_printf(gstr, "%" G_GUINT64_FORMAT, v); +} + void nm_json_gstr_append_obj_name(GString *gstr, const char *key, char start_container); /*****************************************************************************/ @@ -240,6 +246,44 @@ nm_jansson_json_as_int(const NMJsonVt *vt, const nm_json_t *elem, int *out_val) } static inline int +nm_jansson_json_as_int64(const NMJsonVt *vt, const nm_json_t *elem, gint64 *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 < G_MININT64 || v > G_MAXINT64) + return -ERANGE; + + NM_SET_OUT(out_val, v); + return 1; +} + +static inline int +nm_jansson_json_as_uint64(const NMJsonVt *vt, const nm_json_t *elem, guint64 *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 < 0 || v > G_MAXUINT64) + 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) @@ -272,6 +316,12 @@ nm_value_type_to_json(NMValueType value_type, GString *gstr, gconstpointer p_fie case NM_VALUE_TYPE_INT: nm_json_gstr_append_int64(gstr, *((const int *) p_field)); return; + case NM_VALUE_TYPE_INT64: + nm_json_gstr_append_int64(gstr, *((const gint64 *) p_field)); + return; + case NM_VALUE_TYPE_UINT64: + nm_json_gstr_append_uint64(gstr, *((const guint64 *) p_field)); + return; case NM_VALUE_TYPE_STRING: nm_json_gstr_append_string(gstr, *((const char *const *) p_field)); return; @@ -294,6 +344,10 @@ nm_value_type_from_json(const NMJsonVt * vt, 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); + case NM_VALUE_TYPE_INT64: + return (nm_jansson_json_as_int64(vt, elem, out_val) > 0); + case NM_VALUE_TYPE_UINT64: + return (nm_jansson_json_as_uint64(vt, elem, out_val) > 0); /* warning: this overwrites/leaks the previous value. You better have *out_val * point to uninitialized memory or NULL. */ diff --git a/src/libnm-glib-aux/nm-logging-fwd.h b/src/libnm-glib-aux/nm-logging-fwd.h index df0bb161e1..0ede91b2bc 100644 --- a/src/libnm-glib-aux/nm-logging-fwd.h +++ b/src/libnm-glib-aux/nm-logging-fwd.h @@ -93,6 +93,8 @@ void _nm_log_impl(const char *file, const char *fmt, ...) _nm_printf(10, 11); +#define _nm_log_full(...) _nm_log_impl(__VA_ARGS__) + static inline NMLogLevel nm_log_level_from_syslog(int syslog_level) { diff --git a/src/libnm-glib-aux/nm-macros-internal.h b/src/libnm-glib-aux/nm-macros-internal.h index fb16ddc703..cc3b19c3a1 100644 --- a/src/libnm-glib-aux/nm-macros-internal.h +++ b/src/libnm-glib-aux/nm-macros-internal.h @@ -1275,8 +1275,14 @@ default: \ (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_ANY(flags, check) (((flags) & (check)) != 0) + +#define NM_FLAGS_ALL(flags, check) \ + ({ \ + const typeof(check) _check = (check); \ + \ + (((flags) & (_check)) == (_check)); \ + }) #define NM_FLAGS_SET(flags, val) \ ({ \ @@ -1831,6 +1837,19 @@ nm_decode_version(guint version, guint *major, guint *minor, guint *micro) /*****************************************************************************/ +#define nm_va_args_one_ptr(last) \ + ({ \ + va_list _va_args; \ + gpointer _ptr; \ + \ + va_start(_va_args, (last)); \ + _ptr = va_arg(_va_args, gpointer); \ + va_end(_va_args); \ + _ptr; \ + }) + +/*****************************************************************************/ + #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_, diff --git a/src/libnm-glib-aux/nm-value-type.h b/src/libnm-glib-aux/nm-value-type.h index f9edebdb6c..f1cce4800b 100644 --- a/src/libnm-glib-aux/nm-value-type.h +++ b/src/libnm-glib-aux/nm-value-type.h @@ -6,12 +6,14 @@ #ifndef __NM_VALUE_TYPE_H__ #define __NM_VALUE_TYPE_H__ -typedef enum { +typedef enum _nm_packed { 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, + NM_VALUE_TYPE_INT64 = 5, + NM_VALUE_TYPE_UINT64 = 6, + NM_VALUE_TYPE_STRING = 7, } NMValueType; /*****************************************************************************/ @@ -21,6 +23,8 @@ typedef enum { typedef union { bool v_bool; gint32 v_int32; + gint64 v_int64; + guint64 v_uint64; int v_int; const char *v_string; @@ -78,6 +82,12 @@ nm_value_type_cmp(NMValueType value_type, gconstpointer p_a, gconstpointer p_b) case NM_VALUE_TYPE_INT: NM_CMP_DIRECT(*((const int *) p_a), *((const int *) p_b)); return 0; + case NM_VALUE_TYPE_INT64: + NM_CMP_DIRECT(*((const gint64 *) p_a), *((const gint64 *) p_b)); + return 0; + case NM_VALUE_TYPE_UINT64: + NM_CMP_DIRECT(*((const guint64 *) p_a), *((const guint64 *) 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: @@ -106,6 +116,12 @@ nm_value_type_copy(NMValueType value_type, gpointer dst, gconstpointer src) case NM_VALUE_TYPE_INT: (*((int *) dst) = *((const int *) src)); return; + case NM_VALUE_TYPE_INT64: + (*((gint64 *) dst) = *((const gint64 *) src)); + return; + case NM_VALUE_TYPE_UINT64: + (*((guint64 *) dst) = *((const guint64 *) src)); + return; case NM_VALUE_TYPE_STRING: /* self assignment safe! */ if (*((char **) dst) != *((const char *const *) src)) { @@ -132,6 +148,12 @@ nm_value_type_get_from_variant(NMValueType value_type, case NM_VALUE_TYPE_INT32: *((gint32 *) dst) = g_variant_get_int32(variant); return; + case NM_VALUE_TYPE_INT64: + *((gint64 *) dst) = g_variant_get_int64(variant); + return; + case NM_VALUE_TYPE_UINT64: + *((guint64 *) dst) = g_variant_get_uint64(variant); + return; case NM_VALUE_TYPE_STRING: if (clone) { g_free(*((char **) dst)); @@ -163,6 +185,10 @@ nm_value_type_to_variant(NMValueType value_type, gconstpointer src) 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_INT64: + return g_variant_new_int64(*((const gint64 *) src)); + case NM_VALUE_TYPE_UINT64: + return g_variant_new_uint64(*((const guint64 *) src)); case NM_VALUE_TYPE_STRING: v_string = *((const char *const *) src); return v_string ? g_variant_new_string(v_string) : NULL; @@ -187,6 +213,10 @@ nm_value_type_get_variant_type(NMValueType value_type) return G_VARIANT_TYPE_BOOLEAN; case NM_VALUE_TYPE_INT32: return G_VARIANT_TYPE_INT32; + case NM_VALUE_TYPE_INT64: + return G_VARIANT_TYPE_INT64; + case NM_VALUE_TYPE_UINT64: + return G_VARIANT_TYPE_UINT64; case NM_VALUE_TYPE_STRING: return G_VARIANT_TYPE_STRING; diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c index f30240b347..b290dfea9a 100644 --- a/src/libnm-glib-aux/tests/test-shared-general.c +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -720,13 +720,19 @@ test_nm_utils_get_next_realloc_size(void) {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_232, + NM_UTILS_GET_NEXT_REALLOC_SIZE_232, + NM_UTILS_GET_NEXT_REALLOC_SIZE_232}, {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_32 == 32u); + G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_40 == 40u); G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_104 == 104u); + G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_232 == 232u); G_STATIC_ASSERT_EXPR(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 == 1000u); for (i = 0; i < G_N_ELEMENTS(test_data) + 5000u; i++) { diff --git a/src/libnm-log-core/nm-logging.h b/src/libnm-log-core/nm-logging.h index 574c225c2e..8eecb7e41b 100644 --- a/src/libnm-log-core/nm-logging.h +++ b/src/libnm-log-core/nm-logging.h @@ -26,24 +26,20 @@ //#define _NM_LOG_FUNC G_STRFUNC #define _NM_LOG_FUNC NULL -/* A wrapper for the _nm_log_impl() function that adds call site information. +/* A wrapper for _nm_log_full() 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 + _nm_log_full(__FILE__, \ + __LINE__, \ + _NM_LOG_FUNC, \ + (mt_require_locking), \ + (level), \ + (domain), \ + (error), \ + (ifname), \ + (con_uuid), \ + ""__VA_ARGS__) #define _nm_log(level, domain, error, ifname, con_uuid, ...) \ _nm_log_mt(!(NM_THREAD_SAFE_ON_MAIN_THREAD), \ diff --git a/src/libnm-std-aux/nm-std-utils.h b/src/libnm-std-aux/nm-std-utils.h index 9c851f1f18..76d49d2f5f 100644 --- a/src/libnm-std-aux/nm-std-utils.h +++ b/src/libnm-std-aux/nm-std-utils.h @@ -29,6 +29,7 @@ #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_232 ((size_t) 232) #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); 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 index fd8352ab69..e15032eaa2 100644 --- 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 @@ -114,6 +114,10 @@ _nm_gettid(void) #define HAVE_RT_SIGQUEUEINFO 0 #endif + #ifndef ALTIFNAMSIZ + #define ALTIFNAMSIZ 128 + #endif + #define HAVE_LINUX_TIME_TYPES_H 0 #ifndef __COMPAR_FN_T diff --git a/src/libnm-systemd-shared/src/basic/env-util.c b/src/libnm-systemd-shared/src/basic/env-util.c index 7a66eed223..a13aaac5d7 100644 --- a/src/libnm-systemd-shared/src/basic/env-util.c +++ b/src/libnm-systemd-shared/src/basic/env-util.c @@ -518,10 +518,10 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { ALTERNATE_VALUE, } state = WORD; - const char *e, *word = format, *test_value; + const char *e, *word = format, *test_value = NULL; /* test_value is initialized to appease gcc */ char *k; _cleanup_free_ char *r = NULL; - size_t i, len; + size_t i, len = 0; /* len is initialized to appease gcc */ int nest = 0; assert(format); @@ -584,13 +584,12 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { word = e+1; state = WORD; } else if (*e == ':') { - if (!(flags & REPLACE_ENV_ALLOW_EXTENDED)) + if (flags & REPLACE_ENV_ALLOW_EXTENDED) { + len = e - word - 2; + state = TEST; + } else /* Treat this as unsupported syntax, i.e. do no replacement */ state = WORD; - else { - len = e-word-2; - state = TEST; - } } break; diff --git a/src/libnm-systemd-shared/src/basic/fileio.c b/src/libnm-systemd-shared/src/basic/fileio.c index b3c5def57d..27ec9b96c8 100644 --- a/src/libnm-systemd-shared/src/basic/fileio.c +++ b/src/libnm-systemd-shared/src/basic/fileio.c @@ -124,7 +124,7 @@ int write_string_stream_ts( const struct timespec *ts) { bool needs_nl; - int r, fd; + int r, fd = -1; assert(f); assert(line); @@ -143,8 +143,8 @@ int write_string_stream_ts( 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 */ + /* 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; @@ -167,6 +167,7 @@ int write_string_stream_ts( if (ts) { const struct timespec twice[2] = {*ts, *ts}; + assert(fd >= 0); if (futimens(fd, twice) < 0) return -errno; } @@ -389,20 +390,10 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re if (fd < 0) return -errno; - /* Start size for files in /proc/ which usually report a file size of 0. (Files in /sys/ report a - * file size of 4K, which is probably OK for sizing our initial buffer, and sysfs attributes can't be - * larger anyway.) - * - * It's one less than 4k, so that the malloc() below allocates exactly 4k. */ - size = 4095; - /* 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; @@ -413,24 +404,20 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX); if (st.st_size > 0) { if (st.st_size > READ_FULL_BYTES_MAX) - return -E2BIG; + return -EFBIG; size = st.st_size; n_retries--; } else { - /* Double the buffer size */ - if (size >= READ_FULL_BYTES_MAX) - return -E2BIG; - if (size > READ_FULL_BYTES_MAX / 2 - 1) - size = READ_FULL_BYTES_MAX; /* clamp to max */ - else - size = size * 2 + 1; /* Stay always one less than page size, so we malloc evenly */ + size = READ_FULL_BYTES_MAX; + n_retries = 0; } buf = malloc(size + 1); if (!buf) return -ENOMEM; - size = malloc_usable_size(buf) - 1; /* Use a bigger allocation if we got it anyway */ + /* Use a bigger allocation if we got it anyway, but not more than the limit. */ + size = MIN(malloc_usable_size(buf) - 1, READ_FULL_BYTES_MAX); for (;;) { ssize_t k; @@ -457,6 +444,9 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re * processing, let's try again either with a bigger guessed size or the new * file size. */ + if (n_retries <= 0) + return st.st_size > 0 ? -EIO : -EFBIG; + if (lseek(fd, 0, SEEK_SET) < 0) return -errno; @@ -470,8 +460,7 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re p = realloc(buf, n + 1); if (!p) return -ENOMEM; - - buf = TAKE_PTR(p); + buf = p; } if (ret_size) diff --git a/src/libnm-systemd-shared/src/basic/log.h b/src/libnm-systemd-shared/src/basic/log.h index bcb3d494a1..0664977562 100644 --- a/src/libnm-systemd-shared/src/basic/log.h +++ b/src/libnm-systemd-shared/src/basic/log.h @@ -113,7 +113,7 @@ int log_internal( 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), \ + _nm_log_full(_nm_location ? _nm_location + 1 : ("" file), \ (line), \ (func), \ !(NM_THREAD_SAFE_ON_MAIN_THREAD), \ diff --git a/src/libnm-systemd-shared/src/basic/ordered-set.c b/src/libnm-systemd-shared/src/basic/ordered-set.c index db979864f5..62a36b5dc7 100644 --- a/src/libnm-systemd-shared/src/basic/ordered-set.c +++ b/src/libnm-systemd-shared/src/basic/ordered-set.c @@ -37,30 +37,33 @@ int ordered_set_consume(OrderedSet *s, void *p) { return r; } -int ordered_set_put_strdup(OrderedSet *s, const char *p) { +int _ordered_set_put_strdup(OrderedSet **s, const char *p HASHMAP_DEBUG_PARAMS) { char *c; int r; assert(s); assert(p); + r = _ordered_set_ensure_allocated(s, &string_hash_ops_free HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + if (ordered_set_contains(*s, p)) + return 0; + c = strdup(p); if (!c) return -ENOMEM; - r = ordered_set_consume(s, c); - if (r == -EEXIST) - return 0; - - return r; + return ordered_set_consume(*s, c); } -int ordered_set_put_strdupv(OrderedSet *s, char **l) { +int _ordered_set_put_strdupv(OrderedSet **s, char **l HASHMAP_DEBUG_PARAMS) { int n = 0, r; char **i; STRV_FOREACH(i, l) { - r = ordered_set_put_strdup(s, *i); + r = _ordered_set_put_strdup(s, *i HASHMAP_DEBUG_PASS_ARGS); if (r < 0) return r; @@ -70,7 +73,7 @@ int ordered_set_put_strdupv(OrderedSet *s, char **l) { return n; } -int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l) { +int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l) { int n = 0, r; char *p; diff --git a/src/libnm-systemd-shared/src/basic/ordered-set.h b/src/libnm-systemd-shared/src/basic/ordered-set.h index baf8202088..a377f20b1f 100644 --- a/src/libnm-systemd-shared/src/basic/ordered-set.h +++ b/src/libnm-systemd-shared/src/basic/ordered-set.h @@ -26,6 +26,10 @@ static inline OrderedSet* ordered_set_free_free(OrderedSet *s) { return (OrderedSet*) ordered_hashmap_free_free((OrderedHashmap*) s); } +static inline int ordered_set_contains(OrderedSet *s, const void *p) { + return ordered_hashmap_contains((OrderedHashmap*) s, p); +} + static inline int ordered_set_put(OrderedSet *s, void *p) { return ordered_hashmap_put((OrderedHashmap*) s, p, p); } @@ -59,9 +63,11 @@ static inline char** ordered_set_get_strv(OrderedSet *s) { } int ordered_set_consume(OrderedSet *s, void *p); -int ordered_set_put_strdup(OrderedSet *s, const char *p); -int ordered_set_put_strdupv(OrderedSet *s, char **l); -int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l); +int _ordered_set_put_strdup(OrderedSet **s, const char *p HASHMAP_DEBUG_PARAMS); +#define ordered_set_put_strdup(s, p) _ordered_set_put_strdup(s, p HASHMAP_DEBUG_SRC_ARGS) +int _ordered_set_put_strdupv(OrderedSet **s, char **l HASHMAP_DEBUG_PARAMS); +#define ordered_set_put_strdupv(s, l) _ordered_set_put_strdupv(s, l HASHMAP_DEBUG_SRC_ARGS) +int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l); void ordered_set_print(FILE *f, const char *field, OrderedSet *s); #define _ORDERED_SET_FOREACH(e, s, i) \ diff --git a/src/libnm-systemd-shared/src/basic/parse-util.c b/src/libnm-systemd-shared/src/basic/parse-util.c index 76ae8e31d7..13758108fb 100644 --- a/src/libnm-systemd-shared/src/basic/parse-util.c +++ b/src/libnm-systemd-shared/src/basic/parse-util.c @@ -93,6 +93,7 @@ int parse_mode(const char *s, mode_t *ret) { *ret = m; return 0; } +#endif /* NM_IGNORED */ int parse_ifindex(const char *s) { int ifi, r; @@ -108,6 +109,7 @@ int parse_ifindex(const char *s) { return ifi; } +#if 0 /* NM_IGNORED */ int parse_mtu(int family, const char *s, uint32_t *ret) { uint64_t u; size_t m; diff --git a/src/libnm-systemd-shared/src/basic/path-util.c b/src/libnm-systemd-shared/src/basic/path-util.c index cf1607a56c..a867e65a26 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.c +++ b/src/libnm-systemd-shared/src/basic/path-util.c @@ -1203,10 +1203,4 @@ bool prefixed_path_strv_contains(char **l, const char *path) { 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 index e679e8a73d..48f0c873db 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.h +++ b/src/libnm-systemd-shared/src/basic/path-util.h @@ -185,5 +185,3 @@ static inline const char *empty_to_root(const char *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/socket-util.c b/src/libnm-systemd-shared/src/basic/socket-util.c index 0aef1617f9..da36c2806c 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.c +++ b/src/libnm-systemd-shared/src/basic/socket-util.c @@ -752,6 +752,7 @@ static const char* const ip_tos_table[] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); +#endif /* NM_IGNORED */ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { bool numeric = true; @@ -809,6 +810,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { return true; } +#if 0 /* NM_IGNORED */ bool address_label_valid(const char *p) { if (isempty(p)) diff --git a/src/libnm-systemd-shared/src/basic/socket-util.h b/src/libnm-systemd-shared/src/basic/socket-util.h index 51c03a1578..a8a915beeb 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.h +++ b/src/libnm-systemd-shared/src/basic/socket-util.h @@ -14,6 +14,7 @@ #include <sys/types.h> #include <sys/un.h> +#include "errno-util.h" #include "macro.h" #include "missing_network.h" #include "missing_socket.h" @@ -266,7 +267,7 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) { socklen_t sl = sizeof(v); if (getsockopt(fd, level, optname, &v, &sl) < 0) - return -errno; + return negative_errno(); if (sl != sizeof(v)) return -EIO; diff --git a/src/libnmt-newt/nmt-newt-utils.c b/src/libnmt-newt/nmt-newt-utils.c index 1216b8d356..480c819421 100644 --- a/src/libnmt-newt/nmt-newt-utils.c +++ b/src/libnmt-newt/nmt-newt-utils.c @@ -10,11 +10,13 @@ #include "libnm-client-aux-extern/nm-default-client.h" +#include "nmt-newt-utils.h" + #include <stdarg.h> #include <unistd.h> #include <sys/wait.h> -#include "nmt-newt-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" static void nmt_newt_dialog_g_log_handler(const char * log_domain, @@ -101,8 +103,109 @@ nmt_newt_suspend_callback(gpointer user_data) newtResume(); } +static void +_newtSetColor(int colorset, const char *fg, const char *bg) +{ + newtSetColor(colorset, (char *) fg, (char *) bg); +} + /** - * nmt_newt_init: + * nmt_newt_parse_colors: + * @s: buffer with color settings + * @is_newt: boolean indicating if buffer s + * contains NEWT (true) or NMT (false) color setting + * + * Parses content of buffer s and sets color accordingly + * with newtSetColor() + */ +static void +nmt_newt_parse_colors(const char *s, bool is_newt) +{ + gs_free const char **lines = NULL; + size_t i; + + lines = nm_utils_strsplit_set(s, ";:\n\r\t "); + + if (!lines) + return; + + for (i = 0; lines[i]; i++) { + const char *name; + const char *fg; + const char *bg; + char * parsed_s; + + parsed_s = (char *) lines[i]; + name = parsed_s; + + if (!(parsed_s = strchr(parsed_s, '=')) || !*parsed_s) + continue; + + *parsed_s = '\0'; + fg = ++parsed_s; + + if (!(parsed_s = strchr(parsed_s, ',')) || !*parsed_s) + continue; + + *parsed_s = '\0'; + + bg = ++parsed_s; + + if (is_newt) { + if (nm_streq(name, "checkbox")) + _newtSetColor(NEWT_COLORSET_CHECKBOX, fg, bg); + } else { + if (nm_streq(name, "badLabel")) { + _newtSetColor(NMT_NEWT_COLORSET_BAD_LABEL, fg, bg); + } else if (nm_streq(name, "plainLabel")) { + _newtSetColor(NMT_NEWT_COLORSET_PLAIN_LABEL, fg, bg); + } else if (nm_streq(name, "disabledButton")) { + _newtSetColor(NMT_NEWT_COLORSET_DISABLED_BUTTON, fg, bg); + } else if (nm_streq(name, "textboxWithBackground")) { + _newtSetColor(NMT_NEWT_COLORSET_TEXTBOX_WITH_BACKGROUND, fg, bg); + } + } + } +} + +/** + * nmt_newt_nit_colors: + * @is_newt: boolean indicating if the function is looking for NEWT or NMT env var + * + * Looks for enviroment variables for aditional + * color set up in nmtui + */ +static void +nmt_newt_init_colors(gboolean is_newt) +{ + const char * colors; + gs_free char *file_content = NULL; + + colors = getenv(is_newt ? "NEWT_COLORS" : "NMT_NEWT_COLORS"); + + if (!colors) { + const char *file_name; + + file_name = getenv(is_newt ? "NEWT_COLORS_FILE" : "NMT_NEWT_COLORS_FILE"); + + if (file_name && file_name[0] != '\0' + && (nm_utils_file_get_contents(-1, + file_name, + 16384, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &file_content, + NULL, + NULL, + NULL))) { + colors = file_content; + } + } + + nmt_newt_parse_colors(colors, is_newt); +} + +/** +libnm-client-aux-extern * nmt_newt_init: * * Wrapper for newtInit() that also does some nmt-newt-internal setup. * This should be called once, before any other nmt-newt functions. @@ -119,6 +222,9 @@ nmt_newt_init(void) newtSetColor(NMT_NEWT_COLORSET_DISABLED_BUTTON, "blue", "lightgray"); newtSetColor(NMT_NEWT_COLORSET_TEXTBOX_WITH_BACKGROUND, "black", "white"); + nmt_newt_init_colors(TRUE); + nmt_newt_init_colors(FALSE); + if (g_getenv("NMTUI_DEBUG")) g_log_set_default_handler(nmt_newt_dialog_g_log_handler, NULL); else diff --git a/tools/create-exports-NetworkManager.sh b/tools/create-exports-NetworkManager.sh index f7fd3bab95..21ba369a41 100755 --- a/tools/create-exports-NetworkManager.sh +++ b/tools/create-exports-NetworkManager.sh @@ -35,15 +35,18 @@ _sort() { } call_nm() { - "${NM:-nm}" "$1" | - sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p' + if [ -n "$from_meson" ]; then + "${NM:-nm}" "$1" | + sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p' + else + libtool=(${LIBTOOL:-libtool}) + ${libtool[@]} --mode=execute "${NM:-nm}" "$1" | + sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p' + fi } get_symbols_nm () { - base=./src/core/.libs/NetworkManager-all-sym - if ! test -f "$base"; then - base=./src/core/NetworkManager-all-sym - fi + base=./src/core/NetworkManager-all-sym call_nm "$base" | sed -n 's/^[tTDGRBS] //p' | _sort @@ -85,6 +88,14 @@ do_update() { do_generate > ./src/core/NetworkManager.ver } +if [ -f "build.ninja" ]; then + from_meson=1 + libs= +else + from_meson= + libs=.libs/ +fi + SYMBOLS_MISSING="$(get_symbols_missing | pretty)" SYMBOLS_EXPLICIT="$(get_symbols_explicit | pretty)" @@ -102,14 +113,6 @@ local: EOF } -if [ -f "build.ninja" ]; then - from_meson=1 - libs= -else - from_meson= - libs=.libs/ -fi - test -f ./src/core/${libs}libNetworkManager.a || die "must be called from NetworkManager top build dir after building the tree" case "$1" in |