From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mail.toke.dk (Postfix) with ESMTPS id E8273982BBD for ; Tue, 28 Jun 2022 21:49:07 +0200 (CEST) Authentication-Results: mail.toke.dk; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=fUzg17LH DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1656445748; x=1687981748; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=k1Fba8eV9f/mQyTWxsBVzDTB/kS8fIdX5n6chBSOvzk=; b=fUzg17LHcxhniFQ0ykVX9GmYPt5eeMJ/dTobKn19PAXlhsA0eJfx4ovu TC4EiTc5mEdw7W/nDUvkBOR4ftN5jJ4hLMuxfzUsei94npDjiCoIOEcSl HJ5N/IJDDllFwKiPZh7guw74ZIZn94cBEc5uMMKxXTaOkh7F/9mdBuJ77 psDVJ7Cypgm3Yfoctr08dyJk+gloiZtbn05bRwo3017QWeCS7ZHR5/RbH B+BHhtt1Pt6Byvm8AAYaMMMySbvRspGCftLxnUjA1EkDEOyEn91076rPR ZwKMLna+1cjOAiOH4V7y8pLW3XAhyvXK90JppopcHdft84RogLa6EHOuw g==; X-IronPort-AV: E=McAfee;i="6400,9594,10392"; a="307319480" X-IronPort-AV: E=Sophos;i="5.92,229,1650956400"; d="scan'208";a="307319480" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jun 2022 12:49:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,229,1650956400"; d="scan'208";a="680182418" Received: from irvmail001.ir.intel.com ([10.43.11.63]) by FMSMGA003.fm.intel.com with ESMTP; 28 Jun 2022 12:48:59 -0700 Received: from newjersey.igk.intel.com (newjersey.igk.intel.com [10.102.20.203]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id 25SJmr93022013; Tue, 28 Jun 2022 20:48:57 +0100 From: Alexander Lobakin To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Date: Tue, 28 Jun 2022 21:47:23 +0200 Message-Id: <20220628194812.1453059-4-alexandr.lobakin@intel.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220628194812.1453059-1-alexandr.lobakin@intel.com> References: <20220628194812.1453059-1-alexandr.lobakin@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: KONVKT5QBT3BSCUNT7DLUN7BOTUQHZVA X-Message-ID-Hash: KONVKT5QBT3BSCUNT7DLUN7BOTUQHZVA X-MailFrom: alexandr.lobakin@intel.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Alexander Lobakin , Larysa Zaremba , Michal Swiatkowski , Jesper Dangaard Brouer , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Magnus Karlsson , Maciej Fijalkowski , Jonathan Lemon , Toke Hoiland-Jorgensen , Lorenzo Bianconi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jesse Brandeburg , John Fastabend , Yajun Deng , Willem de Bruijn , bpf@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, xdp-hints@xdp-project.net X-Mailman-Version: 3.3.5 Precedence: list Subject: [xdp-hints] [PATCH RFC bpf-next 03/52] libbpf: add function to get the pair BTF ID + type ID for a given type List-Id: XDP hardware hints design discussion Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add new libbpf API function libbpf_get_type_btf_id() to provide a short way to get the pair of BTF ID << 32 | type ID for the provided type. The primary purpose is to use it in userspace BPF prog loaders to pass those IDs to the kernel to tell what XDP generic metadata to create, as well as in AF_XDP programs to be able to compare them against the ones from frame metadata. Signed-off-by: Alexander Lobakin --- tools/lib/bpf/libbpf.c | 113 +++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.h | 1 + tools/lib/bpf/libbpf.map | 1 + 3 files changed, 115 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 8e27bad5e80f..9bda111c8167 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -2252,6 +2252,28 @@ const char *btf_kind_str(const struct btf_type *t) return __btf_kind_str(btf_kind(t)); } +static __u32 btf_kind_from_str(const char **type) +{ + const char *pos, *orig = *type; + __u32 kind; + int len; + + pos = strchr(orig, ' '); + if (pos) { + len = pos - orig; + *type = pos + 1; + } else { + len = strlen(orig); + } + + for (kind = BTF_KIND_UNKN; kind < NR_BTF_KINDS; kind++) { + if (!strncmp(orig, __btf_kind_str(kind), len)) + break; + } + + return kind < NR_BTF_KINDS ? kind : BTF_KIND_UNKN; +} + /* * Fetch integer attribute of BTF map definition. Such attributes are * represented using a pointer to an array, in which dimensionality of array @@ -9617,6 +9639,97 @@ int libbpf_find_vmlinux_btf_id(const char *name, return libbpf_err(err); } +static __s32 libbpf_find_btf_id(const char *type, __u32 kind, + struct btf **res_btf) +{ + char name[BTF_NAME_BUF_LEN] = { }; + struct btf *vmlinux_btf, *btf; + struct bpf_btf_info info; + __u32 id = 0; + __s32 ret; + + if (res_btf) + *res_btf = NULL; + + if (!type || !*type) + return -EINVAL; + + vmlinux_btf = btf__load_vmlinux_btf(); + ret = libbpf_get_error(vmlinux_btf); + if (ret < 0) + goto free_vmlinux; + + ret = btf__find_by_name_kind(vmlinux_btf, type, kind); + if (ret > 0) { + btf = vmlinux_btf; + goto out; + } + + while (true) { + memset(&info, 0, sizeof(info)); + info.name = ptr_to_u64(name); + info.name_len = sizeof(name); + + btf = btf_load_next_with_info(id, &info, vmlinux_btf, false); + ret = libbpf_get_error(btf); + if (ret) + break; + + ret = btf__find_by_name_kind(btf, type, kind); + if (ret > 0) + break; + + id = btf_obj_id(btf); + btf__free(btf); + } + +free_vmlinux: + btf__free(vmlinux_btf); + +out: + if (ret > 0 && res_btf) + *res_btf = btf; + + return ret ? : -ESRCH; +} + +/** + * libbpf_get_type_btf_id - get the pair BTF ID + type ID for a given type + * @type: pointer to the name of the type to look for + * @res_id: pointer to write the result to + * + * Tries to find the BTF corresponding to the provided type (full string) and + * write the pair of BTF ID << 32 | type ID. Such coded __u64 are being used + * in XDP generic-compatible metadata to distinguish between different + * metadata structures. + * @res_id can be %NULL to only check if a particular type exists within + * the BTF. + * + * Returns 0 in case of success, -errno otherwise. + */ +int libbpf_get_type_btf_id(const char *type, __u64 *res_id) +{ + struct btf *btf = NULL; + __s32 type_id; + __u32 kind; + + if (res_id) + *res_id = 0; + + if (!type || !*type) + return libbpf_err(-EINVAL); + + kind = btf_kind_from_str(&type); + + type_id = libbpf_find_btf_id(type, kind, &btf); + if (type_id > 0 && res_id) + *res_id = ((__u64)btf_obj_id(btf) << 32) | type_id; + + btf__free(btf); + + return libbpf_err(min(type_id, 0)); +} + static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) { struct bpf_prog_info info = {}; diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index fa27969da0da..4056e9038086 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -295,6 +295,7 @@ LIBBPF_API int libbpf_attach_type_by_name(const char *name, enum bpf_attach_type *attach_type); LIBBPF_API int libbpf_find_vmlinux_btf_id(const char *name, enum bpf_attach_type attach_type); +LIBBPF_API int libbpf_get_type_btf_id(const char *type, __u64 *id); /* Accessors of bpf_program */ struct bpf_program; diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 116a2a8ee7c2..f0987df15b7a 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -468,6 +468,7 @@ LIBBPF_1.0.0 { libbpf_bpf_link_type_str; libbpf_bpf_map_type_str; libbpf_bpf_prog_type_str; + libbpf_get_type_btf_id; local: *; }; -- 2.36.1