1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2023 Marvell International Ltd. 3 */ 4 5 #include <fcntl.h> 6 #include <sys/ioctl.h> 7 #include <sys/socket.h> 8 #include <unistd.h> 9 10 #include <rte_debug.h> 11 #include <rte_ethdev.h> 12 #include <rte_graph.h> 13 #include <rte_graph_worker.h> 14 #include <rte_ip.h> 15 16 #include "kernel_tx_priv.h" 17 #include "node_private.h" 18 19 static __rte_always_inline void 20 kernel_tx_process_mbuf(struct rte_node *node, struct rte_mbuf **mbufs, uint16_t cnt) 21 { 22 kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx; 23 struct sockaddr_in sin = {0}; 24 struct rte_ipv4_hdr *ip4; 25 size_t len; 26 char *buf; 27 int i; 28 29 for (i = 0; i < cnt; i++) { 30 ip4 = rte_pktmbuf_mtod(mbufs[i], struct rte_ipv4_hdr *); 31 len = rte_pktmbuf_data_len(mbufs[i]); 32 buf = (char *)ip4; 33 34 sin.sin_family = AF_INET; 35 sin.sin_port = 0; 36 sin.sin_addr.s_addr = ip4->dst_addr; 37 38 if (sendto(ctx->sock, buf, len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) 39 node_err("kernel_tx", "Unable to send packets: %s\n", strerror(errno)); 40 } 41 } 42 43 static uint16_t 44 kernel_tx_node_process(struct rte_graph *graph __rte_unused, struct rte_node *node, void **objs, 45 uint16_t nb_objs) 46 { 47 struct rte_mbuf **pkts = (struct rte_mbuf **)objs; 48 uint16_t obj_left = nb_objs; 49 50 #define PREFETCH_CNT 4 51 52 while (obj_left >= 12) { 53 /* Prefetch next-next mbufs */ 54 rte_prefetch0(pkts[8]); 55 rte_prefetch0(pkts[9]); 56 rte_prefetch0(pkts[10]); 57 rte_prefetch0(pkts[11]); 58 59 /* Prefetch next mbuf data */ 60 rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[4], void *, pkts[4]->l2_len)); 61 rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[5], void *, pkts[5]->l2_len)); 62 rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[6], void *, pkts[6]->l2_len)); 63 rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[7], void *, pkts[7]->l2_len)); 64 65 kernel_tx_process_mbuf(node, pkts, PREFETCH_CNT); 66 67 obj_left -= PREFETCH_CNT; 68 pkts += PREFETCH_CNT; 69 } 70 71 while (obj_left > 0) { 72 kernel_tx_process_mbuf(node, pkts, 1); 73 74 obj_left--; 75 pkts++; 76 } 77 78 rte_pktmbuf_free_bulk((struct rte_mbuf **)objs, nb_objs); 79 80 return nb_objs; 81 } 82 83 static int 84 kernel_tx_node_init(const struct rte_graph *graph __rte_unused, struct rte_node *node) 85 { 86 kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx; 87 88 ctx->sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 89 if (ctx->sock < 0) 90 node_err("kernel_tx", "Unable to open RAW socket\n"); 91 92 return 0; 93 } 94 95 static void 96 kernel_tx_node_fini(const struct rte_graph *graph __rte_unused, struct rte_node *node) 97 { 98 kernel_tx_node_ctx_t *ctx = (kernel_tx_node_ctx_t *)node->ctx; 99 100 if (ctx->sock >= 0) { 101 close(ctx->sock); 102 ctx->sock = -1; 103 } 104 } 105 106 static struct rte_node_register kernel_tx_node_base = { 107 .process = kernel_tx_node_process, 108 .name = "kernel_tx", 109 110 .init = kernel_tx_node_init, 111 .fini = kernel_tx_node_fini, 112 113 .nb_edges = 0, 114 }; 115 116 struct rte_node_register * 117 kernel_tx_node_get(void) 118 { 119 return &kernel_tx_node_base; 120 } 121 122 RTE_NODE_REGISTER(kernel_tx_node_base); 123