From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 46127A0C52; Tue, 27 Jul 2021 18:36:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5363D41109; Tue, 27 Jul 2021 18:36:21 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 03323410F0 for ; Tue, 27 Jul 2021 18:36:18 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10057"; a="273561556" X-IronPort-AV: E=Sophos;i="5.84,274,1620716400"; d="scan'208";a="273561556" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jul 2021 09:36:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,274,1620716400"; d="scan'208";a="517018277" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga002.fm.intel.com with ESMTP; 27 Jul 2021 09:36:11 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Date: Tue, 27 Jul 2021 17:36:07 +0100 Message-Id: <20210727163609.97769-3-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210727163609.97769-1-cristian.dumitrescu@intel.com> References: <20210727163609.97769-1-cristian.dumitrescu@intel.com> Subject: [dpdk-dev] [PATCH 3/5] pipeline: add variable size headers extract instruction X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Added a mechanism to extract variable size headers through a special flavor of the extract instruction. The length of the last struct field which has variable size is passed as argument to the instruction. Signed-off-by: Cristian Dumitrescu --- lib/pipeline/rte_swx_pipeline.c | 75 ++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c index 1a8259ffee..d87fe77d91 100644 --- a/lib/pipeline/rte_swx_pipeline.c +++ b/lib/pipeline/rte_swx_pipeline.c @@ -303,6 +303,9 @@ enum instruction_type { INSTR_HDR_EXTRACT7, INSTR_HDR_EXTRACT8, + /* extract h.header m.last_field_size */ + INSTR_HDR_EXTRACT_M, + /* emit h.header */ INSTR_HDR_EMIT, INSTR_HDR_EMIT_TX, @@ -3088,16 +3091,35 @@ instr_hdr_extract_translate(struct rte_swx_pipeline *p, struct header *h; CHECK(!action, EINVAL); - CHECK(n_tokens == 2, EINVAL); + CHECK((n_tokens == 2) || (n_tokens == 3), EINVAL); h = header_parse(p, tokens[1]); CHECK(h, EINVAL); - CHECK(!h->st->var_size, EINVAL); - instr->type = INSTR_HDR_EXTRACT; - instr->io.hdr.header_id[0] = h->id; - instr->io.hdr.struct_id[0] = h->struct_id; - instr->io.hdr.n_bytes[0] = h->st->n_bits / 8; + if (n_tokens == 2) { + CHECK(!h->st->var_size, EINVAL); + + instr->type = INSTR_HDR_EXTRACT; + instr->io.hdr.header_id[0] = h->id; + instr->io.hdr.struct_id[0] = h->struct_id; + instr->io.hdr.n_bytes[0] = h->st->n_bits / 8; + } else { + struct field *mf; + + CHECK(h->st->var_size, EINVAL); + + mf = metadata_field_parse(p, tokens[2]); + CHECK(mf, EINVAL); + CHECK(!mf->var_size, EINVAL); + + instr->type = INSTR_HDR_EXTRACT_M; + instr->io.io.offset = mf->offset / 8; + instr->io.io.n_bits = mf->n_bits; + instr->io.hdr.header_id[0] = h->id; + instr->io.hdr.struct_id[0] = h->struct_id; + instr->io.hdr.n_bytes[0] = h->st->n_bits_min / 8; + } + return 0; } @@ -3237,6 +3259,46 @@ instr_hdr_extract8_exec(struct rte_swx_pipeline *p) thread_ip_inc(p); } +static inline void +instr_hdr_extract_m_exec(struct rte_swx_pipeline *p) +{ + struct thread *t = &p->threads[p->thread_id]; + struct instruction *ip = t->ip; + + uint64_t valid_headers = t->valid_headers; + uint8_t *ptr = t->ptr; + uint32_t offset = t->pkt.offset; + uint32_t length = t->pkt.length; + + uint32_t n_bytes_last = METADATA_READ(t, ip->io.io.offset, ip->io.io.n_bits); + uint32_t header_id = ip->io.hdr.header_id[0]; + uint32_t struct_id = ip->io.hdr.struct_id[0]; + uint32_t n_bytes = ip->io.hdr.n_bytes[0]; + + struct header_runtime *h = &t->headers[header_id]; + + TRACE("[Thread %2u]: extract header %u (%u + %u bytes)\n", + p->thread_id, + header_id, + n_bytes, + n_bytes_last); + + n_bytes += n_bytes_last; + + /* Headers. */ + t->structs[struct_id] = ptr; + t->valid_headers = MASK64_BIT_SET(valid_headers, header_id); + h->n_bytes = n_bytes; + + /* Packet. */ + t->pkt.offset = offset + n_bytes; + t->pkt.length = length - n_bytes; + t->ptr = ptr + n_bytes; + + /* Thread. */ + thread_ip_inc(p); +} + /* * emit. */ @@ -8842,6 +8904,7 @@ static instr_exec_t instruction_table[] = { [INSTR_HDR_EXTRACT6] = instr_hdr_extract6_exec, [INSTR_HDR_EXTRACT7] = instr_hdr_extract7_exec, [INSTR_HDR_EXTRACT8] = instr_hdr_extract8_exec, + [INSTR_HDR_EXTRACT_M] = instr_hdr_extract_m_exec, [INSTR_HDR_EMIT] = instr_hdr_emit_exec, [INSTR_HDR_EMIT_TX] = instr_hdr_emit_tx_exec, -- 2.17.1