From: Adrien Mazarguil Date: Mon, 21 May 2018 11:44:28 +0000 (+0200) Subject: ethdev: fix shallow copy of flow API RAW item X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=a68e95faccdf77b6f4424b24b6f1307b2d217915;p=dpdk.git ethdev: fix shallow copy of flow API RAW item 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 Signed-off-by: Adrien Mazarguil --- diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index 7947529da7..b2afba0895 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -300,15 +300,24 @@ 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; @@ -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: