From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from alln-iport-2.cisco.com (alln-iport-2.cisco.com [173.37.142.89]) by dpdk.org (Postfix) with ESMTP id D1D4556A1 for ; Thu, 28 Feb 2019 08:05:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=3964; q=dns/txt; s=iport; t=1551337531; x=1552547131; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=pHmtyHOjxTOoD9FhCIhryRC2t7OQiNxCavFW1tEuqpM=; b=F5d2lueNk7d5cLVMK/sk13dpX3E5Y77BeKMg+9mAvIiDdl/i6MII/8t+ RosBFOf/uaokCP69TAKTuxe8xvls1Q+BIWDQ9ha0HTt0ZAIeOK9nJPfA2 L0zdGEqpDrN5CZ9e9CMprmArGwrIUg7tfe4KzDZm/56S2BFFLq+xufiNO w=; X-IronPort-AV: E=Sophos;i="5.58,422,1544486400"; d="scan'208";a="241659324" Received: from alln-core-1.cisco.com ([173.36.13.131]) by alln-iport-2.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2019 07:05:30 +0000 Received: from cisco.com (savbu-usnic-a.cisco.com [10.193.184.48]) by alln-core-1.cisco.com (8.15.2/8.15.2) with ESMTP id x1S75TcI009225; Thu, 28 Feb 2019 07:05:29 GMT Received: by cisco.com (Postfix, from userid 508933) id 88A0F20F2001; Wed, 27 Feb 2019 23:05:29 -0800 (PST) From: Hyong Youb Kim To: Ferruh Yigit Cc: dev@dpdk.org, John Daley , Hyong Youb Kim Date: Wed, 27 Feb 2019 23:03:11 -0800 Message-Id: <20190228070317.17002-10-hyonkim@cisco.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20190228070317.17002-1-hyonkim@cisco.com> References: <20190228070317.17002-1-hyonkim@cisco.com> X-Outbound-SMTP-Client: 10.193.184.48, savbu-usnic-a.cisco.com X-Outbound-Node: alln-core-1.cisco.com Subject: [dpdk-dev] [PATCH 09/15] net/enic: enable limited support for RAW flow item X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Feb 2019 07:05:31 -0000 Some apps like VPP use a raw item to match UDP tunnel headers like VXLAN or GENEVE. The NIC hardware supports such usage via L5 match, which does pattern match on packet data immediately following the outer L4 header. Accept raw items for these limited use cases. Signed-off-by: Hyong Youb Kim --- drivers/net/enic/enic_flow.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c index fda641b6f..ffc6ce1da 100644 --- a/drivers/net/enic/enic_flow.c +++ b/drivers/net/enic/enic_flow.c @@ -77,6 +77,7 @@ struct enic_action_cap { static enic_copy_item_fn enic_copy_item_ipv4_v1; static enic_copy_item_fn enic_copy_item_udp_v1; static enic_copy_item_fn enic_copy_item_tcp_v1; +static enic_copy_item_fn enic_copy_item_raw_v2; static enic_copy_item_fn enic_copy_item_eth_v2; static enic_copy_item_fn enic_copy_item_vlan_v2; static enic_copy_item_fn enic_copy_item_ipv4_v2; @@ -123,6 +124,14 @@ static const struct enic_items enic_items_v1[] = { * that layer 3 must be specified. */ static const struct enic_items enic_items_v2[] = { + [RTE_FLOW_ITEM_TYPE_RAW] = { + .copy_item = enic_copy_item_raw_v2, + .valid_start_item = 0, + .prev_items = (const enum rte_flow_item_type[]) { + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, + }, + }, [RTE_FLOW_ITEM_TYPE_ETH] = { .copy_item = enic_copy_item_eth_v2, .valid_start_item = 1, @@ -196,6 +205,14 @@ static const struct enic_items enic_items_v2[] = { /** NICs with Advanced filters enabled */ static const struct enic_items enic_items_v3[] = { + [RTE_FLOW_ITEM_TYPE_RAW] = { + .copy_item = enic_copy_item_raw_v2, + .valid_start_item = 0, + .prev_items = (const enum rte_flow_item_type[]) { + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, + }, + }, [RTE_FLOW_ITEM_TYPE_ETH] = { .copy_item = enic_copy_item_eth_v2, .valid_start_item = 1, @@ -835,6 +852,54 @@ enic_copy_item_vxlan_v2(struct copy_item_args *arg) return 0; } +/* + * Copy raw item into version 2 NIC filter. Currently, raw pattern match is + * very limited. It is intended for matching UDP tunnel header (e.g. vxlan + * or geneve). + */ +static int +enic_copy_item_raw_v2(struct copy_item_args *arg) +{ + const struct rte_flow_item *item = arg->item; + struct filter_v2 *enic_filter = arg->filter; + uint8_t *inner_ofst = arg->inner_ofst; + const struct rte_flow_item_raw *spec = item->spec; + const struct rte_flow_item_raw *mask = item->mask; + struct filter_generic_1 *gp = &enic_filter->u.generic_1; + + FLOW_TRACE(); + + /* Cannot be used for inner packet */ + if (*inner_ofst) + return EINVAL; + /* Need both spec and mask */ + if (!spec || !mask) + return EINVAL; + /* Only supports relative with offset 0 */ + if (!spec->relative || spec->offset != 0 || spec->search || spec->limit) + return EINVAL; + /* Need non-null pattern that fits within the NIC's filter pattern */ + if (spec->length == 0 || spec->length > FILTER_GENERIC_1_KEY_LEN || + !spec->pattern || !mask->pattern) + return EINVAL; + /* + * Mask fields, including length, are often set to zero. Assume that + * means "same as spec" to avoid breaking existing apps. If length + * is not zero, then it should be >= spec length. + * + * No more pattern follows this, so append to the L4 layer instead of + * L5 to work with both recent and older VICs. + */ + if (mask->length != 0 && mask->length < spec->length) + return EINVAL; + memcpy(gp->layer[FILTER_GENERIC_1_L4].mask + sizeof(struct udp_hdr), + mask->pattern, spec->length); + memcpy(gp->layer[FILTER_GENERIC_1_L4].val + sizeof(struct udp_hdr), + spec->pattern, spec->length); + + return 0; +} + /** * Return 1 if current item is valid on top of the previous one. * -- 2.16.2