From patchwork Wed Jul 24 17:00:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136433 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="agh1vc5e"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1n56v6Bz9s8m for ; Thu, 25 Jul 2019 03:00:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727313AbfGXRAZ (ORCPT ); Wed, 24 Jul 2019 13:00:25 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:53921 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726600AbfGXRAY (ORCPT ); Wed, 24 Jul 2019 13:00:24 -0400 Received: by mail-pl1-f202.google.com with SMTP id y22so24457016plr.20 for ; Wed, 24 Jul 2019 10:00:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=UK3cLmopCyo0xo53LOpbyMn8ZKhtUu3HrgkMh97T/xw=; b=agh1vc5e4oRELu6pa6JWiEOl3V2izSM92RLkkakwTC/L7GVv/WNKmuWoLwCffY77QF 6s18tzxtRiF1OyU4C8rGiJITM9uBpzVx6a3DMEtqvgTulLh4foRmf2jPhgrtKUBVkrOt V8YpZbOtBxQ3vDXHUBq55I3QX5IBls81HPmDx+g9qhQ9YOittWrwfTRy6+u1Iop1kSpH 7gQNGMTEVgyfBk8Lff0+QMeXvbKTLCf6184MkWSgUUQVfUv03GfS2ZJRqjg0zZnfZ4za aZ5LUkJTp0Io01OmWSfbNDP81FYD0JAg3KQ3iBfWkAdLeu+k+n3DriRwX2hTrKBVYizt X48Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=UK3cLmopCyo0xo53LOpbyMn8ZKhtUu3HrgkMh97T/xw=; b=Gpd05rVwQtY1wXau8kltc1guuV4bBhxcLVPTXsCjxTicLQCEanyQSpK9BarQod9KWM pjpX3GL8UTdn3t1RUXG7cv5McbviNrlFcJ7DkAlBvAulqUhrjlgtkRLgPldwq3zBja+w 6yNyOglEHKUX45faHIkkIlBr6F3xoJTuqrHtdvl7OJZF6TNaUYUjib7s34NgU8kqJmzS KHbg9wleV2BUHhVFPovZ2qv3fVI3i2xCDJhKZ5C08Olc53Gc2j8lQt50cz5GQY1aBkku xi+SdANw6HBpCo7pSgXOyiFRaRPnyQGp0fsX1dgZvM+rVl/iyi2pkomNriXFaCd+WHo8 54eg== X-Gm-Message-State: APjAAAXODd6QPUaQzdltj1r68cLtOBBxYNiZiUvPCcDrzh3WQqu6H2Te SLcEszbx1VLUCIOomIk0c67NVjY= X-Google-Smtp-Source: APXvYqxIr4bqJ++l5HeQeglDprHYtZis4rGkdQIztLHDE1JZvVKK5uwLvQRl/aqGN4+VLGy/0A3ji6I= X-Received: by 2002:a65:5584:: with SMTP id j4mr51878707pgs.258.1563987623238; Wed, 24 Jul 2019 10:00:23 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:12 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-2-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 1/7] bpf/flow_dissector: pass input flags to BPF flow dissector program From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org C flow dissector supports input flags that tell it to customize parsing by either stopping early or trying to parse as deep as possible. Pass those flags to the BPF flow dissector so it can make the same decisions. In the next commits I'll add support for those flags to our reference bpf_flow.c Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- include/linux/skbuff.h | 2 +- include/net/flow_dissector.h | 4 ---- include/uapi/linux/bpf.h | 5 +++++ net/bpf/test_run.c | 2 +- net/core/flow_dissector.c | 5 +++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 718742b1c505..9b7a8038beec 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1271,7 +1271,7 @@ static inline int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr) struct bpf_flow_dissector; bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx, - __be16 proto, int nhoff, int hlen); + __be16 proto, int nhoff, int hlen, unsigned int flags); bool __skb_flow_dissect(const struct net *net, const struct sk_buff *skb, diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 90bd210be060..3e2642587b76 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -253,10 +253,6 @@ enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_MAX, }; -#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0) -#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(1) -#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(2) - struct flow_dissector_key { enum flow_dissector_key_id key_id; size_t offset; /* offset of struct flow_dissector_key_* diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index fa1c753dcdbc..b4ad19bd6aa8 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3507,6 +3507,10 @@ enum bpf_task_fd_type { BPF_FD_TYPE_URETPROBE, /* filename + offset */ }; +#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0) +#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1) +#define FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2) + struct bpf_flow_keys { __u16 nhoff; __u16 thoff; @@ -3528,6 +3532,7 @@ struct bpf_flow_keys { __u32 ipv6_dst[4]; /* in6_addr; network order */ }; }; + __u32 flags; }; struct bpf_func_info { diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 80e6f3a6864d..4e41d15a1098 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -419,7 +419,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, time_start = ktime_get_ns(); for (i = 0; i < repeat; i++) { retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN, - size); + size, 0); if (signal_pending(current)) { preempt_enable(); diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 3e6fedb57bc1..a74c4ed1b30d 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -784,7 +784,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, } bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx, - __be16 proto, int nhoff, int hlen) + __be16 proto, int nhoff, int hlen, unsigned int flags) { struct bpf_flow_keys *flow_keys = ctx->flow_keys; u32 result; @@ -794,6 +794,7 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx, flow_keys->n_proto = proto; flow_keys->nhoff = nhoff; flow_keys->thoff = flow_keys->nhoff; + flow_keys->flags = flags; preempt_disable(); result = BPF_PROG_RUN(prog, ctx); @@ -914,7 +915,7 @@ bool __skb_flow_dissect(const struct net *net, } ret = bpf_flow_dissect(attached, &ctx, n_proto, nhoff, - hlen); + hlen, flags); __skb_flow_bpf_to_target(&flow_keys, flow_dissector, target_container); rcu_read_unlock(); From patchwork Wed Jul 24 17:00:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136434 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="LrR4x2dg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1n75KNxz9s8m for ; Thu, 25 Jul 2019 03:00:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726613AbfGXRA1 (ORCPT ); Wed, 24 Jul 2019 13:00:27 -0400 Received: from mail-qt1-f202.google.com ([209.85.160.202]:36095 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726600AbfGXRA1 (ORCPT ); Wed, 24 Jul 2019 13:00:27 -0400 Received: by mail-qt1-f202.google.com with SMTP id q26so42089396qtr.3 for ; Wed, 24 Jul 2019 10:00:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=G+yYdG6igELhRZiNMxwdMomIHFGwkL0QZy6cMwmj/g0=; b=LrR4x2dgaJ21/SAfNkrVkwTHqN2jLKO4ke84XL/QsEdRV/5Sn1GpvkfhDTwZM0K1X9 JhWNwkcwkNRuOI/zgGnPTp3mqrRRcTuFqusGJZxesYlhcOyeKI2nYbCFFMnn8C4SLnPs B6IYygzbcSuUQHp2cHN9VD4UmPNH94a1GLFK7bUMWxuvt5AsztWWd5tqNvSDHHdTF/SE ScootZE4fAReRxFaE7iorHjQHoZN8kdIXXoyV3soUb1srcYyBAqOzP2xZVeaHT4MlznN PfmxFcrABUCLVMLO2uKKRT3yeFi5q7DcfyhjI87KK7GaGzzOEAyHooXduZWJ/o+FAyWp 30dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=G+yYdG6igELhRZiNMxwdMomIHFGwkL0QZy6cMwmj/g0=; b=TJ22oRhNeIry07bf8penDKoCZQkLRFQGBC2l83gHbSmWXk9/mNECajPZgsEZ6WLV6a wgXMEocAdUpBCui1RYGB/z+WY5XWo1mzI26wk3yyy5bKPKlEdTeZSuQVS2fc6zN7iPyk R1OIU7Oyucp3BRRUb0f7P73dHShSFblDmk921FixSc6atu+vGGJLMXJkyLeLzDK1Ew/G Rg3L0GeVTEpoGOuHvq4HohOamA3YiLugGu7ep6X6NlPhKjO/k6QoyXMF/ybzcDd01nft xJyCi0OVT5OsbqMNpPXBEd5DMTRaxpfTzRI9eE1aQ8PpWRtAaeLJe6m42leHbLITcFSn sRPg== X-Gm-Message-State: APjAAAXoZ692dWoF7TbSRs0RLSQ9y13TM1q+/3pFypYLPdj/U6tNKFJV c5Wh2SLC33s/0M1QercM2ixN/3c= X-Google-Smtp-Source: APXvYqwQqtuORMLGmhbXfDXwexP3LHW5EmV8cQIZTi6c+q2rs3e5zxoanmB8xIL+tL72yYLiPWecakQ= X-Received: by 2002:a37:dc45:: with SMTP id v66mr54180753qki.24.1563987626051; Wed, 24 Jul 2019 10:00:26 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:13 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-3-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 2/7] bpf/flow_dissector: document flags From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Describe what each input flag does and who uses it. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- Documentation/bpf/prog_flow_dissector.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/bpf/prog_flow_dissector.rst b/Documentation/bpf/prog_flow_dissector.rst index ed343abe541e..0f3f380b2ce4 100644 --- a/Documentation/bpf/prog_flow_dissector.rst +++ b/Documentation/bpf/prog_flow_dissector.rst @@ -26,6 +26,7 @@ and output arguments. * ``nhoff`` - initial offset of the networking header * ``thoff`` - initial offset of the transport header, initialized to nhoff * ``n_proto`` - L3 protocol type, parsed out of L2 header + * ``flags`` - optional flags Flow dissector BPF program should fill out the rest of the ``struct bpf_flow_keys`` fields. Input arguments ``nhoff/thoff/n_proto`` should be @@ -101,6 +102,23 @@ can be called for both cases and would have to be written carefully to handle both cases. +Flags +===== + +``flow_keys->flags`` might contain optional input flags that work as follows: + +* ``FLOW_DISSECTOR_F_PARSE_1ST_FRAG`` - tells BPF flow dissector to continue + parsing first fragment; the default expected behavior is that flow dissector + returns as soon as it finds out that the packet is fragmented; + used by ``eth_get_headlen`` to estimate length of all headers for GRO. +* ``FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL`` - tells BPF flow dissector to stop + parsing as soon as it reaches IPv6 flow label; used by ``___skb_get_hash`` + and ``__skb_get_hash_symmetric`` to get flow hash. +* ``FLOW_DISSECTOR_F_STOP_AT_ENCAP`` - tells BPF flow dissector to stop + parsing as soon as it reaches encapsulated headers; used by routing + infrastructure. + + Reference Implementation ======================== From patchwork Wed Jul 24 17:00:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136436 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="uk0Uqa59"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1nB3pMcz9s8m for ; Thu, 25 Jul 2019 03:00:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726531AbfGXRA3 (ORCPT ); Wed, 24 Jul 2019 13:00:29 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:45605 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726632AbfGXRA3 (ORCPT ); Wed, 24 Jul 2019 13:00:29 -0400 Received: by mail-pf1-f201.google.com with SMTP id i27so28963071pfk.12 for ; Wed, 24 Jul 2019 10:00:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=6ld3c/snjLG2m54lTG5RUnO37rwyBY0HMvP7Ki2mWFA=; b=uk0Uqa59DlPB3JTGLrnurnvaVEoOSZzGiCD/vTu/RceRZ/eNQ4HVeK5ch3LbztI6M2 Sh4KHR8FE7Wt23KHGossa6U0f7/1EXjQTErCTrBTv5hkPdSyBwuvx5ApoCFk0V7RVg3K 2Za/f9zwV0Upx9xGCUA4d7F8vKX+AB8eqRipEuDvltE24tMKv20KV1EFg6TYYwbczrvn Fg6ehfONdT1eEfvShgDqtYqIAKOqu8ZiuRywdHeDJVSfbXG/lIllhsVWUpoJXeOTbzBb F2k/yu0Z5c0m5x+HXEyWp9RuFPbTg379jc+7mc+koBbhtLqlCnc1e4+/0FwHllH6wjvj 1kRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=6ld3c/snjLG2m54lTG5RUnO37rwyBY0HMvP7Ki2mWFA=; b=hrp9qSSrbtFnKM3aEp2BvrB+QXj14xdUOTVHxWZIOW87hdNWUdPDA73rW7A4lpHNec NOE3aICywtS5kfonLLAJ1+Vwev04gPND+mucUq7AA9EYIT/hz2dbXHl6GD0w0L+DnXNR Y8kBh1EqtLBo77/r7dcKhY3zgGdNOhhXbKvu3zN1vd/io6ypaZv+KzlzSbrYhpqSSByV c1aTY7L8v2mXllcdJ6UeD2mlNYwU97ZOaS1pEPPxRgKIvdJ/XcDdccwnKX92lBWjsMG2 XAJ67JpqyhRiXgx7MJXDYFsp/pUXvlHs24upYPq5zpfeHUlA4CvLA68FWGtceVMt3pau EuOg== X-Gm-Message-State: APjAAAWyEGoVhDsqMydC0WJH6OHIrcdu5zN0QRRk1DQAaw9sreMjI4Zs w6gII8cCoA48CR6frrX4yst6FvE7EWWcWLTAvepMC2Q3Vhy85gi60hXnGchhp6NQSgPX4bSm++6 gV1s69NKTvjnNnYWICJIANsPxRSjIhLKhtTrrPkWkhZkHevSVQMcQ3g== X-Google-Smtp-Source: APXvYqxKX6jt4jiH3SzovabK1tbiMDvYXSWvp3QqwKQLy1ZCVNQze/W0RKcA7CJ3QZAQQAQTeeCNgKo= X-Received: by 2002:a63:2006:: with SMTP id g6mr81008358pgg.287.1563987628267; Wed, 24 Jul 2019 10:00:28 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:14 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-4-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 3/7] bpf/flow_dissector: support flags in BPF_PROG_TEST_RUN From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This will allow us to write tests for those flags. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- net/bpf/test_run.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 4e41d15a1098..444a7baed791 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -377,6 +377,22 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, return ret; } +static int verify_user_bpf_flow_keys(struct bpf_flow_keys *ctx) +{ + /* make sure the fields we don't use are zeroed */ + if (!range_is_zero(ctx, 0, offsetof(struct bpf_flow_keys, flags))) + return -EINVAL; + + /* flags is allowed */ + + if (!range_is_zero(ctx, offsetof(struct bpf_flow_keys, flags) + + FIELD_SIZEOF(struct bpf_flow_keys, flags), + sizeof(struct bpf_flow_keys))) + return -EINVAL; + + return 0; +} + int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr) @@ -384,9 +400,11 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, u32 size = kattr->test.data_size_in; struct bpf_flow_dissector ctx = {}; u32 repeat = kattr->test.repeat; + struct bpf_flow_keys *user_ctx; struct bpf_flow_keys flow_keys; u64 time_start, time_spent = 0; const struct ethhdr *eth; + unsigned int flags = 0; u32 retval, duration; void *data; int ret; @@ -395,9 +413,6 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR) return -EINVAL; - if (kattr->test.ctx_in || kattr->test.ctx_out) - return -EINVAL; - if (size < ETH_HLEN) return -EINVAL; @@ -410,6 +425,18 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (!repeat) repeat = 1; + user_ctx = bpf_ctx_init(kattr, sizeof(struct bpf_flow_keys)); + if (IS_ERR(user_ctx)) { + kfree(data); + return PTR_ERR(user_ctx); + } + if (user_ctx) { + ret = verify_user_bpf_flow_keys(user_ctx); + if (ret) + goto out; + flags = user_ctx->flags; + } + ctx.flow_keys = &flow_keys; ctx.data = data; ctx.data_end = (__u8 *)data + size; @@ -419,7 +446,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, time_start = ktime_get_ns(); for (i = 0; i < repeat; i++) { retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN, - size, 0); + size, flags); if (signal_pending(current)) { preempt_enable(); @@ -450,8 +477,12 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys), retval, duration); + if (!ret) + ret = bpf_ctx_finish(kattr, uattr, user_ctx, + sizeof(struct bpf_flow_keys)); out: kfree(data); + kfree(user_ctx); return ret; } From patchwork Wed Jul 24 17:00:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136438 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="ZkfjP79f"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1nD5QzVz9sBF for ; Thu, 25 Jul 2019 03:00:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727336AbfGXRAc (ORCPT ); Wed, 24 Jul 2019 13:00:32 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:50571 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726632AbfGXRAc (ORCPT ); Wed, 24 Jul 2019 13:00:32 -0400 Received: by mail-pg1-f202.google.com with SMTP id q9so28639416pgv.17 for ; Wed, 24 Jul 2019 10:00:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5PMPzWIi54TuG8trdkiDS7NRHXm1UpJoF4P7uSxvOC8=; b=ZkfjP79fQlugj9oRiKGTXzOIt7HG4wTkP4ttxamQ1H2fXL12z0W4v3jLA8+JOLFCLp jjPyQhq7+OqufH9UwSObbCma6xYUlYUQKsZqwMCQBdaqV0FpuwytWHLQtRxzYLtZG0Pm LhXYjAd1tfD3+Bxxlc1tnZOL9wW5goycfiL9fHsO0ZB30ekAMk/OwtB0REelQqkPZrhr 50u6TVifj4khG4VGjYuvk7wxY092rWQxzfvnaYqTeHxa/Kkzlc6Y2oPCuxs3IS8uEc1Z St/qco1Pet2w8ISFGdtncwLWi888LCfJCh6QfbFEtANjgiidP78hVp2azC2uTx5ipF5P LXQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5PMPzWIi54TuG8trdkiDS7NRHXm1UpJoF4P7uSxvOC8=; b=scpP3wGEZ32kYqBDTIWdBptXMwUBXa1BhZWFzEVfWxUKXozRgjijsGQN9zlY7KO1LA D0IlDJAee1QoRxfZHtRs0IOuv5qdyUrJhkjWHxL6q3MDkYngG84FuDWCVxOHYtp1rCMt FjYElmMCcYPu+BmEFDV+MTDNrKbWFHUxSwkra3MBw4wkYwMr1EorsC+tv9HkZoJsweRa VtdNO/RLAWSDtPPvDe4fGDWoGC0d50atwGKaggtxNGtxoEnOtH3otqDJv40dRF1734af l++LiqkDFiGjh5m+BephSofIkxr+1DcQ8EOAb+2xXxmmBD8MdkyYNech/EQsnCRx4o37 rjOA== X-Gm-Message-State: APjAAAUg5JjzU/nRv225Stfp2AoBtVo0ZDtQLiJvJXEC4c98tksCoVPS IjfErF8lN7KrWpnmY1lWuYiK68w= X-Google-Smtp-Source: APXvYqxwinw/JzYT/Sfh5yugln/Pl+rujP5HPMle4krOX1orqcd5Sptnnw4VwpGrpVkNsFkFGbyNM64= X-Received: by 2002:a63:e306:: with SMTP id f6mr80983714pgh.39.1563987630889; Wed, 24 Jul 2019 10:00:30 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:15 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-5-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 4/7] tools/bpf: sync bpf_flow_keys flags From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Export bpf_flow_keys flags to tools/libbpf/selftests. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- tools/include/uapi/linux/bpf.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4e455018da65..a0e1c891b56f 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3504,6 +3504,10 @@ enum bpf_task_fd_type { BPF_FD_TYPE_URETPROBE, /* filename + offset */ }; +#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0) +#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1) +#define FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2) + struct bpf_flow_keys { __u16 nhoff; __u16 thoff; @@ -3525,6 +3529,7 @@ struct bpf_flow_keys { __u32 ipv6_dst[4]; /* in6_addr; network order */ }; }; + __u32 flags; }; struct bpf_func_info { From patchwork Wed Jul 24 17:00:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136440 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="YL7vEhYi"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1nH68ffz9s8m for ; Thu, 25 Jul 2019 03:00:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727496AbfGXRAf (ORCPT ); Wed, 24 Jul 2019 13:00:35 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:35768 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726390AbfGXRAf (ORCPT ); Wed, 24 Jul 2019 13:00:35 -0400 Received: by mail-pg1-f202.google.com with SMTP id g2so7420201pgj.2 for ; Wed, 24 Jul 2019 10:00:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=WzUKL43PtR3kawunxRxpZ6BQdnRq3E6WalU2t+7zPeA=; b=YL7vEhYiQrhncmQPkVY8yoCCVUEkIruZSD3GzhdNf1r/MAw0/TCidL5m0xRrypaUb8 zVSMC0rTBWSzhQF2vKBTz3GkT8nedkxdphmLIxB6SbJ5iZ0+t7s5KsKSOZ+sGuC6QOGN 6JJWuxghUxNdafGZSn5GuwEanXr6Y5hYHK1GSt1riIV9uBEOlHOBUGJLDo16zOB/iGYb oo7EApjsG0Hlv5XfPm88hLHsuTWlthk7grg7RDnZEkF5PHhx+mVe3cs9W3gqGTEp0CtN TAEUBFfMugUL+ZbErtD96HK0NEnpjubhhRifFLQ8EZX1sqqaRaB4RESz0Nsg0cMNW7pZ PyCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=WzUKL43PtR3kawunxRxpZ6BQdnRq3E6WalU2t+7zPeA=; b=r0fX6hllbm5I/vRpe5Q+D2tNiwIeC2rB3KK6ty4OUZq6EFZcQkSqyp4ghlxKzhIUeV N5cFjzUY0bWkQXAuuMky591buegVSv83xOY1LI34sLH/WzP3hgSOQCGYLGxkV1LhOgek yzUzAj3wVHycHkl+430bbDg5+kgsLgSOQpUXDaJtnFk0vTtp+EFnNKGo84RJ2KkFYle/ CJLfz3ViA3wj32OGdeUVHSEtArfPER3b4fBW1TN9sdDIxoLrNPp1IbP4GT3UVVgUWhtZ 2ze1yA2AhB90q+QTQ1AQiloSnWjg9kS3l2RmPKKHz4ddg8NXc5V7vKShCdijuci4CCLA SZnw== X-Gm-Message-State: APjAAAUJWmQ6+hzaOXiWIW9L1BHwWv4Ktj67UogCg7BlTk10L6m2Bx7r XYi8XS42Jvyc7wLIkBu5q2CKKeo= X-Google-Smtp-Source: APXvYqzpH/AOC1ONnPfAydA57Rw5d2usWoJ5bbr3of7K9snhg+ihye37eXywlkrRHQSHzhPhku8S1Y4= X-Received: by 2002:a63:2bd2:: with SMTP id r201mr81004299pgr.193.1563987633597; Wed, 24 Jul 2019 10:00:33 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:16 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-6-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 5/7] sefltests/bpf: support FLOW_DISSECTOR_F_PARSE_1ST_FRAG From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org bpf_flow.c: exit early unless FLOW_DISSECTOR_F_PARSE_1ST_FRAG is passed in flags. Also, set ip_proto earlier, this makes sure we have correct value with fragmented packets. Add selftest cases to test ipv4/ipv6 fragments and skip eth_get_headlen tests that don't have FLOW_DISSECTOR_F_PARSE_1ST_FRAG flag. eth_get_headlen calls flow dissector with FLOW_DISSECTOR_F_PARSE_1ST_FRAG flag so we can't run tests that have different set of input flags against it. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev --- .../selftests/bpf/prog_tests/flow_dissector.c | 129 ++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 28 +++- 2 files changed, 151 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index c938283ac232..966cb3b06870 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -5,6 +5,10 @@ #include #include +#ifndef IP_MF +#define IP_MF 0x2000 +#endif + #define CHECK_FLOW_KEYS(desc, got, expected) \ CHECK_ATTR(memcmp(&got, &expected, sizeof(got)) != 0, \ desc, \ @@ -49,6 +53,18 @@ struct ipv6_pkt { struct tcphdr tcp; } __packed; +struct ipv6_frag_pkt { + struct ethhdr eth; + struct ipv6hdr iph; + struct frag_hdr { + __u8 nexthdr; + __u8 reserved; + __be16 frag_off; + __be32 identification; + } ipf; + struct tcphdr tcp; +} __packed; + struct dvlan_ipv6_pkt { struct ethhdr eth; __u16 vlan_tci; @@ -65,9 +81,11 @@ struct test { struct ipv4_pkt ipv4; struct svlan_ipv4_pkt svlan_ipv4; struct ipv6_pkt ipv6; + struct ipv6_frag_pkt ipv6_frag; struct dvlan_ipv6_pkt dvlan_ipv6; } pkt; struct bpf_flow_keys keys; + __u32 flags; }; #define VLAN_HLEN 4 @@ -143,6 +161,102 @@ struct test tests[] = { .n_proto = __bpf_constant_htons(ETH_P_IPV6), }, }, + { + .name = "ipv4-frag", + .pkt.ipv4 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_TCP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.frag_off = __bpf_constant_htons(IP_MF), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_frag = true, + .is_first_frag = true, + .sport = 80, + .dport = 8080, + }, + .flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + }, + { + .name = "ipv4-no-frag", + .pkt.ipv4 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_TCP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.frag_off = __bpf_constant_htons(IP_MF), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_frag = true, + .is_first_frag = true, + }, + }, + { + .name = "ipv6-frag", + .pkt.ipv6_frag = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_FRAGMENT, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .ipf.nexthdr = IPPROTO_TCP, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr) + + sizeof(struct frag_hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .is_frag = true, + .is_first_frag = true, + .sport = 80, + .dport = 8080, + }, + .flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG, + }, + { + .name = "ipv6-no-frag", + .pkt.ipv6_frag = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_FRAGMENT, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .ipf.nexthdr = IPPROTO_TCP, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr) + + sizeof(struct frag_hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .is_frag = true, + .is_first_frag = true, + }, + }, }; static int create_tap(const char *ifname) @@ -225,6 +339,13 @@ void test_flow_dissector(void) .data_size_in = sizeof(tests[i].pkt), .data_out = &flow_keys, }; + static struct bpf_flow_keys ctx = {}; + + if (tests[i].flags) { + tattr.ctx_in = &ctx; + tattr.ctx_size_in = sizeof(ctx); + ctx.flags = tests[i].flags; + } err = bpf_prog_test_run_xattr(&tattr); CHECK_ATTR(tattr.data_size_out != sizeof(flow_keys) || @@ -255,6 +376,14 @@ void test_flow_dissector(void) struct bpf_prog_test_run_attr tattr = {}; __u32 key = 0; + /* Don't run tests that are not marked as + * FLOW_DISSECTOR_F_PARSE_1ST_FRAG; eth_get_headlen + * sets this flag. + */ + + if (tests[i].flags != FLOW_DISSECTOR_F_PARSE_1ST_FRAG) + continue; + err = tx_tap(tap_fd, &tests[i].pkt, sizeof(tests[i].pkt)); CHECK(err < 0, "tx_tap", "err %d errno %d\n", err, errno); diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 5ae485a6af3f..0eabe5e57944 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -153,7 +153,6 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) struct tcphdr *tcp, _tcp; struct udphdr *udp, _udp; - keys->ip_proto = proto; switch (proto) { case IPPROTO_ICMP: icmp = bpf_flow_dissect_get_header(skb, sizeof(*icmp), &_icmp); @@ -231,7 +230,6 @@ static __always_inline int parse_ipv6_proto(struct __sk_buff *skb, __u8 nexthdr) { struct bpf_flow_keys *keys = skb->flow_keys; - keys->ip_proto = nexthdr; switch (nexthdr) { case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: @@ -266,6 +264,7 @@ PROG(IP)(struct __sk_buff *skb) keys->addr_proto = ETH_P_IP; keys->ipv4_src = iph->saddr; keys->ipv4_dst = iph->daddr; + keys->ip_proto = iph->protocol; keys->thoff += iph->ihl << 2; if (data + keys->thoff > data_end) @@ -273,13 +272,19 @@ PROG(IP)(struct __sk_buff *skb) if (iph->frag_off & bpf_htons(IP_MF | IP_OFFSET)) { keys->is_frag = true; - if (iph->frag_off & bpf_htons(IP_OFFSET)) + if (iph->frag_off & bpf_htons(IP_OFFSET)) { /* From second fragment on, packets do not have headers * we can parse. */ done = true; - else + } else { keys->is_first_frag = true; + /* No need to parse fragmented packet unless + * explicitly asked for. + */ + if (!(keys->flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) + done = true; + } } if (done) @@ -301,6 +306,7 @@ PROG(IPV6)(struct __sk_buff *skb) memcpy(&keys->ipv6_src, &ip6h->saddr, 2*sizeof(ip6h->saddr)); keys->thoff += sizeof(struct ipv6hdr); + keys->ip_proto = ip6h->nexthdr; return parse_ipv6_proto(skb, ip6h->nexthdr); } @@ -317,7 +323,8 @@ PROG(IPV6OP)(struct __sk_buff *skb) /* hlen is in 8-octets and does not include the first 8 bytes * of the header */ - skb->flow_keys->thoff += (1 + ip6h->hdrlen) << 3; + keys->thoff += (1 + ip6h->hdrlen) << 3; + keys->ip_proto = ip6h->nexthdr; return parse_ipv6_proto(skb, ip6h->nexthdr); } @@ -333,9 +340,18 @@ PROG(IPV6FR)(struct __sk_buff *skb) keys->thoff += sizeof(*fragh); keys->is_frag = true; - if (!(fragh->frag_off & bpf_htons(IP6_OFFSET))) + keys->ip_proto = fragh->nexthdr; + + if (!(fragh->frag_off & bpf_htons(IP6_OFFSET))) { keys->is_first_frag = true; + /* No need to parse fragmented packet unless + * explicitly asked for. + */ + if (!(keys->flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) + return export_flow_keys(keys, BPF_OK); + } + return parse_ipv6_proto(skb, fragh->nexthdr); } From patchwork Wed Jul 24 17:00:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136442 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="hEYafFBD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1nL40QPz9s8m for ; Thu, 25 Jul 2019 03:00:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727747AbfGXRAh (ORCPT ); Wed, 24 Jul 2019 13:00:37 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:55397 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727211AbfGXRAh (ORCPT ); Wed, 24 Jul 2019 13:00:37 -0400 Received: by mail-pf1-f202.google.com with SMTP id i26so28879157pfo.22 for ; Wed, 24 Jul 2019 10:00:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=nAq1zfo67s49u0DMebVzksFPvWcTITLUE75je4eUK9g=; b=hEYafFBDcOk3LJy+10I9VclxWycwTlmD7snYcbwYx37YcefWQ7AsEh0BCTsA0/rgCk DYK/4srBO4tE4CaUH64w0JLjT2KnKh/190J8gM0G1gNBDSv08vZIe09YJ1GNPIM1fYDH y3zZUYbyE5t+WzZptbhJPkiuuZQ9EPbylJlYO9LQzOnHC45bcHBxKNghVB2grx3AvJAX TdZcBcdSXf3aiZFUi6cPrVa2Dt37eHxnYvwfX3fb4h3ezCQIRDsLeu6Lt8BbSJGKKsdm JXXAxUgdRCICq796N+q9zPvAQJ4FHAC8p/Z2k6XXnoVAiwE9/tyesdfXPB7j0VBce3wD 9sxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=nAq1zfo67s49u0DMebVzksFPvWcTITLUE75je4eUK9g=; b=CRLkZ8woN6BvPHp+iW8RPx2N4eGGAzZRG3EZOhCyvuCWOUCilRhvqRietGyokFjq6Y ugnCpjHhDZVEEs2+GfO6MXdhP5YhGOXCZnE+Sou03BFUTkMTpfoqsoSD4wO15qwLHPHp SjIvH4BBDerxpgAmU1TqDlqGnHf+eB/WmGuFOM4NKz9f4fBpTVhdx6Rb/39xzRnoE871 tu8AyYWaA1BkbgcDPWG4BrQzUHjNeA82zak7F0On0TDfiqpstpV7Q5sSm3C3XfDKVNL1 iFnj+xFhUx2wTnQc2OHauQM4CUrbMDC3kjXNS4d+jGBBAtKuR+6ADDvgOmrkfVPNVlo+ 5L3Q== X-Gm-Message-State: APjAAAWeJjMj72IU2u2RuFjr2/Q2scyFhtCbIA9fMRu2rxclw0rV0Wv4 2IcOabgBZ8tX44vh8Y76E/gjgpc= X-Google-Smtp-Source: APXvYqy2m9N35HEuM4ZufLYeugD5J+K8g+fqFqCiBZgVjOx7rnipNb43Di0SqQ9D4So1N8uD2E2AdLc= X-Received: by 2002:a65:6284:: with SMTP id f4mr24542823pgv.416.1563987636251; Wed, 24 Jul 2019 10:00:36 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:17 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-7-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 6/7] bpf/flow_dissector: support ipv6 flow_label and FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Add support for exporting ipv6 flow label via bpf_flow_keys. Export flow label from bpf_flow.c and also return early when FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL is passed. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- include/uapi/linux/bpf.h | 1 + net/core/flow_dissector.c | 9 ++++ tools/include/uapi/linux/bpf.h | 1 + .../selftests/bpf/prog_tests/flow_dissector.c | 46 +++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 10 ++++ 5 files changed, 67 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index b4ad19bd6aa8..83b4150466af 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3533,6 +3533,7 @@ struct bpf_flow_keys { }; }; __u32 flags; + __be32 flow_label; }; struct bpf_func_info { diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index a74c4ed1b30d..bcdb863cad28 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -737,6 +737,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, struct flow_dissector_key_basic *key_basic; struct flow_dissector_key_addrs *key_addrs; struct flow_dissector_key_ports *key_ports; + struct flow_dissector_key_tags *key_tags; key_control = skb_flow_dissector_target(flow_dissector, FLOW_DISSECTOR_KEY_CONTROL, @@ -781,6 +782,14 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, key_ports->src = flow_keys->sport; key_ports->dst = flow_keys->dport; } + + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL)) { + key_tags = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL, + target_container); + key_tags->flow_label = ntohl(flow_keys->flow_label); + } } bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx, diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index a0e1c891b56f..c26ca432b1b3 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3530,6 +3530,7 @@ struct bpf_flow_keys { }; }; __u32 flags; + __be32 flow_label; }; struct bpf_func_info { diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 966cb3b06870..1ea921c4cdc0 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -20,6 +20,7 @@ "is_encap=%u/%u " \ "ip_proto=0x%x/0x%x " \ "n_proto=0x%x/0x%x " \ + "flow_label=0x%x/0x%x " \ "sport=%u/%u " \ "dport=%u/%u\n", \ got.nhoff, expected.nhoff, \ @@ -30,6 +31,7 @@ got.is_encap, expected.is_encap, \ got.ip_proto, expected.ip_proto, \ got.n_proto, expected.n_proto, \ + got.flow_label, expected.flow_label, \ got.sport, expected.sport, \ got.dport, expected.dport) @@ -257,6 +259,50 @@ struct test tests[] = { .is_first_frag = true, }, }, + { + .name = "ipv6-flow-label", + .pkt.ipv6 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_TCP, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.flow_lbl = { 0xb, 0xee, 0xef }, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .sport = 80, + .dport = 8080, + .flow_label = __bpf_constant_htonl(0xbeeef), + }, + }, + { + .name = "ipv6-no-flow-label", + .pkt.ipv6 = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6), + .iph.nexthdr = IPPROTO_TCP, + .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES), + .iph.flow_lbl = { 0xb, 0xee, 0xef }, + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct ipv6hdr), + .addr_proto = ETH_P_IPV6, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IPV6), + .flow_label = __bpf_constant_htonl(0xbeeef), + }, + .flags = FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, + }, }; static int create_tap(const char *ifname) diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 0eabe5e57944..7d73b7bfe609 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -83,6 +83,12 @@ static __always_inline int export_flow_keys(struct bpf_flow_keys *keys, return ret; } +#define IPV6_FLOWLABEL_MASK __bpf_constant_htonl(0x000FFFFF) +static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr) +{ + return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK; +} + static __always_inline void *bpf_flow_dissect_get_header(struct __sk_buff *skb, __u16 hdr_size, void *buffer) @@ -307,6 +313,10 @@ PROG(IPV6)(struct __sk_buff *skb) keys->thoff += sizeof(struct ipv6hdr); keys->ip_proto = ip6h->nexthdr; + keys->flow_label = ip6_flowlabel(ip6h); + + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) + return export_flow_keys(keys, BPF_OK); return parse_ipv6_proto(skb, ip6h->nexthdr); } From patchwork Wed Jul 24 17:00:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 1136444 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="sKogE6EV"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45v1nN505cz9s8m for ; Thu, 25 Jul 2019 03:00:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727962AbfGXRAk (ORCPT ); Wed, 24 Jul 2019 13:00:40 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:46735 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727789AbfGXRAj (ORCPT ); Wed, 24 Jul 2019 13:00:39 -0400 Received: by mail-pg1-f202.google.com with SMTP id u1so28680093pgr.13 for ; Wed, 24 Jul 2019 10:00:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=FRNcRu6lDB1xBr2PsV6vHeQry9zflSkPR0VRFovMcCM=; b=sKogE6EVxLd6hnxUxXZdL1LW5vrdjutf18p7yL1gwUisRRpBpS+19pGtYqKj8uHZCv 8Ecis7k9yKgG9GKiBpUftao5xZYoCcCBhWrDC5JRH6RMPLFaElXgHOedMrvdX0bI+GB+ +8afVrxJkxfACUEqwUMbntYetKv4GT2I9hdkvUhWKmPVa7f+S4PMOq5Mb001cs5THkRk P53hyCeK2+94SqdSR2xuNR8fWki3PXp9iaubEmHpFGTER8j5Emh6WQ8V1sQ2t+wWunon dnE9giUuDVzBxdgt3/l2YdRWX3pnd/jZgxLjsSP0paUHw4zJzWHqP1QJ3E62+dvWO4VB 4wow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=FRNcRu6lDB1xBr2PsV6vHeQry9zflSkPR0VRFovMcCM=; b=I9cr/lHGk5Pp0bzP5jJPXtDJOmFf6s4Lt7iY5bNsFSym5GOXwgAO6sURZ8rH488h+M FcSwR2TPYlv+kZTm+9uBAE0l2Zg+1XdkKJM/H9TxFHYmrnIFNtDO+OSP6GB1lGtx4hFv 4XQaMrRpu8FX6rlN+Q2QBtIW/DQ9ljRwIjKc8mL2x+I+5jo+5eUPS+Ff/mN+FSjK2d45 VhCLrt+F5rILlOMTH1cI/ufPRKy9LLfjAPvpDj0u7lnbcTtOvoM4wDMu139LCiA2wGFe 2BNvUVPdaCs4RGBKDa1itY3PKNXa6n8IGWtL4tgiss6wwTBXeyOL94p7fimcszgLqESo lTOA== X-Gm-Message-State: APjAAAUvs6tXuUcRiG6HZF92jJXqOwM+v0dQh/jc39bg8zbYzcYlum6F Sr+wDs6iUaXpGKpV9PmFfnqqLrk= X-Google-Smtp-Source: APXvYqzOVy+j7WJJns5lw5LsSY3MEvQu+tIk4RP4vIyx02wnzV6/OK2b2A7bLI+5DN7lwsNrYgxKJ1g= X-Received: by 2002:a65:4489:: with SMTP id l9mr84811810pgq.207.1563987638862; Wed, 24 Jul 2019 10:00:38 -0700 (PDT) Date: Wed, 24 Jul 2019 10:00:18 -0700 In-Reply-To: <20190724170018.96659-1-sdf@google.com> Message-Id: <20190724170018.96659-8-sdf@google.com> Mime-Version: 1.0 References: <20190724170018.96659-1-sdf@google.com> X-Mailer: git-send-email 2.22.0.657.g960e92d24f-goog Subject: [PATCH bpf-next 7/7] selftests/bpf: support FLOW_DISSECTOR_F_STOP_AT_ENCAP From: Stanislav Fomichev To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net, Stanislav Fomichev , Willem de Bruijn , Petar Penkov Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Exit as soon as we found that packet is encapped when FLOW_DISSECTOR_F_STOP_AT_ENCAP is passed. Add appropriate selftest cases. Cc: Willem de Bruijn Cc: Petar Penkov Signed-off-by: Stanislav Fomichev Acked-by: Song Liu --- .../selftests/bpf/prog_tests/flow_dissector.c | 60 +++++++++++++++++++ tools/testing/selftests/bpf/progs/bpf_flow.c | 8 +++ 2 files changed, 68 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 1ea921c4cdc0..e382264fbc40 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -41,6 +41,13 @@ struct ipv4_pkt { struct tcphdr tcp; } __packed; +struct ipip_pkt { + struct ethhdr eth; + struct iphdr iph; + struct iphdr iph_inner; + struct tcphdr tcp; +} __packed; + struct svlan_ipv4_pkt { struct ethhdr eth; __u16 vlan_tci; @@ -82,6 +89,7 @@ struct test { union { struct ipv4_pkt ipv4; struct svlan_ipv4_pkt svlan_ipv4; + struct ipip_pkt ipip; struct ipv6_pkt ipv6; struct ipv6_frag_pkt ipv6_frag; struct dvlan_ipv6_pkt dvlan_ipv6; @@ -303,6 +311,58 @@ struct test tests[] = { }, .flags = FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL, }, + { + .name = "ipip-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph_inner.ihl = 5, + .iph_inner.protocol = IPPROTO_TCP, + .iph_inner.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .nhoff = 0, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr) + + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_TCP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + .sport = 80, + .dport = 8080, + }, + }, + { + .name = "ipip-no-encap", + .pkt.ipip = { + .eth.h_proto = __bpf_constant_htons(ETH_P_IP), + .iph.ihl = 5, + .iph.protocol = IPPROTO_IPIP, + .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .iph_inner.ihl = 5, + .iph_inner.protocol = IPPROTO_TCP, + .iph_inner.tot_len = __bpf_constant_htons(MAGIC_BYTES), + .tcp.doff = 5, + .tcp.source = 80, + .tcp.dest = 8080, + }, + .keys = { + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, + .nhoff = ETH_HLEN, + .thoff = ETH_HLEN + sizeof(struct iphdr), + .addr_proto = ETH_P_IP, + .ip_proto = IPPROTO_IPIP, + .n_proto = __bpf_constant_htons(ETH_P_IP), + .is_encap = true, + }, + .flags = FLOW_DISSECTOR_F_STOP_AT_ENCAP, + }, }; static int create_tap(const char *ifname) diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c index 7d73b7bfe609..b6236cdf8564 100644 --- a/tools/testing/selftests/bpf/progs/bpf_flow.c +++ b/tools/testing/selftests/bpf/progs/bpf_flow.c @@ -167,9 +167,15 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) return export_flow_keys(keys, BPF_OK); case IPPROTO_IPIP: keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IP)); case IPPROTO_IPV6: keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); + return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6)); case IPPROTO_GRE: gre = bpf_flow_dissect_get_header(skb, sizeof(*gre), &_gre); @@ -189,6 +195,8 @@ static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto) keys->thoff += 4; /* Step over sequence number */ keys->is_encap = true; + if (keys->flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) + return export_flow_keys(keys, BPF_OK); if (gre->proto == bpf_htons(ETH_P_TEB)) { eth = bpf_flow_dissect_get_header(skb, sizeof(*eth),