From patchwork Tue Aug 7 15:35:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954561 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="tAGtT0p5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJX942XYz9s3x for ; Wed, 8 Aug 2018 01:36:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389931AbeHGRvP (ORCPT ); Tue, 7 Aug 2018 13:51:15 -0400 Received: from mail-qt0-f193.google.com ([209.85.216.193]:39307 "EHLO mail-qt0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733213AbeHGRvP (ORCPT ); Tue, 7 Aug 2018 13:51:15 -0400 Received: by mail-qt0-f193.google.com with SMTP id q12-v6so18303805qtp.6 for ; Tue, 07 Aug 2018 08:36:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zVrpWTv3GI0MrFNAUIxKXolXzb1AGDC72XLr8Dihfc0=; b=tAGtT0p5XuBAOPbPuLU40YcTVK/X9zJiInrAvF0wZCFwNqRuBIN9mjrlLMTaWi+Ecv edGo1iE9EsvhFczjPA9HeD6E7jB1jqmOFbNy9w9JtAFRqIS7HmMzRvqdQOtuA/pDe2Ql 2nFY6rnLjDLe+g0pAwbRiEKZURYuUxlZWqYa19T1WVuby510cU33LRrkyb5ti7Cet3nL gAKK4BD35wWNxtJgZWdXDwZeFxdHRnZFmpx4jH6mUsz9bKfi8bWlKpskPRD0icCJSGrO ESEpg5IV85mGyz9wenjhAFnRKN0uggt2jlfkkpWppRCXwrP3RKPB+whN23/gkxF8x7nT i23w== 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; bh=zVrpWTv3GI0MrFNAUIxKXolXzb1AGDC72XLr8Dihfc0=; b=eb6OCJgvT/XIGsWyM5b3XOwvq2828SqK8bPQp2aV9Hh35mAQEFMNNwROiZeHN2Fq6z yNLI6O6Ezek6Wb0oOyXa44qRM/Fum4jtLtYGGLF7a5DL47uPofAIupF6AaO2LTfzIwSF OxNce875JxIqi14PxoInNgkG+NSd+DPMm0EC52cWz6L9zP+EDjJqMEel+ZM5x6RJxr27 L4paOoCBXgj5BUuEPYvoINzVTK92vy7dNAVAkXITo4dmuP0k2geJaoxL67AFRtu98Tpl /IJ3UwHJ1T4qUDlDhfA73pfqJh5I//AjaKV/sjWRNsx0Zz96n6YP3WaskcaprrwdZ0y8 jhiA== X-Gm-Message-State: AOUpUlFm9bbh8eowtnbNmkPp8BNMigfRyDU4PrT3ldOA/5vfcEMZ9MaN sEnCe/Kc4cGEs9KzSI0/2Qb9Kw== X-Google-Smtp-Source: AAOMgpdqp8jOQDtqxMT73kLB4kq+m5K3/ZLc+EbnDwoLlXYZzPpFaCp8jTWrARIyS4N/gXQHUVGjFA== X-Received: by 2002:ac8:705a:: with SMTP id y26-v6mr19953482qtm.118.1533656181906; Tue, 07 Aug 2018 08:36:21 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:21 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 1/6] nfp: flower: set ip tunnel ttl from encap action Date: Tue, 7 Aug 2018 17:35:58 +0200 Message-Id: <20180807153603.1815-2-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley The TTL for encapsulating headers in IPv4 UDP tunnels is taken from a route lookup. Modify this to first check if a user has specified a TTL to be used in the TC action. Signed-off-by: John Hurley Reviewed-by: Jakub Kicinski Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/action.c | 39 ++++++++++++---------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index e56b815a8dc6..a79d078ab3e8 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -238,18 +238,12 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); u32 tmp_set_ip_tun_type_index = 0; - struct flowi4 flow = {}; /* Currently support one pre-tunnel so index is always 0. */ int pretun_idx = 0; - struct rtable *rt; - struct net *net; - int err; if (ip_tun->options_len) return -EOPNOTSUPP; - net = dev_net(netdev); - set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; @@ -261,19 +255,28 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); set_tun->tun_id = ip_tun->key.tun_id; - /* Do a route lookup to determine ttl - if fails then use default. - * Note that CONFIG_INET is a requirement of CONFIG_NET_SWITCHDEV so - * must be defined here. - */ - flow.daddr = ip_tun->key.u.ipv4.dst; - flow.flowi4_proto = IPPROTO_UDP; - rt = ip_route_output_key(net, &flow); - err = PTR_ERR_OR_ZERO(rt); - if (!err) { - set_tun->ttl = ip4_dst_hoplimit(&rt->dst); - ip_rt_put(rt); + if (ip_tun->key.ttl) { + set_tun->ttl = ip_tun->key.ttl; } else { - set_tun->ttl = net->ipv4.sysctl_ip_default_ttl; + struct net *net = dev_net(netdev); + struct flowi4 flow = {}; + struct rtable *rt; + int err; + + /* Do a route lookup to determine ttl - if fails then use + * default. Note that CONFIG_INET is a requirement of + * CONFIG_NET_SWITCHDEV so must be defined here. + */ + flow.daddr = ip_tun->key.u.ipv4.dst; + flow.flowi4_proto = IPPROTO_UDP; + rt = ip_route_output_key(net, &flow); + err = PTR_ERR_OR_ZERO(rt); + if (!err) { + set_tun->ttl = ip4_dst_hoplimit(&rt->dst); + ip_rt_put(rt); + } else { + set_tun->ttl = net->ipv4.sysctl_ip_default_ttl; + } } set_tun->tos = ip_tun->key.tos; From patchwork Tue Aug 7 15:35:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954562 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="iYzU7jgq"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJXB6NRYz9rvt for ; Wed, 8 Aug 2018 01:36:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389949AbeHGRvR (ORCPT ); Tue, 7 Aug 2018 13:51:17 -0400 Received: from mail-qt0-f172.google.com ([209.85.216.172]:36231 "EHLO mail-qt0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733213AbeHGRvR (ORCPT ); Tue, 7 Aug 2018 13:51:17 -0400 Received: by mail-qt0-f172.google.com with SMTP id t5-v6so18317684qtn.3 for ; Tue, 07 Aug 2018 08:36:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c/sQv0hyHh1aTCAUeirng7P3reo/IODv3BzeqYjMIn4=; b=iYzU7jgqZwU++MG53QgS4+WB2DFSl02wnJbzp5J+OOGfUITbvYDQkUa8TEZy2Wgr4X nDF4JKLBxiO/2oyxzKffrCRDGRRVin7lK3WkmpedqP5yjfWXRAAKKczsI7+It7aOxQFe TNT+uOwEFsYSloBBn7dueUCLJDeULSQ6v2PQnVr+fpu/mcoOUanrXxO+gEjToyyKdgiJ J22mG4xutcr6/gVq+zLZabYNDXOFADVoaDEWDJ0EQb7p9ydC8RZ89YEin9YxJwa5xKCO RNvCX0lmHRYSpZi5wv10FqgSQIlkNl4gYEahWOIu+M5k86E4FpHPh8/7gNKW6jd3s6AF mk7w== 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; bh=c/sQv0hyHh1aTCAUeirng7P3reo/IODv3BzeqYjMIn4=; b=EyUubST2mwlLb2Qck8BllieTm1l423ymNrgsDr3rTgC9QG8ciuvp/hJq78tBJCz5pH rVrcMPGLHMBlYn4dY6AX4mwFtfXuXXrcjE/8/q1bxXsly0i/nxmapLMp3z/ltlWc0sGj fGcIcH1UK80ohHemOof1puFabJUotwLX/kxYj8hXYNTAuK3jFrVOw5ezgJQn0qK0TMcs kq5YLgc0aLrGWaPtzc4DejYM28Jis0VL4Ni/8ILStO8MabbQ9Vq9JU/IvSpUyjDWGBsu 3e7JXKHbyIOYK2tW9InvnptTMsyM76y1oHBZfL2CI6k38Z+jqN8UllB8zMmySJpSRVtJ ePtA== X-Gm-Message-State: AOUpUlGzx8NQkABHkcE0UVptei0nNhIxbU378LZj9pPMWozKDaQJk6IV aywqTjTGZsWmHvVUCcoN4fH2gQ== X-Google-Smtp-Source: AAOMgpff5YcokMdakvIcGizuNJztZlsrqCR+B6q/4FdZZV3e9RuH5A/KfGZHhQktiTwSdFIFsvrMiw== X-Received: by 2002:ac8:42b:: with SMTP id v43-v6mr18197569qtg.319.1533656183499; Tue, 07 Aug 2018 08:36:23 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:22 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 2/6] nfp: flower: allow matching on ipv4 UDP tunnel tos and ttl Date: Tue, 7 Aug 2018 17:35:59 +0200 Message-Id: <20180807153603.1815-3-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley The addition of FLOW_DISSECTOR_KEY_ENC_IP to TC flower means that the ToS and TTL of the tunnel header can now be matched on. Extend the NFP tunnel match function to include these new fields. Signed-off-by: John Hurley Reviewed-by: Jakub Kicinski Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 7 +++++-- drivers/net/ethernet/netronome/nfp/flower/match.c | 9 +++++++++ drivers/net/ethernet/netronome/nfp/flower/offload.c | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 15f1eacd76b6..174acecfba01 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -346,7 +346,7 @@ struct nfp_flower_ipv6 { * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ipv4_addr_dst | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | + * | Reserved | tos | ttl | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -356,7 +356,10 @@ struct nfp_flower_ipv6 { struct nfp_flower_ipv4_udp_tun { __be32 ip_src; __be32 ip_dst; - __be32 reserved[2]; + __be16 reserved1; + u8 tos; + u8 ttl; + __be32 reserved2; __be32 tun_id; }; diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index 84f7a5dbea9d..b1cbe6927cba 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -270,6 +270,7 @@ nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame, struct fl_flow_key *target = mask_version ? flow->mask : flow->key; struct flow_dissector_key_ipv4_addrs *tun_ips; struct flow_dissector_key_keyid *vni; + struct flow_dissector_key_ip *ip; memset(frame, 0, sizeof(struct nfp_flower_ipv4_udp_tun)); @@ -293,6 +294,14 @@ nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame, frame->ip_src = tun_ips->src; frame->ip_dst = tun_ips->dst; } + + if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ENC_IP)) { + ip = skb_flow_dissector_target(flow->dissector, + FLOW_DISSECTOR_KEY_ENC_IP, + target); + frame->tos = ip->tos; + frame->ttl = ip->ttl; + } } int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 6bc8a97f7e03..d2230a0e49b9 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -66,6 +66,7 @@ BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \ BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \ + BIT(FLOW_DISSECTOR_KEY_ENC_IP) | \ BIT(FLOW_DISSECTOR_KEY_MPLS) | \ BIT(FLOW_DISSECTOR_KEY_IP)) @@ -74,7 +75,8 @@ BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \ - BIT(FLOW_DISSECTOR_KEY_ENC_PORTS)) + BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \ + BIT(FLOW_DISSECTOR_KEY_ENC_IP)) #define NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R \ (BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \ From patchwork Tue Aug 7 15:36:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954563 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="sx0vud+1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJXC5Wdgz9s3x for ; Wed, 8 Aug 2018 01:36:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389958AbeHGRvS (ORCPT ); Tue, 7 Aug 2018 13:51:18 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:36898 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389829AbeHGRvR (ORCPT ); Tue, 7 Aug 2018 13:51:17 -0400 Received: by mail-qk0-f196.google.com with SMTP id t79-v6so11719422qke.4 for ; Tue, 07 Aug 2018 08:36:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ywIC0xe1k00tiJ8wzJV2Fm6Nio5+RFvhQ/+pPfaR8JU=; b=sx0vud+1s9KfqvdqAtCSe7/ujQ700VtRPr4z1+6SVC3XyPG86Uzs56F8lmUBE+y/z3 9Z2o5ZGpygAu6mInMUbVslXj7fkern6QLeFg/UTpFsQCyw0VCG6QVDvVOgW1QJWLa6lx xQbXPx5/yA4C5eC9rhRyC0VqDVZ5GdDvGqLYakDwK4ahRKzR/tgxlniIWPJ2mPPgcT/9 fkoCrOeBlob8emt76KvBoJAt5Mnp/U/XqNUsD+3HB5gcSXpASBitdie4ldADulMREnJ6 lZj7GPVrZFlaGN6kO7uFd0gbzSgcVEgBr2zOGD1w0Bam6KwER6KVTrAe+iJsVCmBn20X xjoA== 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; bh=ywIC0xe1k00tiJ8wzJV2Fm6Nio5+RFvhQ/+pPfaR8JU=; b=WDiMwP1xE7NG1xRSukRFFwulQth/Al1Dzt0pylx8GfZNZZoAf3PDy/65e/4UOQ5aYW 63t/o9MBurPr1JQfmPqjo+0CXEMdgz1rs15NbmuB6uZ+LSDTo3JIQpSi+ybEi4GfpFTW pyZxIEFCjgcslB3HzNwMpwmOeJymq357pg2QiOr8q1xbjRYd4aDjCPL8tIUywbLdKbOH Wm8qTRT6Iq+3MIKw7YpT7sF8UsZTLl8O6q7NGPG7D60YHHeqoTbuBGJxYAqXX59seA+r 1mtuXnOmFEH5AjJ97HoDlBvxbh9M7S+nB2zS81c6Gerzv+t1Z/od9mLUMwPrHUFJBxXL RE/g== X-Gm-Message-State: AOUpUlEUjukr+XV1QGlC3VTuRy//X6XOT/epy9fHrSGmQ7Iwjp/4eHh6 r6C1eX6XIEZC0CTXJo5Ilp8J1g== X-Google-Smtp-Source: AAOMgpeZitx19sMOql7E7L86h2rBJt0YTNCOfLF/aP13lVUDw1fxdQG1fGeI+KtNJTB/G65XsxtljQ== X-Received: by 2002:a37:a704:: with SMTP id q4-v6mr18070751qke.325.1533656185131; Tue, 07 Aug 2018 08:36:25 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:24 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 3/6] flow_dissector: allow dissection of tunnel options from metadata Date: Tue, 7 Aug 2018 17:36:00 +0200 Message-Id: <20180807153603.1815-4-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allow the existing 'dissection' of tunnel metadata to 'dissect' options already present in tunnel metadata. This dissection is controlled by a new dissector key, FLOW_DISSECTOR_KEY_ENC_OPTS. This dissection only occurs when skb_flow_dissect_tunnel_info() is called, currently only the Flower classifier makes that call. So there should be no impact on other users of the flow dissector. This is in preparation for allowing the flower classifier to match on Geneve options. Signed-off-by: Simon Horman Signed-off-by: Pieter Jansen van Vuuren Reviewed-by: Jakub Kicinski --- include/net/flow_dissector.h | 17 +++++++++++++++++ net/core/flow_dissector.c | 19 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 2a17f041f7a1..6a4586dcdede 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -57,6 +57,21 @@ struct flow_dissector_key_mpls { mpls_label:20; }; +#define FLOW_DIS_TUN_OPTS_MAX 255 +/** + * struct flow_dissector_key_enc_opts: + * @data: tunnel option data + * @len: length of tunnel option data + * @dst_opt_type: tunnel option type + */ +struct flow_dissector_key_enc_opts { + u8 data[FLOW_DIS_TUN_OPTS_MAX]; /* Using IP_TUNNEL_OPTS_MAX is desired + * here but seems difficult to #include + */ + u8 len; + __be16 dst_opt_type; +}; + struct flow_dissector_key_keyid { __be32 keyid; }; @@ -208,6 +223,8 @@ enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */ FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */ FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */ + FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */ + FLOW_DISSECTOR_KEY_MAX, }; diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 08a5184f4b34..ce9eeeb7c024 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -154,7 +154,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_PORTS) && !dissector_uses_key(flow_dissector, - FLOW_DISSECTOR_KEY_ENC_IP)) + FLOW_DISSECTOR_KEY_ENC_IP) && + !dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_ENC_OPTS)) return; info = skb_tunnel_info(skb); @@ -224,6 +226,21 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ip->tos = key->tos; ip->ttl = key->ttl; } + + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_OPTS)) { + struct flow_dissector_key_enc_opts *enc_opt; + + enc_opt = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_ENC_OPTS, + target_container); + + if (info->options_len) { + enc_opt->len = info->options_len; + ip_tunnel_info_opts_get(enc_opt->data, info); + enc_opt->dst_opt_type = info->key.tun_flags & + TUNNEL_OPTIONS_PRESENT; + } + } } EXPORT_SYMBOL(skb_flow_dissect_tunnel_info); From patchwork Tue Aug 7 15:36:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954564 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="vodMwzQn"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJXG0dK3z9rvt for ; Wed, 8 Aug 2018 01:36:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389979AbeHGRvV (ORCPT ); Tue, 7 Aug 2018 13:51:21 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:41176 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389961AbeHGRvU (ORCPT ); Tue, 7 Aug 2018 13:51:20 -0400 Received: by mail-qt0-f195.google.com with SMTP id e19-v6so18291702qtp.8 for ; Tue, 07 Aug 2018 08:36:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jM1yQ8/67dCkZ2Lfk6XBN6txlnWZryebcwtCfnLpWz8=; b=vodMwzQnxrY5tGkYd4ixjU1jbkHC1zDymiuhMc86mrRw6oZH+YrHFeh1oZXje+7I47 +5tmhT73m/tzzhrSYhLxqJE2xW3tf7llekXPFH0IlaNrFmReOt9qjtImMCIxfI2YRFWu 9ErHxWJT07x2cZahb1pYpk7VBXTnPtlXVmIWWjoWAOXvoUCM6KGAEJCxhT+a3O2pldwd t7gcLfp2EXuTz3kR3eHo3MVnJtDSYfLUQHVcPRtG+s9whkgYU+77ZksEzg9F192jmaSS GhjF6lN9xG6XN7IKzLshkcLWobPQPjQ8fHRp9iXesT63vHM6wyWFZ9Z/47SrGd3kJ5gJ c3WQ== 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; bh=jM1yQ8/67dCkZ2Lfk6XBN6txlnWZryebcwtCfnLpWz8=; b=e0BFyfU9ZV2ItDm6vyXIhhoygd6ygFxQRKN5gKL1ic8UWDQ5ZwO93I91D2v5qZLV27 6OVcP5tyBlgiMNerZEbnmoh42IrXaZ0cV8ZKrtaS2oYs8uzOLbbHzMhKnibecjY2DFin WyUPSca7kBq+/onDLs4ooueSaiMAQTSuPdKkc3rAhGSqzIjGqArDbArpRLNLGEk270ur iL41SHQjAhpiSBCwgL/BetFnerbnKr120k+krF0/aQ6xlUuKHCB6wqU5hvogwN3UwFli y/ZXKQYsFJCf2wLRjsgKDK9mtmHsiVt6YywAQjIL8ePzSBAZHp4bOsfVwWHaJZvyWt8u zH5A== X-Gm-Message-State: AOUpUlGspwaGOzx5fRgVrSV9u2nnag81LuKaJiMujjwKv5U3MghUjqjp rnOYMChk7EDgpoHsyhP5oKoMKw== X-Google-Smtp-Source: AAOMgpdzYXmMaW2IuvDC32sdOlrk+4Q7UouNiR8YOpyXMkW1yEU7U3OOBU7xGV+2tS44H5NjpYT/xQ== X-Received: by 2002:ac8:395:: with SMTP id t21-v6mr19131922qtg.283.1533656186763; Tue, 07 Aug 2018 08:36:26 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:26 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 4/6] net/sched: allow flower to match tunnel options Date: Tue, 7 Aug 2018 17:36:01 +0200 Message-Id: <20180807153603.1815-5-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Pieter Jansen van Vuuren Allow matching on options in Geneve tunnel headers. This makes use of existing tunnel metadata support. The options can be described in the form CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK, where CLASS is represented as a 16bit hexadecimal value, TYPE as an 8bit hexadecimal value and DATA as a variable length hexadecimal value. e.g. # ip link add name geneve0 type geneve dstport 0 external # tc qdisc add dev geneve0 ingress # tc filter add dev geneve0 protocol ip parent ffff: \ flower \ enc_src_ip 10.0.99.192 \ enc_dst_ip 10.0.99.193 \ enc_key_id 11 \ geneve_opts 0102:80:1122334421314151/ffff:ff:ffffffffffffffff \ ip_proto udp \ action mirred egress redirect dev eth1 This patch adds support for matching Geneve options in the order supplied by the user. This leads to an efficient implementation in the software datapath (and in our opinion hardware datapaths that offload this feature). It is also compatible with Geneve options matching provided by the Open vSwitch kernel datapath which is relevant here as the Flower classifier may be used as a mechanism to program flows into hardware as a form of Open vSwitch datapath offload (sometimes referred to as OVS-TC). The netlink Kernel/Userspace API may be extended, for example by adding a flag, if other matching options are desired, for example matching given options in any order. This would require an implementation in the TC software datapath. And be done in a way that drivers that facilitate offload of the Flower classifier can reject or accept such flows based on hardware datapath capabilities. This approach was discussed and agreed on at Netconf 2018 in Seoul. Signed-off-by: Simon Horman Signed-off-by: Pieter Jansen van Vuuren Acked-by: Jakub Kicinski --- include/uapi/linux/pkt_cls.h | 26 +++++ net/sched/cls_flower.c | 244 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 269 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index 48e5b5d49a34..be382fb0592d 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -480,12 +480,38 @@ enum { TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */ TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */ + TCA_FLOWER_KEY_ENC_OPTS, + TCA_FLOWER_KEY_ENC_OPTS_MASK, + __TCA_FLOWER_MAX, }; #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1) enum { + TCA_FLOWER_KEY_ENC_OPTS_UNSPEC, + TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested + * TCA_FLOWER_KEY_ENC_OPT_GENEVE_ + * attributes + */ + __TCA_FLOWER_KEY_ENC_OPTS_MAX, +}; + +#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1) + +enum { + TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC, + TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, /* u16 */ + TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */ + TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */ + + __TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, +}; + +#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \ + (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1) + +enum { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), }; diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index a3b69bb6f4b0..9da244235170 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,7 @@ struct fl_flow_key { struct flow_dissector_key_tcp tcp; struct flow_dissector_key_ip ip; struct flow_dissector_key_ip enc_ip; + struct flow_dissector_key_enc_opts enc_opts; } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ struct fl_flow_mask_range { @@ -482,6 +484,21 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { [TCA_FLOWER_KEY_ENC_IP_TOS_MASK] = { .type = NLA_U8 }, [TCA_FLOWER_KEY_ENC_IP_TTL] = { .type = NLA_U8 }, [TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 }, + [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NLA_NESTED }, + [TCA_FLOWER_KEY_ENC_OPTS_MASK] = { .type = NLA_NESTED }, +}; + +static const struct nla_policy +enc_opts_policy[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1] = { + [TCA_FLOWER_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED }, +}; + +static const struct nla_policy +geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = { + [TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 }, + [TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 }, + [TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY, + .len = 128 }, }; static void fl_set_key_val(struct nlattr **tb, @@ -603,6 +620,145 @@ static void fl_set_key_ip(struct nlattr **tb, bool encap, fl_set_key_val(tb, &key->ttl, ttl_key, &mask->ttl, ttl_mask, sizeof(key->ttl)); } +static int fl_set_geneve_opt(const struct nlattr *nla, struct fl_flow_key *key, + int depth, int option_len, + struct netlink_ext_ack *extack) +{ + struct nlattr *tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1]; + struct nlattr *class = NULL, *type = NULL, *data = NULL; + struct geneve_opt *opt; + int err, data_len = 0; + + if (option_len > sizeof(struct geneve_opt)) + data_len = option_len - sizeof(struct geneve_opt); + + opt = (struct geneve_opt *)&key->enc_opts.data[key->enc_opts.len]; + memset(opt, 0xff, option_len); + opt->length = data_len / 4; + opt->r1 = 0; + opt->r2 = 0; + opt->r3 = 0; + + /* If no mask has been prodived we assume an exact match. */ + if (!depth) + return sizeof(struct geneve_opt) + data_len; + + if (nla_type(nla) != TCA_FLOWER_KEY_ENC_OPTS_GENEVE) { + NL_SET_ERR_MSG(extack, "Non-geneve option type for mask"); + return -EINVAL; + } + + err = nla_parse_nested(tb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX, + nla, geneve_opt_policy, extack); + if (err < 0) + return err; + + /* We are not allowed to omit any of CLASS, TYPE or DATA + * fields from the key. + */ + if (!option_len && + (!tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] || + !tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] || + !tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA])) { + NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data"); + return -EINVAL; + } + + /* Omitting any of CLASS, TYPE or DATA fields is allowed + * for the mask. + */ + if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]) { + int new_len = key->enc_opts.len; + + data = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]; + data_len = nla_len(data); + if (data_len < 4) { + NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long"); + return -ERANGE; + } + if (data_len % 4) { + NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long"); + return -ERANGE; + } + + new_len += sizeof(struct geneve_opt) + data_len; + BUILD_BUG_ON(FLOW_DIS_TUN_OPTS_MAX != IP_TUNNEL_OPTS_MAX); + if (new_len > FLOW_DIS_TUN_OPTS_MAX) { + NL_SET_ERR_MSG(extack, "Tunnel options exceeds max size"); + return -ERANGE; + } + opt->length = data_len / 4; + memcpy(opt->opt_data, nla_data(data), data_len); + } + + if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]) { + class = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]; + opt->opt_class = nla_get_be16(class); + } + + if (tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]) { + type = tb[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]; + opt->type = nla_get_u8(type); + } + + return sizeof(struct geneve_opt) + data_len; +} + +static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, + struct fl_flow_key *mask, + struct netlink_ext_ack *extack) +{ + const struct nlattr *nla_enc_key, *nla_opt_key, *nla_opt_msk = NULL; + int option_len, key_depth, msk_depth = 0; + + nla_enc_key = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS]); + + if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) { + nla_opt_msk = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]); + msk_depth = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]); + } + + nla_for_each_attr(nla_opt_key, nla_enc_key, + nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]), key_depth) { + switch (nla_type(nla_opt_key)) { + case TCA_FLOWER_KEY_ENC_OPTS_GENEVE: + option_len = 0; + key->enc_opts.dst_opt_type = TUNNEL_GENEVE_OPT; + option_len = fl_set_geneve_opt(nla_opt_key, key, + key_depth, option_len, + extack); + if (option_len < 0) + return option_len; + + key->enc_opts.len += option_len; + /* At the same time we need to parse through the mask + * in order to verify exact and mask attribute lengths. + */ + mask->enc_opts.dst_opt_type = TUNNEL_GENEVE_OPT; + option_len = fl_set_geneve_opt(nla_opt_msk, mask, + msk_depth, option_len, + extack); + if (option_len < 0) + return option_len; + + mask->enc_opts.len += option_len; + if (key->enc_opts.len != mask->enc_opts.len) { + NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); + return -EINVAL; + } + + if (msk_depth) + nla_opt_msk = nla_next(nla_opt_msk, &msk_depth); + break; + default: + NL_SET_ERR_MSG(extack, "Unknown tunnel option type"); + return -EINVAL; + } + } + + return 0; +} + static int fl_set_key(struct net *net, struct nlattr **tb, struct fl_flow_key *key, struct fl_flow_key *mask, struct netlink_ext_ack *extack) @@ -799,6 +955,12 @@ static int fl_set_key(struct net *net, struct nlattr **tb, fl_set_key_ip(tb, true, &key->enc_ip, &mask->enc_ip); + if (tb[TCA_FLOWER_KEY_ENC_OPTS]) { + ret = fl_set_enc_opt(tb, key, mask, extack); + if (ret) + return ret; + } + if (tb[TCA_FLOWER_KEY_FLAGS]) ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags); @@ -894,6 +1056,8 @@ static void fl_init_dissector(struct flow_dissector *dissector, FLOW_DISSECTOR_KEY_ENC_PORTS, enc_tp); FL_KEY_SET_IF_MASKED(mask, keys, cnt, FLOW_DISSECTOR_KEY_ENC_IP, enc_ip); + FL_KEY_SET_IF_MASKED(mask, keys, cnt, + FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts); skb_flow_dissector_init(dissector, keys, cnt); } @@ -1414,6 +1578,83 @@ static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask) return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask); } +static int fl_dump_key_geneve_opt(struct sk_buff *skb, + struct flow_dissector_key_enc_opts *enc_opts) +{ + struct geneve_opt *opt; + struct nlattr *nest; + int opt_off = 0; + + nest = nla_nest_start(skb, TCA_FLOWER_KEY_ENC_OPTS_GENEVE); + if (!nest) + goto nla_put_failure; + + while (enc_opts->len > opt_off) { + opt = (struct geneve_opt *)&enc_opts->data[opt_off]; + + if (nla_put_be16(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, + opt->opt_class)) + goto nla_put_failure; + if (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, + opt->type)) + goto nla_put_failure; + if (nla_put(skb, TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, + opt->length * 4, opt->opt_data)) + goto nla_put_failure; + + opt_off += sizeof(struct geneve_opt) + opt->length * 4; + } + nla_nest_end(skb, nest); + return 0; + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + +static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type, + struct flow_dissector_key_enc_opts *enc_opts) +{ + struct nlattr *nest; + int err; + + if (!enc_opts->len) + return 0; + + nest = nla_nest_start(skb, enc_opt_type); + if (!nest) + goto nla_put_failure; + + switch (enc_opts->dst_opt_type) { + case TUNNEL_GENEVE_OPT: + err = fl_dump_key_geneve_opt(skb, enc_opts); + if (err) + goto nla_put_failure; + break; + default: + goto nla_put_failure; + } + nla_nest_end(skb, nest); + return 0; + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + +static int fl_dump_key_enc_opt(struct sk_buff *skb, + struct flow_dissector_key_enc_opts *key_opts, + struct flow_dissector_key_enc_opts *msk_opts) +{ + int err; + + err = fl_dump_key_options(skb, TCA_FLOWER_KEY_ENC_OPTS, key_opts); + if (err) + return err; + + return fl_dump_key_options(skb, TCA_FLOWER_KEY_ENC_OPTS_MASK, msk_opts); +} + static int fl_dump_key(struct sk_buff *skb, struct net *net, struct fl_flow_key *key, struct fl_flow_key *mask) { @@ -1594,7 +1835,8 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net, &mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, sizeof(key->enc_tp.dst)) || - fl_dump_key_ip(skb, true, &key->enc_ip, &mask->enc_ip)) + fl_dump_key_ip(skb, true, &key->enc_ip, &mask->enc_ip) || + fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts)) goto nla_put_failure; if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags)) From patchwork Tue Aug 7 15:36:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954565 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="1OYtxHYS"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJXJ0yrNz9rvt for ; Wed, 8 Aug 2018 01:36:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389990AbeHGRvW (ORCPT ); Tue, 7 Aug 2018 13:51:22 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:40723 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389966AbeHGRvV (ORCPT ); Tue, 7 Aug 2018 13:51:21 -0400 Received: by mail-qt0-f195.google.com with SMTP id h4-v6so18301809qtj.7 for ; Tue, 07 Aug 2018 08:36:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4YhXTFuyw23aOk5otIbqAeAGrd6lU6J6LG1e3823b7s=; b=1OYtxHYSmeNrMPGVjI/GpsWW6GvlNh6+G48a74M6eolDTxxLNIYP+n7bXr7oUPZDUQ kyAqkEoMRylx7SvjPv1VZm7uGD1LzCOzUR1LfecBDztqUaNmndKyDml94Kgj9aLbyitt SaIODEriPc0fooz4jtM/K2PTTSZM9ddYR/eCaYpQGLwiUyn1UgnFPxetEwVw/bjb2ItK 1SUdhmWVEZkvLnCtAsRcGgJa+oesVy6GDcbIWaQjUKz00+7j19L5a9P8QarLGw8N6Abk 5+Se8NoWWXDeLLGwP0G1zDxLaWPTzrddEFirhJwMBnI0HaXhN2+u8dzVESYLOwqyW+5E FjEQ== 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; bh=4YhXTFuyw23aOk5otIbqAeAGrd6lU6J6LG1e3823b7s=; b=TrO6lykIJGemCX0Bg6+eYLX/emJ9uZUDRVhjQhZIINBE710JudEZKZ5dxOKU7DAh9X IUChZyVGJQhwn1QVaUPKiK8O5U8PK/uqMLbRspAaXpRgW7eIIlOxyUNvADNmMAC32orW WoYWrxbCs+8r/Vi30FFVTRNjrSQ4Q0K2ua56T/Vrz2kIcEycGqWsq+ACgA7GGZDqnQ3o g3QFlOVtbwv1+Z5uuEKwYRSuEebPaRnrlwfRsYz4OFKzFDTGzmbWWw57Q+WBl5+zdtop V26l9MdSgdUJSmNYOnwCJ/ktxxhTqJXRyvYFLzzQYXrhm4EMrlw5rVlAl7QoNqHrCfOv gpdA== X-Gm-Message-State: AOUpUlH8ZK4gr8ULgc1Ulb/Ly8CeTfKBRvuAwYq0hSrSdALLIE8DlmAX CnbMstFTUFA/5gjgl0KGMDiZFg== X-Google-Smtp-Source: AAOMgpeUKZ9iH+qt+3E7orT8y0A302iOWko5fgG8aZ3YV7yfeU5onnFWuJ6+TpC6JFQS0xj1e9gs8Q== X-Received: by 2002:a0c:c130:: with SMTP id f45-v6mr17481497qvh.7.1533656188417; Tue, 07 Aug 2018 08:36:28 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:27 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 5/6] nfp: flower: add geneve option push action offload Date: Tue, 7 Aug 2018 17:36:02 +0200 Message-Id: <20180807153603.1815-6-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Pieter Jansen van Vuuren Introduce new push geneve option action. This allows offloading filters configured to entunnel geneve with options. Signed-off-by: Pieter Jansen van Vuuren Reviewed-by: Jakub Kicinski Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/action.c | 100 +++++++++++++++++++-- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 20 ++++- drivers/net/ethernet/netronome/nfp/flower/main.h | 1 + 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index a79d078ab3e8..0ba0356ec4e6 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -32,6 +32,7 @@ */ #include +#include #include #include #include @@ -45,7 +46,15 @@ #include "main.h" #include "../nfp_net_repr.h" -#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS (TUNNEL_CSUM | TUNNEL_KEY) +/* The kernel versions of TUNNEL_* are not ABI and therefore vulnerable + * to change. Such changes will break our FW ABI. + */ +#define NFP_FL_TUNNEL_CSUM cpu_to_be16(0x01) +#define NFP_FL_TUNNEL_KEY cpu_to_be16(0x04) +#define NFP_FL_TUNNEL_GENEVE_OPT cpu_to_be16(0x0800) +#define NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS (NFP_FL_TUNNEL_CSUM | \ + NFP_FL_TUNNEL_KEY | \ + NFP_FL_TUNNEL_GENEVE_OPT) static void nfp_fl_pop_vlan(struct nfp_fl_pop_vlan *pop_vlan) { @@ -229,7 +238,71 @@ static struct nfp_fl_pre_tunnel *nfp_fl_pre_tunnel(char *act_data, int act_len) } static int -nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, +nfp_fl_push_geneve_options(struct nfp_fl_payload *nfp_fl, int *list_len, + const struct tc_action *action) +{ + struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); + int opt_len, opt_cnt, act_start, tot_push_len; + u8 *src = ip_tunnel_info_opts(ip_tun); + + /* We need to populate the options in reverse order for HW. + * Therefore we go through the options, calculating the + * number of options and the total size, then we populate + * them in reverse order in the action list. + */ + opt_cnt = 0; + tot_push_len = 0; + opt_len = ip_tun->options_len; + while (opt_len > 0) { + struct geneve_opt *opt = (struct geneve_opt *)src; + + opt_cnt++; + if (opt_cnt > NFP_FL_MAX_GENEVE_OPT_CNT) + return -EOPNOTSUPP; + + tot_push_len += sizeof(struct nfp_fl_push_geneve) + + opt->length * 4; + if (tot_push_len > NFP_FL_MAX_GENEVE_OPT_ACT) + return -EOPNOTSUPP; + + opt_len -= sizeof(struct geneve_opt) + opt->length * 4; + src += sizeof(struct geneve_opt) + opt->length * 4; + } + + if (*list_len + tot_push_len > NFP_FL_MAX_A_SIZ) + return -EOPNOTSUPP; + + act_start = *list_len; + *list_len += tot_push_len; + src = ip_tunnel_info_opts(ip_tun); + while (opt_cnt) { + struct geneve_opt *opt = (struct geneve_opt *)src; + struct nfp_fl_push_geneve *push; + size_t act_size, len; + + opt_cnt--; + act_size = sizeof(struct nfp_fl_push_geneve) + opt->length * 4; + tot_push_len -= act_size; + len = act_start + tot_push_len; + + push = (struct nfp_fl_push_geneve *)&nfp_fl->action_data[len]; + push->head.jump_id = NFP_FL_ACTION_OPCODE_PUSH_GENEVE; + push->head.len_lw = act_size >> NFP_FL_LW_SIZ; + push->reserved = 0; + push->class = opt->opt_class; + push->type = opt->type; + push->length = opt->length; + memcpy(&push->opt_data, opt->opt_data, opt->length * 4); + + src += sizeof(struct geneve_opt) + opt->length * 4; + } + + return 0; +} + +static int +nfp_fl_set_ipv4_udp_tun(struct nfp_app *app, + struct nfp_fl_set_ipv4_udp_tun *set_tun, const struct tc_action *action, struct nfp_fl_pre_tunnel *pre_tun, enum nfp_flower_tun_type tun_type, @@ -237,11 +310,17 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, { size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); + struct nfp_flower_priv *priv = app->priv; u32 tmp_set_ip_tun_type_index = 0; /* Currently support one pre-tunnel so index is always 0. */ int pretun_idx = 0; - if (ip_tun->options_len) + BUILD_BUG_ON(NFP_FL_TUNNEL_CSUM != TUNNEL_CSUM || + NFP_FL_TUNNEL_KEY != TUNNEL_KEY || + NFP_FL_TUNNEL_GENEVE_OPT != TUNNEL_GENEVE_OPT); + if (ip_tun->options_len && + (tun_type != NFP_FL_TUNNEL_GENEVE || + !(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE_OPT))) return -EOPNOTSUPP; set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; @@ -281,11 +360,16 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, set_tun->tos = ip_tun->key.tos; - if (!(ip_tun->key.tun_flags & TUNNEL_KEY) || + if (!(ip_tun->key.tun_flags & NFP_FL_TUNNEL_KEY) || ip_tun->key.tun_flags & ~NFP_FL_SUPPORTED_IPV4_UDP_TUN_FLAGS) return -EOPNOTSUPP; set_tun->tun_flags = ip_tun->key.tun_flags; + if (tun_type == NFP_FL_TUNNEL_GENEVE) { + set_tun->tun_proto = htons(ETH_P_TEB); + set_tun->tun_len = ip_tun->options_len / 4; + } + /* Complete pre_tunnel action. */ pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; @@ -674,9 +758,13 @@ nfp_flower_loop_action(struct nfp_app *app, const struct tc_action *a, nfp_fl->meta.shortcut = cpu_to_be32(NFP_FL_SC_ACT_NULL); *a_len += sizeof(struct nfp_fl_pre_tunnel); + err = nfp_fl_push_geneve_options(nfp_fl, a_len, a); + if (err) + return err; + set_tun = (void *)&nfp_fl->action_data[*a_len]; - err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type, - netdev); + err = nfp_fl_set_ipv4_udp_tun(app, set_tun, a, pre_tun, + *tun_type, netdev); if (err) return err; *a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun); diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 174acecfba01..f2aeae88cbf0 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -37,6 +37,7 @@ #include #include #include +#include #include "../nfp_app.h" #include "../nfpcore/nfp_cpp.h" @@ -81,6 +82,10 @@ #define NFP_FL_MAX_A_SIZ 1216 #define NFP_FL_LW_SIZ 2 +/* Maximum allowed geneve options */ +#define NFP_FL_MAX_GENEVE_OPT_ACT 32 +#define NFP_FL_MAX_GENEVE_OPT_CNT 64 + /* Action opcodes */ #define NFP_FL_ACTION_OPCODE_OUTPUT 0 #define NFP_FL_ACTION_OPCODE_PUSH_VLAN 1 @@ -94,6 +99,7 @@ #define NFP_FL_ACTION_OPCODE_SET_TCP 15 #define NFP_FL_ACTION_OPCODE_PRE_LAG 16 #define NFP_FL_ACTION_OPCODE_PRE_TUNNEL 17 +#define NFP_FL_ACTION_OPCODE_PUSH_GENEVE 26 #define NFP_FL_ACTION_OPCODE_NUM 32 #define NFP_FL_OUT_FLAGS_LAST BIT(15) @@ -206,7 +212,19 @@ struct nfp_fl_set_ipv4_udp_tun { __be16 tun_flags; u8 ttl; u8 tos; - __be32 extra[2]; + __be32 extra; + u8 tun_len; + u8 res2; + __be16 tun_proto; +}; + +struct nfp_fl_push_geneve { + struct nfp_fl_act_head head; + __be16 reserved; + __be16 class; + u8 type; + u8 length; + u8 opt_data[]; }; /* Metadata with L2 (1W/4B) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index ef2114d13387..85f8209bf007 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -69,6 +69,7 @@ struct nfp_app; /* Extra features bitmap. */ #define NFP_FL_FEATS_GENEVE BIT(0) #define NFP_FL_NBI_MTU_SETTING BIT(1) +#define NFP_FL_FEATS_GENEVE_OPT BIT(2) #define NFP_FL_FEATS_LAG BIT(31) struct nfp_fl_mask_id { From patchwork Tue Aug 7 15:36:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 954566 X-Patchwork-Delegate: davem@davemloft.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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="vgsmiW9i"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41lJXK1L9yz9s0n for ; Wed, 8 Aug 2018 01:36:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389994AbeHGRvY (ORCPT ); Tue, 7 Aug 2018 13:51:24 -0400 Received: from mail-qt0-f174.google.com ([209.85.216.174]:34967 "EHLO mail-qt0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389961AbeHGRvX (ORCPT ); Tue, 7 Aug 2018 13:51:23 -0400 Received: by mail-qt0-f174.google.com with SMTP id r21-v6so6062825qtm.2 for ; Tue, 07 Aug 2018 08:36:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ly/C/xp/x67swwsh0jfSeKelplYdYL0rw14v9faTZNQ=; b=vgsmiW9iKUuxjherRR9DMqiBeMl4nXNCa4f4VJu+go9Fo9bte/44z4Vutbi4rWPkjb k51ik6VC/emmgZ7EDr6bNzsA0lfM7cIGXVxqmPOD8sMTp+wzb9BRwKURSzYCWIQqPVMi Jxo71CJ1MsIQc/DpiMqh83lgfbANXswzCUf2FIwMPMUhkhZopnzyuolrplNhoMlxnDae 7xFUswUHKX2qsLiEiZPuUsSTj3pIUHCVfyf0Pr06gEt6+gK7Bvd9n13qSYV3Xp9cnqAR ODBKf9xx6dxTAD3G2qzp+ty3kcop+xCU8N1S4lc83BA5a7fxppjadnsQA9htT7Ke8b6t bhtw== 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; bh=Ly/C/xp/x67swwsh0jfSeKelplYdYL0rw14v9faTZNQ=; b=g0SCQ7C3RyCvVQaBu9+Rr0rohURLbHLWFimrPNaZ4x3PlIuYXS2DsYb+zXhwGvt+i9 +GT1Gs6idqLojQLJQv3aCGJ3YCxRPa8gOhTCsLtNKh6bp3BIVzzeKzQL0llF+ZX6+Ha4 iK7bSY6Im61Is+lpa4oTz9xOLkjc/02yl+k6NpNl0mu4Gzrw0/WxUl5ugdc8xkzKHkkJ Fa5egB7Ov3jGHsMv8RT/WKEjEAqYDZMUNamN6BmEpz3gRn06wJSkENglqdyUg/B63NQu n6NnVtuyPXJYiYUpgKP7D+udMyo9fnCKx3xWxzjSlRULKYDJF7Aup+pgVggvmle0J5IV RooQ== X-Gm-Message-State: AOUpUlFsoFOVhnrQTiM6G29cf2O0D9ydWiEMYJYPVrDPbhGH4rEk7no4 zL3QLF7BeF6VpX0VkX0DRO76MnjwlRnrhQ== X-Google-Smtp-Source: AAOMgpdapFdk9H0l4BCb58nYgKtpR4HkTHKdJMU1LA9BHRx0YnctOrDII5jj11ZCVE42lAn5W8u3XQ== X-Received: by 2002:ac8:2f31:: with SMTP id j46-v6mr19182376qta.93.1533656189969; Tue, 07 Aug 2018 08:36:29 -0700 (PDT) Received: from reginn.com ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id s31-v6sm1080505qtc.68.2018.08.07.08.36.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Aug 2018 08:36:29 -0700 (PDT) From: Simon Horman To: David Miller Cc: Jiri Pirko , Cong Wang , Jakub Kicinski , netdev@vger.kernel.org, oss-drivers@netronome.com Subject: [PATCH net-next 6/6] nfp: flower: add geneve option match offload Date: Tue, 7 Aug 2018 17:36:03 +0200 Message-Id: <20180807153603.1815-7-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180807153603.1815-1-simon.horman@netronome.com> References: <20180807153603.1815-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Pieter Jansen van Vuuren Introduce a new layer for matching on geneve options. This allows offloading filters configured to match geneve with options. Signed-off-by: Pieter Jansen van Vuuren Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 6 ++++ drivers/net/ethernet/netronome/nfp/flower/match.c | 25 ++++++++++++++ .../net/ethernet/netronome/nfp/flower/offload.c | 38 ++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index f2aeae88cbf0..325954b829c8 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -52,6 +52,7 @@ #define NFP_FLOWER_LAYER_VXLAN BIT(7) #define NFP_FLOWER_LAYER2_GENEVE BIT(5) +#define NFP_FLOWER_LAYER2_GENEVE_OP BIT(6) #define NFP_FLOWER_MASK_VLAN_PRIO GENMASK(15, 13) #define NFP_FLOWER_MASK_VLAN_CFI BIT(12) @@ -85,6 +86,7 @@ /* Maximum allowed geneve options */ #define NFP_FL_MAX_GENEVE_OPT_ACT 32 #define NFP_FL_MAX_GENEVE_OPT_CNT 64 +#define NFP_FL_MAX_GENEVE_OPT_KEY 32 /* Action opcodes */ #define NFP_FL_ACTION_OPCODE_OUTPUT 0 @@ -381,6 +383,10 @@ struct nfp_flower_ipv4_udp_tun { __be32 tun_id; }; +struct nfp_flower_geneve_options { + u8 data[NFP_FL_MAX_GENEVE_OPT_KEY]; +}; + #define NFP_FL_TUN_VNI_OFFSET 8 /* The base header for a control message packet. diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index b1cbe6927cba..a0c72f277faa 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -262,6 +262,21 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame, nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version); } +static int +nfp_flower_compile_geneve_opt(void *key_buf, struct tc_cls_flower_offload *flow, + bool mask_version) +{ + struct fl_flow_key *target = mask_version ? flow->mask : flow->key; + struct flow_dissector_key_enc_opts *opts; + + opts = skb_flow_dissector_target(flow->dissector, + FLOW_DISSECTOR_KEY_ENC_OPTS, + target); + memcpy(key_buf, opts->data, opts->len); + + return 0; +} + static void nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame, struct tc_cls_flower_offload *flow, @@ -424,6 +439,16 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow, nfp_flow->nfp_tun_ipv4_addr = tun_dst; nfp_tunnel_add_ipv4_off(netdev_repr->app, tun_dst); } + + if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) { + err = nfp_flower_compile_geneve_opt(ext, flow, false); + if (err) + return err; + + err = nfp_flower_compile_geneve_opt(msk, flow, true); + if (err) + return err; + } } return 0; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index d2230a0e49b9..2edab01c3beb 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -66,6 +66,7 @@ BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) | \ BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \ + BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IP) | \ BIT(FLOW_DISSECTOR_KEY_MPLS) | \ BIT(FLOW_DISSECTOR_KEY_IP)) @@ -75,6 +76,7 @@ BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | \ + BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_IP)) @@ -141,6 +143,21 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) } static int +nfp_flower_calc_opt_layer(struct flow_dissector_key_enc_opts *enc_opts, + u32 *key_layer_two, int *key_size) +{ + if (enc_opts->len > NFP_FL_MAX_GENEVE_OPT_KEY) + return -EOPNOTSUPP; + + if (enc_opts->len > 0) { + *key_layer_two |= NFP_FLOWER_LAYER2_GENEVE_OP; + *key_size += sizeof(struct nfp_flower_geneve_options); + } + + return 0; +} + +static int nfp_flower_calculate_key_layers(struct nfp_app *app, struct nfp_fl_key_ls *ret_key_ls, struct tc_cls_flower_offload *flow, @@ -153,6 +170,7 @@ nfp_flower_calculate_key_layers(struct nfp_app *app, u32 key_layer_two; u8 key_layer; int key_size; + int err; if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR) return -EOPNOTSUPP; @@ -178,6 +196,7 @@ nfp_flower_calculate_key_layers(struct nfp_app *app, FLOW_DISSECTOR_KEY_ENC_CONTROL)) { struct flow_dissector_key_ipv4_addrs *mask_ipv4 = NULL; struct flow_dissector_key_ports *mask_enc_ports = NULL; + struct flow_dissector_key_enc_opts *enc_op = NULL; struct flow_dissector_key_ports *enc_ports = NULL; struct flow_dissector_key_control *mask_enc_ctl = skb_flow_dissector_target(flow->dissector, @@ -214,11 +233,21 @@ nfp_flower_calculate_key_layers(struct nfp_app *app, if (mask_enc_ports->dst != cpu_to_be16(~0)) return -EOPNOTSUPP; + if (dissector_uses_key(flow->dissector, + FLOW_DISSECTOR_KEY_ENC_OPTS)) { + enc_op = skb_flow_dissector_target(flow->dissector, + FLOW_DISSECTOR_KEY_ENC_OPTS, + flow->key); + } + switch (enc_ports->dst) { case htons(NFP_FL_VXLAN_PORT): *tun_type = NFP_FL_TUNNEL_VXLAN; key_layer |= NFP_FLOWER_LAYER_VXLAN; key_size += sizeof(struct nfp_flower_ipv4_udp_tun); + + if (enc_op) + return -EOPNOTSUPP; break; case htons(NFP_FL_GENEVE_PORT): if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE)) @@ -228,6 +257,15 @@ nfp_flower_calculate_key_layers(struct nfp_app *app, key_size += sizeof(struct nfp_flower_ext_meta); key_layer_two |= NFP_FLOWER_LAYER2_GENEVE; key_size += sizeof(struct nfp_flower_ipv4_udp_tun); + + if (!enc_op) + break; + if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE_OPT)) + return -EOPNOTSUPP; + err = nfp_flower_calc_opt_layer(enc_op, &key_layer_two, + &key_size); + if (err) + return err; break; default: return -EOPNOTSUPP;