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 ?

> +
> +       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
>

Reply via email to