From patchwork Sat Dec 13 01:06:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wunderlich X-Patchwork-Id: 1971 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id A085B68BE; Sat, 13 Dec 2014 02:14:18 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 1CBD86896 for ; Sat, 13 Dec 2014 02:14:06 +0100 (CET) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 12 Dec 2014 17:14:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,567,1413270000"; d="scan'208";a="623052503" Received: from localhost.jf.intel.com (HELO localhost.localdomain) ([10.166.15.219]) by orsmga001.jf.intel.com with ESMTP; 12 Dec 2014 17:14:05 -0800 From: Mark Wunderlich To: dev@dpdk.org Date: Fri, 12 Dec 2014 17:06:38 -0800 Message-ID: <20141213010638.28002.63966.stgit@localhost.localdomain> User-Agent: StGit/0.17-dirty MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] lib/librte_table: Fix table array lookup X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The existing lookup function was returning an unmodified pkts_mask bitmask into lookup_hit_mask. This effectively assumes that all packets would index correctly into one of the array table entries. Also, there was no check that the metadata provided index value was within range of the table max entries. By using using table index bitmask on the metadata provided index the resulting entry position may falsely indicate a hit for index values provided that happen to be greter than the number of table entries. Like other table type lookup functions it would seem that the possibility exists that some of the packets provided to the function would not result in a hit. It is assumed that the metadata provided should be a direct index into the array table. So, code was added to build and return a bitmask for only those packets that correctly index directly into the table array. If the original intent for this table type was to accept any 32-bit value, then by applying the table index bitmask as a modulo index for distribution across table entries, then this patch would be invalid and should be rejected. Signed-off-by: Mark Wunderlich --- lib/librte_table/rte_table_array.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/librte_table/rte_table_array.c b/lib/librte_table/rte_table_array.c index c031070..0164d18 100644 --- a/lib/librte_table/rte_table_array.c +++ b/lib/librte_table/rte_table_array.c @@ -164,8 +164,7 @@ rte_table_array_lookup( void **entries) { struct rte_table_array *t = (struct rte_table_array *) table; - - *lookup_hit_mask = pkts_mask; + uint64_t pkts_out_mask = 0; if ((pkts_mask & (pkts_mask + 1)) == 0) { uint64_t n_pkts = __builtin_popcountll(pkts_mask); @@ -173,26 +172,32 @@ rte_table_array_lookup( for (i = 0; i < n_pkts; i++) { struct rte_mbuf *pkt = pkts[i]; - uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt, - t->offset) & t->entry_pos_mask; + uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt,t->offset); - entries[i] = (void *) &t->array[entry_pos * - t->entry_size]; + if (entry_pos < t->n_entries) { + entries[i] = (void *) &t->array[entry_pos * + t->entry_size]; + pkts_out_mask |= (1LLU << i); + } } } else { for ( ; pkts_mask; ) { uint32_t pkt_index = __builtin_ctzll(pkts_mask); uint64_t pkt_mask = 1LLU << pkt_index; struct rte_mbuf *pkt = pkts[pkt_index]; - uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt, - t->offset) & t->entry_pos_mask; + uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt,t->offset); - entries[pkt_index] = (void *) &t->array[entry_pos * - t->entry_size]; + if (entry_pos < t->n_entries) { + entries[pkt_index] = (void *) &t->array[entry_pos * + t->entry_size]; + pkts_out_mask |= pkt_mask; + } pkts_mask &= ~pkt_mask; } } + *lookup_hit_mask = pkts_out_mask; + return 0; }