xref: /dpdk/lib/node/kernel_tx.c (revision ae282b0611c33aa73a01ee6137d116155053b835)
12a0ae651SVamsi Attunuru /* SPDX-License-Identifier: BSD-3-Clause
22a0ae651SVamsi Attunuru  * Copyright(C) 2023 Marvell International Ltd.
32a0ae651SVamsi Attunuru  */
42a0ae651SVamsi Attunuru 
52a0ae651SVamsi Attunuru #include <fcntl.h>
62a0ae651SVamsi Attunuru #include <sys/ioctl.h>
72a0ae651SVamsi Attunuru #include <sys/socket.h>
82a0ae651SVamsi Attunuru #include <unistd.h>
92a0ae651SVamsi Attunuru 
102a0ae651SVamsi Attunuru #include <rte_debug.h>
112a0ae651SVamsi Attunuru #include <rte_ethdev.h>
122a0ae651SVamsi Attunuru #include <rte_graph.h>
13a2bc0584SZhirun Yan #include <rte_graph_worker.h>
142a0ae651SVamsi Attunuru #include <rte_ip.h>
152a0ae651SVamsi Attunuru 
162a0ae651SVamsi Attunuru #include "kernel_tx_priv.h"
172a0ae651SVamsi Attunuru #include "node_private.h"
182a0ae651SVamsi Attunuru 
192a0ae651SVamsi Attunuru static __rte_always_inline void
kernel_tx_process_mbuf(struct rte_node * node,struct rte_mbuf ** mbufs,uint16_t cnt)202a0ae651SVamsi Attunuru kernel_tx_process_mbuf(struct rte_node *node, struct rte_mbuf **mbufs, uint16_t cnt)
212a0ae651SVamsi Attunuru {
222a0ae651SVamsi Attunuru 	kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx;
232a0ae651SVamsi Attunuru 	struct sockaddr_in sin = {0};
242a0ae651SVamsi Attunuru 	struct rte_ipv4_hdr *ip4;
252a0ae651SVamsi Attunuru 	size_t len;
262a0ae651SVamsi Attunuru 	char *buf;
272a0ae651SVamsi Attunuru 	int i;
282a0ae651SVamsi Attunuru 
292a0ae651SVamsi Attunuru 	for (i = 0; i < cnt; i++) {
302a0ae651SVamsi Attunuru 		ip4 = rte_pktmbuf_mtod(mbufs[i], struct rte_ipv4_hdr *);
312a0ae651SVamsi Attunuru 		len = rte_pktmbuf_data_len(mbufs[i]);
322a0ae651SVamsi Attunuru 		buf = (char *)ip4;
332a0ae651SVamsi Attunuru 
342a0ae651SVamsi Attunuru 		sin.sin_family = AF_INET;
352a0ae651SVamsi Attunuru 		sin.sin_port = 0;
362a0ae651SVamsi Attunuru 		sin.sin_addr.s_addr = ip4->dst_addr;
372a0ae651SVamsi Attunuru 
382a0ae651SVamsi Attunuru 		if (sendto(ctx->sock, buf, len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
39*ae282b06SDavid Marchand 			node_err("kernel_tx", "Unable to send packets: %s", strerror(errno));
402a0ae651SVamsi Attunuru 	}
412a0ae651SVamsi Attunuru }
422a0ae651SVamsi Attunuru 
432a0ae651SVamsi Attunuru static uint16_t
kernel_tx_node_process(struct rte_graph * graph __rte_unused,struct rte_node * node,void ** objs,uint16_t nb_objs)442a0ae651SVamsi Attunuru kernel_tx_node_process(struct rte_graph *graph __rte_unused, struct rte_node *node, void **objs,
452a0ae651SVamsi Attunuru 			 uint16_t nb_objs)
462a0ae651SVamsi Attunuru {
472a0ae651SVamsi Attunuru 	struct rte_mbuf **pkts = (struct rte_mbuf **)objs;
482a0ae651SVamsi Attunuru 	uint16_t obj_left = nb_objs;
492a0ae651SVamsi Attunuru 
502a0ae651SVamsi Attunuru #define PREFETCH_CNT 4
512a0ae651SVamsi Attunuru 
522a0ae651SVamsi Attunuru 	while (obj_left >= 12) {
532a0ae651SVamsi Attunuru 		/* Prefetch next-next mbufs */
542a0ae651SVamsi Attunuru 		rte_prefetch0(pkts[8]);
552a0ae651SVamsi Attunuru 		rte_prefetch0(pkts[9]);
562a0ae651SVamsi Attunuru 		rte_prefetch0(pkts[10]);
572a0ae651SVamsi Attunuru 		rte_prefetch0(pkts[11]);
582a0ae651SVamsi Attunuru 
592a0ae651SVamsi Attunuru 		/* Prefetch next mbuf data */
602a0ae651SVamsi Attunuru 		rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[4], void *, pkts[4]->l2_len));
612a0ae651SVamsi Attunuru 		rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[5], void *, pkts[5]->l2_len));
622a0ae651SVamsi Attunuru 		rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[6], void *, pkts[6]->l2_len));
632a0ae651SVamsi Attunuru 		rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[7], void *, pkts[7]->l2_len));
642a0ae651SVamsi Attunuru 
652a0ae651SVamsi Attunuru 		kernel_tx_process_mbuf(node, pkts, PREFETCH_CNT);
662a0ae651SVamsi Attunuru 
672a0ae651SVamsi Attunuru 		obj_left -= PREFETCH_CNT;
682a0ae651SVamsi Attunuru 		pkts += PREFETCH_CNT;
692a0ae651SVamsi Attunuru 	}
702a0ae651SVamsi Attunuru 
712a0ae651SVamsi Attunuru 	while (obj_left > 0) {
722a0ae651SVamsi Attunuru 		kernel_tx_process_mbuf(node, pkts, 1);
732a0ae651SVamsi Attunuru 
742a0ae651SVamsi Attunuru 		obj_left--;
752a0ae651SVamsi Attunuru 		pkts++;
762a0ae651SVamsi Attunuru 	}
772a0ae651SVamsi Attunuru 
782a0ae651SVamsi Attunuru 	rte_pktmbuf_free_bulk((struct rte_mbuf **)objs, nb_objs);
792a0ae651SVamsi Attunuru 
802a0ae651SVamsi Attunuru 	return nb_objs;
812a0ae651SVamsi Attunuru }
822a0ae651SVamsi Attunuru 
832a0ae651SVamsi Attunuru static int
kernel_tx_node_init(const struct rte_graph * graph __rte_unused,struct rte_node * node)842a0ae651SVamsi Attunuru kernel_tx_node_init(const struct rte_graph *graph __rte_unused, struct rte_node *node)
852a0ae651SVamsi Attunuru {
862a0ae651SVamsi Attunuru 	kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx;
872a0ae651SVamsi Attunuru 
882a0ae651SVamsi Attunuru 	ctx->sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
892a0ae651SVamsi Attunuru 	if (ctx->sock < 0)
90*ae282b06SDavid Marchand 		node_err("kernel_tx", "Unable to open RAW socket");
912a0ae651SVamsi Attunuru 
922a0ae651SVamsi Attunuru 	return 0;
932a0ae651SVamsi Attunuru }
942a0ae651SVamsi Attunuru 
952a0ae651SVamsi Attunuru static void
kernel_tx_node_fini(const struct rte_graph * graph __rte_unused,struct rte_node * node)962a0ae651SVamsi Attunuru kernel_tx_node_fini(const struct rte_graph *graph __rte_unused, struct rte_node *node)
972a0ae651SVamsi Attunuru {
982a0ae651SVamsi Attunuru 	kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx;
992a0ae651SVamsi Attunuru 
1002a0ae651SVamsi Attunuru 	if (ctx->sock >= 0) {
1012a0ae651SVamsi Attunuru 		close(ctx->sock);
1022a0ae651SVamsi Attunuru 		ctx->sock = -1;
1032a0ae651SVamsi Attunuru 	}
1042a0ae651SVamsi Attunuru }
1052a0ae651SVamsi Attunuru 
1062a0ae651SVamsi Attunuru static struct rte_node_register kernel_tx_node_base = {
1072a0ae651SVamsi Attunuru 	.process = kernel_tx_node_process,
1082a0ae651SVamsi Attunuru 	.name = "kernel_tx",
1092a0ae651SVamsi Attunuru 
1102a0ae651SVamsi Attunuru 	.init = kernel_tx_node_init,
1112a0ae651SVamsi Attunuru 	.fini = kernel_tx_node_fini,
1122a0ae651SVamsi Attunuru 
1132a0ae651SVamsi Attunuru 	.nb_edges = 0,
1142a0ae651SVamsi Attunuru };
1152a0ae651SVamsi Attunuru 
1162a0ae651SVamsi Attunuru struct rte_node_register *
kernel_tx_node_get(void)1172a0ae651SVamsi Attunuru kernel_tx_node_get(void)
1182a0ae651SVamsi Attunuru {
1192a0ae651SVamsi Attunuru 	return &kernel_tx_node_base;
1202a0ae651SVamsi Attunuru }
1212a0ae651SVamsi Attunuru 
1222a0ae651SVamsi Attunuru RTE_NODE_REGISTER(kernel_tx_node_base);
123