[v2,1/4] node: add pkt punt to kernel node

Message ID 20230425131516.3308612-2-vattunuru@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series app: introduce testgraph application |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Vamsi Krishna Attunuru April 25, 2023, 1:15 p.m. UTC
  Patch adds a node to punt the packets to kernel over
a raw socket.

Signed-off-by: Vamsi Attunuru <vattunuru@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(+)
  

Comments

Nithin Dabilpuram May 30, 2023, 8:16 a.m. UTC | #1
On Tue, Apr 25, 2023 at 6:45 PM Vamsi Attunuru <vattunuru@marvell.com> wrote:
>
> Patch adds a node to punt the packets to kernel over
> a raw socket.
>
> Signed-off-by: Vamsi Attunuru <vattunuru@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 ?

> +
> +       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
>
  
Vamsi Krishna Attunuru May 31, 2023, 12:35 p.m. UTC | #2
> -----Original Message-----
> From: Nithin Dabilpuram <nithind1988@gmail.com>
> Sent: Tuesday, May 30, 2023 1:47 PM
> To: Vamsi Krishna Attunuru <vattunuru@marvell.com>
> Cc: dev@dpdk.org; thomas@monjalon.net; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Nithin Kumar Dabilpuram
> <ndabilpuram@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 <vattunuru@marvell.com>
> wrote:
> >
> > Patch adds a node to punt the packets to kernel over a raw socket.
> >
> > Signed-off-by: Vamsi Attunuru <vattunuru@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
> >
  

Patch

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);
+
+	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__ */