For all of the users of sample_install_xdp() infra (primarily for xdp_redirect_cpu), add the ability to enable/disable/control generic metadata generation using the new UAPI. The format is either just '-M' to enable it unconditionally or '--meta-thresh=<frame_size>' to enable it starting from frames bigger than <frame_size>. Signed-off-by: Alexander Lobakin <alexandr.lobakin@xxxxxxxxx> --- samples/bpf/xdp_redirect_cpu_user.c | 7 +++++- samples/bpf/xdp_redirect_map_multi_user.c | 7 +++++- samples/bpf/xdp_redirect_map_user.c | 7 +++++- samples/bpf/xdp_redirect_user.c | 6 ++++- samples/bpf/xdp_router_ipv4_user.c | 7 +++++- samples/bpf/xdp_sample_user.c | 28 +++++++++++++++++++---- samples/bpf/xdp_sample_user.h | 1 + 7 files changed, 53 insertions(+), 10 deletions(-) diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 15745d8cb5c2..ca457c34eb0f 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -60,6 +60,7 @@ static const struct option long_options[] = { { "mprog-filename", required_argument, NULL, 'f' }, { "redirect-device", required_argument, NULL, 'r' }, { "redirect-map", required_argument, NULL, 'm' }, + { "meta-thresh", optional_argument, NULL, 'M' }, {} }; @@ -382,7 +383,7 @@ int main(int argc, char **argv) } prog = skel->progs.xdp_prognum5_lb_hash_ip_pairs; - while ((opt = getopt_long(argc, argv, "d:si:Sxp:f:e:r:m:c:q:Fvh", + while ((opt = getopt_long(argc, argv, "d:si:Sxp:f:e:r:m:c:q:FMvh", long_options, &longindex)) != -1) { switch (opt) { case 'd': @@ -461,6 +462,10 @@ int main(int argc, char **argv) case 'v': sample_switch_mode(); break; + case 'M': + opts.meta_thresh = optarg ? strtoul(optarg, NULL, 0) : + 1; + break; case 'h': error = false; default: diff --git a/samples/bpf/xdp_redirect_map_multi_user.c b/samples/bpf/xdp_redirect_map_multi_user.c index 85e66f9dc259..b1c575f3d5f6 100644 --- a/samples/bpf/xdp_redirect_map_multi_user.c +++ b/samples/bpf/xdp_redirect_map_multi_user.c @@ -43,6 +43,7 @@ static const struct option long_options[] = { { "stats", no_argument, NULL, 's' }, { "interval", required_argument, NULL, 'i' }, { "verbose", no_argument, NULL, 'v' }, + { "meta-thresh", optional_argument, NULL, 'M' }, {} }; @@ -89,7 +90,7 @@ int main(int argc, char **argv) bool error = true; int i, opt; - while ((opt = getopt_long(argc, argv, "hSFXi:vs", + while ((opt = getopt_long(argc, argv, "hSFMXi:vs", long_options, NULL)) != -1) { switch (opt) { case 'S': @@ -98,6 +99,10 @@ int main(int argc, char **argv) mask &= ~(SAMPLE_DEVMAP_XMIT_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI); break; + case 'M': + opts.meta_thresh = optarg ? strtoul(optarg, NULL, 0) : + 1; + break; case 'F': opts.force = true; break; diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index d09ef866e62b..29dd7df804dc 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -37,6 +37,7 @@ static const struct option long_options[] = { { "stats", no_argument, NULL, 's' }, { "interval", required_argument, NULL, 'i' }, { "verbose", no_argument, NULL, 'v' }, + { "meta-thresh", optional_argument, NULL, 'M' }, {} }; @@ -58,7 +59,7 @@ int main(int argc, char **argv) bool error = true; int opt, key = 0; - while ((opt = getopt_long(argc, argv, "hSFXi:vs", + while ((opt = getopt_long(argc, argv, "hSFMXi:vs", long_options, NULL)) != -1) { switch (opt) { case 'S': @@ -67,6 +68,10 @@ int main(int argc, char **argv) mask &= ~(SAMPLE_DEVMAP_XMIT_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI); break; + case 'M': + opts.meta_thresh = optarg ? strtoul(optarg, NULL, 0) : + 1; + break; case 'F': opts.force = true; break; diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c index 2da686a9b8a0..f37c570877ca 100644 --- a/samples/bpf/xdp_redirect_user.c +++ b/samples/bpf/xdp_redirect_user.c @@ -36,6 +36,7 @@ static const struct option long_options[] = { {"stats", no_argument, NULL, 's' }, {"interval", required_argument, NULL, 'i' }, {"verbose", no_argument, NULL, 'v' }, + {"meta-thresh", optional_argument, NULL, 'M' }, {} }; @@ -51,7 +52,7 @@ int main(int argc, char **argv) struct xdp_redirect *skel; bool error = true; - while ((opt = getopt_long(argc, argv, "hSFi:vs", + while ((opt = getopt_long(argc, argv, "hSFMi:vs", long_options, NULL)) != -1) { switch (opt) { case 'S': @@ -59,6 +60,9 @@ int main(int argc, char **argv) mask &= ~(SAMPLE_DEVMAP_XMIT_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI); break; + case 'M': + opts.meta_thresh = optarg ? strtoul(optarg, NULL, 0) : + 1; case 'F': opts.force = true; break; diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c index 48e9bcb38c8e..5ff12688a31b 100644 --- a/samples/bpf/xdp_router_ipv4_user.c +++ b/samples/bpf/xdp_router_ipv4_user.c @@ -53,6 +53,7 @@ static const struct option long_options[] = { { "interval", required_argument, NULL, 'i' }, { "verbose", no_argument, NULL, 'v' }, { "stats", no_argument, NULL, 's' }, + { "meta-thresh", optional_argument, NULL, 'M' }, {} }; @@ -593,7 +594,7 @@ int main(int argc, char **argv) goto end_destroy; } - while ((opt = getopt_long(argc, argv, "si:SFvh", + while ((opt = getopt_long(argc, argv, "si:SFMvh", long_options, &longindex)) != -1) { switch (opt) { case 's': @@ -621,6 +622,10 @@ int main(int argc, char **argv) total_ifindex--; ifname_list++; break; + case 'M': + opts.meta_thresh = optarg ? strtoul(optarg, NULL, 0) : + 1; + break; case 'h': error = false; default: diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 8bc23b4c5f19..354352541c5e 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -1283,6 +1283,8 @@ static int __sample_remove_xdp(int ifindex, __u32 prog_id, int xdp_flags) int sample_install_xdp(struct bpf_program *xdp_prog, const struct sample_install_opts *opts) { + LIBBPF_OPTS(bpf_xdp_attach_opts, attach_opts, + .meta_thresh = opts->meta_thresh); __u32 ifindex = opts->ifindex; int ret, xdp_flags = 0; __u32 prog_id = 0; @@ -1293,18 +1295,34 @@ int sample_install_xdp(struct bpf_program *xdp_prog, return -ENOTSUP; } + if (attach_opts.meta_thresh) { + ret = libbpf_get_type_btf_id("struct xdp_meta_generic", + &attach_opts.btf_id); + if (ret) { + fprintf(stderr, "Failed to retrieve BTF ID: %s\n", + strerror(-ret)); + return ret; + } + } + xdp_flags |= !opts->force ? XDP_FLAGS_UPDATE_IF_NOEXIST : 0; xdp_flags |= opts->generic ? XDP_FLAGS_SKB_MODE : XDP_FLAGS_DRV_MODE; - ret = bpf_xdp_attach(ifindex, bpf_program__fd(xdp_prog), xdp_flags, NULL); + ret = bpf_xdp_attach(ifindex, bpf_program__fd(xdp_prog), xdp_flags, + &attach_opts); if (ret < 0) { ret = -errno; fprintf(stderr, - "Failed to install program \"%s\" on ifindex %d, mode = %s, " - "force = %s: %s\n", + "Failed to install program \"%s\" on ifindex %d, mode = %s, force = %s, metadata = ", bpf_program__name(xdp_prog), ifindex, opts->generic ? "skb" : "native", - opts->force ? "true" : "false", - strerror(-ret)); + opts->force ? "true" : "false"); + if (attach_opts.meta_thresh) + fprintf(stderr, + "true (from %u bytes, BTF ID is 0x%16llx)", + attach_opts.meta_thresh, attach_opts.btf_id); + else + fprintf(stderr, "false"); + fprintf(stderr, ": %s\n", strerror(-ret)); return ret; } diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index 22afe844ae30..207953406ee1 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -34,6 +34,7 @@ struct sample_install_opts { int ifindex; __u32 force:1; __u32 generic:1; + __u32 meta_thresh; }; int sample_setup_maps(struct bpf_map **maps); -- 2.36.1