From patchwork Mon May 24 22:05:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12277049 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,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 C1559C04FF3 for ; Mon, 24 May 2021 22:07:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9ED1A6140B for ; Mon, 24 May 2021 22:07:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233912AbhEXWIe (ORCPT ); Mon, 24 May 2021 18:08:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51606 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232911AbhEXWIe (ORCPT ); Mon, 24 May 2021 18:08:34 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94EE7C061574 for ; Mon, 24 May 2021 15:07:05 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id t21so15341186plo.2 for ; Mon, 24 May 2021 15:07: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=6a9lhHf+fLKHysi7Q2ycbgWcGIJmoZLmOLY95lVcsgw=; b=OuleOEc18TGSeoiRgPqgegFaPY84iCzgoS+voPUY4GcFjVv4zHe6O9/NJWsDT73tqn 6EwBunAwFYcfm1NR+VtnEAtctJikBa3LmsB/Ea3Pmfrbre6vrKrpBrvlxt0PjjjjHC5o edfJ9YypfrbhM8bf2pKMAExKbFkGlkyLFDD1M= 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=6a9lhHf+fLKHysi7Q2ycbgWcGIJmoZLmOLY95lVcsgw=; b=eXYPeJdMV/36iPHadiSxEzo2EY738idCI6JS0avQu+F790jZoJZjVJ4vGaFUP7QuWS i/u9wH0bpVwoqxTbaNDDs3FmlCBFt0M63xrBrB/EtAzKjPM7Ee+pADGuSPVeJUAIcAkH 9qDv989/7SqRGuCmwyUVvaEGF4xXm4oYq4LDXxvOxH1jzA5y22FLddO5S12PwYigqqkq ownpa6MMApuS+t2r1tM2DBJEdsvPiRFqqx4DA2CHcPJBzfjSNZDom86IBCN3UdM6S620 9h/5/YyUo9QdY1EWEjsT4qegGjLqvzF9SN1q9XoCouQCG/sNc+vKz195EoxSJu64+EXh yoXg== X-Gm-Message-State: AOAM5328heCZxMCGvaEB3aRkSbBujrytKMv+ee6uGNVH1kyUYNZCy0oV wI5r7Nd5dPVgCs8SqCkPvE2Ze53d07dpMT6Q X-Google-Smtp-Source: ABdhPJzjJeGf//UoqM6p+2NKIsxbqCASO9/U5o706m9ed5Xx93ulXW7mkC/luYPt2P2udhKkmBRmYQ== X-Received: by 2002:a17:90a:a78d:: with SMTP id f13mr26686201pjq.161.1621894023936; Mon, 24 May 2021 15:07:03 -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 k15sm12133338pfi.0.2021.05.24.15.07.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 15:07:03 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next 1/3] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Date: Mon, 24 May 2021 22:05:53 +0000 Message-Id: <20210524220555.251473-2-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524220555.251473-1-zeffron@riotgames.com> References: <20210524220555.251473-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 | 80 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 418b9b813d65..5a8d9d5a0068 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..1eaa0959b03a 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,35 +735,65 @@ 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) + 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->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(ctx); + kfree(data); + 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(ctx); kfree(data); 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 Mon May 24 22:05:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12277051 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,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 90DF3C04FF3 for ; Mon, 24 May 2021 22:07:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 735F9613D6 for ; Mon, 24 May 2021 22:07:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233897AbhEXWIj (ORCPT ); Mon, 24 May 2021 18:08:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232911AbhEXWIj (ORCPT ); Mon, 24 May 2021 18:08:39 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49B71C061574 for ; Mon, 24 May 2021 15:07:10 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id v13-20020a17090abb8db029015f9f7d7290so695507pjr.0 for ; Mon, 24 May 2021 15:07: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=jz8DJ79IeD0bBmW1K0X2g1fKWdajXX13diKnZt2JK1w=; b=Ft//+sjiNzQnAAw6Lo9Q2fyiGB4WZ1DmyoeGozIw1r26JDsxmpW9pt4kBFv3yeAT0b Js+DXn3P6ivBbCifEeB7q9XmJtF6K+Ai0GiZojUc9i7NUkN2JUYxlfqSSlDREhGHlKwH MaLfTLys6x0Gi2r1rvQDbjRBH8WrLJfB2yvcQ= 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=jz8DJ79IeD0bBmW1K0X2g1fKWdajXX13diKnZt2JK1w=; b=cH6SnkJMd53BhYTDMOwmfkS3ewzII3V5OZwXxNHGEfyvZPFWMin/AStaE55bbNj5lD 8drblOhiQ/w06qyoxUiJFh/sBPHp86KThhuBYdISR4zs61mrAFL931GdmK6D7fbZosuM RkQ0zgsnChmVDGPdMSZRBqAgH84z8FfS1JkrwwgFEgJziCy+3PpKwRQKknSeRmVmA6/V 7dsrIC6MT3C7m5KNwkfbpO/LYBXYf/9xMTOhC/KJz3NoPrPR/bgvP9PGSfMBBFcX0kW0 AilRoMlXc85VPyLKWBXDDG96qLV6kTU8OgvybB36MxWlbc78xya57J0l6MJ1tn5JtEvc cnLw== X-Gm-Message-State: AOAM5314x/SEIUc4/XE2az9WO/GOyU1Q67joTdg2y8pNttwTgp4WGlta +JaTKXDZrdpxnlqYv9X6SKaCs6Y0B8AgfsbQ X-Google-Smtp-Source: ABdhPJymBCqTatN9vo1zU0WkxV0lbQ5juq8Y9lU8wOJxOz50XL2WWjyk8RzkQM+p2l1sK6Pg74OKNQ== X-Received: by 2002:a17:90a:4092:: with SMTP id l18mr1341177pjg.35.1621894029453; Mon, 24 May 2021 15:07:09 -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 k15sm12133338pfi.0.2021.05.24.15.07.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 15:07:09 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next 2/3] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN Date: Mon, 24 May 2021 22:05:54 +0000 Message-Id: <20210524220555.251473-3-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524220555.251473-1-zeffron@riotgames.com> References: <20210524220555.251473-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 1eaa0959b03a..d882a4831c18 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 Mon May 24 22:05:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12277053 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,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 A2E89C04FF3 for ; Mon, 24 May 2021 22:07:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 804356140B for ; Mon, 24 May 2021 22:07:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233938AbhEXWIn (ORCPT ); Mon, 24 May 2021 18:08:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232911AbhEXWIm (ORCPT ); Mon, 24 May 2021 18:08:42 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 32055C061574 for ; Mon, 24 May 2021 15:07:14 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id ot16so13734718pjb.3 for ; Mon, 24 May 2021 15:07:14 -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=UibHIA6PtHUsJc/Axd9GpqQT8nt/JMe7JNTu9yj2c9M=; b=W+aIgMhGVDJjezRWypAhI9hMjaxyOO6rU6BwHqHgcvZRkUP/Czgwd6zA/LirbycANm 4w2Apz2aKNJWVJXch2eJTGaoXRP7tmSayrHDwlTUA2L7CrXiN9DQwsPiLCiPgKqUsAJo wy1UXZuYCi4Rum6hIbV2CUPtHIbcByRJx4amM= 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=UibHIA6PtHUsJc/Axd9GpqQT8nt/JMe7JNTu9yj2c9M=; b=cbqJEXgFhL6DDc0Fg8vg3/O6vKArbvdNzRAYwN1wpssyh0PFIjIJJs3QlmMMZp/Aji vEeFJLGyNQUKX+sxY9XqCe7X8pL1I7Mh7kqbZNbxCjyCPU+MhNBImXp7JYVG2BvavG39 nySD5VmVVmDnb/6Hzv4uGgOHxamJ3GnlsW/+07U9+wX+zTbxPSRbUUpWQGwXM5kCPL4J r+g6QMcImC5dDqDxYvl9UqMEKYVsMrCdCu6FV1yxA6g/DvB49HGLFjhionMHWic9sQKG EWBzaG3fU4yBQSz4AfyBfiJXdYvHKrlTuj1F/JgFYTl6YUzOexsAZgiQQOfCedBYo8Q1 x75w== X-Gm-Message-State: AOAM530EEhDoENzSIjdaMKfiVAcg6BBKhgyZ7yjsD0f0evjCUcZSVi83 IhYOfWaD0alpb9eSGm32FIjmhttoE4nv/3/n X-Google-Smtp-Source: ABdhPJyyfIemJwATjv2FOGZy3Enqha6aiXZPThQ2pwfXBREPSIrE6IAZWLm2KxTKwJoNkFz9V/ysEg== X-Received: by 2002:a17:90a:a481:: with SMTP id z1mr1294166pjp.97.1621894033368; Mon, 24 May 2021 15:07:13 -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 k15sm12133338pfi.0.2021.05.24.15.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 15:07:12 -0700 (PDT) From: Zvi Effron To: bpf@vger.kernel.org Cc: Alexei Starovoitov , "David S. Miller" , Daniel Borkmann , Jesper Dangaard Brouer , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next 3/3] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN Date: Mon, 24 May 2021 22:05:55 +0000 Message-Id: <20210524220555.251473-4-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210524220555.251473-1-zeffron@riotgames.com> References: <20210524220555.251473-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 | 117 ++++++++++++++++++ .../bpf/progs/test_xdp_context_test_run.c | 22 ++++ 2 files changed, 139 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..92ce2e4a5c30 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +void test_xdp_context_test_run(void) +{ + const char *file = "./test_xdp_context_test_run.o"; + struct bpf_object *obj; + 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; + + err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); + if (CHECK_FAIL(err)) + return; + + *(__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); + CHECK_ATTR(err || tattr.retval != XDP_PASS || + tattr.data_size_out != sizeof(pkt_v4) || + tattr.ctx_size_out != tattr.ctx_size_in || + ctx_out.data_meta != 0 || + ctx_out.data != ctx_out.data_meta || + ctx_out.data_end != sizeof(pkt_v4), "xdp_md context", + "err %d errno %d retval %d data size out %d context size out %d data_meta %d data %d data_end %d\n", + err, errno, tattr.retval, tattr.data_size_out, + tattr.ctx_size_out, ctx_out.data_meta, ctx_out.data, + ctx_out.data_end); + + /* 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); + CHECK_ATTR(!err || errno != 22, "bad context", "err %d errno %d\n", + err, errno); + + /* The egress cannot be specified */ + ctx_in.egress_ifindex = 1; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + CHECK_ATTR(!err || errno != 22, + "nonzero egress index", "err %d errno %d\n", err, 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); + CHECK_ATTR(!err || errno != 22, "nonzero data_meta", + "err %d errno %d\n", err, 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); + CHECK_ATTR(!err || errno != 22, "metadata too long", + "err %d errno %d\n", err, errno); + + /* Metadata's size must be a multiple of 4 */ + ctx_in.data = 3; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + CHECK_ATTR(!err || errno != 22, "multiple of 4", + "err %d errno %d\n", err, 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); + CHECK_ATTR(!err || errno != 22, "data too long", "err %d errno %d\n", + err, errno); + + ctx_in.data_end = sizeof(pkt_v4) + 4; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + CHECK_ATTR(!err || errno != 22, "data too short", "err %d errno %d\n", + err, 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); + CHECK_ATTR(!err || errno != 22, "no ingress if", + "err %d, rx_queue_index %d\n", err, ctx_out.rx_queue_index); + + ctx_in.ingress_ifindex = 1; + ctx_in.rx_queue_index = 1; + err = bpf_prog_test_run_opts(prog_fd, &tattr); + CHECK_ATTR(!err || errno != 22, "invalid rx queue", + "err %d, rx_queue_index %d\n", err, ctx_out.rx_queue_index); + + bpf_object__close(obj); +} 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..c66a756b238e --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +int _version SEC("version") = 1; + +SEC("xdp_context") +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";