From nobody Sat Sep 26 01:04:57 2026 Received: from out-2uec-a116.jellyfish.systems (out-2uec-a116.jellyfish.systems [63.250.43.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0ECF38A736 for ; Sun, 6 Sep 2026 17:07:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=63.250.43.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714478; cv=none; b=E0rXOI8TSU83fBNel3xFcWQZQfMx/+9vnKo63GiPZ/nChT7B0WXAUZ93qKm/+cIWgt96mvP9WkzWCtI2KNz2kFQepOIKFM+a+o8XqamCGeCn1r+9zU5yBGy5HeKL4hFoBxBOVJ8EY+Uf2debH3OeBjUBNzYHDTw2hAnrstfPv0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714478; c=relaxed/simple; bh=usxubgOoX74CgAcYdCMyfRvlDB7WtZG8c5wleHYh4gQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JHGVphyMIyqHW/f+LPUWa00uvzhOiyBV2Lnba1AfXk/XTmxXiYbZxN41FYpLtfGUJLx4P73bZ6xq2C5QAaRdvp7GcKS3fL/iy+CnXFh3gYhTntDnXNSNQfMGc3h4LBhLfVi0F9QkVA3FlgNv38NzeQ6P+7RTKuIuJWvA1R+iwn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tychen.cc; spf=pass smtp.mailfrom=tychen.cc; dkim=pass (2048-bit key) header.d=tychen.cc header.i=@tychen.cc header.b=cjeMIX1Z; arc=none smtp.client-ip=63.250.43.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tychen.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tychen.cc Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tychen.cc header.i=@tychen.cc header.b="cjeMIX1Z" Received: from fedora (unknown [69.5.53.41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.spacemail.com (Postfix) with ESMTPSA id 4hdGpq5khQz2xBb; Sun, 06 Sep 2026 17:07:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tychen.cc; s=spacemail; t=1788714458; bh=cX4ZE1QxqcGy81AGsDk0TwQkgBBiC27MtNtkMQ1CotQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cjeMIX1ZDCQCvCjZoD43VZ4qiMTOTSppmmIb8aiKPzCTPKPgBWEryxPT6zG6KZ1lW r6S7cbm95pUP8Wgj+FcQ2i8f7WQl7KTu/zIpxbQ09AnLK9jKMtaJbkV7rM5i1h3TLG sluwIE111w+F/oTc04kDvWMDmO0G6vo0Hg2sHqIPdDAc/rcy5oYxzdEFOCGP/5LjrT cQIXC9FiIBwFGESE5hdDvtmiPzjhJY7Iz5X2/5l9NZ5yerT4/+eOtrXVApCQG25/iO PaIJKRFbksVH587vkzgmp+Fv7EI2bMAZHNq+od3HMtHjpF/Be2Sv6Oj2DjskLxpwDN 9OhusA/WOvEhQ== From: Tianyi Chen To: bpf@vger.kernel.org Cc: Tianyi Chen , Quentin Monnet , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next 1/2] bpftool: Accept symbolic map creation flags Date: Mon, 7 Sep 2026 01:07:14 +0800 Message-ID: <20260906170715.1212085-2-hi@tychen.cc> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260906170715.1212085-1-hi@tychen.cc> References: <20260906170715.1212085-1-hi@tychen.cc> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Envelope-From: hi@tychen.cc Content-Type: text/plain; charset="utf-8" Accept comma-separated BPF_F_* names for map create flags, so callers can use the UAPI names without looking up their numeric values. Keep base-0 numeric input, including bits unknown to this bpftool. Reject empty names, unknown names, mixed numeric and symbolic lists, and values outside the unsigned 32-bit range. Limit symbolic names to map creation flags and let the kernel validate map-specific combinations. Document the syntax and complete names within comma-separated lists. Assisted-by: Codex:GPT-6 Signed-off-by: Tianyi Chen --- .../bpf/bpftool/Documentation/bpftool-map.rst | 13 +++- tools/bpf/bpftool/bash-completion/bpftool | 25 +++++- tools/bpf/bpftool/map.c | 77 ++++++++++++++++++- 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bp= ftool/Documentation/bpftool-map.rst index 5daf3de5c74..375321d5582 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -76,9 +76,16 @@ bpftool map { show | list } [*MAP*] bpftool map create *FILE* type *TYPE* key *KEY_SIZE* value *VALUE_SIZE* e= ntries *MAX_ENTRIES* name *NAME* [flags *FLAGS*] [inner_map *MAP*] [offload= _dev *NAME*] Create a new map with given parameters and pin it to *bpffs* as *FILE*. =20 - *FLAGS* should be an integer which is the combination of desired flags, - e.g. 1024 for **BPF_F_MMAPABLE** (see bpf.h UAPI header for existing - flags). + *FLAGS* accepts an unsigned 32-bit integer combining the desired flags + (decimal, hexadecimal with a **0x** prefix, or octal with a **0** pref= ix), + or a comma-separated list of full, case-sensitive map creation flag na= mes + from the bpf.h UAPI header. For example, **1024**, **0x400**, and + **BPF_F_MMAPABLE** are equivalent. Multiple names are combined with + bitwise OR, for example **BPF_F_NO_PREALLOC,BPF_F_RDONLY_PROG**. + Repeated names are allowed. Empty list elements, abbreviated names, and + lists mixing numbers with names are not accepted. Use **0** for no fla= gs. + Numeric values can include bits unknown to bpftool. The kernel checks + whether the flags are valid for the requested map type. =20 To create maps of type array-of-maps or hash-of-maps, the **inner_map** keyword must be used to pass an inner map. The kernel needs it to coll= ect diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/= bash-completion/bpftool index 75cbcb512eb..95f16fff876 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -718,6 +718,10 @@ _bpftool() esac ;; create) + # Keep a flags list together if readline splits at com= mas. + if [[ $COMP_WORDBREAKS =3D=3D *,* && ( $cur =3D=3D , |= | $prev =3D=3D , ) ]]; then + _get_comp_words_by_ref -n , cur prev + fi case $prev in $command) _filedir @@ -729,7 +733,26 @@ _bpftool() COMPREPLY=3D( $( compgen -W "$BPFTOOL_MAP_CREA= TE_TYPES" -- "$cur" ) ) return 0 ;; - key|value|flags|entries) + flags) + local flags=3D'BPF_F_NO_PREALLOC BPF_F_NO_COMM= ON_LRU + BPF_F_NUMA_NODE BPF_F_RDONLY BPF_F_WRONLY + BPF_F_STACK_BUILD_ID BPF_F_ZERO_SEED + BPF_F_RDONLY_PROG BPF_F_WRONLY_PROG BPF_F_= CLONE + BPF_F_MMAPABLE BPF_F_PRESERVE_ELEMS BPF_F_= INNER_MAP + BPF_F_LINK BPF_F_VTYPE_BTF_OBJ_FD BPF_F_TO= KEN_FD + BPF_F_SEGV_ON_FAULT BPF_F_NO_USER_CONV + BPF_F_RB_OVERWRITE' + local prefix=3D flag + # Readline replaces only the suffix after a wo= rd break. + if [[ $cur =3D=3D *,* && $COMP_WORDBREAKS !=3D= *,* ]]; then + prefix=3D"${cur%,*}," + fi + for flag in $(compgen -W "$flags" -- "${cur##*= ,}"); do + COMPREPLY+=3D( "${prefix}${flag}" ) + done + return 0 + ;; + key|value|entries) return 0 ;; inner_map) diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index 684a8fb7241..d703af60d0b 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -1250,6 +1250,73 @@ static int do_pin(int argc, char **argv) return err; } =20 +static const struct { + const char *name; + __u32 value; +} map_create_flags[] =3D { +#define MAP_CREATE_FLAG(flag) { #flag, flag } + MAP_CREATE_FLAG(BPF_F_NO_PREALLOC), + MAP_CREATE_FLAG(BPF_F_NO_COMMON_LRU), + MAP_CREATE_FLAG(BPF_F_NUMA_NODE), + MAP_CREATE_FLAG(BPF_F_RDONLY), + MAP_CREATE_FLAG(BPF_F_WRONLY), + MAP_CREATE_FLAG(BPF_F_STACK_BUILD_ID), + MAP_CREATE_FLAG(BPF_F_ZERO_SEED), + MAP_CREATE_FLAG(BPF_F_RDONLY_PROG), + MAP_CREATE_FLAG(BPF_F_WRONLY_PROG), + MAP_CREATE_FLAG(BPF_F_CLONE), + MAP_CREATE_FLAG(BPF_F_MMAPABLE), + MAP_CREATE_FLAG(BPF_F_PRESERVE_ELEMS), + MAP_CREATE_FLAG(BPF_F_INNER_MAP), + MAP_CREATE_FLAG(BPF_F_LINK), + MAP_CREATE_FLAG(BPF_F_VTYPE_BTF_OBJ_FD), + MAP_CREATE_FLAG(BPF_F_TOKEN_FD), + MAP_CREATE_FLAG(BPF_F_SEGV_ON_FAULT), + MAP_CREATE_FLAG(BPF_F_NO_USER_CONV), + MAP_CREATE_FLAG(BPF_F_RB_OVERWRITE), +#undef MAP_CREATE_FLAG +}; + +static int parse_map_create_flags(const char *arg, __u32 *flags) +{ + const char *name =3D arg, *comma; + long long value; + __u32 parsed =3D 0; + size_t len, i; + char *end; + + /* Keep base-0 numeric input, including bits unknown to this bpftool. */ + if (strncmp(arg, "BPF_F_", 6)) { + errno =3D 0; + value =3D strtoll(arg, &end, 0); + if (errno || end =3D=3D arg || *end || value < 0 || value > UINT32_MAX) + goto invalid; + *flags =3D value; + return 0; + } + + do { + comma =3D strchr(name, ','); + len =3D comma ? (size_t)(comma - name) : strlen(name); + for (i =3D 0; i < ARRAY_SIZE(map_create_flags); i++) { + if (strlen(map_create_flags[i].name) =3D=3D len && + !strncmp(name, map_create_flags[i].name, len)) + break; + } + if (i =3D=3D ARRAY_SIZE(map_create_flags)) + goto invalid; + parsed |=3D map_create_flags[i].value; + if (comma) + name =3D comma + 1; + } while (comma); + + *flags =3D parsed; + return 0; +invalid: + p_err("can't parse %s as map creation flags", arg); + return -1; +} + static int do_create(int argc, char **argv) { LIBBPF_OPTS(bpf_map_create_opts, attr); @@ -1301,9 +1368,14 @@ static int do_create(int argc, char **argv) "max entries")) goto exit; } else if (is_prefix(*argv, "flags")) { - if (parse_u32_arg(&argc, &argv, &attr.map_flags, - "flags")) + NEXT_ARG(); + if (attr.map_flags) { + p_err("flags already specified"); + goto exit; + } + if (parse_map_create_flags(*argv, &attr.map_flags)) goto exit; + NEXT_ARG(); } else if (is_prefix(*argv, "dev")) { p_info("Warning: 'bpftool map create [...] dev ' syntax is depr= ecated.\n" "Going further, please use 'offload_dev ' to request har= dware offload for the map."); @@ -1474,6 +1546,7 @@ static int do_help(int argc, char **argv) " DATA :=3D { [hex] BYTES }\n" " " HELP_SPEC_PROGRAM "\n" " VALUE :=3D { DATA | MAP | PROG }\n" + " FLAGS :=3D { integer | BPF_F_NAME[,BPF_F_NAME...] }\n" " UPDATE_FLAGS :=3D { any | exist | noexist }\n" " TYPE :=3D { hash | array | prog_array | perf_event_array | percp= u_hash |\n" " percpu_array | stack_trace | cgroup_array | lru_hash |= \n" --=20 2.55.0 From nobody Sat Sep 26 01:04:57 2026 Received: from out-zbxj-a65.jellyfish.systems (out-zbxj-a65.jellyfish.systems [198.54.127.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D502438A739 for ; Sun, 6 Sep 2026 17:07:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.54.127.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714478; cv=none; b=AmnEvFnt6WGVirHLa6MNE/VB3WmFnMwZusqZvVGAAPk8N86qvA4tWmDCmMGbdIcjc/4HYjZpJXeMVPAoWBhtHertBqyYIK2jjbfAfvlfTFkQgNSRaR3I7Qq1+KnnZBHEQIz3zHyFT+iOKebE+fVZS5VERkkWVudYELi10SFSVsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788714478; c=relaxed/simple; bh=IRE56WVX3dwqVWzGZI4zmf8UloIQ3ZU31Z9VISf2cs8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PXzW5ks4EiNPjQazsJJG1lh6nJP2jWeNGj5XG9JpAojGMhq8oejbo8lldBgQSwqBTSlE+DTUztJY76iYOq7bXcvBhEbRN6xFMuMKtqQ5MHZd92LYZleJJwRgS8IghxoKMkG98rn5e0G3EhrOXo4LPh8TZ5HUhXYM18PDBFJxgaI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tychen.cc; spf=pass smtp.mailfrom=tychen.cc; dkim=pass (2048-bit key) header.d=tychen.cc header.i=@tychen.cc header.b=mpFT3SgM; arc=none smtp.client-ip=198.54.127.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=tychen.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tychen.cc Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tychen.cc header.i=@tychen.cc header.b="mpFT3SgM" Received: from fedora (unknown [69.5.53.41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.spacemail.com (Postfix) with ESMTPSA id 4hdGpz2kMnz2xBD; Sun, 06 Sep 2026 17:07:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tychen.cc; s=spacemail; t=1788714466; bh=XfxKpBvhfXs8G4qxM4Uz03DjYwo8QijjCQSAF1xi5yU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mpFT3SgMBjqNjl8uctFw81Cd/LaEeCBT3X67joiTM0ohLumpadntue8j9SCDPcrmE Fa9PlaiNzOI10BHNxVJa73FcBTVbFhdCAoRbu0CPxqX91HCcT7ume0LQQGu9f+LhVS Nxz4Vif7BypqWjtHnvH0FSbSTwoveY2U+GC4HxHQv+rdMpwsr+b3Qm3hGIFGdIg0Fb 8IZ6H5rrQ2b8V5L2+w2YYbUeeGtxkAEQZ9NIFcY22DzWSfioaMDkY5iul2/AUpP86T R87CLPY4/CRFloWBn+Jt02WYYLXKNX3ypzd2suFXbkClioOWbSEAamcIVjjigoKvCp 81d+yrBWwbO9g== From: Tianyi Chen To: bpf@vger.kernel.org Cc: Tianyi Chen , Quentin Monnet , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf-next 2/2] selftests/bpf: Cover symbolic bpftool map creation flags Date: Mon, 7 Sep 2026 01:07:15 +0800 Message-ID: <20260906170715.1212085-3-hi@tychen.cc> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260906170715.1212085-1-hi@tychen.cc> References: <20260906170715.1212085-1-hi@tychen.cc> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Envelope-From: hi@tychen.cc Content-Type: text/plain; charset="utf-8" Check numeric and symbolic map creation flags, including combined and repeated names, against map information read independently with libbpf. Exercise malformed names and lists, update-only flags, empty input and numeric range errors. Verify rejected input leaves no pinned map. Assisted-by: Codex:GPT-6 Signed-off-by: Tianyi Chen --- .../bpf/prog_tests/bpftool_map_flags.c | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/bpftool_map_flag= s.c diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_map_flags.c b/t= ools/testing/selftests/bpf/prog_tests/bpftool_map_flags.c new file mode 100644 index 00000000000..140401dd254 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/bpftool_map_flags.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include + +static const struct map_flags_test { + const char *name; + const char *flags; + __u32 expected_flags; + const char *error; +} tests[] =3D { + { "zero", "0", 0 }, + { "decimal", "129", BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG }, + { "hexadecimal", "0x81", BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG }, + { "octal", "0201", BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG }, + { "positive_sign", "+1", BPF_F_NO_PREALLOC }, + { "single_name", "BPF_F_NO_PREALLOC", BPF_F_NO_PREALLOC }, + { "combined_names", "BPF_F_NO_PREALLOC,BPF_F_RDONLY_PROG", + BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG }, + { "repeated_name", "BPF_F_NO_PREALLOC,BPF_F_NO_PREALLOC", BPF_F_NO_PREALL= OC }, + { "unknown_name", "BPF_F_NOT_A_MAP_FLAG", 0, "can't parse" }, + { "other_command_flag", "BPF_F_PATH_FD", 0, "can't parse" }, + { "update_flag", "BPF_F_LOCK", 0, "can't parse" }, + { "abbreviated_name", "BPF_F_NO_PRE", 0, "can't parse" }, + { "lowercase_name", "bpf_f_no_prealloc", 0, "can't parse" }, + { "empty", "", 0, "can't parse" }, + { "whitespace", " ", 0, "can't parse" }, + { "empty_list", ",", 0, "can't parse" }, + { "leading_comma", ",BPF_F_NO_PREALLOC", 0, "can't parse" }, + { "trailing_comma", "BPF_F_NO_PREALLOC,", 0, "can't parse" }, + { "empty_element", "BPF_F_NO_PREALLOC,,BPF_F_RDONLY_PROG", 0, "can't pars= e" }, + { "number_then_name", "1,BPF_F_RDONLY_PROG", 0, "can't parse" }, + { "name_then_number", "BPF_F_NO_PREALLOC,128", 0, "can't parse" }, + { "numeric_list", "1,128", 0, "can't parse" }, + { "whitespace_in_list", "BPF_F_NO_PREALLOC, BPF_F_RDONLY_PROG", 0, "can't= parse" }, + { "overflow_u32", "4294967296", 0, "can't parse" }, + { "overflow_hex", "0x100000000", 0, "can't parse" }, + { "overflow_u64", "18446744073709551616", 0, "can't parse" }, + { "negative", "-1", 0, "can't parse" }, + /* Numeric bits unknown to bpftool must still reach the kernel. */ + { "all_bits", "0xffffffff", 0, "map create failed" }, + { "invalid_combination", "BPF_F_RDONLY,BPF_F_WRONLY", 0, "map create fail= ed" }, +}; + +static void test_map_flags(const struct map_flags_test *test, const char *= path) +{ + char cmd[MAX_BPFTOOL_CMD_LEN], output[1024] =3D {}; + struct bpf_map_info info =3D {}; + __u32 info_len =3D sizeof(info); + int fd, err; + + /* Let the flags parser handle negative numbers instead of getopt(). */ + err =3D snprintf(cmd, sizeof(cmd), + "-- map create %s type hash key 4 value 4 entries 1 name flags_te= st flags '%s' 2>&1", + path, test->flags); + if (!ASSERT_GT(err, 0, "format_command") || + !ASSERT_LT(err, sizeof(cmd), "command_length")) + return; + + err =3D get_bpftool_command_output(cmd, output, sizeof(output)); + if (test->error) { + ASSERT_NEQ(err, 0, "reject_flags"); + ASSERT_HAS_SUBSTR(output, test->error, "error_message"); + err =3D access(path, F_OK); + ASSERT_EQ(err, -1, "no_pin"); + ASSERT_EQ(errno, ENOENT, "pin_absent"); + goto cleanup; + } + if (!ASSERT_OK(err, "create_map")) + goto cleanup; + + fd =3D bpf_obj_get(path); + if (!ASSERT_OK_FD(fd, "open_map")) + goto cleanup; + if (ASSERT_OK(bpf_map_get_info_by_fd(fd, &info, &info_len), "map_info")) + ASSERT_EQ(info.map_flags, test->expected_flags, "map_flags"); + close(fd); +cleanup: + unlink(path); +} + +void test_bpftool_map_flags(void) +{ + char dir[] =3D "/sys/fs/bpf/bpftool_flags_XXXXXX"; + char path[sizeof(dir) + sizeof("/map")]; + int i; + + if (!ASSERT_OK_PTR(mkdtemp(dir), "create_pin_dir")) + return; + snprintf(path, sizeof(path), "%s/map", dir); + for (i =3D 0; i < ARRAY_SIZE(tests); i++) { + if (test__start_subtest(tests[i].name)) + test_map_flags(&tests[i], path); + } + ASSERT_OK(rmdir(dir), "remove_pin_dir"); +} --=20 2.55.0