From patchwork Thu Feb 20 13:45:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maciej Fijalkowski X-Patchwork-Id: 13983982 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99C2E15ECD7; Thu, 20 Feb 2025 13:45:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059125; cv=none; b=TAppI4Iyv0XrDpfc2UOraSHJ3Y+Cwk8mqUapbd4jfDteJlm1/pWQv9V2BguuQIZ/vvkM8RmEcznogbQ27TZQ92cAGUXnXG0ORaamY+e8u4rldpKxucQ3YMstAVEvJwN6hqBpF/Go6ilvOPRxj503BM+7vxyY4BLCIIRULTqU7W8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059125; c=relaxed/simple; bh=o+7AbNx28kTmjaHrZMgZVOwFZ65jE+f8pFCru/Rt8rs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qHB2a1AAaKOEQAyTkIRtI9hwM2gZ/s8qg4qFsorBkIcHTXwQYII8H2BAnCnFJE2QZxOzNOjjtDFlnCfQ+RlBEK1u8Y7Gsz7tE8oPueNkPUtzO/q4zpi/+ygFS+oYh5Y3QdIZP6IGvNycLzTpjoeIH4P50P3f4xWd4NxuwchL7PY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BPwg/LWw; arc=none smtp.client-ip=192.198.163.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BPwg/LWw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740059124; x=1771595124; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=o+7AbNx28kTmjaHrZMgZVOwFZ65jE+f8pFCru/Rt8rs=; b=BPwg/LWwgiSBgsxqOA6/OUQnuL5plM7J2KSv7mq6ItIlL+mPen90GO9o FGnf7qfg2BD2ZWECNry2YMDN3hT4bmDHxoX8kPiWndw03rM/iQmkd/At1 jo259SrxwlFPRpuCyubn0hvM9kY/5wpxg7rZJSLS91H7ehgmh+t6aceCd zm96P2ikXKWgyuG4nyIyD1lo2Cf/Zwa1EZNDMoZVH4e+SMQcvpK1r/E59 gSRFRSHF92ssi+cPgbpsTrJPFxUpgEAUd+vfkwhGAc3r/l5C/VSvcQQ7U YSWQ/IzWN5DlC1XOQsMf4dG3C3GzQLplUdN3tXLoW30i/Yy4vinxbMmWg w==; X-CSE-ConnectionGUID: lxHjjGenTcaLxuZ44tu3Zg== X-CSE-MsgGUID: GPG7nXR+RGK9fSvpcTnvag== X-IronPort-AV: E=McAfee;i="6700,10204,11351"; a="51479217" X-IronPort-AV: E=Sophos;i="6.13,301,1732608000"; d="scan'208";a="51479217" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Feb 2025 05:45:23 -0800 X-CSE-ConnectionGUID: 8DUjGMx9QfW4BQF02X/Ywg== X-CSE-MsgGUID: lkilHUjkQPWQRUiQdQg1UA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119146253" Received: from boxer.igk.intel.com ([10.102.20.173]) by fmviesa003.fm.intel.com with ESMTP; 20 Feb 2025 05:45:20 -0800 From: Maciej Fijalkowski To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: netdev@vger.kernel.org, magnus.karlsson@intel.com, martin.lau@linux.dev, Maciej Fijalkowski Subject: [PATCH bpf-next 1/3] bpf: call btf_is_projection_of() conditionally Date: Thu, 20 Feb 2025 14:45:01 +0100 Message-Id: <20250220134503.835224-2-maciej.fijalkowski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20250220134503.835224-1-maciej.fijalkowski@intel.com> References: <20250220134503.835224-1-maciej.fijalkowski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Currently verifier thinks when sk_buff is used as kfunc's argument it is coming as pointer to context (KF_ARG_PTR_TO_CTX) but in kfuncs that are going to be introduced for sk_buff's refcount handling we want it to be interpreted as KF_ARG_PTR_TO_BTF_ID. Make it possible by calling btf_is_projection_of() conditionally. Signed-off-by: Maciej Fijalkowski --- include/linux/btf.h | 4 ++-- kernel/bpf/btf.c | 11 ++++++----- kernel/bpf/verifier.c | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index ebc0c0c9b944..1307ea17542a 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -585,7 +585,7 @@ struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id); bool btf_is_projection_of(const char *pname, const char *tname); bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, const struct btf_type *t, enum bpf_prog_type prog_type, - int arg); + int arg, bool check_proj); int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type); bool btf_types_are_same(const struct btf *btf1, u32 id1, const struct btf *btf2, u32 id2); @@ -661,7 +661,7 @@ static inline struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf static inline bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, const struct btf_type *t, enum bpf_prog_type prog_type, - int arg) + int arg, bool check_proj) { return false; } diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 69f5752e880b..62bdf6980cfb 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5909,7 +5909,7 @@ bool btf_is_projection_of(const char *pname, const char *tname) bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, const struct btf_type *t, enum bpf_prog_type prog_type, - int arg) + int arg, bool check_proj) { const struct btf_type *ctx_type; const char *tname, *ctx_tname; @@ -5969,8 +5969,9 @@ bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, * int socket_filter_bpf_prog(struct __sk_buff *skb) * { // no fields of skb are ever used } */ - if (btf_is_projection_of(ctx_tname, tname)) - return true; + if (check_proj) + if (btf_is_projection_of(ctx_tname, tname)) + return true; if (strcmp(ctx_tname, tname)) { /* bpf_user_pt_regs_t is a typedef, so resolve it to * underlying struct and check name again @@ -6133,7 +6134,7 @@ static int btf_translate_to_vmlinux(struct bpf_verifier_log *log, enum bpf_prog_type prog_type, int arg) { - if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg)) + if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg, true)) return -ENOENT; return find_kern_ctx_type_id(prog_type); } @@ -7739,7 +7740,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog) if (!btf_type_is_ptr(t)) goto skip_pointer; - if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i)) { + if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i, true)) { if (tags & ~ARG_TAG_CTX) { bpf_log(log, "arg#%d has invalid combination of tags\n", i); return -EINVAL; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e57b7c949860..6492bfa4bc7a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11997,7 +11997,8 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env, * type to our caller. When a set of conditions hold in the BTF type of * arguments, we resolve it to a known kfunc_ptr_arg_type. */ - if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno)) + if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), + argno, false)) return KF_ARG_PTR_TO_CTX; if (is_kfunc_arg_nullable(meta->btf, &args[argno]) && register_is_null(reg)) From patchwork Thu Feb 20 13:45:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maciej Fijalkowski X-Patchwork-Id: 13983983 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2853C1509A0; Thu, 20 Feb 2025 13:45:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059126; cv=none; b=hOIPP+jmdW4gg+LrucO0EVX3MIjz5hGMTTIMXMc4Lbfi79TS9UsfB2zSFVh+NQDFYgiP6Aee4yiHhmPzzYa20LxJyer2/lcW7Iq/kzJIRAlbljS5GwrJwGj+mo04JlDhZll/Fc9Na/Zv+uWDvBxLX2LJ/LUhCSp8pokJP/xCd3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059126; c=relaxed/simple; bh=JI/Wwd8A4e4sWUCVqMbNoPp92TuHqN3f9dGGdJsEg04=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WUTcS9EgKdG7osYBGA05yOldXGYt1kP/yz5IVxQdp7FQBSwhkVE0/LS8Pkuem2SR+nxyNOonimArXQeCenexBuYlg0N5AZusNzBRBx47os6jJEUL+BtdE602DZWsZph2EbExIgASOCftzNB3211kzqDOWP0gAm5HqxMAYm0fs4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Moi3UME0; arc=none smtp.client-ip=192.198.163.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Moi3UME0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740059125; x=1771595125; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JI/Wwd8A4e4sWUCVqMbNoPp92TuHqN3f9dGGdJsEg04=; b=Moi3UME0+sl5sv59iBUN9OBNfC4lSbMkeAQCZk2PKD95s2Y45GppURuh 89bgA0kH/VWNw4CBqrk9tZYyWOAKPeq+Xe9JZUOtmk/SRN+kIsR1m5T4g EY8m6YD4JAXJoYfa7ygTmq7h7mNi9IfztnzFHi3ZpDxjCIYhI09FcksOb SrDUw/rPK6HfZ8B4jJRbOI8rj0hw/WWt1QhA8eM5OxXXZwd1G41sQuVsl hCuWXuxISadG27vzru83v7EUCPkjnCIgdXOe0S7KP5t+GQi70c5W3Pieo R+mndOt74404DDq6vXIFndNfERPGU+DakoHt+azdBNVOiGSuIlBcTu3Tf g==; X-CSE-ConnectionGUID: Srn4ZhbGSf2GpiKvyNfBdA== X-CSE-MsgGUID: OTxskq0KTh2tnQAWzK41Nw== X-IronPort-AV: E=McAfee;i="6700,10204,11351"; a="51479224" X-IronPort-AV: E=Sophos;i="6.13,301,1732608000"; d="scan'208";a="51479224" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Feb 2025 05:45:25 -0800 X-CSE-ConnectionGUID: skcWtEYTRLO8DjTiMiMjtg== X-CSE-MsgGUID: 0bq/geJlSsG3kpYVmbIR2g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119146263" Received: from boxer.igk.intel.com ([10.102.20.173]) by fmviesa003.fm.intel.com with ESMTP; 20 Feb 2025 05:45:23 -0800 From: Maciej Fijalkowski To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: netdev@vger.kernel.org, magnus.karlsson@intel.com, martin.lau@linux.dev, Maciej Fijalkowski Subject: [PATCH bpf-next 2/3] bpf: add kfunc for skb refcounting Date: Thu, 20 Feb 2025 14:45:02 +0100 Message-Id: <20250220134503.835224-3-maciej.fijalkowski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20250220134503.835224-1-maciej.fijalkowski@intel.com> References: <20250220134503.835224-1-maciej.fijalkowski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net These have been mostly taken from Amery Hung's work related to bpf qdisc implementation. bpf_skb_{acquire,release}() are for increment/decrement sk_buff::users whereas bpf_skb_destroy() is called for map entries that have not been released and map is being wiped out from system. Signed-off-by: Maciej Fijalkowski --- net/core/filter.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/net/core/filter.c b/net/core/filter.c index 2ec162dd83c4..9bd2701be088 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12064,6 +12064,56 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, __bpf_kfunc_end_defs(); +__diag_push(); +__diag_ignore_all("-Wmissing-prototypes", + "Global functions as their definitions will be in vmlinux BTF"); + +/* bpf_skb_acquire - Acquire a reference to an skb. An skb acquired by this + * kfunc which is not stored in a map as a kptr, must be released by calling + * bpf_skb_release(). + * @skb: The skb on which a reference is being acquired. + */ +__bpf_kfunc struct sk_buff *bpf_skb_acquire(struct sk_buff *skb) +{ + if (refcount_inc_not_zero(&skb->users)) + return skb; + return NULL; +} + +/* bpf_skb_release - Release the reference acquired on an skb. + * @skb: The skb on which a reference is being released. + */ +__bpf_kfunc void bpf_skb_release(struct sk_buff *skb) +{ + skb_unref(skb); +} + +/* bpf_skb_destroy - Release an skb reference acquired and exchanged into + * an allocated object or a map. + * @skb: The skb on which a reference is being released. + */ +__bpf_kfunc void bpf_skb_destroy(struct sk_buff *skb) +{ + (void)skb_unref(skb); + consume_skb(skb); +} + +__diag_pop(); + +BTF_KFUNCS_START(skb_kfunc_btf_ids) +BTF_ID_FLAGS(func, bpf_skb_acquire, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_skb_release, KF_RELEASE) +BTF_KFUNCS_END(skb_kfunc_btf_ids) + +static const struct btf_kfunc_id_set skb_kfunc_set = { + .owner = THIS_MODULE, + .set = &skb_kfunc_btf_ids, +}; + +BTF_ID_LIST(skb_kfunc_dtor_ids) +BTF_ID(struct, sk_buff) +BTF_ID_FLAGS(func, bpf_skb_destroy, KF_RELEASE) + int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, struct bpf_dynptr *ptr__uninit) { @@ -12117,6 +12167,13 @@ static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { static int __init bpf_kfunc_init(void) { + const struct btf_id_dtor_kfunc skb_kfunc_dtors[] = { + { + .btf_id = skb_kfunc_dtor_ids[0], + .kfunc_btf_id = skb_kfunc_dtor_ids[1] + }, + }; + int ret; ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_skb); @@ -12133,6 +12190,11 @@ static int __init bpf_kfunc_init(void) ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, &bpf_kfunc_set_sock_addr); + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &skb_kfunc_set); + + ret = ret ?: register_btf_id_dtor_kfuncs(skb_kfunc_dtors, + ARRAY_SIZE(skb_kfunc_dtors), + THIS_MODULE); return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_tcp_reqsk); } late_initcall(bpf_kfunc_init); From patchwork Thu Feb 20 13:45:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maciej Fijalkowski X-Patchwork-Id: 13983984 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB3BB1FBC89; Thu, 20 Feb 2025 13:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059129; cv=none; b=Wdi5Mx5zJKjwXFPBfAjYGfLDwyNy4/pHLFtrLKKRXA10hjMIAj/A/qM+Z7lQ54F9OP8nBhexrZ3LurFGGviUsWN3zwwAzHUaWb2fI+9+ydOnQ22Z+L8Wd02n0KPboI6T4I7aY464pIFIE2GmMZLbsQ44nZGLnyTM6OuLBleUpjs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740059129; c=relaxed/simple; bh=5fj7mFPrfSNstxUkY6VTZHCkWduWWJVFcL0TwY04dWQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TrOKK8h91vS/SzyCE1HiTyo8AhO6d0wy1Fg9ukm85YI2u9N1nPSruO9Q6lukX2bO2XA8uXiLUNHq3zI4Y8idD1JgB10dwF4piunQTwtsRRaoMTsRKa1mMiD4GZatuXZUQ8hyLi9WLkXWbqzEltwg03W8oLJXKBzIJKHvrzqrLsM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FBUR3bPa; arc=none smtp.client-ip=192.198.163.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FBUR3bPa" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740059128; x=1771595128; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5fj7mFPrfSNstxUkY6VTZHCkWduWWJVFcL0TwY04dWQ=; b=FBUR3bPagA0WuWDDEW4bUhuq9UtA5JsZqaTpHEE1LTyDCxI1RjoKLAni 9zrAGgX/lumdsMAepD0z1ujPj4cXllAkePGCgZpTyRx3RzDTMPtNZDl7F ffngAzrRxh2FYJuyXC/FZvWvXiLgcXW/CQIAGZRv6DulhONdwVep0+DC8 O1mbcsfEA/bDKH4+ujFeh7NGcvqwCohCM1llxGA384N71Tp9HGe7X1VjO IOGDTgQ7LliLvzDw457GdPpK1LcRSRAE/2ykXm9zEbiJSwZ1zStmmdji2 9zEex0ep+UEAet0hARG/4RfTwC/1ywWYPPfoeYS0JqwBdnMy/ehzd2tne Q==; X-CSE-ConnectionGUID: uTZmziaLTwKO2+IgRZxrHQ== X-CSE-MsgGUID: vPjVxNRnTR2uRgvQht3ItA== X-IronPort-AV: E=McAfee;i="6700,10204,11351"; a="51479231" X-IronPort-AV: E=Sophos;i="6.13,301,1732608000"; d="scan'208";a="51479231" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Feb 2025 05:45:27 -0800 X-CSE-ConnectionGUID: zRbntPTvT+2KVa7fQY7hXQ== X-CSE-MsgGUID: SFDwJGMrRx2dGwkvxBahVg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119146274" Received: from boxer.igk.intel.com ([10.102.20.173]) by fmviesa003.fm.intel.com with ESMTP; 20 Feb 2025 05:45:25 -0800 From: Maciej Fijalkowski To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: netdev@vger.kernel.org, magnus.karlsson@intel.com, martin.lau@linux.dev, Maciej Fijalkowski Subject: [PATCH bpf-next 3/3] selftests: bpf: implement test case for skb kptr map storage Date: Thu, 20 Feb 2025 14:45:03 +0100 Message-Id: <20250220134503.835224-4-maciej.fijalkowski@intel.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20250220134503.835224-1-maciej.fijalkowski@intel.com> References: <20250220134503.835224-1-maciej.fijalkowski@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add a test case to exercise kptrs behavior against sk_buff structs stored in eBPF map. Let us have two programs, one for store and other for retrieving sk_buffs from pinned map. Load first prog and run as many times as size of map so that second program will see the map full and will be able to retrieve each of sk_buff that bpf_prog_test_run_skb() created for us. Reason for running the progs MAX_ENTRIES times from user space instead of utilizing @repeat argument of is that we would like to have unique skbs handled in map. With @repeat usage it would result in storing the same skb. Signed-off-by: Maciej Fijalkowski --- .../selftests/bpf/prog_tests/skb_map_kptrs.c | 75 ++++++++++++++++++ .../selftests/bpf/progs/skb_map_kptrs.c | 77 +++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/skb_map_kptrs.c create mode 100644 tools/testing/selftests/bpf/progs/skb_map_kptrs.c diff --git a/tools/testing/selftests/bpf/prog_tests/skb_map_kptrs.c b/tools/testing/selftests/bpf/prog_tests/skb_map_kptrs.c new file mode 100644 index 000000000000..993beac6c344 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/skb_map_kptrs.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +#define SKB_KPTR_MAP_PATH "/sys/fs/bpf/skb_kptr_map" + +static void skb_map_kptrs(void) +{ + int err, prog_fd, store_fd, get_fd, map_fd; + struct bpf_program *prog; + struct bpf_object *obj; + char buff[128] = {}; + struct bpf_map *map; + int i; + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = buff, + .data_size_in = sizeof(buff), + .repeat = 1, + ); + + err = bpf_prog_test_load("skb_map_kptrs.bpf.o", BPF_PROG_TYPE_SCHED_CLS, &obj, + &prog_fd); + if (CHECK_FAIL(err)) + return; + + map = bpf_object__find_map_by_name(obj, "skb_map"); + if (CHECK_FAIL(!map)) + goto map_err; + + map_fd = bpf_map__fd(map); + if (map_fd < 0) + goto map_err; + + err = bpf_obj_pin(map_fd, SKB_KPTR_MAP_PATH); + if (err < 0) + goto map_err; + + prog = bpf_object__find_program_by_name(obj, "tc_skb_map_store"); + if (CHECK_FAIL(!prog)) + goto out; + + store_fd = bpf_program__fd(prog); + if (CHECK_FAIL(store_fd < 0)) + goto out; + + // store skbs + for (i = 0; i < bpf_map__max_entries(map); i++) { + err = bpf_prog_test_run_opts(store_fd, &topts); + ASSERT_OK(err, "skb kptr store"); + } + + prog = bpf_object__find_program_by_name(obj, "tc_skb_map_get"); + if (CHECK_FAIL(!prog)) + goto out; + + get_fd = bpf_program__fd(prog); + if (CHECK_FAIL(get_fd < 0)) + goto out; + + // get skbs + for (i = 0; i < bpf_map__max_entries(map); i++) { + err = bpf_prog_test_run_opts(get_fd, &topts); + ASSERT_OK(err, "skb kptr get"); + } + +out: + unlink(SKB_KPTR_MAP_PATH); +map_err: + bpf_object__close(obj); +} + +void test_skb_map_kptrs(void) +{ + skb_map_kptrs(); +} + diff --git a/tools/testing/selftests/bpf/progs/skb_map_kptrs.c b/tools/testing/selftests/bpf/progs/skb_map_kptrs.c new file mode 100644 index 000000000000..f4972978cb04 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/skb_map_kptrs.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "vmlinux.h" +#include + +void *bpf_cast_to_kern_ctx(void *) __ksym; +struct sk_buff *bpf_skb_acquire(struct sk_buff *skb) __ksym; +void bpf_skb_release(struct sk_buff *skb) __ksym; + +struct skb_map_val { + struct sk_buff __kptr * skb; +}; + +static __u32 get_idx; +static __u32 store_idx; + +#define MAX_ENTRIES 100 + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, __u32); + __type(value, struct skb_map_val); + __uint(max_entries, MAX_ENTRIES); +} skb_map SEC(".maps"); + +static __always_inline __u32 idx_bump(__u32 idx) +{ + return idx >= MAX_ENTRIES ? 0 : idx + 1; +} + +SEC("tc") int tc_skb_map_store(struct __sk_buff *ctx) +{ + struct sk_buff *skbk = bpf_cast_to_kern_ctx(ctx); + struct skb_map_val *map_entry, tmp_entry; + struct sk_buff *tmp; + + tmp_entry.skb = NULL; + bpf_map_update_elem(&skb_map, &store_idx, &tmp_entry, BPF_ANY); + map_entry = bpf_map_lookup_elem(&skb_map, &store_idx); + if (!map_entry) + return -1; + + skbk = bpf_skb_acquire(skbk); + if (!skbk) + return -2; + + tmp = bpf_kptr_xchg(&map_entry->skb, skbk); + if (tmp) + bpf_skb_release(tmp); + + store_idx = idx_bump(store_idx); + + return 0; +} + +SEC("tc") int tc_skb_map_get(struct __sk_buff *ctx) +{ + struct sk_buff *stored_skb = NULL; + struct skb_map_val *map_entry; + struct sk_buff *tmp = NULL; + + (void)ctx; + + map_entry = bpf_map_lookup_elem(&skb_map, &get_idx); + if (!map_entry) + return -1; + + stored_skb = bpf_kptr_xchg(&map_entry->skb, tmp); + if (!stored_skb) + return -2; + + bpf_skb_release(stored_skb); + get_idx = idx_bump(get_idx); + + return 0; +} + +char _license[] SEC("license") = "GPL";