From patchwork Thu Jun 24 21:13:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12343219 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 22C0CC49EA5 for ; Thu, 24 Jun 2021 21:13:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED411613C3 for ; Thu, 24 Jun 2021 21:13:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232397AbhFXVPd (ORCPT ); Thu, 24 Jun 2021 17:15:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230116AbhFXVPc (ORCPT ); Thu, 24 Jun 2021 17:15:32 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63128C061574 for ; Thu, 24 Jun 2021 14:13:13 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id b3so3624955plg.2 for ; Thu, 24 Jun 2021 14:13:13 -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=Kqo+96VFKjlfVy/mad4ioLL51Fxv6ZwOZvh4XlzGWBU=; b=B8fH6nWHHXsxWZD6NDBLH09IT8Xl6hAWmX/lUDl1Nap4auwuQS6+9th9Qo/CcJOTCn aQxzXfQ8sE6xCToVaKQScpgpSHfr3f5ceBRskUyFC7FFBYQ/zfjadHO+7waqyQqwFUzV tRqXJdH7wY72sM4WetJezK53avYnTS+nct6RE= 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=Kqo+96VFKjlfVy/mad4ioLL51Fxv6ZwOZvh4XlzGWBU=; b=n095MuIWH1JeASjJJWuQwNu9qV2UWdCiyKm+ipuxBHLUVFwXkZznm4CoHd+xQ6Bbr5 JY9fd+8c9VzJD7Mdt7hIx2kEG92/tP392pKjvmAQumLHLV0GpEik/I/M/i/wdeJzn6Mn EAXKAsLcvFCf9Dpk8F4Vstr6poJm4rO8x6FjLcR3CyKr2DWEuLfBuTsHdNwHd3t5s0AA 4Kz/e5TMOADdW1uN7QVwPcC6m1CaZHp1uL1ZRMYMMeXMF0MVGDHdwZ47PnGKrhb0eeWy 1xTxm1MJoJcDxrt7IGTeZyo73ZgAqXTaO5ouaiXxBEk2yZXWeFg8UN3oRlkkUzgsOJcQ C25g== X-Gm-Message-State: AOAM532PMs0aMZyb2iZFOlf6WEKVHns/v2w7QkU+c1NcvUzLvEnAbfLN 5kKCTo/HtmTaMh+OchIiTiUXYYuThmHZtbz5 X-Google-Smtp-Source: ABdhPJwM7TjrkKQtwMuATMox3XD+f4+LzMks9hzVbyaKa/QOPweVqIGa6jouVFl0PadBpn9KJdLlBA== X-Received: by 2002:a17:90b:3a91:: with SMTP id om17mr7636667pjb.50.1624569192136; Thu, 24 Jun 2021 14:13:12 -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 d13sm3615394pfn.136.2021.06.24.14.13.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jun 2021 14:13:11 -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 , Martin KaFai Lau , Yonghong Song , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v7 1/4] bpf: add function for XDP meta data length check Date: Thu, 24 Jun 2021 21:13:01 +0000 Message-Id: <20210624211304.90807-2-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210624211304.90807-1-zeffron@riotgames.com> References: <20210624211304.90807-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 This commit prepares to use the XDP meta data length check in multiple places by making it into a static inline function instead of a literal. 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 Acked-by: Yonghong Song --- include/net/xdp.h | 5 +++++ net/core/filter.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/net/xdp.h b/include/net/xdp.h index 5533f0ab2afc..ad5b02dcb6f4 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -276,6 +276,11 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp) return unlikely(xdp->data_meta > xdp->data); } +static inline bool xdp_metalen_invalid(unsigned long metalen) +{ + return (metalen & (sizeof(__u32) - 1)) || (metalen > 32); +} + struct xdp_attachment_info { struct bpf_prog *prog; u32 flags; diff --git a/net/core/filter.c b/net/core/filter.c index 0b13d8157a8f..118158d6e883 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -77,6 +77,7 @@ #include #include #include +#include static const struct bpf_func_proto * bpf_sk_base_func_proto(enum bpf_func_id func_id); @@ -3906,8 +3907,7 @@ BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset) if (unlikely(meta < xdp_frame_end || meta > xdp->data)) return -EINVAL; - if (unlikely((metalen & (sizeof(__u32) - 1)) || - (metalen > 32))) + if (unlikely(xdp_metalen_invalid(metalen))) return -EACCES; xdp->data_meta = meta; From patchwork Thu Jun 24 21:13:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12343225 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 140F9C49EA5 for ; Thu, 24 Jun 2021 21:13:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E961A613C3 for ; Thu, 24 Jun 2021 21:13:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232559AbhFXVPe (ORCPT ); Thu, 24 Jun 2021 17:15:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230116AbhFXVPe (ORCPT ); Thu, 24 Jun 2021 17:15:34 -0400 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E6F9C061574 for ; Thu, 24 Jun 2021 14:13:14 -0700 (PDT) Received: by mail-pf1-x42d.google.com with SMTP id y4so6268554pfi.9 for ; Thu, 24 Jun 2021 14:13: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=TVFqh6EgRMGzBVVuOuD42u7mzGcwsEHA3R/s/xKM4Rc=; b=OWmBE/3qHFRjUSX6xaEQ/qWdtnvYRJg8mmfHCDcjIdKzkkWixOCjkr1+rFS24X2yzz YrFmGHpp/YBwcW1Mrteu3WDIMEbnK4v77h8/q6Vv5WNa+BBlzuoudceykALlGlVfLv7Q 5FOcpsec0Eaeby+D7C2EGdvsSPDtz6Q8DVX+A= 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=TVFqh6EgRMGzBVVuOuD42u7mzGcwsEHA3R/s/xKM4Rc=; b=gwSSeNI/ISpqJweZe33fVQ3XvGXsHUXUpes94I+doOtO5blnD4Tgq2K+r+YZKfsJpJ yXnuyWVEZtaZ6hHJLTcQOWsc72znT79VlEIc1EDKrPgWR3GukMtn2hn0bgCYUPXaQ1da oi+oicaRvO3TCU+Qd7/lgS0X4OUmsHKRVFsswuVcbVhY9l4Z/CIqRBLfPHp09boPA0yv tvtCSdn8PiON0uuQPKxAsv0CGcqVi7jxijI640hB9/em/Va/QKEw03Yo0I0Th0WDlrhZ aiCgRjCL8kHDCFZJDhH+lsJMy0C4grgG9Kwu6JpaslfcTpKQLbaAXEQJCyx7XKjnR6v6 3TmA== X-Gm-Message-State: AOAM532JtP72ivW42g6W1bo2f/msiA8Ya502oGnIF31ZMdDFGrOEQFgO GgXJ8fJrdDNaQidthyEijyUJmkxYNzxWfWcM X-Google-Smtp-Source: ABdhPJzdK/hALbOdhTfs63nGXAp9xk9AJDbi9VZBxx586bR/6MdhM8OBXLUZnFVYSOeop4kkh/XqbQ== X-Received: by 2002:a65:50c5:: with SMTP id s5mr6370044pgp.138.1624569193246; Thu, 24 Jun 2021 14:13: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 d13sm3615394pfn.136.2021.06.24.14.13.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jun 2021 14:13:12 -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 , Martin KaFai Lau , Yonghong Song , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v7 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 24 Jun 2021 21:13:02 +0000 Message-Id: <20210624211304.90807-3-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210624211304.90807-1-zeffron@riotgames.com> References: <20210624211304.90807-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 Acked-by: Yonghong Song --- include/uapi/linux/bpf.h | 3 -- net/bpf/test_run.c | 67 +++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index bf9252c7381e..b46a383e8db7 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..229c5deb813c 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -15,6 +15,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -687,6 +688,22 @@ 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_md *xdp_md, struct xdp_buff *xdp) +{ + if (!xdp_md) + return 0; + + if (xdp_md->egress_ifindex != 0) + return -EINVAL; + + if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0) + return -EINVAL; + + xdp->data = xdp->data_meta + xdp_md->data; + + return 0; +} + int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr) { @@ -697,35 +714,69 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, struct netdev_rx_queue *rxqueue; struct xdp_buff xdp = {}; u32 retval, duration; + struct xdp_md *ctx; u32 max_data_sz; void *data; - int ret; + int ret = -EINVAL; - 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); + + if (ctx) { + /* There can't be user provided data before the meta data */ + if (ctx->data_meta || ctx->data_end != size || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data))) + goto free_ctx; + /* Meta data is allocated from the headroom */ + headroom -= ctx->data; + } /* 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)) - return PTR_ERR(data); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + goto free_ctx; + } 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(ctx, &xdp); + if (ret) + goto free_data; + 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; + + if (ctx) { + ctx->data = xdp.data - xdp.data_meta; + ctx->data_end = xdp.data_end - xdp.data_meta; + } + + 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); +free_data: kfree(data); +free_ctx: + kfree(ctx); return ret; } From patchwork Thu Jun 24 21:13:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12343223 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 7D5E8C49EA7 for ; Thu, 24 Jun 2021 21:13:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 645B7613CB for ; Thu, 24 Jun 2021 21:13:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230116AbhFXVPf (ORCPT ); Thu, 24 Jun 2021 17:15:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232460AbhFXVPe (ORCPT ); Thu, 24 Jun 2021 17:15:34 -0400 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34968C061756 for ; Thu, 24 Jun 2021 14:13:15 -0700 (PDT) Received: by mail-pf1-x434.google.com with SMTP id w71so6293426pfd.4 for ; Thu, 24 Jun 2021 14:13:15 -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=M2oyGbnv4aKmoaUdSONfGQ4n1QXcyTD2iBZeIIQjJPo=; b=hel1LkaR4TZ/AJEYsOTNi3md5/5dwfl4LTGhH6la8egqCekzxaoElNj4Mcgbknpbmu cNKf2k0EcXd19+8+w8VLeNpfQtLduMzdPlPaKrAMZOaBSqqj9QUit2GS6N3aGKra65Xr 9y+ma8yodVuNqedj9/xQIyDRdPVuuIywwYLxk= 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=M2oyGbnv4aKmoaUdSONfGQ4n1QXcyTD2iBZeIIQjJPo=; b=eIzJgijw5aVkmmTxO6yphyHww/c+kJrBkl3ptPXBwUJttnA0C7vWVt6KRNdiR6g3MY /74o6k1FQCDW1VUI4ep2ajNmPXDbDekfdFoULAd4tlBR/lFwCjfaDzvZx721E3SbzL0H o8Ce+UA105Xf75jjm8GFSa1O3SSNenChcoD1kJMaKkuIlJIywH3rJc84WNCid53c9kg8 tgqhS+jiO7N0iTxhusWB49wG/q9RANdSaGhXJx+9+EtSikrWAZ42lk50vXdNq02BeatG T3qIXhR1xasAEuMKJkLNVTC2stDFcxDi/dpusNlq9kWmMF4xHkCcitpB3j2ubWIWpKsA W2VA== X-Gm-Message-State: AOAM530RF1sJwecVHQwqmOSl20GSGCeEEiOW6mD9PAvPd4CLunUPHX7u 5bIkDjRY2yxG7D7XwKOjmZ0s6BYRUizhdLeE X-Google-Smtp-Source: ABdhPJwyfZf6qyAG1P/XIYNWomORtnak91blwkLT8QXR6h5SyXDXln2eegntdkM9xbZxlsfstI2MlA== X-Received: by 2002:a63:4e4d:: with SMTP id o13mr6362901pgl.361.1624569194375; Thu, 24 Jun 2021 14:13:14 -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 d13sm3615394pfn.136.2021.06.24.14.13.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jun 2021 14:13:13 -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 , Martin KaFai Lau , Yonghong Song , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v7 3/4] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 24 Jun 2021 21:13:03 +0000 Message-Id: <20210624211304.90807-4-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210624211304.90807-1-zeffron@riotgames.com> References: <20210624211304.90807-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 | 54 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 229c5deb813c..f61f9e41ecaa 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -690,18 +690,58 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp) { + unsigned int ingress_ifindex, rx_queue_index; + struct netdev_rx_queue *rxqueue; + struct net_device *device; + if (!xdp_md) return 0; if (xdp_md->egress_ifindex != 0) return -EINVAL; - if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0) + ingress_ifindex = xdp_md->ingress_ifindex; + rx_queue_index = xdp_md->rx_queue_index; + + if (!ingress_ifindex && rx_queue_index) return -EINVAL; - xdp->data = xdp->data_meta + xdp_md->data; + if (ingress_ifindex) { + device = dev_get_by_index(current->nsproxy->net_ns, + ingress_ifindex); + if (!device) + return -ENODEV; + + if (rx_queue_index >= device->real_num_rx_queues) + goto free_dev; + + rxqueue = __netif_get_rx_queue(device, rx_queue_index); + if (!xdp_rxq_info_is_reg(&rxqueue->xdp_rxq)) + goto free_dev; + + xdp->rxq = &rxqueue->xdp_rxq; + /* The device is now tracked in the xdp->rxq for later dev_put() */ + } + + xdp->data = xdp->data_meta + xdp_md->data; return 0; + +free_dev: + dev_put(device); + return -EINVAL; +} + +static void xdp_convert_buff_to_md(struct xdp_buff *xdp, struct xdp_md *xdp_md) +{ + if (!xdp_md) + return; + + xdp_md->data = xdp->data - xdp->data_meta; + xdp_md->data_end = xdp->data_end - xdp->data_meta; + + if (xdp_md->ingress_ifindex) + dev_put(xdp->rxq->dev); } int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, @@ -753,6 +793,11 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, bpf_prog_change_xdp(NULL, prog); ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); + /* We convert the xdp_buff back to an xdp_md before checking the return + * code so the reference count of any held netdevice will be decremented + * even if the test run failed. + */ + xdp_convert_buff_to_md(&xdp, ctx); if (ret) goto out; @@ -760,11 +805,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, xdp.data_end != xdp.data_meta + size) size = xdp.data_end - xdp.data_meta; - if (ctx) { - ctx->data = xdp.data - xdp.data_meta; - ctx->data_end = xdp.data_end - xdp.data_meta; - } - ret = bpf_test_finish(kattr, uattr, xdp.data_meta, size, retval, duration); if (!ret) From patchwork Thu Jun 24 21:13:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zvi Effron X-Patchwork-Id: 12343227 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 A8561C49EA7 for ; Thu, 24 Jun 2021 21:13:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8F66F613CB for ; Thu, 24 Jun 2021 21:13:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232598AbhFXVPh (ORCPT ); Thu, 24 Jun 2021 17:15:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232460AbhFXVPf (ORCPT ); Thu, 24 Jun 2021 17:15:35 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B00AC061574 for ; Thu, 24 Jun 2021 14:13:16 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id bb20so4231431pjb.3 for ; Thu, 24 Jun 2021 14:13:16 -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=A7ulsYfJ0MfqaARRsxHfgDB76o1kt2u5dSehW+gl5BI=; b=VtjnMsQ71LxuoZPxD3GputJgRQ98WXD1fNDmw84h+FiEd1BmJIxco9ktC0P/4qzTLS S48SJ5sEqZ6ieV24wxq3NNO0Rzf+M0bB0YGv6EK0ILtcYdp628Ik8cs72iNF93pBYf1Z aZAXTBkfDrz6SdG2Z4vwS/hWqWxb86kFiWXGo= 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=A7ulsYfJ0MfqaARRsxHfgDB76o1kt2u5dSehW+gl5BI=; b=YmOBcU+sIgxGQIVbeRKQQkrBkhE5JKerBhPAjITt8UYsYCiXOYyI3d+gqrnSTP9u6+ xRwf+qZDrwiG6h6IIfwSx5nmgXN9f1whgvkWi1r8wOl4GBpSem2uWTpCvsrveT0X120o K9XUIBWF8oqu3jcs6vOllpXkAlpJV+nk/mC134ryktvUWtM237zGpnuMDr1yyl9JtYpX Ook6bhqrxxtuFx1mWBAbKiCNl2LitTEu6Qe+7WzsRD9m9aIeCO7/hEVQwiSFT98afb9r w2lw5PA41mp46Jviokk1KfSAcUD7W3O30YTi80Gia66BqUn3WDnUS3v5YNuoYz9dBChS GVYw== X-Gm-Message-State: AOAM531uKRm8jtC/AibOEFYarmaUoqmxSRB23y3AYkm0dgGoZqA+qejY QYrtIG3FVHVMZTtbFg9XGvrE3V943oO8B7wf X-Google-Smtp-Source: ABdhPJyRq6eTSZDhqnpTxqSQsE1DfMBEc3zEYua3qY4Vf0SiDobapZrD4ny/QyfQQPgg8UcP++WoTw== X-Received: by 2002:a17:90a:c788:: with SMTP id gn8mr7494085pjb.207.1624569195481; Thu, 24 Jun 2021 14:13:15 -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 d13sm3615394pfn.136.2021.06.24.14.13.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Jun 2021 14:13:14 -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 , Martin KaFai Lau , Yonghong Song , Zvi Effron , Cody Haas , Lisa Watanabe Subject: [PATCH bpf-next v7 4/4] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN Date: Thu, 24 Jun 2021 21:13:04 +0000 Message-Id: <20210624211304.90807-5-zeffron@riotgames.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210624211304.90807-1-zeffron@riotgames.com> References: <20210624211304.90807-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 meta data, then reduces the size of the XDP meta data 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 meta data 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 | 105 ++++++++++++++++++ .../bpf/progs/test_xdp_context_test_run.c | 20 ++++ 2 files changed, 125 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..ab4952b9fb1d --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "test_xdp_context_test_run.skel.h" + +void test_xdp_context_error(int prog_fd, struct bpf_test_run_opts opts, + __u32 data_meta, __u32 data, __u32 data_end, + __u32 ingress_ifindex, __u32 rx_queue_index, + __u32 egress_ifindex) +{ + struct xdp_md ctx = { + .data = data, + .data_end = data_end, + .data_meta = data_meta, + .ingress_ifindex = ingress_ifindex, + .rx_queue_index = rx_queue_index, + .egress_ifindex = egress_ifindex, + }; + int err; + + opts.ctx_in = &ctx; + opts.ctx_size_in = sizeof(ctx); + err = bpf_prog_test_run_opts(prog_fd, &opts); + ASSERT_EQ(errno, EINVAL, "errno-EINVAL"); + ASSERT_ERR(err, "bpf_prog_test_run"); +} + +void test_xdp_context_test_run(void) +{ + struct test_xdp_context_test_run *skel = NULL; + char data[sizeof(pkt_v4) + sizeof(__u32)]; + char bad_ctx[sizeof(struct xdp_md) + 1]; + struct xdp_md ctx_in, ctx_out; + DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, + .data_in = &data, + .data_size_in = sizeof(data), + .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); + + /* 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, E2BIG, "extradata-errno"); + ASSERT_ERR(err, "bpf_prog_test_run(extradata)"); + + *(__u32 *)data = XDP_PASS; + *(struct ipv4_packet *)(data + sizeof(__u32)) = pkt_v4; + opts.ctx_in = &ctx_in; + opts.ctx_size_in = sizeof(ctx_in); + memset(&ctx_in, 0, 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(valid)"); + ASSERT_EQ(opts.retval, XDP_PASS, "valid-retval"); + ASSERT_EQ(opts.data_size_out, sizeof(pkt_v4), "valid-datasize"); + ASSERT_EQ(opts.ctx_size_out, opts.ctx_size_in, "valid-ctxsize"); + ASSERT_EQ(ctx_out.data_meta, 0, "valid-datameta"); + ASSERT_EQ(ctx_out.data, 0, "valid-data"); + ASSERT_EQ(ctx_out.data_end, sizeof(pkt_v4), "valid-dataend"); + + /* Meta data's size must be a multiple of 4 */ + test_xdp_context_error(prog_fd, opts, 0, 1, sizeof(data), 0, 0, 0); + + /* data_meta must reference the start of data */ + test_xdp_context_error(prog_fd, opts, 4, sizeof(__u32), sizeof(data), + 0, 0, 0); + + /* Meta data must be 32 bytes or smaller */ + test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0); + + /* Total size of data must match data_end - data_meta */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), + sizeof(data) - 1, 0, 0, 0); + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), + sizeof(data) + 1, 0, 0, 0); + + /* RX queue cannot be specified without specifying an ingress */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), + 0, 1, 0); + + /* Interface 1 is always the loopback interface which always has only + * one RX queue (index 0). This makes index 1 an invalid rx queue index + * for interface 1. + */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), + 1, 1, 0); + + /* The egress cannot be specified */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), + 0, 0, 1); + + 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..d7b88cd05afd --- /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 *)(long)xdp->data; + __u32 *metadata = (void *)(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";