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 A63DA42672; Fri, 29 Sep 2023 12:58:53 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 924F840E03; Fri, 29 Sep 2023 12:58:53 +0200 (CEST) Received: from mail-qt1-f177.google.com (mail-qt1-f177.google.com [209.85.160.177]) by mails.dpdk.org (Postfix) with ESMTP id B52CB40287 for ; Fri, 29 Sep 2023 12:58:51 +0200 (CEST) Received: by mail-qt1-f177.google.com with SMTP id d75a77b69052e-4195035800fso39497971cf.3 for ; Fri, 29 Sep 2023 03:58:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695985131; x=1696589931; darn=dpdk.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=jTGzIJ9qAvEn0X0WdNdFVV0vyklw38ETZb/3ZV4GOjI=; b=G3yurW6tXuFBTJMD+SDvLaTGtvTaD4VGno0TEDCUgi3X0Lw26fWLRHX8pSe7bpjcyR r0QDV8XXlefWoVphCjBZb5womaRRgpOUWR9jkjAhU1ZwPaj3Z694QMefvCXSdAWibM+g MscLHro4EVgvIb+LCje4KEfeQd//ZaMZUs/gevY5itEhJIPkaMarGwkdMgXJ5TK1jay4 0aSWGTbfsKibTDRkcvt8dcMIGFOElfS6zzplCNJKDbWnlDf5Im6Nkrk7Ay5rdzCn9QG6 ImK6CLmX+prB+AMRw+Rm8PB1D3TK3P5EhaFdLbNWb08u9F81FGi39wisXAk6q39TraGu Vihg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695985131; x=1696589931; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jTGzIJ9qAvEn0X0WdNdFVV0vyklw38ETZb/3ZV4GOjI=; b=qXkAowj9wEAy9RbAO9rXRFWxNlrKcNFI/kq0X/X7prrD9lc8bu8NK0XujFIQngzo69 sTnvQmv/pY8pxQcoGo5z+RPKEPvdvdbt2LpcArdlbZNzo9/apAGjLHYm6yDlu2ggW4kz s4awl2YoIA8PbJQCeTF8EZYY43K88oP543EL+n0hOazKBcQNGASyDM3CPXd6VDRRIXqp anKjMEcnxAg1e9zpWdthlCg8Anz9u6jtnr4LuYqPoZ9hCzcLpNwxc4ux2SByXB8d2wm6 GGiBX1BAKaYu2bINNLBPK/19jcXv7yzpGVWkXmKcPYrqij/ZYGxuAqGHZZNv8T9ksIj9 Ua0Q== X-Gm-Message-State: AOJu0YwjEd7g4tNhDZIjFyNhc4zMKlA9lReQtSMud0fhxhSqP0kM9ubB iHxSkGCR0z+V4FZeO6XfSOvkV1940lUnl94oF7BlY0qI/as= X-Google-Smtp-Source: AGHT+IGpE4FQCzegoOw4g7T43HL2yIXzE1aBFbLV82UgLPtPZ38KXqJLMBvFDA/pxOFogJ1AptDKmhgma71z0BpQjo8= X-Received: by 2002:ac8:7d56:0:b0:418:d14:1ca0 with SMTP id h22-20020ac87d56000000b004180d141ca0mr3696032qtb.27.1695985130997; Fri, 29 Sep 2023 03:58:50 -0700 (PDT) MIME-Version: 1.0 References: <20230927124100.4108588-1-rkudurumalla@marvell.com> <20230928102529.4118346-1-rkudurumalla@marvell.com> <20230928102529.4118346-2-rkudurumalla@marvell.com> In-Reply-To: <20230928102529.4118346-2-rkudurumalla@marvell.com> From: Nithin Dabilpuram Date: Fri, 29 Sep 2023 16:28:37 +0530 Message-ID: Subject: Re: [PATCH v6 2/2] node: add UDP v4 support To: Rakesh Kudurumalla Cc: Jerin Jacob , Kiran Kumar K , Nithin Dabilpuram , Zhirun Yan , Pavan Nikhilesh , dev@dpdk.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 Acked-by: Nithin Dabilpuram On Thu, Sep 28, 2023 at 4:06=E2=80=AFPM Rakesh Kudurumalla wrote: > > IPv4 UDP packets are given to application > with specified UDP destination port given > by user. > > Signed-off-by: Rakesh Kudurumalla > --- > doc/api/doxy-api-index.md | 3 +- > doc/guides/prog_guide/graph_lib.rst | 25 ++ > .../img/graph_inbuilt_node_flow.svg | 165 ++++++++----- > lib/node/meson.build | 2 + > lib/node/rte_node_udp4_input_api.h | 61 +++++ > lib/node/udp4_input.c | 226 ++++++++++++++++++ > lib/node/version.map | 2 + > 7 files changed, 418 insertions(+), 66 deletions(-) > create mode 100644 lib/node/rte_node_udp4_input_api.h > create mode 100644 lib/node/udp4_input.c > > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md > index fdeda13932..96282d3fd0 100644 > --- a/doc/api/doxy-api-index.md > +++ b/doc/api/doxy-api-index.md > @@ -206,7 +206,8 @@ The public API headers are grouped by topics: > * graph_nodes: > [eth_node](@ref rte_node_eth_api.h), > [ip4_node](@ref rte_node_ip4_api.h), > - [ip6_node](@ref rte_node_ip6_api.h) > + [ip6_node](@ref rte_node_ip6_api.h), > + [udp4_input_node](@ref rte_node_udp4_input_api.h) > > - **basic**: > [bitops](@ref rte_bitops.h), > diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/= graph_lib.rst > index f2e04a68b9..3572560362 100644 > --- a/doc/guides/prog_guide/graph_lib.rst > +++ b/doc/guides/prog_guide/graph_lib.rst > @@ -513,3 +513,28 @@ On packet_type lookup failure, objects are redirecte= d to ``pkt_drop`` node. > depth to receive to packets. > To achieve home run, node use ``rte_node_stream_move()`` as mentioned in= above > sections. > + > +udp4_input > +~~~~~~~~~~ > +This node is an intermediate node that does udp destination port lookup = for > +the received ipv4 packets and the result determines each packets next no= de. > + > +User registers a new node ``udp4_input`` into graph library during initi= alization > +and attach user specified node as edege to this node using > +``rte_node_udp4_usr_node_add()``, and create empty hash table with desti= nation > +port and node id as its feilds. > + > +After successful addition of user node as edege, edge id is returned to = the user. > + > +User would register ``ip4_lookup`` table with specified ip address and 3= 2 bit as mask > +for ip filtration using api ``rte_node_ip4_route_add()``. > + > +After graph is created user would update hash table with custom port wit= h > +and previously obtained edge id using API ``rte_node_udp4_dst_port_add()= ``. > + > +When packet is received lpm look up is performed if ip is matched the pa= cket > +is handed over to ip4_local node, then packet is verified for udp proto = and > +on success packet is enqueued to ``udp4_input`` node. > + > +Hash lookup is performed in ``udp4_input`` node with registered destinat= ion port > +and destination port in UDP packet , on success packet is handed to ``ud= p_user_node``. > diff --git a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg b/doc/= guides/prog_guide/img/graph_inbuilt_node_flow.svg > index b954f6fba1..7c451371a7 100644 > --- a/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg > +++ b/doc/guides/prog_guide/img/graph_inbuilt_node_flow.svg > @@ -39,192 +39,227 @@ digraph dpdk_inbuilt_nodes_flow { > kernel_tx -> kernel_rx [color=3D"red" style=3D"dashed"] > ip4_lookup -> ip4_local > ip4_local -> pkt_drop [color=3D"cyan" style=3D"dashed"] > + ip4_local -> udp4_input [ label=3D"udpv4"] > + udp4_input -> udp_user_node > + udp4_input -> pkt_drop [color=3D"cyan" style=3D"dashed"] > + > } > > --> > > > - - viewBox=3D"0.00 0.00 524.91 458.00" xmlns=3D"http://www.w3.org/2000/svg= " xmlns:xlink=3D"http://www.w3.org/1999/xlink"> > - > + + viewBox=3D"0.00 0.00 630.95 437.00" xmlns=3D"http://www.w3.org/2000/svg= " xmlns:xlink=3D"http://www.w3.org/1999/xlink"> > + > dpdk_inbuilt_nodes_flow > - > + > > > ethdev_rx > - > -ethdev_rx > + > +ethdev_rx > > > > pkt_cls > - > -pkt_cls > + > +pkt_cls > > > > ethdev_rx->pkt_cls > - > - > + > + > > > > kernel_rx > - > -kernel_rx > + > +kernel_rx > > > > kernel_rx->pkt_cls > - > - > + > + > > > > ethdev_tx > - > -ethdev_tx > + > +ethdev_tx > > > > pkt_drop > - > -pkt_drop > + > +pkt_drop > > > > ethdev_tx->pkt_drop > - > - > + > + > > > > kernel_tx > - > -kernel_tx > + > +kernel_tx > > > > kernel_tx->kernel_rx > - > - > + > + > > > > pkt_cls->pkt_drop > - > - > + > + > > > > pkt_cls->kernel_tx > - > - > -exception pkts > + > + > +exception pkts > > > > ip4_lookup > - > -ip4_lookup > + > +ip4_lookup > > > > pkt_cls->ip4_lookup > - > - > -ipv4 > + > + > +ipv4 > > > > ip6_lookup > - > -ip6_lookup > + > +ip6_lookup > > > > pkt_cls->ip6_lookup > - > - > -ipv6 > + > + > +ipv6 > > > > ip4_lookup->pkt_drop > - > - > + > + > > > > ip4_rewrite > - > -ip4_rewrite > + > +ip4_rewrite > > > > ip4_lookup->ip4_rewrite > - > - > + > + > > > > ip4_local > - > -ip4_local > + > +ip4_local > > > > ip4_lookup->ip4_local > - > - > + > + > > > > ip6_lookup->pkt_drop > - > - > + > + > > > > ip6_rewrite > - > -ip6_rewrite > + > +ip6_rewrite > > > > ip6_lookup->ip6_rewrite > - > - > + > + > > > > ip4_rewrite->ethdev_tx > - > - > + > + > > > > ip4_rewrite->pkt_drop > - > - > + > + > > > > ip6_rewrite->ethdev_tx > - > - > + > + > > > > ip6_rewrite->pkt_drop > - > - > + > + > > > > ip4_local->pkt_drop > - > - > + > + > + > + > + > +udp4_input > + > +udp4_input > + > + > + > +ip4_local->udp4_input > + > + > +udpv4 > + > + > + > +udp4_input->pkt_drop > + > + > + > + > + > +udp_user_node > + > +udp_user_node > + > + > + > +udp4_input->udp_user_node > + > + > > > > diff --git a/lib/node/meson.build b/lib/node/meson.build > index c0d5b09e2f..c5b8ee656e 100644 > --- a/lib/node/meson.build > +++ b/lib/node/meson.build > @@ -22,11 +22,13 @@ sources =3D files( > 'null.c', > 'pkt_cls.c', > 'pkt_drop.c', > + 'udp4_input.c', > ) > headers =3D files( > 'rte_node_eth_api.h', > 'rte_node_ip4_api.h', > 'rte_node_ip6_api.h', > + 'rte_node_udp4_input_api.h', > ) > > # Strict-aliasing rules are violated by uint8_t[] to context size casts. > diff --git a/lib/node/rte_node_udp4_input_api.h b/lib/node/rte_node_udp4_= input_api.h > new file mode 100644 > index 0000000000..c873acbbe0 > --- /dev/null > +++ b/lib/node/rte_node_udp4_input_api.h > @@ -0,0 +1,61 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2023 Marvell International Ltd. > + */ > + > +#ifndef __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__ > +#define __INCLUDE_RTE_NODE_UDP4_INPUT_API_H__ > + > +/** > + * @file rte_node_udp4_input_api.h > + * > + * @warning > + * @b EXPERIMENTAL: > + * All functions in this file may be changed or removed without prior no= tice. > + * > + * This API allows to control path functions of udp4_* nodes > + * like udp4_input. > + * > + */ > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include > +#include > + > +#include "rte_graph.h" > +/** > + * UDP4 lookup next nodes. > + */ > +enum rte_node_udp4_input_next { > + RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP, > + /**< Packet drop node. */ > +}; > + > +/** > + * Add usr node to receive udp4 frames. > + * > + * @param usr_node > + * Node registered by user to receive data. > + */ > +__rte_experimental > +int rte_node_udp4_usr_node_add(const char *usr_node); > + > +/** > + * Add udpv4 dst_port to lookup table. > + * > + * @param dst_port > + * Dst Port of packet to be added for consumption. > + * @param next_node > + * Next node packet to be added for consumption. > + * @return > + * 0 on success, negative otherwise. > + */ > +__rte_experimental > +int rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __INCLUDE_RTE_NODE_UDP4_API_H__ */ > diff --git a/lib/node/udp4_input.c b/lib/node/udp4_input.c > new file mode 100644 > index 0000000000..80cedce548 > --- /dev/null > +++ b/lib/node/udp4_input.c > @@ -0,0 +1,226 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2023 Marvell International Ltd. > + */ > + > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +#include "rte_node_udp4_input_api.h" > + > +#include "node_private.h" > + > +#define UDP4_INPUT_HASH_TBL_SIZE 1024 > + > +#define UDP4_INPUT_NODE_HASH(ctx) \ > + (((struct udp4_input_node_ctx *)ctx)->hash) > + > +#define UDP4_INPUT_NODE_NEXT_INDEX(ctx) \ > + (((struct udp4_input_node_ctx *)ctx)->next_index) > + > + > +/* UDP4 input global data struct */ > +struct udp4_input_node_main { > + struct rte_hash *hash_tbl[RTE_MAX_NUMA_NODES]; > +}; > + > +static struct udp4_input_node_main udp4_input_nm; > + > +struct udp4_input_node_ctx { > + /* Socket's Hash table */ > + struct rte_hash *hash; > + /* Cached next index */ > + uint16_t next_index; > +}; > + > +struct flow_key { > + uint32_t prt_dst; > +}; > + > +static struct rte_hash_parameters udp4_params =3D { > + .entries =3D UDP4_INPUT_HASH_TBL_SIZE, > + .key_len =3D sizeof(uint32_t), > + .hash_func =3D rte_jhash, > + .hash_func_init_val =3D 0, > + .socket_id =3D 0, > +}; > + > +int > +rte_node_udp4_dst_port_add(uint32_t dst_port, rte_edge_t next_node) > +{ > + uint8_t socket; > + int rc; > + > + for (socket =3D 0; socket < RTE_MAX_NUMA_NODES; socket++) { > + if (!udp4_input_nm.hash_tbl[socket]) > + continue; > + > + rc =3D rte_hash_add_key_data(udp4_input_nm.hash_tbl[socke= t], > + &dst_port, (void *)(uintptr_t)= next_node); > + if (rc < 0) { > + node_err("udp4_lookup", "Failed to add key for so= ck %u, rc=3D%d", > + socket, rc); > + return rc; > + } > + } > + return 0; > +} > + > +int > +rte_node_udp4_usr_node_add(const char *usr_node) > +{ > + const char *next_nodes =3D usr_node; > + rte_node_t udp4_input_node_id, count; > + > + udp4_input_node_id =3D rte_node_from_name("udp4_input"); > + count =3D rte_node_edge_update(udp4_input_node_id, RTE_EDGE_ID_IN= VALID, > + &next_nodes, 1); > + if (count =3D=3D 0) { > + node_dbg("udp4_input", "Adding usr node as edge to udp4_i= nput failed"); > + return count; > + } > + count =3D rte_node_edge_count(udp4_input_node_id) - 1; > + return count; > +} > + > +static int > +setup_udp4_dstprt_hash(struct udp4_input_node_main *nm, int socket) > +{ > + struct rte_hash_parameters *hash_udp4 =3D &udp4_params; > + char s[RTE_HASH_NAMESIZE]; > + > + /* One Hash table per socket */ > + if (nm->hash_tbl[socket]) > + return 0; > + > + /* create Hash table */ > + snprintf(s, sizeof(s), "UDP4_INPUT_HASH_%d", socket); > + hash_udp4->name =3D s; > + hash_udp4->socket_id =3D socket; > + nm->hash_tbl[socket] =3D rte_hash_create(hash_udp4); > + if (nm->hash_tbl[socket] =3D=3D NULL) > + return -rte_errno; > + > + return 0; > +} > + > +static int > +udp4_input_node_init(const struct rte_graph *graph, struct rte_node *nod= e) > +{ > + uint16_t socket, lcore_id; > + static uint8_t init_once; > + int rc; > + > + RTE_SET_USED(graph); > + RTE_BUILD_BUG_ON(sizeof(struct udp4_input_node_ctx) > RTE_NODE_CT= X_SZ); > + > + if (!init_once) { > + > + /* Setup HASH tables for all sockets */ > + RTE_LCORE_FOREACH(lcore_id) > + { > + socket =3D rte_lcore_to_socket_id(lcore_id); > + rc =3D setup_udp4_dstprt_hash(&udp4_input_nm, soc= ket); > + if (rc) { > + node_err("udp4_lookup", > + "Failed to setup hash tbl= for sock %u, rc=3D%d", > + socket, rc); > + return rc; > + } > + } > + init_once =3D 1; > + } > + > + UDP4_INPUT_NODE_HASH(node->ctx) =3D udp4_input_nm.hash_tbl[graph-= >socket]; > + > + node_dbg("udp4_input", "Initialized udp4_input node"); > + return 0; > +} > + > +static uint16_t > +udp4_input_node_process_scalar(struct rte_graph *graph, struct rte_node = *node, > + void **objs, uint16_t nb_objs) > +{ > + struct rte_hash *hash_tbl_handle =3D UDP4_INPUT_NODE_HASH(node->c= tx); > + rte_edge_t next_index, udplookup_node; > + struct rte_udp_hdr *pkt_udp_hdr; > + uint16_t last_spec =3D 0; > + void **to_next, **from; > + struct rte_mbuf *mbuf; > + uint16_t held =3D 0; > + uint16_t next =3D 0; > + int i, rc; > + > + /* Speculative next */ > + next_index =3D UDP4_INPUT_NODE_NEXT_INDEX(node->ctx); > + > + from =3D objs; > + > + to_next =3D rte_node_next_stream_get(graph, node, next_index, nb_= objs); > + for (i =3D 0; i < nb_objs; i++) { > + struct flow_key key_port; > + > + mbuf =3D (struct rte_mbuf *)objs[i]; > + pkt_udp_hdr =3D rte_pktmbuf_mtod_offset(mbuf, struct rte_= udp_hdr *, > + sizeof(struct rte_ether_h= dr) + > + sizeof(struct rte_ipv4_hd= r)); > + > + key_port.prt_dst =3D rte_cpu_to_be_16(pkt_udp_hdr->dst_po= rt); > + rc =3D rte_hash_lookup_data(hash_tbl_handle, > + &key_port.prt_dst, > + (void **)&udplookup_node); > + next =3D (rc < 0) ? RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP > + : udplookup_node; > + > + if (unlikely(next_index !=3D next)) { > + /* Copy things successfully speculated till now *= / > + rte_memcpy(to_next, from, last_spec * sizeof(from= [0])); > + from +=3D last_spec; > + to_next +=3D last_spec; > + held +=3D last_spec; > + last_spec =3D 0; > + > + rte_node_enqueue_x1(graph, node, next, from[0]); > + from +=3D 1; > + } else { > + last_spec +=3D 1; > + } > + } > + /* !!! Home run !!! */ > + if (likely(last_spec =3D=3D nb_objs)) { > + rte_node_next_stream_move(graph, node, next_index); > + return nb_objs; > + } > + held +=3D last_spec; > + rte_memcpy(to_next, from, last_spec * sizeof(from[0])); > + rte_node_next_stream_put(graph, node, next_index, held); > + /* Save the last next used */ > + UDP4_INPUT_NODE_NEXT_INDEX(node->ctx) =3D next; > + > + return nb_objs; > +} > + > +static struct rte_node_register udp4_input_node =3D { > + .process =3D udp4_input_node_process_scalar, > + .name =3D "udp4_input", > + > + .init =3D udp4_input_node_init, > + > + .nb_edges =3D RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP + 1, > + .next_nodes =3D { > + [RTE_NODE_UDP4_INPUT_NEXT_PKT_DROP] =3D "pkt_drop", > + }, > +}; > + > +RTE_NODE_REGISTER(udp4_input_node); > diff --git a/lib/node/version.map b/lib/node/version.map > index 40df308bfe..c51befce09 100644 > --- a/lib/node/version.map > +++ b/lib/node/version.map > @@ -6,6 +6,8 @@ EXPERIMENTAL { > rte_node_ip4_rewrite_add; > rte_node_ip6_rewrite_add; > rte_node_ip6_route_add; > + rte_node_udp4_usr_node_add; > + rte_node_udp4_dst_port_add; > rte_node_logtype; > local: *; > }; > -- > 2.25.1 >