From patchwork Thu Nov 16 19:42:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458214 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Gs3pXLP/" Received: from mail-ot1-x332.google.com (mail-ot1-x332.google.com [IPv6:2607:f8b0:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F8E7196 for ; Thu, 16 Nov 2023 11:43:12 -0800 (PST) Received: by mail-ot1-x332.google.com with SMTP id 46e09a7af769-6ce327458a6so580786a34.1 for ; Thu, 16 Nov 2023 11:43:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163791; x=1700768591; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=BzaCTZlR32Fo7kXCFMno+T8cUIukwclcqaYQngZoWNg=; b=Gs3pXLP/En9touuD8wvV9BdA8B3/iWixJJ37PfwdvRTcjRcb16tLExxnbBfLTd95U8 ilNqoZCU7f9Q3kZgsmbEb9O2JrRiSJLH7IlI36pQRyYUY2NXCvTtnON+dyjQ/cCyn2aY f/GChVQEqZR+EUyaUBx0YF54+zzX+kkgRBeOxxdU6OXBq4g9Duil2p+uKZN1sFkEZlGM PFFFm98DiiceiFINy8vRaETdyxQT1+vdmzYPEV16CUZkG9RxfAxDmGebFrqDY/BF6SK6 BImLdC04yXOrZ9DDu+JMDGYgcP9v6kS8PGbSgxxbTpVzCtXCLx0uG1FPdN8onHrsH9wm SaqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163791; x=1700768591; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BzaCTZlR32Fo7kXCFMno+T8cUIukwclcqaYQngZoWNg=; b=HUDBOdrtlS+nJXJYtetyq8/elyBiiK3z/YnSNkZ5RI50iKRaUKbxLgz/0DiEyqeTtO ZVdIWnpNqVwTqohlA+R3/RPWPT4bJ1+zg8O49zvFLPdyUrYZ+X6yTuEmVIL7l0UlzFjC KYqXSj2gDxHAOHUMmIg/SsSYl/tik99NdTS8yBLzROTBIrHy45w74v/sZf9zlRye9uV6 7ufyD4XL6KpqY+qQb+WAQO2Hi4dQcckbjb7OjFrRqiaBGGcqRPvO2wVPXb8i+07D2ejC jCYYzShIJ16SRKsrvkHQr+ngm90bFHgf8BBG3v5TSrGTYgJONlPuXb2BKjubkkhFs08v rkbQ== X-Gm-Message-State: AOJu0YyMqP+Afn7KpgQjSdCgb7XjwWf7w4USF2x46WPAR1qtTWja8QeI rncgXRuBudRvKjTmk91JqLMWRocjbbFW2A== X-Google-Smtp-Source: AGHT+IFslngQ1DYj4pVuDT5Fjs1/u0NGmtT3UH47hpOeJNRG0PYrf8uKuGE0xWjeQK4eb4wCw0L5JQ== X-Received: by 2002:a9d:7387:0:b0:6bd:9f5:a9a with SMTP id j7-20020a9d7387000000b006bd09f50a9amr1195158otk.18.1700163791013; Thu, 16 Nov 2023 11:43:11 -0800 (PST) Received: from localhost (fwdproxy-vll-001.fbsv.net. [2a03:2880:12ff:1::face:b00c]) by smtp.gmail.com with ESMTPSA id q3-20020a9d6543000000b006cd09ba046fsm1164otl.61.2023.11.16.11.43.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:10 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 1/9] bpftool: add testing skeleton Date: Thu, 16 Nov 2023 11:42:28 -0800 Message-Id: <20231116194236.1345035-2-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add minimal cargo project to test bpftool. An environment variable `BPFTOOL_PATH` can be used to provide the path to bpftool, defaulting to /usr/sbin/bpftool $ cargo check --tests Finished dev [unoptimized + debuginfo] target(s) in 0.00s $ cargo clippy --tests Finished dev [unoptimized + debuginfo] target(s) in 0.05s $ BPFTOOL_PATH='../bpftool' cargo test -- --nocapture Finished test [unoptimized + debuginfo] target(s) in 0.05s Running unittests src/main.rs (target/debug/deps/bpftool_tests-172b867215e9364e) running 1 test Running command "../bpftool" "version" test bpftool_tests::run_bpftool ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Signed-off-by: Manu Bretelle --- .../selftests/bpf/bpftool_tests/.gitignore | 3 +++ .../selftests/bpf/bpftool_tests/Cargo.toml | 4 ++++ .../bpf/bpftool_tests/src/bpftool_tests.rs | 20 +++++++++++++++++++ .../selftests/bpf/bpftool_tests/src/main.rs | 3 +++ 4 files changed, 30 insertions(+) create mode 100644 tools/testing/selftests/bpf/bpftool_tests/.gitignore create mode 100644 tools/testing/selftests/bpf/bpftool_tests/Cargo.toml create mode 100644 tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs create mode 100644 tools/testing/selftests/bpf/bpftool_tests/src/main.rs diff --git a/tools/testing/selftests/bpf/bpftool_tests/.gitignore b/tools/testing/selftests/bpf/bpftool_tests/.gitignore new file mode 100644 index 000000000000..cf8177c6aabd --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/target/** +/Cargo.lock diff --git a/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml new file mode 100644 index 000000000000..34df3002003f --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "bpftool_tests" +version = "0.1.0" +edition = "2021" diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs new file mode 100644 index 000000000000..251dbf3861fe --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +use std::process::Command; + +const BPFTOOL_PATH_ENV: &str = "BPFTOOL_PATH"; +const BPFTOOL_PATH: &str = "/usr/sbin/bpftool"; + +/// Run a bpftool command and returns the output +fn run_bpftool_command(args: &[&str]) -> std::process::Output { + let mut cmd = Command::new(std::env::var(BPFTOOL_PATH_ENV).unwrap_or(BPFTOOL_PATH.to_string())); + cmd.args(args); + println!("Running command {:?}", cmd); + cmd.output().expect("failed to execute process") +} + +/// Simple test to make sure we can run bpftool +#[test] +fn run_bpftool() { + let output = run_bpftool_command(&["version"]); + assert!(output.status.success()); +} diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/main.rs b/tools/testing/selftests/bpf/bpftool_tests/src/main.rs new file mode 100644 index 000000000000..6b4ffcde7406 --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/src/main.rs @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +#[cfg(test)] +mod bpftool_tests; From patchwork Thu Nov 16 19:42:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458216 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vpr5lRdq" Received: from mail-oa1-x2a.google.com (mail-oa1-x2a.google.com [IPv6:2001:4860:4864:20::2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7BE5718D for ; Thu, 16 Nov 2023 11:43:15 -0800 (PST) Received: by mail-oa1-x2a.google.com with SMTP id 586e51a60fabf-1efabc436e4so617773fac.1 for ; Thu, 16 Nov 2023 11:43:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163794; x=1700768594; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=rv85a8FjKpza20e5qCpINaXLe3icI43373bIc5/Wuw0=; b=Vpr5lRdqNtRJXC4wHSEHtnPXuBmqlkltcJwr7PgNNiCSmgdNdRXDSv0Q0YLqxzgbvw L2W0AFS83H6qy8/4uJvS5l0n80L10vUctgVNWF7aDIVu4DrXx1tObrKtwWeEoy8H62qZ XjecCbPWxn5hMbky0esRpD4HyB38JK3yK7qtt3RMrZu1xXdJWXjUH/1kv9e8FoZgFikp jc2brpxOyUyYh86CUmfZcWqiDHMMTgg5A+1/H5abuwX2qDVns00mzd/jrxJqDJdcrDF4 YoPAkPYOCrk91R5K0wlJw5n97xWtGvLluZrf/aVyLxYi8lABXvKePutdsDxA0OlSmuU1 LraQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163794; x=1700768594; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rv85a8FjKpza20e5qCpINaXLe3icI43373bIc5/Wuw0=; b=lOdR5gFSFqPar+abYkvHutKRyjmCfZgEHZCLZ9xaZA9nlu7/STgOi3RSFaarKFgX5i ZtTCblqzijeBJAo2F13CYhtjphiXCyDj6j6JFCEQHc6Dj6dMOmjahT9Ze3nHLybm8L6M Oj2npJyCcz3FkX8NjCQY1y+18Ee0a/+/sFlIZjJjjQZCrOb9+Qe7fPZbAu/FDk9PGc4h GOL1XsvphsbXgpNbIY4Nu8pO0g6xD7oR9gxe6CS8bi3gmYdyfYpUTZLXSmgWe6qQPVM/ GxisvdrrRnYnfqD3woEZDid8o7aZ6kp6gm95JCLbD+utiW0RuYumH359CWab0hvRXpqM Y2fA== X-Gm-Message-State: AOJu0YxsaK0w+UZvkfNNIALfO822kuGJa0EOj7xr1ZYUy8ZUdnIp8Y3k UaLPXp+CrybkdRNHCZaghdlrrlzDXIwpMg== X-Google-Smtp-Source: AGHT+IHRuJ5u6gtR5PO+ZqC6Ca0fOQdiZGK6JJYWzyQ/V8AHQ/ugcktFU7FxeryQSYJEg/Dk7NAbyg== X-Received: by 2002:a05:6871:53ca:b0:1f0:597d:fe30 with SMTP id hz10-20020a05687153ca00b001f0597dfe30mr19754981oac.44.1700163794063; Thu, 16 Nov 2023 11:43:14 -0800 (PST) Received: from localhost (fwdproxy-vll-007.fbsv.net. [2a03:2880:12ff:7::face:b00c]) by smtp.gmail.com with ESMTPSA id zb8-20020a05687126c800b001efc94cc21bsm3880oab.58.2023.11.16.11.43.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:13 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 2/9] bpftool: add libbpf-rs dependency and minimal bpf program Date: Thu, 16 Nov 2023 11:42:29 -0800 Message-Id: <20231116194236.1345035-3-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Setting up the basic requirements to build a bpf program using libbpf-rs. $ cargo test Compiling bpftool_tests v0.1.0 (/data/users/chantra/bpf-next/tools/bpf/bpftool/testing) Finished test [unoptimized + debuginfo] target(s) in 0.64s Running unittests src/main.rs (target/debug/deps/bpftool_tests-b5112057d979eb52) running 1 test test bpftool_tests::run_bpftool ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Signed-off-by: Manu Bretelle --- .../selftests/bpf/bpftool_tests/Cargo.toml | 7 +++++++ .../selftests/bpf/bpftool_tests/build.rs | 17 ++++++++++++++++ .../bpftool_tests/src/bpf/bpftool_tests.bpf.c | 20 +++++++++++++++++++ .../bpf/bpftool_tests/src/bpf/vmlinux.h | 1 + .../bpf/bpftool_tests/src/bpftool_tests.rs | 4 ++++ 5 files changed, 49 insertions(+) create mode 100644 tools/testing/selftests/bpf/bpftool_tests/build.rs create mode 100644 tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c create mode 120000 tools/testing/selftests/bpf/bpftool_tests/src/bpf/vmlinux.h diff --git a/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml index 34df3002003f..35c834082351 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml +++ b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml @@ -2,3 +2,10 @@ name = "bpftool_tests" version = "0.1.0" edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +libbpf-rs = "0.21" + +[build-dependencies] +libbpf-cargo = "0.21" diff --git a/tools/testing/selftests/bpf/bpftool_tests/build.rs b/tools/testing/selftests/bpf/bpftool_tests/build.rs new file mode 100644 index 000000000000..ce01824fcd1d --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/build.rs @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +use libbpf_cargo::SkeletonBuilder; +use std::env; +use std::path::PathBuf; + +const SRC: &str = "src/bpf/bpftool_tests.bpf.c"; + +fn main() { + let mut out = + PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR must be set in build script")); + out.push("bpftool_tests.skel.rs"); + SkeletonBuilder::new() + .source(SRC) + .build_and_generate(&out) + .unwrap(); + println!("cargo:rerun-if-changed={SRC}"); +} diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c new file mode 100644 index 000000000000..8b92171145de --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +#include "vmlinux.h" +#include + +char LICENSE[] SEC("license") = "Dual BSD/GPL"; + +int my_pid = 0; + +SEC("tp/syscalls/sys_enter_write") +int handle_tp(void *ctx) +{ + int pid = bpf_get_current_pid_tgid() >> 32; + + if (pid != my_pid) + return 0; + + bpf_printk("BPF triggered from PID %d.\n", pid); + + return 0; +} diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/vmlinux.h b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/vmlinux.h new file mode 120000 index 000000000000..f9515b260426 --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/vmlinux.h @@ -0,0 +1 @@ +../../../tools/include/vmlinux.h \ No newline at end of file diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index 251dbf3861fe..35eb35831dce 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -1,4 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +mod bpftool_tests_skel { + include!(concat!(env!("OUT_DIR"), "/bpftool_tests.skel.rs")); +} + use std::process::Command; const BPFTOOL_PATH_ENV: &str = "BPFTOOL_PATH"; From patchwork Thu Nov 16 19:42:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458217 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hIh5lIdB" Received: from mail-oa1-x2c.google.com (mail-oa1-x2c.google.com [IPv6:2001:4860:4864:20::2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57DAB196 for ; Thu, 16 Nov 2023 11:43:18 -0800 (PST) Received: by mail-oa1-x2c.google.com with SMTP id 586e51a60fabf-1ea82246069so604587fac.3 for ; Thu, 16 Nov 2023 11:43:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163797; x=1700768597; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=H608VgudrD6edIFRUAcWatdKfbzlLpKzpDlMJ9cjEko=; b=hIh5lIdBC6+EPSIvkMAYz3bGGguUsjoye+rGJbyjkJp66/Lplt4C+V/s+04OFfOVWY 5EQiTVfyVgRydzEVvvWECiKjI6HJ+vtUrr4aCl28CHZOC/LsRrbbUhEmL+mZoLD2203r +saBysJegI6EtXCmh6E3oICXFIpiN68cTtO1DnAFBJ4vi++2VTrqXM0Os0lmdUnlsyqw 9eKV/+Z99marLk41rf5uKZtW37OGS01odisCNY3PPu9tsMeng4YnRhF2ypSOqZvvs03h bzVyS8w3WlCS2iW+ZSKzgXxjjLekXxKg2apzq71wlxXQo9A6ierKmE+iwcsSKyMumBIk PI9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163797; x=1700768597; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H608VgudrD6edIFRUAcWatdKfbzlLpKzpDlMJ9cjEko=; b=tx6VdmaMp+eDek1GQgjv0V3RgwNuJPyFV3caxijPd4JyS52rs7ChTv7tWpkEqbOxap 4UBfKRa8mVuEHBjVjA3/r2REbbtdAyWVuitVBwNy67hoYTUVQbokBgdNZ/08mbJ/6qGN SYz4IjNYs6FbAiIMeqI6kBxXU7ye5Smw2OIbKeew7Nmp7hb9qoAlTcDlSnCHJ7l0xC/b Ho6Q4FXKncPO4Kw5wF9Yi3n++HwxRfgUokNfpQd2cwbASil4EszPmyWgg9KgnJGocWnb wnKsi3Uk9jd5LQSDNrX8ziKUuqdFj7BehbA8ZtCpmLfZdjEBaMKW0CenUPptEWgPWaGE xlRQ== X-Gm-Message-State: AOJu0YxPICAd7wMrvqlLx1h6kEbQeU7NExDV4aLgSkmlHSKDQjC7kCUj eR4QBz5Oym4cBZQuvVAkZIfU8FfpXWCx+A== X-Google-Smtp-Source: AGHT+IHwSJE6619ha6eECv5rLmMoTewrpN/6/+wEImi9C1t9xTxyeIHIUziT1V54Rj1wHj0uxpZgwQ== X-Received: by 2002:a05:6871:4594:b0:1f4:d347:df08 with SMTP id nl20-20020a056871459400b001f4d347df08mr21598736oab.17.1700163796857; Thu, 16 Nov 2023 11:43:16 -0800 (PST) Received: from localhost (fwdproxy-vll-120.fbsv.net. [2a03:2880:12ff:78::face:b00c]) by smtp.gmail.com with ESMTPSA id cj3-20020a05687c040300b001e11ad88f7csm6506oac.30.2023.11.16.11.43.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:16 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 3/9] bpftool: open and load bpf object Date: Thu, 16 Nov 2023 11:42:30 -0800 Message-Id: <20231116194236.1345035-4-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add an initial test that excercises opening and loading a bpf object. BPFTOOL_PATH=../bpftool CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" cargo test -- --nocapture Finished test [unoptimized + debuginfo] target(s) in 0.04s Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) running 2 tests Running command "../bpftool" "version" Running command "../bpftool" "map" "list" "--json" test bpftool_tests::run_bpftool ... ok test bpftool_tests::run_bpftool_map_list ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.19s Signed-off-by: Manu Bretelle --- .../selftests/bpf/bpftool_tests/Cargo.toml | 3 ++ .../bpf/bpftool_tests/src/bpftool_tests.rs | 50 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml index 35c834082351..cc1fa65189f2 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml +++ b/tools/testing/selftests/bpf/bpftool_tests/Cargo.toml @@ -5,7 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1" libbpf-rs = "0.21" +serde = { version = "1", features = ["derive"] } +serde_json = "1" [build-dependencies] libbpf-cargo = "0.21" diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index 35eb35831dce..fb58898a4a1a 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -3,11 +3,49 @@ mod bpftool_tests_skel { include!(concat!(env!("OUT_DIR"), "/bpftool_tests.skel.rs")); } +use anyhow::Result; +use bpftool_tests_skel::BpftoolTestsSkel; +use bpftool_tests_skel::BpftoolTestsSkelBuilder; +use libbpf_rs::skel::OpenSkel; +use libbpf_rs::skel::SkelBuilder; +use serde::Deserialize; +use serde::Serialize; + use std::process::Command; const BPFTOOL_PATH_ENV: &str = "BPFTOOL_PATH"; const BPFTOOL_PATH: &str = "/usr/sbin/bpftool"; +/// A struct representing a pid entry from map/prog dump +#[derive(Serialize, Deserialize, Debug)] +struct Pid { + comm: String, + pid: u64, +} + +/// A struct representing a map entry from `bpftool map list -j` +#[derive(Serialize, Deserialize, Debug)] +struct Map { + name: Option, + id: u64, + r#type: String, + #[serde(default)] + pids: Vec, +} + +/// Setup our bpftool_tests.bpf.c program. +/// Open and load and return an opened object. +fn setup() -> Result> { + let mut skel_builder = BpftoolTestsSkelBuilder::default(); + skel_builder.obj_builder.debug(false); + + let open_skel = skel_builder.open()?; + + let skel = open_skel.load()?; + + Ok(skel) +} + /// Run a bpftool command and returns the output fn run_bpftool_command(args: &[&str]) -> std::process::Output { let mut cmd = Command::new(std::env::var(BPFTOOL_PATH_ENV).unwrap_or(BPFTOOL_PATH.to_string())); @@ -22,3 +60,15 @@ fn run_bpftool() { let output = run_bpftool_command(&["version"]); assert!(output.status.success()); } + +/// A test to validate that we can list maps using bpftool +#[test] +fn run_bpftool_map_list() { + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&["map", "list", "--json"]); + + let maps = serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(output.status.success(), "bpftool returned an error."); + assert!(!maps.is_empty(), "No maps were listed"); +} From patchwork Thu Nov 16 19:42:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458218 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xv55Vuc+" Received: from mail-oa1-x2b.google.com (mail-oa1-x2b.google.com [IPv6:2001:4860:4864:20::2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F9A81A8 for ; Thu, 16 Nov 2023 11:43:20 -0800 (PST) Received: by mail-oa1-x2b.google.com with SMTP id 586e51a60fabf-1f4bbf525c7so580961fac.0 for ; Thu, 16 Nov 2023 11:43:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163799; x=1700768599; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=etSYgH62EA674SBlOtz+kIIlTGcfq6rOe2EK9PTrnDA=; b=Xv55Vuc+7UOR6KsVxouSaPjdAPRhslCVfMV8D/8BPBRihwvWugLhfqauNRSQaqZesP 8pq2KkDNJofU1Fwu4IhR2rC9/5VDKcNvsffvCpbJrZXAdpbvGm0hOyxPD6KlQkldYn18 CRxAlEQB/7pEr0dr14e08Tps+h0ZflkGM+mT8fqa38Qm7LWXc01Ur1Ezh6h9C3COHUW2 VOimcH06mXqg+4rKrxxZD08aVhd4LZhYBbpEqpgHyo7dMOswC95hGq3O/0iwwK7YG0nz 5kC+dcm33bIDAhKwJSxViDJ2nu2XCPEOPdvdsJEARxwFH1BkGY9InD9LSXhpYE49NXhK YaMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163799; x=1700768599; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=etSYgH62EA674SBlOtz+kIIlTGcfq6rOe2EK9PTrnDA=; b=MuJD0ut5xY5/vXh5jThtue/cdRMq5L7JtCEHd18uxkEuW7LE/+kqPmSyrd/ZfGaSQt pa+VpJ6E8wF4kHx7k/rJ3F52LFdZpKuwv0sTB6WNihsRDNT1SWDttMra2KOIQglP+Poq 0guCFNHYcneFJliS3cVA0CU0uoG7SdFGJW4gZRvsGpGaNaZZqNDLxrc0n2oHbwU5lZQ8 A/8+dIYl0izCCclddfn40gnhg5B697ao7YsqLwxa8nQ724z4p/XvwFkUPYxj+cm0an1z /+gATdfxTejbEaTSidSy0FenKm6fpIfbC1yUydx3zFuXZLC73GIiObF7OAGj8U0IHJyR fhmg== X-Gm-Message-State: AOJu0YxbxzRNKz9YGsn8c3YNH8TDEt/ETnsY+Y/lNsroLjgqbxx9gtF8 OiwOLwNOCuZhvvkSD/nz0ISYOlDRnhnMuQ== X-Google-Smtp-Source: AGHT+IH0LtnOgrSu7lUA1etmI7ZncIaM4KKZfsPmnfTJzFtYWule60pBlZQL5XAYiOj4NiT3OqKWFQ== X-Received: by 2002:a05:6870:b254:b0:1ef:9292:1dcc with SMTP id b20-20020a056870b25400b001ef92921dccmr1437434oam.14.1700163799300; Thu, 16 Nov 2023 11:43:19 -0800 (PST) Received: from localhost (fwdproxy-vll-003.fbsv.net. [2a03:2880:12ff:3::face:b00c]) by smtp.gmail.com with ESMTPSA id dv11-20020a0568716e8b00b001eb64e95c8bsm4335oac.57.2023.11.16.11.43.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:18 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 4/9] bpftool: Add test to verify that pids are associated to maps. Date: Thu, 16 Nov 2023 11:42:31 -0800 Message-Id: <20231116194236.1345035-5-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Signed-off-by: Manu Bretelle --- .../bpftool_tests/src/bpf/bpftool_tests.bpf.c | 7 +++++ .../bpf/bpftool_tests/src/bpftool_tests.rs | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c index 8b92171145de..dbd4e2aad277 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c @@ -4,6 +4,13 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL"; +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10240); + __type(key, u32); + __type(value, u64); +} pid_write_calls SEC(".maps"); + int my_pid = 0; SEC("tp/syscalls/sys_enter_write") diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index fb58898a4a1a..a832b255e988 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -72,3 +72,32 @@ fn run_bpftool_map_list() { assert!(output.status.success(), "bpftool returned an error."); assert!(!maps.is_empty(), "No maps were listed"); } + +/// A test to validate that we can find PIDs associated with a map +#[test] +fn run_bpftool_map_pids() { + let map_name = "pid_write_calls"; + + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&["map", "list", "--json"]); + + let maps = serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(output.status.success(), "bpftool returned an error."); + + // `pid_write_calls` is a map our bpftool_tests.bpf.c uses. It should have at least + // one entry for our current process. + let map = maps + .iter() + .find(|m| m.name.is_some() && m.name.as_ref().unwrap() == map_name) + .unwrap_or_else(|| panic!("Did not find {} map", map_name)); + + let mypid = std::process::id() as u64; + assert!( + map.pids.iter().any(|p| p.pid == mypid), + "Did not find test runner pid ({}) in pids list associated with map *{}*: {:?}", + mypid, + map_name, + map.pids + ); +} From patchwork Thu Nov 16 19:42:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458219 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ns/jTeg7" Received: from mail-oi1-x234.google.com (mail-oi1-x234.google.com [IPv6:2607:f8b0:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC84218D for ; Thu, 16 Nov 2023 11:43:22 -0800 (PST) Received: by mail-oi1-x234.google.com with SMTP id 5614622812f47-3b2e73a17a0so721234b6e.3 for ; Thu, 16 Nov 2023 11:43:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163802; x=1700768602; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=zSAFrdd8ohAsBGoigzzsKM5sLuyIw6fjiuYJlf0IDdw=; b=Ns/jTeg7ycg+AAMzWBy3yPIdEwsCx0qHTWzh82UbT7rDUMU0i7lRXlTozPkDVbyvMV KdmnTbqBKpFp1EqG8Gvx9WRzyYDvbEc2QX8uIGNP15XZDBMtq0/s0Jf1JpAn45Uj/aZH 1RHnjYie2z2u6RrKPfDHsZ1duw5y+vzoxIezhMwJcYikMoE0Ynj0lh/mujBhJiZMBfw2 MnjCaOYTxiwbNeGQtpBp5Apw1aVLL/FwCDWSaS1k2LfkxjIooPRWYbM4m5EtgOc9wLZ+ 9OYxOtV/XDYKeMIUT2vJgVYBbSKXR11/YRNcw1xbFzDCmiQsGMbkUiElvRw4nB2tTGGk p+xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163802; x=1700768602; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zSAFrdd8ohAsBGoigzzsKM5sLuyIw6fjiuYJlf0IDdw=; b=dzJbVzaV3hRvA+PpQcs2Pk1bLk0MdNDoNI9nfj2O13HOyxlkLAiLQ0ZiDk8GmnRIT9 IZBLUX8b3BiaL/W+Ncj9xhzhvpLfCEmEMlt3uMrBOZVDkCHY7RLfo2+j8s7oaExd8l7C CM+vOg5/Gd2+3oEOqqynLouBh/omvR4zdPtLDrHc1nRVbs9NVjsGdqJfxSy1y9GJUpVz E5a/EIBUSt7j3ODVIasyM692R6t1ZHayyy+LmS+vEC3xVAU0mj6DXIMc+wBO4I9mARH/ 5Qnrx3QqYh6k9OjzISmkf/ltdZYz8lhdYlLNFvvqOFKqcRXB0ir9Sqh57NsNDfZNtVQ3 9oPA== X-Gm-Message-State: AOJu0YwCJnebSBdotuffMIKkDwgMphsg6cys7pX0tZJFlW4EveLXP7rj dYL5eQ16zklXaKRx2eWWwh/Lvk6MIRvSsA== X-Google-Smtp-Source: AGHT+IEYOTGDgZjDSlYphUtBB+oUfAmMtxnxwCu9m6PV3G9pPTFH11l0yi4DMm9s3ZflDOVizi03wg== X-Received: by 2002:a54:4097:0:b0:3ad:fc3f:1202 with SMTP id i23-20020a544097000000b003adfc3f1202mr18120828oii.53.1700163801747; Thu, 16 Nov 2023 11:43:21 -0800 (PST) Received: from localhost (fwdproxy-vll-116.fbsv.net. [2a03:2880:12ff:74::face:b00c]) by smtp.gmail.com with ESMTPSA id n7-20020a05680803a700b003ae3768ba4csm9158oie.58.2023.11.16.11.43.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:21 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 5/9] bpftool: add test for bpftool prog Date: Thu, 16 Nov 2023 11:42:32 -0800 Message-Id: <20231116194236.1345035-6-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add tests that validate `bpftool prog list` functions, that we can associate pids with them, and that we can show a prog by id. $ BPFTOOL_PATH=../bpftool CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" cargo test -- --nocapture Finished test [unoptimized + debuginfo] target(s) in 0.05s Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) running 6 tests Running command "../bpftool" "version" test bpftool_tests::run_bpftool ... ok Running command "../bpftool" "map" "list" "--json" Running command "../bpftool" "prog" "list" "--json" Running command "../bpftool" "prog" "list" "--json" Running command "../bpftool" "map" "list" "--json" Running command "../bpftool" "prog" "show" "id" "3160417" "--json" test bpftool_tests::run_bpftool_prog_show_id ... ok test bpftool_tests::run_bpftool_map_pids ... ok test bpftool_tests::run_bpftool_map_list ... ok test bpftool_tests::run_bpftool_prog_pids ... ok test bpftool_tests::run_bpftool_prog_list ... ok test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.20s Signed-off-by: Manu Bretelle --- .../bpftool_tests/src/bpf/bpftool_tests.bpf.c | 2 +- .../bpf/bpftool_tests/src/bpftool_tests.rs | 79 ++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c index dbd4e2aad277..e2b18dd36207 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c @@ -14,7 +14,7 @@ struct { int my_pid = 0; SEC("tp/syscalls/sys_enter_write") -int handle_tp(void *ctx) +int handle_tp_sys_enter_write(void *ctx) { int pid = bpf_get_current_pid_tgid() >> 32; diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index a832b255e988..695a1cbc5be8 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -8,9 +8,10 @@ mod bpftool_tests_skel { use bpftool_tests_skel::BpftoolTestsSkelBuilder; use libbpf_rs::skel::OpenSkel; use libbpf_rs::skel::SkelBuilder; +use libbpf_rs::Program; use serde::Deserialize; use serde::Serialize; - +use std::os::fd::AsFd; use std::process::Command; const BPFTOOL_PATH_ENV: &str = "BPFTOOL_PATH"; @@ -23,6 +24,17 @@ struct Pid { pid: u64, } +/// A struct representing a prog entry from `bpftool prog list -j` +#[derive(Serialize, Deserialize, Debug)] +struct Prog { + name: Option, + id: u32, + r#type: String, + tag: String, + #[serde(default)] + pids: Vec, +} + /// A struct representing a map entry from `bpftool map list -j` #[derive(Serialize, Deserialize, Debug)] struct Map { @@ -101,3 +113,68 @@ fn run_bpftool_map_pids() { map.pids ); } + +/// A test to validate that we can list programs using bpftool +#[test] +fn run_bpftool_prog_list() { + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&["prog", "list", "--json"]); + + let progs = serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(output.status.success()); + assert!(!progs.is_empty(), "No programs were listed"); +} + +/// A test to validate that we can find PIDs associated with a program +#[test] +fn run_bpftool_prog_pids() { + let hook_name = "handle_tp_sys_enter_write"; + + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&["prog", "list", "--json"]); + + let progs = serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + assert!(output.status.success(), "bpftool returned an error."); + + // `handle_tp_sys_enter_write` is a hook our bpftool_tests.bpf.c attaches + // to (tp/syscalls/sys_enter_write). + // It should have at least one entry for our current process. + let prog = progs + .iter() + .find(|m| m.name.is_some() && m.name.as_ref().unwrap() == hook_name) + .unwrap_or_else(|| panic!("Did not find {} prog", hook_name)); + + let mypid = std::process::id() as u64; + assert!( + prog.pids.iter().any(|p| p.pid == mypid), + "Did not find test runner pid ({}) in pids list associated with prog *{}*: {:?}", + mypid, + hook_name, + prog.pids + ); +} + +/// A test to validate that we can run `bpftool prog show ` +/// an extract the expected information. +#[test] +fn run_bpftool_prog_show_id() { + let skel = setup().expect("Failed to set up BPF program"); + let binding = skel.progs(); + let handle_tp_sys_enter_write = binding.handle_tp_sys_enter_write(); + let prog_id = + Program::get_id_by_fd(handle_tp_sys_enter_write.as_fd()).expect("Failed to get prog ID"); + + let output = run_bpftool_command(&["prog", "show", "id", &prog_id.to_string(), "--json"]); + assert!(output.status.success(), "bpftool returned an error."); + + let prog = serde_json::from_slice::(&output.stdout).expect("Failed to parse JSON"); + + assert_eq!(prog_id, prog.id); + assert_eq!( + handle_tp_sys_enter_write.name(), + prog.name + .expect("Program handle_tp_sys_enter_write has no name") + ); + assert_eq!("tracepoint", prog.r#type); +} From patchwork Thu Nov 16 19:42:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458220 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YNP+GwmI" Received: from mail-oo1-xc29.google.com (mail-oo1-xc29.google.com [IPv6:2607:f8b0:4864:20::c29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59DE6D4B for ; Thu, 16 Nov 2023 11:43:25 -0800 (PST) Received: by mail-oo1-xc29.google.com with SMTP id 006d021491bc7-58786e23d38so672328eaf.3 for ; Thu, 16 Nov 2023 11:43:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163804; x=1700768604; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Y+6v8r+I4Xjr9cce6cYqpibCf+6XfAvex5lLVZa0Wjg=; b=YNP+GwmIwiey7qUK//HIz+eyf+qJnuFc4ystRzfVgWHQV6YLcEgxHhqqp3UdI5GpNc SPEEtNPythiEiV5t5BXDiVAuYL3/JLBgM/BoRWBD6fY+2Ck6LUIdHp2rGuHiHrIR97tK UyrVSv5PnrV9iG134N8JqBW/Rn71tf8nhst0jtTKuzo34gVdATKVBP9JAqzyC1Jl+tkZ cXolHhr7Le3UO2369kp0zOQkoZhLdSpdN4zK+5c728Fxl6HejDjTN6/8t5S4jXJ6Hb38 3lXCPfFV4mkYOcwRJymS4XGLswPyQP/yT9xZ06lHzs7UhTP44Ic3MUPVduVBpY1hr64t v99g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163804; x=1700768604; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Y+6v8r+I4Xjr9cce6cYqpibCf+6XfAvex5lLVZa0Wjg=; b=TzI/Yw2rsURh5szBFen6SlfrxgA+7ffX8+m9Jw32WrIjSEOnKd0dgjeLn6I60mM0y8 XZcAloQHoSt7AU7rpj9Xoc/ITQ/BZbFG+1bVAQSe/Ak6sHzAuorSsfKRJTDApO0coLqG 75/Q5rBZCRP8F/kvbo32F/4KPZx5w63bSkCGsKmbv0Rt4HwD39sU9pj1YnOkLqrRtmuF BCdjxUz2z7q2mzfYOq0YhDlymoSk/rmZeZnaVn6T8FE64nu1SVgoUEC+TV2zlTBnOTID 5r9hud1oWpQeBAAg6VtDPxlPPdp/HY2zcB8r+dZqL6UT2oyyKtLwzm0RizZ0OmVg6ARt Xaww== X-Gm-Message-State: AOJu0YwxKhB86Qhns2nSmIpAcxlfjoa1hGiyCE+0G70P623qD0DFTcjY jtLdtNk1z52GynTlV0UdchXN5pZRme2l6g== X-Google-Smtp-Source: AGHT+IGXeb9/ODvyJuHd/BYS1DoqBmh36xMsaSw7pIWGkD9DWkJMgY/Jm5MNKhaYGN+hiVV8YS593Q== X-Received: by 2002:a4a:de0b:0:b0:58a:231d:750d with SMTP id y11-20020a4ade0b000000b0058a231d750dmr16094942oot.9.1700163804263; Thu, 16 Nov 2023 11:43:24 -0800 (PST) Received: from localhost (fwdproxy-vll-009.fbsv.net. [2a03:2880:12ff:9::face:b00c]) by smtp.gmail.com with ESMTPSA id a2-20020a4a9882000000b0057b74352e3asm18199ooj.25.2023.11.16.11.43.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:23 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 6/9] bpftool: test that we can dump and read the content of a map Date: Thu, 16 Nov 2023 11:42:33 -0800 Message-Id: <20231116194236.1345035-7-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net This test adds a hardcoded key/value pair to a test map and verify that bpftool is able to dump its content and read/format it. $ BPFTOOL_PATH=../bpftool CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" cargo test -- --nocapture Finished test [unoptimized + debuginfo] target(s) in 0.05s Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) running 7 tests Running command "../bpftool" "version" test bpftool_tests::run_bpftool ... ok Running command "../bpftool" "map" "dump" "id" "1848713" "--json" Running command "../bpftool" "prog" "list" "--json" Running command "../bpftool" "map" "list" "--json" Running command "../bpftool" "prog" "list" "--json" Running command "../bpftool" "prog" "show" "id" "3160759" "--json" Running command "../bpftool" "map" "list" "--json" test bpftool_tests::run_bpftool_map_dump_id ... ok test bpftool_tests::run_bpftool_prog_show_id ... ok test bpftool_tests::run_bpftool_map_pids ... ok test bpftool_tests::run_bpftool_prog_pids ... ok test bpftool_tests::run_bpftool_prog_list ... ok test bpftool_tests::run_bpftool_map_list ... ok test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s Signed-off-by: Manu Bretelle --- .../bpftool_tests/src/bpf/bpftool_tests.bpf.c | 7 ++ .../bpf/bpftool_tests/src/bpftool_tests.rs | 86 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c index e2b18dd36207..a90c8921b4ee 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c @@ -11,6 +11,13 @@ struct { __type(value, u64); } pid_write_calls SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10); + __type(key, char[6]); + __type(value, char[6]); +} bpftool_test_map SEC(".maps"); + int my_pid = 0; SEC("tp/syscalls/sys_enter_write") diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index 695a1cbc5be8..90187152c1d1 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -45,6 +45,37 @@ struct Map { pids: Vec, } +/// A struct representing a formatted map entry from `bpftool map dump -j` +#[derive(Serialize, Deserialize, Debug)] +struct FormattedMapItem { + key: String, + value: String, +} + +type MapVecString = Vec; + +/// A struct representing a map entry from `bpftool map dump -j` +#[derive(Serialize, Deserialize, Debug)] +struct MapItem { + key: MapVecString, + value: MapVecString, + formatted: Option, +} + +/// A helper function to convert a vector of strings as returned by bpftool +/// into a vector of bytes. +/// bpftool returns key/value in the form of a sequence of strings +/// hexadecimal numbers. We need to convert them back to bytes. +/// for instance, the value of the key "key" is represented as ["0x6b","0x65","0x79"] +fn to_vec_u8(m: &MapVecString) -> Vec { + m.iter() + .map(|s| { + u8::from_str_radix(s.trim_start_matches("0x"), 16) + .unwrap_or_else(|_| panic!("Failed to parse {:?}", s)) + }) + .collect() +} + /// Setup our bpftool_tests.bpf.c program. /// Open and load and return an opened object. fn setup() -> Result> { @@ -114,6 +145,61 @@ fn run_bpftool_map_pids() { ); } +/// A test to validate that we can run `bpftool map dump ` +/// and extract the expected information. +/// The test adds a key, value pair to the map and then dumps it. +/// The test validates that the dumped data matches what was added. +/// It also validate that bpftool was able to format the key/value pairs. +#[test] +fn run_bpftool_map_dump_id() { + // By having key/value null terminated, we can check that bpftool also returns the + // formatted content. + let key = b"key\0\0\0"; + let value = b"value\0"; + let skel = setup().expect("Failed to set up BPF program"); + let binding = skel.maps(); + let bpftool_test_map_map = binding.bpftool_test_map(); + bpftool_test_map_map + .update(key, value, libbpf_rs::MapFlags::NO_EXIST) + .expect("Failed to update map"); + let map_id = bpftool_test_map_map + .info() + .expect("Failed to get map info") + .info + .id; + + let output = run_bpftool_command(&["map", "dump", "id", &map_id.to_string(), "--json"]); + assert!(output.status.success(), "bpftool returned an error."); + + let items = + serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert_eq!(items.len(), 1); + + let item = items.first().expect("Expected a map item"); + assert_eq!(to_vec_u8(&item.key), key); + assert_eq!(to_vec_u8(&item.value), value); + + // Validate "formatted" values. + // The keys and values are null terminated so we need to trim them before comparing. + let formatted = item + .formatted + .as_ref() + .expect("Formatted values are missing"); + assert_eq!( + formatted.key, + std::str::from_utf8(key) + .expect("Invalid UTF-8") + .trim_end_matches('\0'), + ); + assert_eq!( + formatted.value, + std::str::from_utf8(value) + .expect("Invalid UTF-8") + .trim_end_matches('\0'), + ); +} + /// A test to validate that we can list programs using bpftool #[test] fn run_bpftool_prog_list() { From patchwork Thu Nov 16 19:42:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458221 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KOnhOMYA" Received: from mail-oi1-x233.google.com (mail-oi1-x233.google.com [IPv6:2607:f8b0:4864:20::233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1784D50 for ; Thu, 16 Nov 2023 11:43:27 -0800 (PST) Received: by mail-oi1-x233.google.com with SMTP id 5614622812f47-3b6d80daae8so752709b6e.2 for ; Thu, 16 Nov 2023 11:43:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163807; x=1700768607; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=YrWhBCNz4UmXv7NkWcd22Z4lzc3/kxqEnof8fA00d/U=; b=KOnhOMYA1vik2A+MsdaqrjI92/dr+vVB4tfS+IKAHKYEWtNoMgNeypNkLNDTQRci4t 9uodgthdoTBSpM/87JpwS9M30wI1m1MqdTWN9WnGpapBllfZ2YjsfhELTGOCbVb6vafj ZhR38W58sJl/qDMa2/C8I/01ESk3veNJLhp3DnVnv7wvnop1MvN2Z+fO4sn0IdVC6Bu7 z2o4/7PNcRQlZFW4AwCQ6C9Pw2Qx3u3eKuBu8dUs74xtzC0BJrXriTPo+b9ZqT/p7Jdu LfOgw+daKV6fKvPSBXaDZ0+ebgxwZYs59k/Jp1wOzR3sBXonAjavxj72o5Mh1kyvpwVz LwkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163807; x=1700768607; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YrWhBCNz4UmXv7NkWcd22Z4lzc3/kxqEnof8fA00d/U=; b=pcNFovCGeYyjaPDa0WXvlEuJaGq1oFl3dFf/SD0tsFmTFc45w/6MH9o0BUbWhgvyYE AHaZIuQQv5UAW2p6/e6Lj1NikrhwfiZNS7QZbvOvwIzivMnEOrwAsiS6o2863AuVH5N8 7jLvZIvSwfUkvKgujcqFKFox5D0Kl0zBhpo/mRhE7uyLAAH1jREEMPPglVtIZHpTzC3j 82KcIHMDFMT+8J7KrMVC5/QrpYMIdLRKS63Kj4t401e41Xu4gmC6FLhHifizCSYw2pUL f4fvbiFVZmKUqPiOEHCB6Czxsh3Eh2xzkZ1MBg6vP621jxagIIBBq8VCQbvqD2GLiLCq 6UqQ== X-Gm-Message-State: AOJu0YyjfwXh4t10vT3Ez1TziSTw8LcDiSMhOZrVq/uOy2+cZ8LD0u3E E4Aa5YmP1mAiPC5vfJObLQSZQ+MvExATVA== X-Google-Smtp-Source: AGHT+IHMKwWIEzxhuNTNCBWoCe385B3Bz7MiP0Pewia9yc6zHHthpHRnI3LuvNiT4rcg7aLvN4O8lw== X-Received: by 2002:a05:6808:208e:b0:3af:611c:c74f with SMTP id s14-20020a056808208e00b003af611cc74fmr23128136oiw.5.1700163806849; Thu, 16 Nov 2023 11:43:26 -0800 (PST) Received: from localhost (fwdproxy-vll-006.fbsv.net. [2a03:2880:12ff:6::face:b00c]) by smtp.gmail.com with ESMTPSA id v16-20020a056808005000b003b2e7231faasm13362oic.28.2023.11.16.11.43.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:26 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 7/9] bpftool: Add struct_ops tests Date: Thu, 16 Nov 2023 11:42:34 -0800 Message-Id: <20231116194236.1345035-8-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add test to verify that we can: - unregister a struct_ops by id and name - list struct_ops - dump a struct_ops by name $ RUST_TEST_THREADS=1 BPFTOOL_PATH=../tools/build/bpftool/bpftool CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" cargo test -- --nocapture Finished test [unoptimized + debuginfo] target(s) in 0.05s Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) running 11 tests test bpftool_tests::run_bpftool ... Running command "../tools/build/bpftool/bpftool" "version" ok test bpftool_tests::run_bpftool_map_dump_id ... Running command "../tools/build/bpftool/bpftool" "map" "dump" "id" "1851884" "--json" ok test bpftool_tests::run_bpftool_map_list ... Running command "../tools/build/bpftool/bpftool" "map" "list" "--json" ok test bpftool_tests::run_bpftool_map_pids ... Running command "../tools/build/bpftool/bpftool" "map" "list" "--json" ok test bpftool_tests::run_bpftool_prog_list ... Running command "../tools/build/bpftool/bpftool" "prog" "list" "--json" ok test bpftool_tests::run_bpftool_prog_pids ... Running command "../tools/build/bpftool/bpftool" "prog" "list" "--json" ok test bpftool_tests::run_bpftool_prog_show_id ... Running command "../tools/build/bpftool/bpftool" "prog" "show" "id" "3166535" "--json" ok test bpftool_tests::run_bpftool_struct_ops_can_unregister_id ... Running command "../tools/build/bpftool/bpftool" "struct_ops" "dump" "name" "bt_e2e_tco" "--pretty" Running command "../tools/build/bpftool/bpftool" "struct_ops" "unregister" "id" "1851939" ok test bpftool_tests::run_bpftool_struct_ops_can_unregister_name ... Running command "../tools/build/bpftool/bpftool" "struct_ops" "dump" "name" "bt_e2e_tco" "--pretty" Running command "../tools/build/bpftool/bpftool" "struct_ops" "unregister" "name" "bt_e2e_tco" ok test bpftool_tests::run_bpftool_struct_ops_dump_name ... Running command "../tools/build/bpftool/bpftool" "struct_ops" "dump" "name" "bt_e2e_tco" "--pretty" ok test bpftool_tests::run_bpftool_struct_ops_list ... Running command "../tools/build/bpftool/bpftool" "struct_ops" "list" "--json" ok test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.84s Signed-off-by: Manu Bretelle --- .../bpftool_tests/src/bpf/bpftool_tests.bpf.c | 55 +++++++ .../bpf/bpftool_tests/src/bpftool_tests.rs | 145 ++++++++++++++++++ 2 files changed, 200 insertions(+) diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c index a90c8921b4ee..c59df9d947ed 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpf/bpftool_tests.bpf.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause #include "vmlinux.h" #include +#include + char LICENSE[] SEC("license") = "Dual BSD/GPL"; @@ -32,3 +34,56 @@ int handle_tp_sys_enter_write(void *ctx) return 0; } + +// struct_ops example + +#define BPF_STRUCT_OPS(name, args...) \ + SEC("struct_ops/" #name) \ + BPF_PROG(name, args) + +void BPF_STRUCT_OPS(tcp_init, struct sock *sk) +{ + return; +} + +void BPF_STRUCT_OPS(in_ack_event, struct sock *sk, __u32 flags) +{ + return; +} + +__u32 BPF_STRUCT_OPS(ssthresh, struct sock *sk) +{ + return 0; +} + +void BPF_STRUCT_OPS(set_state, struct sock *sk, __u8 new_state) +{ + return; +} + +void BPF_STRUCT_OPS(cwnd_event, struct sock *sk, enum tcp_ca_event ev) +{ + return; +} + +__u32 BPF_STRUCT_OPS(cwnd_undo, struct sock *sk) +{ + return 0; +} + +void BPF_STRUCT_OPS(cong_avoid, struct sock *sk, __u32 ack, __u32 acked) +{ + return; +} + +SEC(".struct_ops") +struct tcp_congestion_ops bt_e2e_tco = { + .init = (void *)tcp_init, + .in_ack_event = (void *)in_ack_event, + .cwnd_event = (void *)cwnd_event, + .ssthresh = (void *)ssthresh, + .cong_avoid = (void *)cong_avoid, + .undo_cwnd = (void *)cwnd_undo, + .set_state = (void *)set_state, + .name = "bt_e2e_tco", +}; diff --git a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs index 90187152c1d1..ecb9e92d7bac 100644 --- a/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs +++ b/tools/testing/selftests/bpf/bpftool_tests/src/bpftool_tests.rs @@ -7,6 +7,7 @@ mod bpftool_tests_skel { use bpftool_tests_skel::BpftoolTestsSkel; use bpftool_tests_skel::BpftoolTestsSkelBuilder; use libbpf_rs::skel::OpenSkel; +use libbpf_rs::skel::Skel; use libbpf_rs::skel::SkelBuilder; use libbpf_rs::Program; use serde::Deserialize; @@ -16,6 +17,7 @@ mod bpftool_tests_skel { const BPFTOOL_PATH_ENV: &str = "BPFTOOL_PATH"; const BPFTOOL_PATH: &str = "/usr/sbin/bpftool"; +const STRUCT_OPS_MAP_NAME: &str = "bt_e2e_tco"; /// A struct representing a pid entry from map/prog dump #[derive(Serialize, Deserialize, Debug)] @@ -62,6 +64,34 @@ struct MapItem { formatted: Option, } +/// A struct representing the map info from `bpftool struct_ops dump id ` +#[derive(Serialize, Deserialize, Debug)] +struct MapInfo { + name: String, + id: u64, +} + +/// A struct representing a struct_ops entry from `bpftool struct_ops list -j` +#[derive(Serialize, Deserialize, Debug)] +struct StructOps { + name: String, + id: u64, + kernel_struct_ops: String, +} + +/// A struct representing a struct_ops entry from `bpftool struct_ops dump id ` +#[derive(Serialize, Deserialize, Debug)] +struct StructOpsCongestion {} + +/// A struct representing a struct_ops entry from `bpftool struct_ops dump id ` +/// The returned json seems to be a tuple of two elements. +/// the first one being a MapInfo, the second one being a StructOpsCongestion. +#[derive(Serialize, Deserialize, Debug)] +struct StructOpsDump { + bpf_map_info: Option, + bpf_struct_ops_tcp_congestion_ops: Option, +} + /// A helper function to convert a vector of strings as returned by bpftool /// into a vector of bytes. /// bpftool returns key/value in the form of a sequence of strings @@ -264,3 +294,118 @@ fn run_bpftool_prog_show_id() { ); assert_eq!("tracepoint", prog.r#type); } + +/// A test to validate that we can list struct_ops using bpftool +#[test] +fn run_bpftool_struct_ops_list() { + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&["struct_ops", "list", "--json"]); + + let maps = + serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(output.status.success(), "bpftool returned an error."); + assert!(!maps.is_empty(), "No maps were listed"); +} + +/// A test to validate that we can dump a struct_ops program using its name +#[test] +fn run_bpftool_struct_ops_dump_name() { + let _skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&[ + "struct_ops", + "dump", + "name", + STRUCT_OPS_MAP_NAME, + "--pretty", + ]); + + assert!(output.status.success(), "bpftool returned an error."); + + let struct_ops = + serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + assert!(!struct_ops.is_empty(), "No struct_ops were found"); + + assert_eq!( + struct_ops[0] + .bpf_map_info + .as_ref() + .expect("Missing bpf_map_info field") + .name, + STRUCT_OPS_MAP_NAME + ); +} + +/// A test to validate that we can unregister a struct_ops using its id +#[test] +fn run_bpftool_struct_ops_can_unregister_id() { + let skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&[ + "struct_ops", + "dump", + "name", + STRUCT_OPS_MAP_NAME, + "--pretty", + ]); + + let _link = skel + .object() + .map(STRUCT_OPS_MAP_NAME) + .unwrap_or_else(|| panic!("Could not find map {}", STRUCT_OPS_MAP_NAME)) + .attach_struct_ops() + .expect("Could not attach to struct_ops"); + + assert!(output.status.success(), "bpftool returned an error."); + + let struct_ops = + serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(!struct_ops.is_empty(), "No struct_ops were found"); + + let id = struct_ops[0] + .bpf_map_info + .as_ref() + .expect("Missing bpf_map_info field") + .id; + + let output = run_bpftool_command(&["struct_ops", "unregister", "id", &id.to_string()]); + assert!( + output.status.success(), + "Failed to unregister struct_ops program: {:?}", + output + ); +} + +/// A test to validate that we can unregister a struct_ops using its name +#[test] +fn run_bpftool_struct_ops_can_unregister_name() { + let skel = setup().expect("Failed to set up BPF program"); + let output = run_bpftool_command(&[ + "struct_ops", + "dump", + "name", + STRUCT_OPS_MAP_NAME, + "--pretty", + ]); + + let _link = skel + .object() + .map(STRUCT_OPS_MAP_NAME) + .unwrap_or_else(|| panic!("Could not find map {}", STRUCT_OPS_MAP_NAME)) + .attach_struct_ops() + .expect("Could not attach to struct_ops"); + + assert!(output.status.success(), "bpftool returned an error."); + + let struct_ops = + serde_json::from_slice::>(&output.stdout).expect("Failed to parse JSON"); + + assert!(!struct_ops.is_empty(), "No struct_ops were found"); + + let output = run_bpftool_command(&["struct_ops", "unregister", "name", STRUCT_OPS_MAP_NAME]); + assert!( + output.status.success(), + "Failed to unregister struct_ops program: {:?}", + output + ); +} From patchwork Thu Nov 16 19:42:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458222 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W8fkaHwp" Received: from mail-oi1-x234.google.com (mail-oi1-x234.google.com [IPv6:2607:f8b0:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16DDB1A8 for ; Thu, 16 Nov 2023 11:43:31 -0800 (PST) Received: by mail-oi1-x234.google.com with SMTP id 5614622812f47-3b58d96a3bbso707018b6e.1 for ; Thu, 16 Nov 2023 11:43:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163810; x=1700768610; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=sudKXxJ9RIg5eZUc/cLdi0zWYdDkByV1m7wl+o4clvk=; b=W8fkaHwpivqLxvnRrui+ajKlQGmVHuNxw6Ps8DTPVZvwBTshiJdHUxw7C04YgZcn/t Dij0HllbXw8PQpyp6Y7YUMbFP5WmtwOBX/zsZT+I2MvY9dzek8juAlmgKSTBEV7I9b3u L33I9c/Jcuk3kLBtq2DM4Y7gChnJRQo78yTlVciS2+9Q/Zu3doSOD3z/qo+c52SSbtiH Pw+RXlgqmuINoX9S+CLbgG9u9R4rc3hSSoZ0AYV3xs4htjLtPx8YwrvShesEhciYmKKZ O9ug2t5Ko/Ssvr6Gu+FvzNss0TdJ5SPGXSHsJ2+eI5CoH31Dfrd2gsQttP782aExse2M GO3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163810; x=1700768610; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sudKXxJ9RIg5eZUc/cLdi0zWYdDkByV1m7wl+o4clvk=; b=cMSFEEu2Pn1xxVNosx/1Eyxx25V2/bRzcONvFok9UxGUeBZjWDPlUJKVlx6t1zZ9f9 54bC26bQhCIUkje945Q+Huh7G9y6JpEC15/F0RIJzhnoMBwPbKyQorNd9pK4UyymYVL9 Y1S5x4Ck5sRxb9Eeu5H7seGH519kDzDtJePECFtQVrwEujJOnfZoRR9H0L6niCH7f74s so9Y7bMPojYMFp3cYnXZ6uzY15oVB7h+3TAf4eRqWx7HszGlzxpqueBi0I/PGlYTg70g u9DSmu4Bb7BpicQyUNsLDpxb6QQ5s6H2T84XDLyMXyTS5GnBXWyRhtAkGrLjMKiWR7/q TgFg== X-Gm-Message-State: AOJu0Yx2ej/oh3Wktujks1H1O4SdUFyWBr2ryPQAjU8VfcC3vLQFmg13 fQ0xfkRUTwy+hdLwYi5hDT8PlOAtWwCFDg== X-Google-Smtp-Source: AGHT+IECxCm6RFuB9dSEt460/YSwr3+MveZkvEMRziCLrXhzDAhFeFgQGEHZqlrxEUwFebI1cdjYAQ== X-Received: by 2002:a05:6808:164d:b0:3ad:c476:9ad9 with SMTP id az13-20020a056808164d00b003adc4769ad9mr22001196oib.4.1700163809961; Thu, 16 Nov 2023 11:43:29 -0800 (PST) Received: from localhost (fwdproxy-vll-006.fbsv.net. [2a03:2880:12ff:6::face:b00c]) by smtp.gmail.com with ESMTPSA id b23-20020a056808011700b003afdc0f000esm14846oie.9.2023.11.16.11.43.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:29 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 8/9] bpftool: Add bpftool_tests README.md Date: Thu, 16 Nov 2023 11:42:35 -0800 Message-Id: <20231116194236.1345035-9-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net A README.md explaining how to run bpftool tests. Signed-off-by: Manu Bretelle --- .../selftests/bpf/bpftool_tests/README.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 tools/testing/selftests/bpf/bpftool_tests/README.md diff --git a/tools/testing/selftests/bpf/bpftool_tests/README.md b/tools/testing/selftests/bpf/bpftool_tests/README.md new file mode 100644 index 000000000000..8ee5d656f6f8 --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/README.md @@ -0,0 +1,91 @@ +## About the testing Framework + +The testing framework uses [RUST's testing framework](https://doc.rust-lang.org/rustc/tests/index.html) +and [libbpf-rs](https://docs.rs/libbpf-rs/latest/libbpf_rs/). + +The former takes care of scheduling tests and reporting their successes/failures. +The latter is used to load bpf programs, maps, and possibly interact with them +programatically through libbpf API. +This allows us to set the environment we want to test and check that `bpftool` +does what we expect. + +This document assumes you have [`cargo` and `rust` installed](https://doc.rust-lang.org/cargo/getting-started/installation.html). + +## Testing bpftool + +This should be no different than typical [`cargo test`](https://doc.rust-lang.org/cargo/commands/cargo-test.html) +but there is a few subtleties to consider when running `bpftool` tests: + +1. bpftool needs to run with root privileges for the most part. So the runner needs to run as root. +1. each tests load a program, possibly modify it, and check expectations. In order to be deterministic, tests need to run serially. + +### Environment variable + +A few environment variable can be used to control the behaviour of the tests: +- `RUST_TEST_THREADS`: This should be set to 1 to run one test at a time and avoid tests to step onto each others. +- `BPFTOOL_PATH`: Allow passing an alternate location for `bpftool`. Default: `/usr/sbin/bpftool` + +### Running the test suite + +Here are a few options to make this happen: + +``` +# build the test binary, extract the test executable location +# and run it with sudo, 1 test at a time. +eval sudo BPFTOOL_PATH=$(pwd)/../bpftool RUST_TEST_THREADS=1 \ + $(cargo test --no-run \ + --message-format=json | jq '. | select(.executable != null ).executable' \ + ) +``` + +or alternatively, one can use the [`CARGO_TARGET__RUNNER` environment variable](https://doc.rust-lang.org/cargo/reference/environment-variables.html#:~:text=CARGO_TARGET_%3Ctriple%3E_RUNNER). + +The benefit of that approach is that compilation errors will show directly in the terminal. + +``` +CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" \ + BPFTOOL_PATH=$(pwd)/../bpftool \ + RUST_TEST_THREADS=1 \ + cargo test +``` + +### Running tests against built kernel/bpftool + +Using [vmtest](https://github.com/danobi/vmtest): + +``` +$ KERNEL_REPO=~/devel/bpf-next/ +$ vmtest -k $KERNEL_REPO/arch/x86_64/boot/bzImage "BPFTOOL_PATH=$KERNEL_REPO/tools/bpf/bpftool/bpftool RUST_TEST_THREADS=1 cargo test" +=> bzImage +===> Booting +===> Setting up VM +===> Running command + Finished test [unoptimized + debuginfo] target(s) in 2.06s + Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) + +running 11 tests +test bpftool_tests::run_bpftool ... ok +test bpftool_tests::run_bpftool_map_dump_id ... ok +test bpftool_tests::run_bpftool_map_list ... ok +test bpftool_tests::run_bpftool_map_pids ... ok +test bpftool_tests::run_bpftool_prog_list ... ok +test bpftool_tests::run_bpftool_prog_pids ... ok +test bpftool_tests::run_bpftool_prog_show_id ... ok +test bpftool_tests::run_bpftool_struct_ops_can_unregister_id ... ok +test bpftool_tests::run_bpftool_struct_ops_can_unregister_name ... ok +test bpftool_tests::run_bpftool_struct_ops_dump_name ... ok +test bpftool_tests::run_bpftool_struct_ops_list ... ok + +test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.88s +``` + +the return code will be 0 on success, non-zero otherwise. + + +## Caveat + +Currently, libbpf-sys crate either uses a vendored libbpf, or the system one. +This could possibly limit tests against features that are being introduced. + +That being said, this is not a blocker now, and can be fixed upstream. +https://github.com/libbpf/libbpf-sys/issues/70 tracks this on libbpf-sys side. From patchwork Thu Nov 16 19:42:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manu Bretelle X-Patchwork-Id: 13458223 X-Patchwork-Delegate: bpf@iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NqTuGCDi" Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A93690 for ; Thu, 16 Nov 2023 11:43:33 -0800 (PST) Received: by mail-ot1-x329.google.com with SMTP id 46e09a7af769-6cd09663b1cso721254a34.3 for ; Thu, 16 Nov 2023 11:43:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700163812; x=1700768612; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=+kxCYimjhScHhOiqFD0x0jmkbAuTB3yGg/QItDo0Jk4=; b=NqTuGCDiZAxdWZIxine5fKV3r/2O7C+PDIyQf7+0Sbaras+vVTfsaOXCGgbQUdLfq+ RR2/1UXU/ZPa7LIviw3AUPznCZFb18wxTQnSW26315X6V7R3TQH9hppcocUZuGzUDaqW CKfZVyAx/Tdmet6ckGUNjKHcBDA9CkPUv17axZIHP9Datgh6+KL7ZGM76WvIP1+HabgL ii6dxHEUROsnhMHgaY4DW2Jk7Nu+9VdEe89FqgGhiVhZwFDHe+zidzPZK7tYJOXBiZdC /0GxkbWjdKa1bhHN2KuL69eVkbrAPmfLHf3gfcLZ+kxedaO9MMb8PurmNDDyD6EMoq5m grQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700163812; x=1700768612; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+kxCYimjhScHhOiqFD0x0jmkbAuTB3yGg/QItDo0Jk4=; b=ic9YsPK58riPFroQ0gqBNS+oxzkFBDyjwtBiFpRyQT79unjv0F11Pk2MYxPuFHTo6T seZNdTqfqv63bBKdNscXH0Ket8+YElB6JVGhup2aT+2beB5ffq0J1e2vor/44eErFa0j fZTnFMZIl8h1UsIZBppQhizjNCIHWDJS7bcmbuxwnFaE+SPpMG3blZUVKgM9IVSjDGJ1 Nx/3HQ+LD9YFziUeGLNe9ylZAjRPvcUAc0d4Wm1pMSVl1IICgo2Q98UJZLjLoNrtXj9z 5GKaNPhFL3FiWv1rlrUwCpftaUVqyXUzzsPROGmpIsv7P3gJgDWgPmgBKEXxfxogDiNS BfZg== X-Gm-Message-State: AOJu0YzJC/389M4DWxz70+Kfk6NUORNTOXLUO8IPO6jDRowUjCZop5zT CP/vSzEGLBD1dpu6lvd5NB83vnjzbV/3KA== X-Google-Smtp-Source: AGHT+IE816fwN7drhSdgULnmKZoWcPgdJQfFW8HEOvmoP5M0nG6DZLR1WBMZoo9Qy9ovtImoR8KoVg== X-Received: by 2002:a9d:4802:0:b0:6bf:1e78:cc52 with SMTP id c2-20020a9d4802000000b006bf1e78cc52mr9342475otf.25.1700163812495; Thu, 16 Nov 2023 11:43:32 -0800 (PST) Received: from localhost (fwdproxy-vll-116.fbsv.net. [2a03:2880:12ff:74::face:b00c]) by smtp.gmail.com with ESMTPSA id em9-20020a056830020900b006d691456571sm1365otb.64.2023.11.16.11.43.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 11:43:32 -0800 (PST) From: Manu Bretelle To: bpf@vger.kernel.org, quentin@isovalent.com, andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org Subject: [PATCH v1 bpf-next 9/9] bpftool: Add Makefile to facilitate bpftool_tests usage Date: Thu, 16 Nov 2023 11:42:36 -0800 Message-Id: <20231116194236.1345035-10-chantr4@gmail.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231116194236.1345035-1-chantr4@gmail.com> References: <20231116194236.1345035-1-chantr4@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Provide some Makefile targets to run the linter, build the tests, and run them on the host or in a VM. $ make vmtest cargo test --no-run --offline Finished test [unoptimized + debuginfo] target(s) in 0.05s Executable unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) vmtest -k /data/users/chantra/bpf-next/arch/x86/boot/bzImage "RUST_TEST_THREADS=1 BPFTOOL_PATH=../tools/build/bpftool/bpftool cargo test" => bzImage ===> Booting ===> Setting up VM ===> Running command Finished test [unoptimized + debuginfo] target(s) in 2.05s Running unittests src/main.rs (target/debug/deps/bpftool_tests-afa5a7eef3cdeafb) running 11 tests test bpftool_tests::run_bpftool ... ok test bpftool_tests::run_bpftool_map_dump_id ... ok test bpftool_tests::run_bpftool_map_list ... ok test bpftool_tests::run_bpftool_map_pids ... ok test bpftool_tests::run_bpftool_prog_list ... ok test bpftool_tests::run_bpftool_prog_pids ... ok test bpftool_tests::run_bpftool_prog_show_id ... ok test bpftool_tests::run_bpftool_struct_ops_can_unregister_id ... ok test bpftool_tests::run_bpftool_struct_ops_can_unregister_name ... ok test bpftool_tests::run_bpftool_struct_ops_dump_name ... ok test bpftool_tests::run_bpftool_struct_ops_list ... ok test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.88s Signed-off-by: Manu Bretelle --- .../selftests/bpf/bpftool_tests/Makefile | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tools/testing/selftests/bpf/bpftool_tests/Makefile diff --git a/tools/testing/selftests/bpf/bpftool_tests/Makefile b/tools/testing/selftests/bpf/bpftool_tests/Makefile new file mode 100644 index 000000000000..0b5633cda8b4 --- /dev/null +++ b/tools/testing/selftests/bpf/bpftool_tests/Makefile @@ -0,0 +1,22 @@ +BPFTOOL := ../tools/build/bpftool/bpftool + +lint: + cargo clippy --tests + cargo check --tests + +# Build the tests but do not run them. +build-test: + cargo test --no-run --offline + +# Run the tests on the host using sudo +test: build-test + RUST_TEST_THREADS=1 BPFTOOL_PATH=$(BPFTOOL) sudo -E $(shell which cargo) test --offline + +# Run the tests in a vm. Requires danobi/vmtest. +vmtest: build-test + $(eval repo_root := $(shell git rev-parse --show-toplevel)) + $(eval kernel_img := $(shell make -s -C $(repo_root) image_name)) + vmtest -k $(repo_root)/$(kernel_img) "RUST_TEST_THREADS=1 BPFTOOL_PATH=$(BPFTOOL) cargo test" + +clean: + cargo clean