Branch data Line data Source code
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 : 0 : struct sockaddr_in sin = {0};
24 : : struct rte_ipv4_hdr *ip4;
25 : : size_t len;
26 : : char *buf;
27 : : int i;
28 : :
29 [ # # # # ]: 0 : for (i = 0; i < cnt; i++) {
30 : 0 : ip4 = rte_pktmbuf_mtod(mbufs[i], struct rte_ipv4_hdr *);
31 : 0 : len = rte_pktmbuf_data_len(mbufs[i]);
32 : : buf = (char *)ip4;
33 : :
34 : 0 : sin.sin_family = AF_INET;
35 : 0 : sin.sin_port = 0;
36 : 0 : sin.sin_addr.s_addr = ip4->dst_addr;
37 : :
38 [ # # # # ]: 0 : if (sendto(ctx->sock, buf, len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
39 : 0 : node_err("kernel_tx", "Unable to send packets: %s", strerror(errno));
40 : : }
41 : : }
42 : :
43 : : static uint16_t
44 : 0 : 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 [ # # ]: 0 : while (obj_left >= 12) {
53 : : /* Prefetch next-next mbufs */
54 : 0 : rte_prefetch0(pkts[8]);
55 : 0 : rte_prefetch0(pkts[9]);
56 : 0 : rte_prefetch0(pkts[10]);
57 : 0 : rte_prefetch0(pkts[11]);
58 : :
59 : : /* Prefetch next mbuf data */
60 : 0 : rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[4], void *, pkts[4]->l2_len));
61 : 0 : rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[5], void *, pkts[5]->l2_len));
62 : 0 : rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[6], void *, pkts[6]->l2_len));
63 : 0 : 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 : 0 : obj_left -= PREFETCH_CNT;
68 : 0 : pkts += PREFETCH_CNT;
69 : : }
70 : :
71 [ # # ]: 0 : while (obj_left > 0) {
72 : : kernel_tx_process_mbuf(node, pkts, 1);
73 : :
74 : 0 : obj_left--;
75 : 0 : pkts++;
76 : : }
77 : :
78 : 0 : rte_pktmbuf_free_bulk((struct rte_mbuf **)objs, nb_objs);
79 : :
80 : 0 : return nb_objs;
81 : : }
82 : :
83 : : static int
84 : 0 : 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 : 0 : ctx->sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
89 [ # # ]: 0 : if (ctx->sock < 0)
90 : 0 : node_err("kernel_tx", "Unable to open RAW socket");
91 : :
92 : 0 : return 0;
93 : : }
94 : :
95 : : static void
96 : 0 : 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 [ # # ]: 0 : if (ctx->sock >= 0) {
101 : 0 : close(ctx->sock);
102 : 0 : ctx->sock = -1;
103 : : }
104 : 0 : }
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 : 0 : kernel_tx_node_get(void)
118 : : {
119 : 0 : return &kernel_tx_node_base;
120 : : }
121 : :
122 : 252 : RTE_NODE_REGISTER(kernel_tx_node_base);
|