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 CBB5142C07; Thu, 1 Jun 2023 21:42:17 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5506F40EF0; Thu, 1 Jun 2023 21:42:17 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 6394040DDC for ; Thu, 1 Jun 2023 21:42:15 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 351IkwjQ009861 for ; Thu, 1 Jun 2023 12:42:14 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=TQ2S0wN8GJgqgVUudycf1chFEMX9kEH00JgjP4i/hro=; b=eel+XeqeP0hASdBPWORynR1moyGh8oV7eUrYGrjPyqaaMus9OJWRngO/XWKNpfHJF0uG FWUevkeL/FOwqcppGysI5RmGAmRcv+MvRZIFrnrMf5eJ923uiWziRC675LqKHVisFhvX J8SCXU7odsUBOjH1gvKJlco2RJYU1qu2uGeaGcRYI3p7T7P6J4rnmrLv72+lXYU/FoIf DS1ktYQvZsjcF99ef6j+J+qJ6NNrDU9hTovvEys9wPXqmckX8cHs8zIRQAZEGHyhsKTi vaNyUQCC2pPBsGUzrlRlbZy4fwB7qgnYuObZ6kctwXB+vZbQSKfrQFuhPDVcd0SpHINU zw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3qxs1bahtj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 01 Jun 2023 12:42:14 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 1 Jun 2023 12:42:12 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Thu, 1 Jun 2023 12:42:12 -0700 Received: from MININT-80QBFE8.corp.innovium.com (unknown [10.28.164.122]) by maili.marvell.com (Postfix) with ESMTP id B18B03F707A; Thu, 1 Jun 2023 12:42:10 -0700 (PDT) From: To: , Kiran Kumar K , "Nithin Dabilpuram" , Pavan Nikhilesh CC: Subject: [PATCH] node: add IPv4 reassembly node Date: Fri, 2 Jun 2023 01:12:07 +0530 Message-ID: <20230601194207.1552-1-pbhagavatula@marvell.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-ORIG-GUID: CYbCYVpePU0g0micqtdO9_5B_y0os9ke X-Proofpoint-GUID: CYbCYVpePU0g0micqtdO9_5B_y0os9ke X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.176.26 definitions=2023-06-01_08,2023-05-31_03,2023-05-22_02 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 From: Pavan Nikhilesh Add IPv4 reassembly node. Signed-off-by: Pavan Nikhilesh --- Depends-on: series-28278 doc/guides/prog_guide/graph_lib.rst | 8 ++ lib/node/ethdev_rx.c | 1 + lib/node/ethdev_rx_priv.h | 1 + lib/node/ip4_reassembly.c | 175 ++++++++++++++++++++++++++++ lib/node/ip4_reassembly_priv.h | 28 +++++ lib/node/meson.build | 3 +- lib/node/rte_node_ip4_api.h | 35 ++++++ lib/node/version.map | 1 + 8 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 lib/node/ip4_reassembly.c create mode 100644 lib/node/ip4_reassembly_priv.h diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst index 841cabe259..49c470e287 100644 --- a/doc/guides/prog_guide/graph_lib.rst +++ b/doc/guides/prog_guide/graph_lib.rst @@ -388,6 +388,14 @@ to determine the L2 header to be written to the packet before sending the packet out to a particular ethdev_tx node. ``rte_node_ip4_rewrite_add()`` is control path API to add next-hop info. +ip4_reassembly +~~~~~~~~~~~~~~ +This node is an intermediate node that reassembles ipv4 fragmented packets, +non-fragmented packets pass through the node un-effected. The node rewrites +it's stream and moves it to the next node. +The fragment table and death row table should be setup via the +``rte_node_ip4_reassembly_configure`` API. + ip6_lookup ~~~~~~~~~~ This node is an intermediate node that does LPM lookup for the received diff --git a/lib/node/ethdev_rx.c b/lib/node/ethdev_rx.c index a19237b42f..6ed2e1834f 100644 --- a/lib/node/ethdev_rx.c +++ b/lib/node/ethdev_rx.c @@ -218,6 +218,7 @@ static struct rte_node_register ethdev_rx_node_base = { /* Default pkt classification node */ [ETHDEV_RX_NEXT_PKT_CLS] = "pkt_cls", [ETHDEV_RX_NEXT_IP4_LOOKUP] = "ip4_lookup", + [ETHDEV_RX_NEXT_IP4_REASSEMBLY] = "ip4_reassembly", }, }; diff --git a/lib/node/ethdev_rx_priv.h b/lib/node/ethdev_rx_priv.h index 7f24cf962e..574a76c2a6 100644 --- a/lib/node/ethdev_rx_priv.h +++ b/lib/node/ethdev_rx_priv.h @@ -39,6 +39,7 @@ struct ethdev_rx_node_elem { enum ethdev_rx_next_nodes { ETHDEV_RX_NEXT_IP4_LOOKUP, ETHDEV_RX_NEXT_PKT_CLS, + ETHDEV_RX_NEXT_IP4_REASSEMBLY, ETHDEV_RX_NEXT_MAX, }; diff --git a/lib/node/ip4_reassembly.c b/lib/node/ip4_reassembly.c new file mode 100644 index 0000000000..907db111c2 --- /dev/null +++ b/lib/node/ip4_reassembly.c @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rte_node_ip4_api.h" + +#include "ip4_reassembly_priv.h" +#include "node_private.h" + +struct ip4_reassembly_elem { + struct ip4_reassembly_elem *next; + struct ip4_reassembly_ctx ctx; + rte_node_t node_id; +}; + +/* IP4 reassembly global data struct */ +struct ip4_reassembly_node_main { + struct ip4_reassembly_elem *head; +}; + +typedef struct ip4_reassembly_ctx ip4_reassembly_ctx_t; +typedef struct ip4_reassembly_elem ip4_reassembly_elem_t; + +static struct ip4_reassembly_node_main ip4_reassembly_main; + +static uint16_t +ip4_reassembly_node_process(struct rte_graph *graph, struct rte_node *node, void **objs, + uint16_t nb_objs) +{ +#define PREFETCH_OFFSET 4 + struct rte_mbuf *mbuf, *mbuf_out; + struct rte_ip_frag_death_row *dr; + struct ip4_reassembly_ctx *ctx; + struct rte_ipv4_hdr *ipv4_hdr; + struct rte_ip_frag_tbl *tbl; + uint16_t idx = 0; + void **to_next; + int i; + + ctx = (struct ip4_reassembly_ctx *)node->ctx; + + /* Get core specific reassembly tbl */ + tbl = ctx->tbl; + dr = ctx->dr; + + for (i = 0; i < PREFETCH_OFFSET && i < nb_objs; i++) { + rte_prefetch0(rte_pktmbuf_mtod_offset((struct rte_mbuf *)objs[i], void *, + sizeof(struct rte_ether_hdr))); + } + + to_next = node->objs; + for (i = 0; i < nb_objs - PREFETCH_OFFSET; i++) { +#if RTE_GRAPH_BURST_SIZE > 64 + /* Prefetch next-next mbufs */ + if (likely(i + 8 < nb_objs)) + rte_prefetch0(objs[i + 8]); +#endif + rte_prefetch0(rte_pktmbuf_mtod_offset((struct rte_mbuf *)objs[i + PREFETCH_OFFSET], + void *, sizeof(struct rte_ether_hdr))); + mbuf = (struct rte_mbuf *)objs[i]; + + ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, + sizeof(struct rte_ether_hdr)); + if (rte_ipv4_frag_pkt_is_fragmented(ipv4_hdr)) { + /* prepare mbuf: setup l2_len/l3_len. */ + mbuf->l2_len = sizeof(struct rte_ether_hdr); + mbuf->l3_len = sizeof(struct rte_ipv4_hdr); + + mbuf_out = rte_ipv4_frag_reassemble_packet(tbl, dr, mbuf, rte_rdtsc(), + ipv4_hdr); + } else { + mbuf_out = mbuf; + } + + if (mbuf_out) + to_next[idx++] = (void *)mbuf_out; + } + + for (; i < nb_objs; i++) { + mbuf = (struct rte_mbuf *)objs[i]; + + ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, + sizeof(struct rte_ether_hdr)); + if (rte_ipv4_frag_pkt_is_fragmented(ipv4_hdr)) { + /* prepare mbuf: setup l2_len/l3_len. */ + mbuf->l2_len = sizeof(struct rte_ether_hdr); + mbuf->l3_len = sizeof(struct rte_ipv4_hdr); + + mbuf_out = rte_ipv4_frag_reassemble_packet(tbl, dr, mbuf, rte_rdtsc(), + ipv4_hdr); + } else { + mbuf_out = mbuf; + } + + if (mbuf_out) + to_next[idx++] = (void *)mbuf_out; + } + node->idx = idx; + rte_node_next_stream_move(graph, node, 0); + rte_ip_frag_free_death_row(dr, 4); + + return idx; +} + +int +rte_node_ip4_reassembly_configure(struct rte_node_ip4_reassembly_cfg *cfg, uint16_t cnt) +{ + ip4_reassembly_elem_t *elem; + int i; + + for (i = 0; i < cnt; i++) { + elem = malloc(sizeof(ip4_reassembly_elem_t)); + if (elem == NULL) + return -ENOMEM; + elem->ctx.dr = cfg[i].dr; + elem->ctx.tbl = cfg[i].tbl; + elem->node_id = cfg[i].node_id; + elem->next = ip4_reassembly_main.head; + ip4_reassembly_main.head = elem; + } + + return 0; +} + +static int +ip4_reassembly_node_init(const struct rte_graph *graph, struct rte_node *node) +{ + ip4_reassembly_ctx_t *ctx = (ip4_reassembly_ctx_t *)node->ctx; + ip4_reassembly_elem_t *elem = ip4_reassembly_main.head; + + RTE_SET_USED(graph); + while (elem) { + if (elem->node_id == node->id) { + /* Update node specific context */ + memcpy(ctx, &elem->ctx, sizeof(ip4_reassembly_ctx_t)); + break; + } + elem = elem->next; + } + + return 0; +} + +static struct rte_node_register ip4_reassembly_node = { + .process = ip4_reassembly_node_process, + .name = "ip4_reassembly", + + .init = ip4_reassembly_node_init, + + .nb_edges = RTE_NODE_IP4_REASSEMBLY_NEXT_MAX, +}; + +struct rte_node_register * +ip4_reassembly_node_get(void) +{ + return &ip4_reassembly_node; +} + +RTE_NODE_REGISTER(ip4_reassembly_node); diff --git a/lib/node/ip4_reassembly_priv.h b/lib/node/ip4_reassembly_priv.h new file mode 100644 index 0000000000..1fa70274ba --- /dev/null +++ b/lib/node/ip4_reassembly_priv.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell International Ltd. + */ + +#ifndef __INCLUDE_IP4_REASSEMBLY_PRIV_H__ +#define __INCLUDE_IP4_REASSEMBLY_PRIV_H__ + +/** + * @internal + * + * Ip4_reassembly context structure. + */ +struct ip4_reassembly_ctx { + struct rte_ip_frag_tbl *tbl; + struct rte_ip_frag_death_row *dr; +}; + +/** + * @internal + * + * Get the IP4 reassembly node + * + * @return + * Pointer to the IP4 reassembly node. + */ +struct rte_node_register *ip4_reassembly_node_get(void); + +#endif /* __INCLUDE_IP4_REASSEMBLY_PRIV_H__ */ diff --git a/lib/node/meson.build b/lib/node/meson.build index b2f04269c5..94d3f36163 100644 --- a/lib/node/meson.build +++ b/lib/node/meson.build @@ -19,8 +19,9 @@ sources = files( 'null.c', 'pkt_cls.c', 'pkt_drop.c', + 'ip4_reassembly.c' ) headers = files('rte_node_ip4_api.h', 'rte_node_ip6_api.h', 'rte_node_eth_api.h') # Strict-aliasing rules are violated by uint8_t[] to context size casts. cflags += '-fno-strict-aliasing' -deps += ['graph', 'mbuf', 'lpm', 'ethdev', 'mempool', 'cryptodev'] +deps += ['graph', 'mbuf', 'lpm', 'ethdev', 'mempool', 'cryptodev', 'ip_frag'] diff --git a/lib/node/rte_node_ip4_api.h b/lib/node/rte_node_ip4_api.h index 46d0d8976b..4d6561604b 100644 --- a/lib/node/rte_node_ip4_api.h +++ b/lib/node/rte_node_ip4_api.h @@ -35,6 +35,27 @@ enum rte_node_ip4_lookup_next { /**< Number of next nodes of lookup node. */ }; +/** + * IP4 reassembly next nodes. + */ +enum rte_node_ip4_reassembly_next { + RTE_NODE_IP4_REASSEMBLY_NEXT_MAX, + /**< Number of next nodes of reassembly node. */ +}; + +/** + * Reassembly configure structure. + * @see rte_node_ip4_reassembly_configure + */ +struct rte_node_ip4_reassembly_cfg { + struct rte_ip_frag_tbl *tbl; + /**< Reassembly fragmentation table. */ + struct rte_ip_frag_death_row *dr; + /**< Reassembly deathrow table. */ + rte_node_t node_id; + /**< Node identifier to configure. */ +}; + /** * Add ipv4 route to lookup table. * @@ -73,6 +94,20 @@ __rte_experimental int rte_node_ip4_rewrite_add(uint16_t next_hop, uint8_t *rewrite_data, uint8_t rewrite_len, uint16_t dst_port); +/** + * Add reassembly node configuration data. + * + * @param cfg + * Pointer to the configuration structure. + * @param cnt + * Number of configuration structures passed. + * + * @return + * 0 on success, negative otherwise. + */ +__rte_experimental +int rte_node_ip4_reassembly_configure(struct rte_node_ip4_reassembly_cfg *cfg, uint16_t cnt); + #ifdef __cplusplus } #endif diff --git a/lib/node/version.map b/lib/node/version.map index 40df308bfe..c10e2e78ea 100644 --- a/lib/node/version.map +++ b/lib/node/version.map @@ -4,6 +4,7 @@ EXPERIMENTAL { rte_node_eth_config; rte_node_ip4_route_add; rte_node_ip4_rewrite_add; + rte_node_ip4_reassembly_configure; rte_node_ip6_rewrite_add; rte_node_ip6_route_add; rte_node_logtype; -- 2.39.1