From: Jesper Dangaard Brouer <brouer@redhat.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: brouer@redhat.com,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"Toke Høiland-Jørgensen" <toke@redhat.com>
Subject: Better ways to validate map via BTF?
Date: Thu, 28 Nov 2019 17:08:37 +0100 [thread overview]
Message-ID: <20191128170837.2236713b@carbon> (raw)
[-- Attachment #1: Type: text/plain, Size: 1429 bytes --]
Hi Andrii,
Is there are better way to validate that a userspace BPF-program uses
the correct map via BTF?
Below and in attached patch, I'm using bpf_obj_get_info_by_fd() to get
some map-info, and check info.value_size and info.max_entries match
what I expect. What I really want, is to check that "map-value" have
same struct layout as:
struct config {
__u32 action;
int ifindex;
__u32 options;
};
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
static void check_config_map_fd_info(int map_fd) {
struct bpf_map_info info = { 0 };
__u32 info_len = sizeof(info);
__u32 exp_value_size = sizeof(struct config);
__u32 exp_entries = 1;
int err;
/* BPF-info via bpf-syscall */
err = bpf_obj_get_info_by_fd(map_fd, &info, &info_len);
if (err) {
fprintf(stderr, "ERR: %s() can't get info - %s\n",
__func__, strerror(errno));
exit(EXIT_FAIL_BPF);
}
if (exp_value_size != info.value_size) {
fprintf(stderr, "ERR: %s() "
"Map value size(%d) mismatch expected size(%d)\n",
__func__, info.value_size, exp_value_size);
exit(EXIT_FAIL_BPF);
}
if (exp_entries != info.max_entries) {
fprintf(stderr, "ERR: %s() "
"Map max_entries(%d) mismatch expected entries(%d)\n",
__func__, info.max_entries, exp_entries);
exit(EXIT_FAIL_BPF);
}
}
struct config {
__u32 action;
int ifindex;
__u32 options;
};
[-- Attachment #2: 02-detect_map_mismatch --]
[-- Type: application/octet-stream, Size: 2423 bytes --]
samples/bpf: xdp_rxq_info check that map have expected size
From: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
samples/bpf/xdp_rxq_info_user.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/samples/bpf/xdp_rxq_info_user.c b/samples/bpf/xdp_rxq_info_user.c
index 51e0d810e070..fa60731fdbad 100644
--- a/samples/bpf/xdp_rxq_info_user.c
+++ b/samples/bpf/xdp_rxq_info_user.c
@@ -453,6 +453,35 @@ static void stats_poll(int interval, int action, __u32 cfg_opt)
free_stats_record(prev);
}
+static void check_config_map_fd_info(int map_fd) {
+ struct bpf_map_info info = { 0 };
+ __u32 info_len = sizeof(info);
+ __u32 exp_value_size = sizeof(struct config);
+ __u32 exp_entries = 1;
+ int err;
+
+ /* BPF-info via bpf-syscall */
+ err = bpf_obj_get_info_by_fd(map_fd, &info, &info_len);
+ if (err) {
+ fprintf(stderr, "ERR: %s() can't get info - %s\n",
+ __func__, strerror(errno));
+ exit(EXIT_FAIL_BPF);
+ }
+
+ if (exp_value_size != info.value_size) {
+ fprintf(stderr, "ERR: %s() "
+ "Map value size(%d) mismatch expected size(%d)\n",
+ __func__, info.value_size, exp_value_size);
+ exit(EXIT_FAIL_BPF);
+ }
+
+ if (exp_entries != info.max_entries) {
+ fprintf(stderr, "ERR: %s() "
+ "Map max_entries(%d) mismatch expected entries(%d)\n",
+ __func__, info.max_entries, exp_entries);
+ exit(EXIT_FAIL_BPF);
+ }
+}
int main(int argc, char **argv)
{
@@ -461,7 +490,7 @@ int main(int argc, char **argv)
struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP,
};
- struct bpf_prog_info info = {};
+ struct bpf_prog_info info = { 0 };
__u32 info_len = sizeof(info);
int prog_fd, map_fd, opt, err;
bool use_separators = true;
@@ -490,6 +519,7 @@ int main(int argc, char **argv)
return EXIT_FAIL;
map = bpf_map__next(NULL, obj);
+// map = bpf_object__find_map_by_name(obj, "config");
stats_global_map = bpf_map__next(map, obj);
rx_queue_index_map = bpf_map__next(stats_global_map, obj);
if (!map || !stats_global_map || !rx_queue_index_map) {
@@ -581,6 +611,7 @@ int main(int argc, char **argv)
setlocale(LC_NUMERIC, "en_US");
/* User-side setup ifindex in config_map */
+ check_config_map_fd_info(map_fd);
err = bpf_map_update_elem(map_fd, &key, &cfg, 0);
if (err) {
fprintf(stderr, "Store config failed (err:%d)\n", err);
next reply other threads:[~2019-11-28 16:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-28 16:08 Jesper Dangaard Brouer [this message]
2019-11-29 5:27 ` Better ways to validate map via BTF? Andrii Nakryiko
2019-11-29 8:27 ` Toke Høiland-Jørgensen
2019-12-02 20:03 ` Andrii Nakryiko
2019-12-03 11:05 ` Toke Høiland-Jørgensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191128170837.2236713b@carbon \
--to=brouer@redhat.com \
--cc=andrii.nakryiko@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=toke@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.