From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adrien Mazarguil Subject: [PATCH v2 2/2] ethdev: fix shallow copy of flow API RAW item Date: Mon, 21 May 2018 13:44:28 +0200 Message-ID: <20180521114345.690-2-adrien.mazarguil@6wind.com> References: <20180516154052.16836-1-adrien.mazarguil@6wind.com> <20180521114345.690-1-adrien.mazarguil@6wind.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: dev@dpdk.org, stable@dpdk.org, Qi Zhang To: Ferruh Yigit Return-path: Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by dpdk.org (Postfix) with ESMTP id 2AC441B16A for ; Mon, 21 May 2018 13:44:44 +0200 (CEST) Received: by mail-wm0-f65.google.com with SMTP id l1-v6so26147198wmb.2 for ; Mon, 21 May 2018 04:44:44 -0700 (PDT) Content-Disposition: inline In-Reply-To: <20180521114345.690-1-adrien.mazarguil@6wind.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Like original commit mentioned below, this fix synchronizes flow rule copy function with testpmd's own implementation following "app/testpmd: fix copy of raw flow item (revisited)". It addresses a crash that occurs when feeding a RAW pattern item to rte_flow_copy(). Besides external applications, two PMDs (bonding and failsafe) rely on this function internally. Note the scope of this patch is limited to the RAW pattern item and has no impact on all others. Fixes: 972bf3610611 ("ethdev: fix shallow copy of flow API RSS action") Cc: stable@dpdk.org Cc: Qi Zhang Signed-off-by: Adrien Mazarguil --- v2 changes: - Fixed commit ID on "Fixes" line. - Described the crash addressed by this patch so people do not have to derive this information from the referenced commits. --- lib/librte_ethdev/rte_flow.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index 7947529da..b2afba089 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -300,17 +300,26 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, enum item_spec_type type) { size_t size = 0; - const void *item_spec = + const void *data = type == ITEM_SPEC ? item->spec : type == ITEM_LAST ? item->last : type == ITEM_MASK ? item->mask : NULL; - if (!item_spec) + if (!item->spec || !data) goto empty; switch (item->type) { union { const struct rte_flow_item_raw *raw; + } spec; + union { + const struct rte_flow_item_raw *raw; + } last; + union { + const struct rte_flow_item_raw *raw; + } mask; + union { + const struct rte_flow_item_raw *raw; } src; union { struct rte_flow_item_raw *raw; @@ -318,11 +327,21 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, size_t off; case RTE_FLOW_ITEM_TYPE_RAW: - src.raw = item_spec; + spec.raw = item->spec; + last.raw = item->last ? item->last : item->spec; + mask.raw = item->mask ? item->mask : &rte_flow_item_raw_mask; + src.raw = data; dst.raw = buf; off = RTE_ALIGN_CEIL(sizeof(struct rte_flow_item_raw), sizeof(*src.raw->pattern)); - size = off + src.raw->length * sizeof(*src.raw->pattern); + if (type == ITEM_SPEC || + (type == ITEM_MASK && + ((spec.raw->length & mask.raw->length) >= + (last.raw->length & mask.raw->length)))) + size = spec.raw->length & mask.raw->length; + else + size = last.raw->length & mask.raw->length; + size = off + size * sizeof(*src.raw->pattern); if (dst.raw) { memcpy(dst.raw, src.raw, sizeof(*src.raw)); dst.raw->pattern = memcpy((uint8_t *)dst.raw + off, @@ -333,7 +352,7 @@ flow_item_spec_copy(void *buf, const struct rte_flow_item *item, default: size = rte_flow_desc_item[item->type].size; if (buf) - memcpy(buf, item_spec, size); + memcpy(buf, data, size); break; } empty: -- 2.11.0