> -----Original Message-----
> From: Nithin Dabilpuram <nithind1...@gmail.com>
> Sent: Tuesday, May 30, 2023 1:47 PM
> To: Vamsi Krishna Attunuru <vattun...@marvell.com>
> Cc: dev@dpdk.org; tho...@monjalon.net; Jerin Jacob Kollanukkaran
> <jer...@marvell.com>; Nithin Kumar Dabilpuram
> <ndabilpu...@marvell.com>
> Subject: [EXT] Re: [PATCH v2 1/4] node: add pkt punt to kernel node
>
> External Email
>
> ----------------------------------------------------------------------
> On Tue, Apr 25, 2023 at 6:45 PM Vamsi Attunuru <vattun...@marvell.com>
> wrote:
> >
> > Patch adds a node to punt the packets to kernel over a raw socket.
> >
> > Signed-off-by: Vamsi Attunuru <vattun...@marvell.com>
> > ---
> > doc/guides/prog_guide/graph_lib.rst | 10 +++
> > lib/node/meson.build | 1 +
> > lib/node/punt_kernel.c | 125 ++++++++++++++++++++++++++++
> > lib/node/punt_kernel_priv.h | 36 ++++++++
> > 4 files changed, 172 insertions(+)
> >
> > diff --git a/doc/guides/prog_guide/graph_lib.rst
> > b/doc/guides/prog_guide/graph_lib.rst
> > index 1cfdc86433..b3b5b14827 100644
> > --- a/doc/guides/prog_guide/graph_lib.rst
> > +++ b/doc/guides/prog_guide/graph_lib.rst
> > @@ -392,3 +392,13 @@ null
> > ~~~~
> > This node ignores the set of objects passed to it and reports that
> > all are processed.
> > +
> > +punt_kernel
> > +~~~~~~~~~~~
> > +This node punts the packets to kernel using a raw socket interface.
> > +For sending the received packets, raw socket uses the packet's
> > +destination IP address in sockaddr_in address structure and node uses
> > +``sendto`` function to send data on the raw socket.
> > +
> > +Aftering sending the burst of packets to kernel, this node redirects
> > +the same objects to pkt_drop node to free up the packet buffers.
> > diff --git a/lib/node/meson.build b/lib/node/meson.build index
> > dbdf673c86..48c2da73f7 100644
> > --- a/lib/node/meson.build
> > +++ b/lib/node/meson.build
> > @@ -17,6 +17,7 @@ sources = files(
> > 'null.c',
> > 'pkt_cls.c',
> > 'pkt_drop.c',
> > + 'punt_kernel.c',
> > )
> > headers = files('rte_node_ip4_api.h', 'rte_node_eth_api.h') #
> > Strict-aliasing rules are violated by uint8_t[] to context size casts.
> > diff --git a/lib/node/punt_kernel.c b/lib/node/punt_kernel.c new file
> > mode 100644 index 0000000000..e5dd15b759
> > --- /dev/null
> > +++ b/lib/node/punt_kernel.c
> > @@ -0,0 +1,125 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(C) 2023 Marvell International Ltd.
> > + */
> > +
> > +#include <fcntl.h>
> > +#include <sys/ioctl.h>
> > +#include <sys/socket.h>
> > +#include <unistd.h>
> > +
> > +#include <rte_debug.h>
> > +#include <rte_ethdev.h>
> > +#include <rte_graph.h>
> > +#include <rte_graph_worker.h>
> > +#include <rte_ip.h>
> > +
> > +#include "node_private.h"
> > +#include "punt_kernel_priv.h"
> > +
> > +static __rte_always_inline void
> > +punt_kernel_process_mbuf(struct rte_node *node, struct rte_mbuf
> > +**mbufs, uint16_t cnt) {
> > + punt_kernel_node_ctx_t *ctx = (punt_kernel_node_ctx_t *)node-
> >ctx;
> > + struct sockaddr_in sin = {0};
> > + struct rte_ipv4_hdr *ip4;
> > + size_t len;
> > + char *buf;
> > + int i;
> > +
> > + for (i = 0; i < cnt; i++) {
> > + ip4 = rte_pktmbuf_mtod(mbufs[i], struct rte_ipv4_hdr *);
> > + len = rte_pktmbuf_data_len(mbufs[i]);
> > + buf = (char *)ip4;
> > +
> > + sin.sin_family = AF_INET;
> > + sin.sin_port = 0;
> > + sin.sin_addr.s_addr = ip4->dst_addr;
> > +
> > + if (sendto(ctx->sock, buf, len, 0, (struct sockaddr *)&sin,
> sizeof(sin)) < 0)
> > + node_err("punt_kernel", "Unable to send packets:
> > %s\n",
> strerror(errno));
> > + }
> > +}
> > +
> > +static uint16_t
> > +punt_kernel_node_process(struct rte_graph *graph __rte_unused,
> struct rte_node *node, void **objs,
> > + uint16_t nb_objs) {
> > + struct rte_mbuf **pkts = (struct rte_mbuf **)objs;
> > + uint16_t obj_left = nb_objs;
> > +
> > +#define PREFETCH_CNT 4
> > +
> > + while (obj_left >= 12) {
> > + /* Prefetch next-next mbufs */
> > + rte_prefetch0(pkts[8]);
> > + rte_prefetch0(pkts[9]);
> > + rte_prefetch0(pkts[10]);
> > + rte_prefetch0(pkts[11]);
> > +
> > + /* Prefetch next mbuf data */
> > + rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[4], void *,
> > pkts[4]-
> >l2_len));
> > + rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[5], void *,
> > pkts[5]-
> >l2_len));
> > + rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[6], void *,
> > pkts[6]-
> >l2_len));
> > + rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[7], void *,
> > + pkts[7]->l2_len));
> > +
> > + punt_kernel_process_mbuf(node, pkts, PREFETCH_CNT);
> > +
> > + obj_left -= PREFETCH_CNT;
> > + pkts += PREFETCH_CNT;
> > + }
> > +
> > + while (obj_left > 0) {
> > + punt_kernel_process_mbuf(node, pkts, 1);
> > +
> > + obj_left--;
> > + pkts++;
> > + }
> > +
> > + rte_node_next_stream_move(graph, node,
> > + PUNT_KERNEL_NEXT_PKT_DROP);
>
> Packet drop node signifies that packet is dropped due to some reason and
> not consumed. Since here the packet is really not dropped but consumed by
> Kernel, can we avoid using pkt drop node and instead free pkts directly ?
>
Ack, will fix in next version.
> > +
> > + return nb_objs;
> > +}
> > +
> > +static int
> > +punt_kernel_node_init(const struct rte_graph *graph __rte_unused,
> > +struct rte_node *node) {
> > + punt_kernel_node_ctx_t *ctx = (punt_kernel_node_ctx_t
> > +*)node->ctx;
> > +
> > + ctx->sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
> > + if (ctx->sock < 0)
> > + node_err("punt_kernel", "Unable to open RAW
> > + socket\n");
> > +
> > + return 0;
> > +}
> > +
> > +static void
> > +punt_kernel_node_fini(const struct rte_graph *graph __rte_unused,
> > +struct rte_node *node) {
> > + punt_kernel_node_ctx_t *ctx = (punt_kernel_node_ctx_t
> > +*)node->ctx;
> > +
> > + if (ctx->sock >= 0) {
> > + close(ctx->sock);
> > + ctx->sock = -1;
> > + }
> > +}
> > +
> > +static struct rte_node_register punt_kernel_node_base = {
> > + .process = punt_kernel_node_process,
> > + .name = "punt_kernel",
> > +
> > + .init = punt_kernel_node_init,
> > + .fini = punt_kernel_node_fini,
> > +
> > + .nb_edges = PUNT_KERNEL_NEXT_MAX,
> > + .next_nodes = {
> > + [PUNT_KERNEL_NEXT_PKT_DROP] = "pkt_drop",
> > + },
> > +};
> > +
> > +struct rte_node_register *
> > +punt_kernel_node_get(void)
> > +{
> > + return &punt_kernel_node_base; }
> > +
> > +RTE_NODE_REGISTER(punt_kernel_node_base);
> > diff --git a/lib/node/punt_kernel_priv.h b/lib/node/punt_kernel_priv.h
> > new file mode 100644 index 0000000000..25ba2072e7
> > --- /dev/null
> > +++ b/lib/node/punt_kernel_priv.h
> > @@ -0,0 +1,36 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(C) 2023 Marvell International Ltd.
> > + */
> > +
> > +#ifndef __INCLUDE_PUNT_KERNEL_PRIV_H__ #define
> > +__INCLUDE_PUNT_KERNEL_PRIV_H__
> > +
> > +struct punt_kernel_node_elem;
> > +struct punt_kernel_node_ctx;
> > +typedef struct punt_kernel_node_elem punt_kernel_node_elem_t;
> > +
> > +/**
> > + * @internal
> > + *
> > + * PUNT Kernel node context structure.
> > + */
> > +typedef struct punt_kernel_node_ctx {
> > + int sock;
> > +} punt_kernel_node_ctx_t;
> > +
> > +enum punt_kernel_next_nodes {
> > + PUNT_KERNEL_NEXT_PKT_DROP,
> > + PUNT_KERNEL_NEXT_MAX,
> > +};
> > +
> > +/**
> > + * @internal
> > + *
> > + * Get the PUNT Kernel node.
> > + *
> > + * @return
> > + * Pointer to the PUNT Kernel node.
> > + */
> > +struct rte_node_register *punt_kernel_node_get(void);
> > +
> > +#endif /* __INCLUDE_PUNT_KERNEL_PRIV_H__ */
> > --
> > 2.25.1
> >