From patchwork Wed Jun 2 19:08:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12295561 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.8 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 0F9F2C4708F for ; Wed, 2 Jun 2021 19:09:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E9F89613E4 for ; Wed, 2 Jun 2021 19:08:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229491AbhFBTKl (ORCPT ); Wed, 2 Jun 2021 15:10:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229467AbhFBTKk (ORCPT ); Wed, 2 Jun 2021 15:10:40 -0400 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DA2BC06174A for ; Wed, 2 Jun 2021 12:08:57 -0700 (PDT) Received: by mail-pj1-x1033.google.com with SMTP id lx17-20020a17090b4b11b029015f3b32b8dbso4034997pjb.0 for ; Wed, 02 Jun 2021 12:08:57 -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=mQyPzP2hRgPg9ikYPzLy7zoJVkTyAzCPPs6rI0FzscM=; b=rwnKHWHnJQRLT6tSbneCjQ7kjaxwkfSwYw8dTx41nqbzxc63VmPxM0EjUPP2EPEwRe f4qJbYApRDmhbqEcCobfVNVbYI6Rn9Au3vAJ2I0c9rb45X2w9NV+gXuGENEiRMWiL+pZ wJ/+T7JvxtC60pLnYG1Ge3Z8S9Y3G8WFyHmq0= 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=mQyPzP2hRgPg9ikYPzLy7zoJVkTyAzCPPs6rI0FzscM=; b=giQ3lpKjV5KJJ7Qj1rD+1LdlPntrgALW8ouqwkXOGyW6V1gf14JirVqjKpsnp9Fjn5 lZO7e9YH1hPVzb1p6bAquxArvEn2zgm5oeVvPNlQMZuMQx5n9qjHFNfB1Eu/z4SH1bZ7 ABCrg5y6eZoGF9SOYI2xAutVqFfM7oXunDxYQpEuPa6tumcFi/VhHh39U5xA3phgyN+2 /sFLE0tFsDbMEWO8B24ZBRtlMaY4ElKGA1qRkSXM6NKlL67GMKsB4oArc87B0VNPlbRm 8eN9ZbvGyIa1y7vy5zHBY49lqQs0gq6tY+S3V0jt6L+uooaTTj6uhlOYzxJjt2/jQTwj j7iQ== X-Gm-Message-State: AOAM533k2/rKvIYw1kkcmq5V6EIkeL9jc6p4mK1P312tuvl+PnmSCAqm rjhwJYaPSbG8npkZtMPu8TJy65JSOTkPPw== X-Google-Smtp-Source: ABdhPJzcxT2mTzJ/ZeHGmGGayHRF6bzu94nTVSKw6J30mRGxX/ekzxg3BgQlCmiN0+ol1FAlhwahFw== X-Received: by 2002:a17:90a:1b8f:: with SMTP id w15mr32023017pjc.101.1622660936234; Wed, 02 Jun 2021 12:08:56 -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 j12sm458036pgs.83.2021.06.02.12.08.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 12:08:55 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Maciej Fijalkowski , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v3 1/3] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Date: Wed, 2 Jun 2021 19:08:13 +0000 Message-Id: <20210602190815.8096-2-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602190815.8096-1-zeffron@riotgames.com> References: <20210602190815.8096-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 | 82 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 75 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..ae8741dd2a54 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -687,6 +687,43 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, return ret; } +static int xdp_convert_md_to_buff(struct xdp_buff *xdp, struct xdp_md *xdp_md) +{ + void *data; + u32 metalen; + + 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 xdp_convert_buff_to_md(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 +733,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 = xdp_convert_md_to_buff(&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; + + xdp_convert_buff_to_md(&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 +878,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 Wed Jun 2 19:08:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12295567 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.8 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 E9248C47083 for ; Wed, 2 Jun 2021 19:10:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D3109613EE for ; Wed, 2 Jun 2021 19:10:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229653AbhFBTMB (ORCPT ); Wed, 2 Jun 2021 15:12:01 -0400 Received: from mail-pg1-f179.google.com ([209.85.215.179]:46945 "EHLO mail-pg1-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229552AbhFBTMA (ORCPT ); Wed, 2 Jun 2021 15:12:00 -0400 Received: by mail-pg1-f179.google.com with SMTP id n12so3032486pgs.13 for ; Wed, 02 Jun 2021 12:10:04 -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=pg1gl8wAGETBw3StSSmWY+F9bYcItGwT/d+uAkBZmJo=; b=e7WRuoUYUzZgFu+xXiFmv1XwR+oxD2X1rBCn77JOMsBaS89gOfgWqAa0WIUf2rIC6G d5KUIjyOPhV1F0+dkRkHKqwDO00GZtLo3YlANkmztPr39tHkQIUyNnBWTTUuO66r0S7z UfhxghhMulCoYhaZaHNT5kP46jvDwFtdZCUzQ= 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=pg1gl8wAGETBw3StSSmWY+F9bYcItGwT/d+uAkBZmJo=; b=ag056oA67fCy2RVM8b5twBzQ7cN/XkNwOqCUd6gU0qsXFIhKyBrahVCs1mnS1TSDMa nWFVhofKjSMAIl3QiBIjJrmXKZvN8eDiL+26Aev2rvnuxdlFAt3lw9mP9api6O3bCPKR JxJ2mK2gmrrNqtNLNH1QQi+VrdoYf7Wu36br+hSFdVjMDpZ2PQyUsm2kI/Z9DxUQfE4z e6EBHDVuE127RSpnUOfJE1jxwdnvEB8s3vnOZIPxt/GWl+McbI6/czQYP7mu6ossvoU3 uDMffytK7KvMVcuAYKsTCu53ic852uHtTvhhhbG7DrI6gYQTomd5EgBl6ffSGpJmeksj LyYg== X-Gm-Message-State: AOAM533tNAom2agqhtNiDxwYmzmqWK+0b0lV0N1PJ0cVNFW7wgget/I0 1PvS8+ubAOx+uXWyqFzqdIhKrIV2KgecDg== X-Google-Smtp-Source: ABdhPJzyO7dY92HQWzX14NiRRh4FAhkWVcgZNpj6CEOR8dRQah7MESgGTUIRwEyxLnBIfFd/i7Fysg== X-Received: by 2002:a65:60c5:: with SMTP id r5mr15749388pgv.79.1622660944178; Wed, 02 Jun 2021 12:09: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 j12sm458036pgs.83.2021.06.02.12.09.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 12:09:03 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Maciej Fijalkowski , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v3 2/3] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN Date: Wed, 2 Jun 2021 19:08:14 +0000 Message-Id: <20210602190815.8096-3-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602190815.8096-1-zeffron@riotgames.com> References: <20210602190815.8096-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 | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index ae8741dd2a54..f139b4ca420f 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -691,6 +691,8 @@ static int xdp_convert_md_to_buff(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; @@ -707,9 +709,21 @@ static int xdp_convert_md_to_buff(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 Wed Jun 2 19:08:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12295565 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.8 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 D4713C47097 for ; Wed, 2 Jun 2021 19:10:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BAF2B613B4 for ; Wed, 2 Jun 2021 19:10:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229654AbhFBTLy (ORCPT ); Wed, 2 Jun 2021 15:11:54 -0400 Received: from mail-pl1-f182.google.com ([209.85.214.182]:46816 "EHLO mail-pl1-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229620AbhFBTLx (ORCPT ); Wed, 2 Jun 2021 15:11:53 -0400 Received: by mail-pl1-f182.google.com with SMTP id e1so1579982pld.13 for ; Wed, 02 Jun 2021 12:10:10 -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=gE6JKqyNdruBi/cWEwhmI0B7uKKCxYgcBMMsx5i3xIY=; b=bI3KUiypFNg9R4jSIaJ9FMd9cczbCRv++cglB3nTUHGO2eRk1sgt9nKORq26KL/KJh xkRX2zk7dRDPFFvZkhjN5teMhY7doxI6DGa5XuKgU0a3PfRMbYWar3AIwbbX2FOumNdn a55qJzZbXt4ni+0kaBBr5I3bCxkJNQFxcly94= 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=gE6JKqyNdruBi/cWEwhmI0B7uKKCxYgcBMMsx5i3xIY=; b=DvpL4ljbGeluWPNg+/Yo4FOQydC2LR/GJFgPcZh9cyMp0GWbw3LDrrIB2Wi7/r0gyq GQ+2WiCthdjxpAMXZwH3hVGC+q269kc/f1CPtClv27eeKNWv1j3gErC8h+AUZJ2UGhrd KVhpMvtVNvhgyWeVSeuIeMD8eH5NzEeoHnojaHTA1GPEcbECoojCWficpogqmf6HQo5N MmnYQeLhkdElJaXpXj1c69r84KUZQrlY7mxD6xvGwUIan3aefy0FcVyoZuupEA9ytAeU gWUptxq7QvGjU184eq5XRfLzRXC+v0I+mOACIRKEQBhNqG34SU6qWdId7/oio/77IrZV MQaA== X-Gm-Message-State: AOAM530MEPolkBhc50ugQpJJ0AUT0bL5gRfpAuYnXbEuZOIr7BDfRoI6 VL8QnS/2O+6Jft/I3kCxAWW4eY5i960xXA== X-Google-Smtp-Source: ABdhPJzw6pbg1LSs9UG71IQMze9IoMAcLaQjOzb3jEwQQOwLaFW2r+PSzch9M+zJGWsh79avlGacvw== X-Received: by 2002:a17:90a:dac1:: with SMTP id g1mr6951482pjx.199.1622660950195; Wed, 02 Jun 2021 12:09:10 -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 j12sm458036pgs.83.2021.06.02.12.09.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 12:09:09 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Andrii Nakryiko , Maciej Fijalkowski , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v3 3/3] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN Date: Wed, 2 Jun 2021 19:08:15 +0000 Message-Id: <20210602190815.8096-4-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210602190815.8096-1-zeffron@riotgames.com> References: <20210602190815.8096-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 | 114 ++++++++++++++++++ .../bpf/progs/test_xdp_context_test_run.c | 20 +++ 2 files changed, 134 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..0dbdebbc66ce --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c @@ -0,0 +1,114 @@ +// 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; + DECLARE_LIBBPF_OPTS(bpf_test_run_opts, 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)); + opts.ctx_in = &ctx_in; + opts.ctx_size_in = sizeof(ctx_in); + + opts.ctx_in = &ctx_in; + opts.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, &opts); + ASSERT_OK(err, "bpf_prog_test_run(test1)"); + ASSERT_EQ(opts.retval, XDP_PASS, "test1-retval"); + ASSERT_EQ(opts.data_size_out, sizeof(pkt_v4), "test1-datasize"); + ASSERT_EQ(opts.ctx_size_out, opts.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; + opts.ctx_in = bad_ctx; + opts.ctx_size_in = sizeof(bad_ctx); + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, 22, "test2-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test2)"); + + /* The egress cannot be specified */ + ctx_in.egress_ifindex = 1; + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, 22, "test3-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test3)"); + + /* 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, &opts); + ASSERT_EQ(errno, 22, "test4-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test4)"); + + /* 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, &opts); + ASSERT_EQ(errno, 22, "test5-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test5)"); + + /* Metadata's size must be a multiple of 4 */ + ctx_in.data = 3; + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, 22, "test6-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test6)"); + + /* 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, &opts); + ASSERT_EQ(errno, 22, "test7-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test7)"); + + ctx_in.data_end = sizeof(pkt_v4) + 4; + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, 22, "test8-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test8)"); + + /* 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, &opts); + ASSERT_EQ(errno, 22, "test9-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test9)"); + + ctx_in.ingress_ifindex = 1; + ctx_in.rx_queue_index = 1; + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, 22, "test10-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(test10)"); + + 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";