From patchwork Sun Jan 3 11:55:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Britstein X-Patchwork-Id: 1421865 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D7xzS0JbXz9sVn for ; Sun, 3 Jan 2021 22:55:48 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id EC8108701A; Sun, 3 Jan 2021 11:55:44 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BBpVlSwvj6Hl; Sun, 3 Jan 2021 11:55:42 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 5C8048700D; Sun, 3 Jan 2021 11:55:42 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3E548C1DA7; Sun, 3 Jan 2021 11:55:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3510CC013A for ; Sun, 3 Jan 2021 11:55:40 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 20F6A8638F for ; Sun, 3 Jan 2021 11:55:40 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id O+9K2kv5o5rO for ; Sun, 3 Jan 2021 11:55:38 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by whitealder.osuosl.org (Postfix) with ESMTP id C547E85BCC for ; Sun, 3 Jan 2021 11:55:37 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from elibr@nvidia.com) with SMTP; 3 Jan 2021 13:55:31 +0200 Received: from nvidia.com (dev-r-vrt-214.mtr.labs.mlnx [10.212.214.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 103BtUPI030577; Sun, 3 Jan 2021 13:55:31 +0200 From: Eli Britstein To: dev@openvswitch.org, Ilya Maximets Date: Sun, 3 Jan 2021 11:55:22 +0000 Message-Id: <20210103115523.4381-4-elibr@nvidia.com> X-Mailer: git-send-email 2.28.0.546.g385c171 In-Reply-To: <20210103115523.4381-1-elibr@nvidia.com> References: <20210103115523.4381-1-elibr@nvidia.com> MIME-Version: 1.0 Cc: Eli Britstein Subject: [ovs-dev] [PATCH 3/4] netdev-offload-dpdk: Support IPv6 fragmentation types X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Support IPv6 fragmentation matching. Signed-off-by: Eli Britstein --- lib/netdev-offload-dpdk.c | 82 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index d1b754211..84aeb26b9 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -330,6 +330,8 @@ dump_flow_pattern(struct ds *s, const struct rte_flow_item *item) ds_put_cstr(s, "ipv6 "); if (ipv6_spec) { + uint8_t has_frag_ext_mask; + if (!ipv6_mask) { ipv6_mask = &rte_flow_item_ipv6_mask; } @@ -353,6 +355,37 @@ dump_flow_pattern(struct ds *s, const struct rte_flow_item *item) DUMP_PATTERN_ITEM(ipv6_mask->hdr.hop_limits, false, "hop", "%"PRIu8, ipv6_spec->hdr.hop_limits, ipv6_mask->hdr.hop_limits, 0); + has_frag_ext_mask = ipv6_mask->has_frag_ext ? UINT8_MAX : 0; + DUMP_PATTERN_ITEM(has_frag_ext_mask, false, "has_frag_ext", + "%"PRIu8, ipv6_spec->has_frag_ext, + ipv6_mask->has_frag_ext, 0); + } + ds_put_cstr(s, "/ "); + } else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT) { + const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_spec = item->spec; + const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_mask = item->mask; + const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_last = item->last; + const struct rte_flow_item_ipv6_frag_ext ipv6_frag_def = { + .hdr.next_header = 0, .hdr.frag_data = 0}; + + ds_put_cstr(s, "ipv6_frag_ext "); + if (ipv6_frag_spec) { + if (!ipv6_frag_mask) { + ipv6_frag_mask = &ipv6_frag_def; + } + if (!ipv6_frag_last) { + ipv6_frag_last = &ipv6_frag_def; + } + DUMP_PATTERN_ITEM(ipv6_frag_mask->hdr.next_header, item->last, + "next_hdr", "%"PRIu8, + ipv6_frag_spec->hdr.next_header, + ipv6_frag_mask->hdr.next_header, + ipv6_frag_last->hdr.next_header); + DUMP_PATTERN_ITEM(ipv6_frag_mask->hdr.frag_data, item->last, + "frag_data", "0x%"PRIx16, + ntohs(ipv6_frag_spec->hdr.frag_data), + ntohs(ipv6_frag_mask->hdr.frag_data), + ntohs(ipv6_frag_last->hdr.frag_data)); } ds_put_cstr(s, "/ "); } else { @@ -857,6 +890,10 @@ parse_flow_match(struct flow_patterns *patterns, sizeof spec->hdr.src_addr); memcpy(spec->hdr.dst_addr, &match->flow.ipv6_dst, sizeof spec->hdr.dst_addr); + if ((match->wc.masks.nw_frag & FLOW_NW_FRAG_ANY) && + (match->flow.nw_frag & FLOW_NW_FRAG_ANY)) { + spec->has_frag_ext = 1; + } mask->hdr.proto = match->wc.masks.nw_proto; mask->hdr.hop_limits = match->wc.masks.nw_ttl; @@ -867,7 +904,6 @@ parse_flow_match(struct flow_patterns *patterns, memcpy(mask->hdr.dst_addr, &match->wc.masks.ipv6_dst, sizeof mask->hdr.dst_addr); - consumed_masks->nw_proto = 0; consumed_masks->nw_ttl = 0; consumed_masks->nw_tos = 0; memset(&consumed_masks->ipv6_src, 0, sizeof consumed_masks->ipv6_src); @@ -877,6 +913,50 @@ parse_flow_match(struct flow_patterns *patterns, /* Save proto for L4 protocol setup. */ proto = spec->hdr.proto & mask->hdr.proto; + + if (spec->has_frag_ext) { + struct rte_flow_item_ipv6_frag_ext *frag_spec, *frag_mask, + *frag_last = NULL; + + frag_spec = xzalloc(sizeof *frag_spec); + frag_mask = xzalloc(sizeof *frag_mask); + + if (match->wc.masks.nw_frag & FLOW_NW_FRAG_LATER) { + if (!(match->flow.nw_frag & FLOW_NW_FRAG_LATER)) { + /* frag=first. */ + frag_spec->hdr.frag_data = htons(RTE_IPV6_EHDR_MF_MASK); + frag_mask->hdr.frag_data = htons(RTE_IPV6_EHDR_MF_MASK | + RTE_IPV6_EHDR_FO_MASK); + /* Move the proto match to the extension item. */ + frag_spec->hdr.next_header = match->flow.nw_proto; + frag_mask->hdr.next_header = match->wc.masks.nw_proto; + spec->hdr.proto = 0; + mask->hdr.proto = 0; + } else { + /* frag=later. */ + frag_last = xzalloc(sizeof *frag_last); + frag_spec->hdr.frag_data = htons(1 << RTE_IPV6_EHDR_FO_SHIFT); + frag_mask->hdr.frag_data = htons(RTE_IPV6_EHDR_FO_MASK); + frag_last->hdr.frag_data = htons(RTE_IPV6_EHDR_FO_MASK); + /* There can't be a proto for later frags. */ + spec->hdr.proto = 0; + mask->hdr.proto = 0; + } + } else { + VLOG_WARN_RL(&rl, "Unknown IPv6 frag (0x%x/0x%x)", + match->flow.nw_frag, match->wc.masks.nw_frag); + return -1; + } + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT, + frag_spec, frag_mask, frag_last); + } + if (match->wc.masks.nw_frag) { + /* frag=no is indicated by spec->has_frag_ext=0. */ + mask->has_frag_ext = 1; + consumed_masks->nw_frag = 0; + } + consumed_masks->nw_proto = 0; } if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP &&