From patchwork Thu May 27 20:13:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12285235 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF01FC4707F for ; Thu, 27 May 2021 20:14:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BD0CF613D8 for ; Thu, 27 May 2021 20:14:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235798AbhE0UPg (ORCPT ); Thu, 27 May 2021 16:15:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235606AbhE0UPf (ORCPT ); Thu, 27 May 2021 16:15:35 -0400 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9958C061574 for ; Thu, 27 May 2021 13:14:01 -0700 (PDT) Received: by mail-pg1-x536.google.com with SMTP id r1so781571pgk.8 for ; Thu, 27 May 2021 13:14:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riotgames.com; s=riotgames; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IEC3u7WqCAAg+EhWK/9uXjp7zZVSRqNtYwLo8QVPRoc=; b=VyRb81ACOnn++bGC5JRrvEiOZyx9W2JBu4lurrDaNVnoRj5B9+ULKhHkcysz6jPibE NJjfeJfRtHXjQfG2kr/pjfl3WuXD6CBY3tE0jlBwCVNqonjE/YGeG5chUYIAiTmU/1lu v1E3q7ZIESx9lDH7VnAPuBh4PrqyAtnGsJfDQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IEC3u7WqCAAg+EhWK/9uXjp7zZVSRqNtYwLo8QVPRoc=; b=pvrsPuenq7aTNv8rTxqR3k5ldzs6MLO4kg28nzDBgVBXexdNVjZFZhxLM5dfkwfnXd Qb+hF9Jgdy3oa2iSjr4isvKHxsFHgl9H4myIMhkg+Po2wqTg/cVIwwZK4hLQlvK90nXp iSK/Va5Jj8p8hnQqFn0xfeg7tsvsb/CpLXZof7n3bBGsPCVp/Nm2XiG4HuTnxMSfr6jU rj9VTaVkzhp0B7hyQRrauML4gCTqjI7+BwjBfNXU7vPPLefSsWAJpoh6emADPCF658o2 rYo7HD6SEiwxL1riwu9WTJ4M0mKORXDUjFeanIBtw2jEE+fncfDq3H9l9ABpqjZwDcyf iOIw== X-Gm-Message-State: AOAM5330xz/yMW9S7OsV13e8pnMX1QRHUHtUE+lPveyzj39PqOv10rj6 l8lZQO3pCM8FI2vRnQn8TaieEVovbbb/QA== X-Google-Smtp-Source: ABdhPJwyc4I75Ae3kixacGjz+bAbJk3GfWt1dioNo+ovRmb1f+yfMm4fGit8Wr+pA5Bpqft+O5TtQQ== X-Received: by 2002:a63:8c55:: with SMTP id q21mr5260281pgn.96.1622146440931; Thu, 27 May 2021 13:14:00 -0700 (PDT) Received: from ip-10-184-182-114.us-west-2.compute.internal (ec2-54-191-147-77.us-west-2.compute.amazonaws.com. [54.191.147.77]) by smtp.gmail.com with ESMTPSA id 4sm2462456pgn.31.2021.05.27.13.14.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 May 2021 13:14:00 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v2 1/3] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 27 May 2021 20:13:39 +0000 Message-Id: <20210527201341.7128-2-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210527201341.7128-1-zeffron@riotgames.com> References: <20210527201341.7128-1-zeffron@riotgames.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Support passing a xdp_md via ctx_in/ctx_out in bpf_attr for BPF_PROG_TEST_RUN. The intended use case is to pass some XDP meta data to the test runs of XDP programs that are used as tail calls. For programs that use bpf_prog_test_run_xdp, support xdp_md input and output. Unlike with an actual xdp_md during a non-test run, data_meta must be 0 because it must point to the start of the provided user data. From the initial xdp_md, use data and data_end to adjust the pointers in the generated xdp_buff. All other non-zero fields are prohibited (with EINVAL). If the user has set ctx_out/ctx_size_out, copy the (potentially different) xdp_md back to the userspace. We require all fields of input xdp_md except the ones we explicitly support to be set to zero. The expectation is that in the future we might add support for more fields and we want to fail explicitly if the user runs the program on the kernel where we don't yet support them. Co-developed-by: Cody Haas Signed-off-by: Cody Haas Co-developed-by: Lisa Watanabe Signed-off-by: Lisa Watanabe Signed-off-by: Zvi Effron --- include/uapi/linux/bpf.h | 3 -- net/bpf/test_run.c | 84 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 2c1ba70abbf1..a9dcf3d8c85a 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -324,9 +324,6 @@ union bpf_iter_link_info { * **BPF_PROG_TYPE_SK_LOOKUP** * *data_in* and *data_out* must be NULL. * - * **BPF_PROG_TYPE_XDP** - * *ctx_in* and *ctx_out* must be NULL. - * * **BPF_PROG_TYPE_RAW_TRACEPOINT**, * **BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE** * diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index aa47af349ba8..3718c8a331dc 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -687,6 +687,45 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, return ret; } +static int convert_xdpmd_to_xdpb(struct xdp_buff *xdp, struct xdp_md *xdp_md) +{ + void *data; + u32 metalen; + struct net_device *device; + struct netdev_rx_queue *rxqueue; + + if (!xdp_md) + return 0; + + if (xdp_md->egress_ifindex != 0) + return -EINVAL; + + metalen = xdp_md->data - xdp_md->data_meta; + data = xdp->data_meta + metalen; + if (data > xdp->data_end) + return -EINVAL; + xdp->data = data; + + if (xdp_md->data_end - xdp_md->data != xdp->data_end - xdp->data) + return -EINVAL; + + if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0) + return -EINVAL; + + return 0; +} + +static void convert_xdpb_to_xdpmd(struct xdp_buff *xdp, struct xdp_md *xdp_md) +{ + if (!xdp_md) + return; + + /* xdp_md->data_meta must always point to the start of the out buffer */ + xdp_md->data_meta = 0; + xdp_md->data = xdp->data - xdp->data_meta; + xdp_md->data_end = xdp->data_end - xdp->data_meta; +} + int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr) { @@ -696,36 +735,68 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, u32 repeat = kattr->test.repeat; struct netdev_rx_queue *rxqueue; struct xdp_buff xdp = {}; + struct xdp_md *ctx = NULL; u32 retval, duration; u32 max_data_sz; + u32 metalen; void *data; int ret; - if (kattr->test.ctx_in || kattr->test.ctx_out) - return -EINVAL; + ctx = bpf_ctx_init(kattr, sizeof(struct xdp_md)); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + /* There can't be user provided data before the metadata */ + if (ctx) { + if (ctx->data_meta != 0) + return -EINVAL; + metalen = ctx->data - ctx->data_meta; + if (unlikely((metalen & (sizeof(__u32) - 1)) || + metalen > 32)) + return -EINVAL; + /* Metadata is allocated from the headroom */ + headroom -= metalen; + } /* XDP have extra tailroom as (most) drivers use full page */ max_data_sz = 4096 - headroom - tailroom; data = bpf_test_init(kattr, max_data_sz, headroom, tailroom); - if (IS_ERR(data)) + if (IS_ERR(data)) { + kfree(ctx); return PTR_ERR(data); + } rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); xdp_init_buff(&xdp, headroom + max_data_sz + tailroom, &rxqueue->xdp_rxq); xdp_prepare_buff(&xdp, data, headroom, size, true); + ret = convert_xdpmd_to_xdpb(&xdp, ctx); + if (ret) { + kfree(data); + kfree(ctx); + return ret; + } + bpf_prog_change_xdp(NULL, prog); ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); if (ret) goto out; - if (xdp.data != data + headroom || xdp.data_end != xdp.data + size) - size = xdp.data_end - xdp.data; - ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration); + + if (xdp.data_meta != data + headroom || xdp.data_end != xdp.data_meta + size) + size = xdp.data_end - xdp.data_meta; + + convert_xdpb_to_xdpmd(&xdp, ctx); + + ret = bpf_test_finish(kattr, uattr, xdp.data_meta, size, retval, duration); + if (!ret) + ret = bpf_ctx_finish(kattr, uattr, ctx, + sizeof(struct xdp_md)); out: bpf_prog_change_xdp(prog, NULL); kfree(data); + kfree(ctx); return ret; } @@ -809,7 +880,6 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (!ret) ret = bpf_ctx_finish(kattr, uattr, user_ctx, sizeof(struct bpf_flow_keys)); - out: kfree(user_ctx); kfree(data); From patchwork Thu May 27 20:13:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12285237 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F8FBC4707F for ; Thu, 27 May 2021 20:14:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49696613D8 for ; Thu, 27 May 2021 20:14:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235576AbhE0UPj (ORCPT ); Thu, 27 May 2021 16:15:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235034AbhE0UPi (ORCPT ); Thu, 27 May 2021 16:15:38 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C81AC061574 for ; Thu, 27 May 2021 13:14:05 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id b15-20020a17090a550fb029015dad75163dso1168251pji.0 for ; Thu, 27 May 2021 13:14:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riotgames.com; s=riotgames; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zABw6PbftX8+J2J+e9RuSfP1aEk29gspY6MJ1vjcFZ4=; b=ZWE6LFavU52z4S3kRvrGHxZAlhEz8yNjOF7c1Sv51f6KfUcEHe0KydWB7JhY0p0EPW bQHnu0ECWwzHem1WcpyxomFntobQLpLVH2iRQ76/YfuIHmbSF7s92yp9bB3CRe8H7bvT /qf52E6ur3/ETNjcgrc9iC9RT+zJbTAoQlZvc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zABw6PbftX8+J2J+e9RuSfP1aEk29gspY6MJ1vjcFZ4=; b=Bh+EtJIOBI9TSEO0vy+TVHD0Bw1d4tMwsMAlk8SfgYhEAM3ln/YUazPhP8w/FQfSB2 YxyVzcnBo7TPywUizpM0a5d52w6AyoDstjksJ7BvH8hzd1mKS68ScNMuVkglG2UMn6QD 0EffgYBAhuSHeZWNgPdAW+HxqahqI5RDScnM71c8ctaxPrz1uqwGJKGYc1DUfjZu7o5V i7Cjn+0YFQQyGILFyxa4jY95hbcZ60tTqBt503/02V4WRYXXkIeVIZiksc7DQkDwUcn4 qDcg5X5T86kOKV3I21O6Y4p+yb0F10ueirvagwdJeE9XRKg4q5/crSCn77OqTH88524y S5Sg== X-Gm-Message-State: AOAM531Yowf5eILyKfXgT6uwBLzFwBSnEf30UHG45su6f0xk6X7uaMtn gSM9+8vCYapHEVC9Bn2bQa6/In/Q582nDA== X-Google-Smtp-Source: ABdhPJwG3ubaMNyzC6ptKcgow1fcFwlGt/U+G8HhtyZ9h44+YkS99ASPBfmNHRNYPuEJQIX/ZtRD5g== X-Received: by 2002:a17:902:d90e:b029:fe:5139:898d with SMTP id c14-20020a170902d90eb02900fe5139898dmr4835761plz.61.1622146444276; Thu, 27 May 2021 13:14:04 -0700 (PDT) Received: from ip-10-184-182-114.us-west-2.compute.internal (ec2-54-191-147-77.us-west-2.compute.amazonaws.com. [54.191.147.77]) by smtp.gmail.com with ESMTPSA id 4sm2462456pgn.31.2021.05.27.13.14.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 May 2021 13:14:03 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v2 2/3] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 27 May 2021 20:13:40 +0000 Message-Id: <20210527201341.7128-3-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210527201341.7128-1-zeffron@riotgames.com> References: <20210527201341.7128-1-zeffron@riotgames.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Support specifying the ingress_ifindex and rx_queue_index of xdp_md contexts for BPF_PROG_TEST_RUN. The intended use case is to allow testing XDP programs that make decisions based on the ingress interface or RX queue. If ingress_ifindex is specified, look up the device by the provided index in the current namespace and use its xdp_rxq for the xdp_buff. If the rx_queue_index is out of range, or is non-zero when the ingress_ifindex is 0, return EINVAL. Co-developed-by: Cody Haas Signed-off-by: Cody Haas Co-developed-by: Lisa Watanabe Signed-off-by: Lisa Watanabe Signed-off-by: Zvi Effron --- net/bpf/test_run.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 3718c8a331dc..e14797eb1e14 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -709,9 +709,21 @@ static int convert_xdpmd_to_xdpb(struct xdp_buff *xdp, struct xdp_md *xdp_md) if (xdp_md->data_end - xdp_md->data != xdp->data_end - xdp->data) return -EINVAL; - if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0) + if (!xdp_md->ingress_ifindex && xdp_md->rx_queue_index) return -EINVAL; + if (xdp_md->ingress_ifindex) { + device = dev_get_by_index(current->nsproxy->net_ns, xdp_md->ingress_ifindex); + if (!device) + return -EINVAL; + + if (xdp_md->rx_queue_index >= device->real_num_rx_queues) + return -EINVAL; + + rxqueue = __netif_get_rx_queue(device, xdp_md->rx_queue_index); + xdp->rxq = &rxqueue->xdp_rxq; + } + return 0; } From patchwork Thu May 27 20:13:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12285239 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DA7EC4707F for ; Thu, 27 May 2021 20:14:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED612613E9 for ; Thu, 27 May 2021 20:14:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235034AbhE0UPp (ORCPT ); Thu, 27 May 2021 16:15:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235606AbhE0UPm (ORCPT ); Thu, 27 May 2021 16:15:42 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18DD7C061574 for ; Thu, 27 May 2021 13:14:08 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id m8-20020a17090a4148b029015fc5d36343so1155372pjg.1 for ; Thu, 27 May 2021 13:14:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riotgames.com; s=riotgames; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Xhh14+NC5dBagYqXQ5KzOQwL64MDTeDSeZOD4eZCp18=; b=BhWoGUcPbbkqPquxLZawTEvk7ysX6Vf0AOXleX8sDNNLB5lDsXHFBuLNsc7ydGlWDX 486ouDWhKxnXjcH8tqQLD6at3CXpKeru1xNyqEEPkdMJ0CzsXuwuus3shwaLtfRAzoMQ xAsrNl8GSkSPUMc5D2X/PRmR5Yh7ATaBFBYD8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Xhh14+NC5dBagYqXQ5KzOQwL64MDTeDSeZOD4eZCp18=; b=e63MoPD0Hm8VzUVYm1Oaq1ZsECkH7wWHrhVeZiLmCRZ6b5nvnrC4sybEx8GXp9zWV8 yD763BBuW/ysnLbg7vP0maokhQ1fhA0wL6CQb1jGJxIl8JKzmba1I3JmjyNR8pMyCyYc WoAsQmYO1k6ZO1EnhBkbsYMPEE6N9mK44CgDrgfdGnvkM6uu7jch6nvc/zq2MzeILVJs itLKQA98/jrZaM+0KVVotF664AANEY4d+SYQyV7W7vXhRkl1bCUrZeSUNthN+O8t3pUG 3Hqh4mp22dA7/2gUo/XC1F8lrIIsrcPXTblNVTgke1hfDeMaFVHmUW+rpCb2BDANpZfJ OnSw== X-Gm-Message-State: AOAM531eMfqKv0l2kHxk0PQ5tu1iNtyLiKpVhVb95YSJz9m60jHXipW0 lUpithYufdMzjkspUm3YOV2yl+lvSNFq0Q== X-Google-Smtp-Source: ABdhPJwwqsSjBJ7KD2AqUSbd/oMzGBejeXplg86FHm0PvhuQq7lMwcwqA44SzwUDrViz1WVUBAg3Ww== X-Received: by 2002:a17:903:30c4:b029:f0:ad43:4ca with SMTP id s4-20020a17090330c4b02900f0ad4304camr4631415plc.70.1622146447244; Thu, 27 May 2021 13:14:07 -0700 (PDT) Received: from ip-10-184-182-114.us-west-2.compute.internal (ec2-54-191-147-77.us-west-2.compute.amazonaws.com. [54.191.147.77]) by smtp.gmail.com with ESMTPSA id 4sm2462456pgn.31.2021.05.27.13.14.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 May 2021 13:14:06 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v2 3/3] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 27 May 2021 20:13:41 +0000 Message-Id: <20210527201341.7128-4-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210527201341.7128-1-zeffron@riotgames.com> References: <20210527201341.7128-1-zeffron@riotgames.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Add a test for using xdp_md as a context to BPF_PROG_TEST_RUN for XDP programs. The test uses a BPF program that takes in a return value from XDP metadata, then reduces the size of the XDP metadata by 4 bytes. Test cases validate the possible failure cases for passing in invalid xdp_md contexts, that the return value is successfully passed in, and that the adjusted metadata is successfully copied out. Co-developed-by: Cody Haas Signed-off-by: Cody Haas Co-developed-by: Lisa Watanabe Signed-off-by: Lisa Watanabe Signed-off-by: Zvi Effron --- .../bpf/prog_tests/xdp_context_test_run.c | 116 ++++++++++++++++++ .../bpf/progs/test_xdp_context_test_run.c | 20 +++ 2 files changed, 136 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c new file mode 100644 index 000000000000..f6d312005b7c --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "test_xdp_context_test_run.skel.h" + +void test_xdp_context_test_run(void) +{ + struct test_xdp_context_test_run *skel = NULL; + char data[sizeof(pkt_v4) + sizeof(__u32)]; + char buf[128]; + char bad_ctx[sizeof(struct xdp_md)]; + struct xdp_md ctx_in, ctx_out; + struct bpf_test_run_opts tattr = { + .sz = sizeof(struct bpf_test_run_opts), + .data_in = &data, + .data_out = buf, + .data_size_in = sizeof(data), + .data_size_out = sizeof(buf), + .ctx_out = &ctx_out, + .ctx_size_out = sizeof(ctx_out), + .repeat = 1, + }; + int err, prog_fd; + + + skel = test_xdp_context_test_run__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel")) + return; + prog_fd = bpf_program__fd(skel->progs._xdp_context); + + *(__u32 *)data = XDP_PASS; + *(struct ipv4_packet *)(data + sizeof(__u32)) = pkt_v4; + + memset(&ctx_in, 0, sizeof(ctx_in)); + tattr.ctx_in = &ctx_in; + tattr.ctx_size_in = sizeof(ctx_in); + + tattr.ctx_in = &ctx_in; + tattr.ctx_size_in = sizeof(ctx_in); + ctx_in.data_meta = 0; + ctx_in.data = sizeof(__u32); + ctx_in.data_end = ctx_in.data + sizeof(pkt_v4); + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_OK(err, "bpf_prog_test_run(test1)"); + ASSERT_EQ(tattr.retval, XDP_PASS, "test1-retval"); + ASSERT_EQ(tattr.data_size_out, sizeof(pkt_v4), "test1-datasize"); + ASSERT_EQ(tattr.ctx_size_out, tattr.ctx_size_in, "test1-ctxsize"); + ASSERT_EQ(ctx_out.data_meta, 0, "test1-datameta"); + ASSERT_EQ(ctx_out.data, ctx_out.data_meta, "test1-data"); + ASSERT_EQ(ctx_out.data_end, sizeof(pkt_v4), "test1-dataend"); + + /* Data past the end of the kernel's struct xdp_md must be 0 */ + bad_ctx[sizeof(bad_ctx) - 1] = 1; + tattr.ctx_in = bad_ctx; + tattr.ctx_size_in = sizeof(bad_ctx); + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test2)"); + ASSERT_EQ(errno, 22, "test2-errno"); + + /* The egress cannot be specified */ + ctx_in.egress_ifindex = 1; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test3)"); + ASSERT_EQ(errno, 22, "test3-errno"); + + /* data_meta must reference the start of data */ + ctx_in.data_meta = sizeof(__u32); + ctx_in.data = ctx_in.data_meta; + ctx_in.data_end = ctx_in.data + sizeof(pkt_v4); + ctx_in.egress_ifindex = 0; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test4)"); + ASSERT_EQ(errno, 22, "test4-errno"); + + /* Metadata must be 32 bytes or smaller */ + ctx_in.data_meta = 0; + ctx_in.data = sizeof(__u32)*9; + ctx_in.data_end = ctx_in.data + sizeof(pkt_v4); + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test5)"); + ASSERT_EQ(errno, 22, "test5-errno"); + + /* Metadata's size must be a multiple of 4 */ + ctx_in.data = 3; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test6)"); + ASSERT_EQ(errno, 22, "test6-errno"); + + /* Total size of data must match data_end - data_meta */ + ctx_in.data = 0; + ctx_in.data_end = sizeof(pkt_v4) - 4; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test7)"); + ASSERT_EQ(errno, 22, "test7-errno"); + + ctx_in.data_end = sizeof(pkt_v4) + 4; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test8)"); + ASSERT_EQ(errno, 22, "test8-errno"); + + /* RX queue cannot be specified without specifying an ingress */ + ctx_in.data_end = sizeof(pkt_v4); + ctx_in.ingress_ifindex = 0; + ctx_in.rx_queue_index = 1; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test9)"); + ASSERT_EQ(errno, 22, "test9-errno"); + + ctx_in.ingress_ifindex = 1; + ctx_in.rx_queue_index = 1; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + ASSERT_ERR(err, "bpf_prog_test_run(test10)"); + ASSERT_EQ(errno, 22, "test10-errno"); + + test_xdp_context_test_run__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c b/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c new file mode 100644 index 000000000000..56fd0995b67c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +SEC("xdp") +int _xdp_context(struct xdp_md *xdp) +{ + void *data = (void *)(unsigned long)xdp->data; + __u32 *metadata = (void *)(unsigned long)xdp->data_meta; + __u32 ret; + + if (metadata + 1 > data) + return XDP_ABORTED; + ret = *metadata; + if (bpf_xdp_adjust_meta(xdp, 4)) + return XDP_ABORTED; + return ret; +} + +char _license[] SEC("license") = "GPL";