1*58fbbccaSRakesh Kudurumalla /* SPDX-License-Identifier: BSD-3-Clause
2*58fbbccaSRakesh Kudurumalla * Copyright(C) 2023 Marvell International Ltd.
3*58fbbccaSRakesh Kudurumalla */
4*58fbbccaSRakesh Kudurumalla
5*58fbbccaSRakesh Kudurumalla #include <arpa/inet.h>
6*58fbbccaSRakesh Kudurumalla #include <sys/socket.h>
7*58fbbccaSRakesh Kudurumalla
8*58fbbccaSRakesh Kudurumalla #include <rte_ethdev.h>
9*58fbbccaSRakesh Kudurumalla #include <rte_ether.h>
10*58fbbccaSRakesh Kudurumalla #include <rte_graph.h>
11*58fbbccaSRakesh Kudurumalla #include <rte_graph_worker.h>
12*58fbbccaSRakesh Kudurumalla #include <rte_ip.h>
13*58fbbccaSRakesh Kudurumalla #include <rte_lpm.h>
14*58fbbccaSRakesh Kudurumalla #include <rte_hash.h>
15*58fbbccaSRakesh Kudurumalla #include <rte_fbk_hash.h>
16*58fbbccaSRakesh Kudurumalla #include <rte_jhash.h>
17*58fbbccaSRakesh Kudurumalla #include <rte_hash_crc.h>
18*58fbbccaSRakesh Kudurumalla
19*58fbbccaSRakesh Kudurumalla #include "rte_node_ip4_api.h"
20*58fbbccaSRakesh Kudurumalla
21*58fbbccaSRakesh Kudurumalla #include "node_private.h"
22*58fbbccaSRakesh Kudurumalla
23*58fbbccaSRakesh Kudurumalla static uint16_t
ip4_local_node_process_scalar(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)24*58fbbccaSRakesh Kudurumalla ip4_local_node_process_scalar(struct rte_graph *graph, struct rte_node *node,
25*58fbbccaSRakesh Kudurumalla void **objs, uint16_t nb_objs)
26*58fbbccaSRakesh Kudurumalla {
27*58fbbccaSRakesh Kudurumalla void **to_next, **from;
28*58fbbccaSRakesh Kudurumalla uint16_t last_spec = 0;
29*58fbbccaSRakesh Kudurumalla rte_edge_t next_index;
30*58fbbccaSRakesh Kudurumalla struct rte_mbuf *mbuf;
31*58fbbccaSRakesh Kudurumalla uint16_t held = 0;
32*58fbbccaSRakesh Kudurumalla uint32_t l4;
33*58fbbccaSRakesh Kudurumalla int i;
34*58fbbccaSRakesh Kudurumalla
35*58fbbccaSRakesh Kudurumalla /* Speculative next */
36*58fbbccaSRakesh Kudurumalla next_index = RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT;
37*58fbbccaSRakesh Kudurumalla
38*58fbbccaSRakesh Kudurumalla from = objs;
39*58fbbccaSRakesh Kudurumalla to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
40*58fbbccaSRakesh Kudurumalla for (i = 0; i < nb_objs; i++) {
41*58fbbccaSRakesh Kudurumalla uint16_t next;
42*58fbbccaSRakesh Kudurumalla
43*58fbbccaSRakesh Kudurumalla mbuf = (struct rte_mbuf *)objs[i];
44*58fbbccaSRakesh Kudurumalla l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK;
45*58fbbccaSRakesh Kudurumalla
46*58fbbccaSRakesh Kudurumalla next = (l4 == RTE_PTYPE_L4_UDP)
47*58fbbccaSRakesh Kudurumalla ? next_index
48*58fbbccaSRakesh Kudurumalla : RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP;
49*58fbbccaSRakesh Kudurumalla
50*58fbbccaSRakesh Kudurumalla if (unlikely(next_index != next)) {
51*58fbbccaSRakesh Kudurumalla /* Copy things successfully speculated till now */
52*58fbbccaSRakesh Kudurumalla rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
53*58fbbccaSRakesh Kudurumalla from += last_spec;
54*58fbbccaSRakesh Kudurumalla to_next += last_spec;
55*58fbbccaSRakesh Kudurumalla held += last_spec;
56*58fbbccaSRakesh Kudurumalla last_spec = 0;
57*58fbbccaSRakesh Kudurumalla
58*58fbbccaSRakesh Kudurumalla rte_node_enqueue_x1(graph, node, next, from[0]);
59*58fbbccaSRakesh Kudurumalla from += 1;
60*58fbbccaSRakesh Kudurumalla } else {
61*58fbbccaSRakesh Kudurumalla last_spec += 1;
62*58fbbccaSRakesh Kudurumalla }
63*58fbbccaSRakesh Kudurumalla }
64*58fbbccaSRakesh Kudurumalla /* !!! Home run !!! */
65*58fbbccaSRakesh Kudurumalla if (likely(last_spec == nb_objs)) {
66*58fbbccaSRakesh Kudurumalla rte_node_next_stream_move(graph, node, next_index);
67*58fbbccaSRakesh Kudurumalla return nb_objs;
68*58fbbccaSRakesh Kudurumalla }
69*58fbbccaSRakesh Kudurumalla held += last_spec;
70*58fbbccaSRakesh Kudurumalla rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
71*58fbbccaSRakesh Kudurumalla rte_node_next_stream_put(graph, node, next_index, held);
72*58fbbccaSRakesh Kudurumalla
73*58fbbccaSRakesh Kudurumalla return nb_objs;
74*58fbbccaSRakesh Kudurumalla }
75*58fbbccaSRakesh Kudurumalla
76*58fbbccaSRakesh Kudurumalla static struct rte_node_register ip4_local_node = {
77*58fbbccaSRakesh Kudurumalla .process = ip4_local_node_process_scalar,
78*58fbbccaSRakesh Kudurumalla .name = "ip4_local",
79*58fbbccaSRakesh Kudurumalla
80*58fbbccaSRakesh Kudurumalla .nb_edges = RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP + 1,
81*58fbbccaSRakesh Kudurumalla .next_nodes = {
82*58fbbccaSRakesh Kudurumalla [RTE_NODE_IP4_LOCAL_NEXT_UDP4_INPUT] = "udp4_input",
83*58fbbccaSRakesh Kudurumalla [RTE_NODE_IP4_LOCAL_NEXT_PKT_DROP] = "pkt_drop",
84*58fbbccaSRakesh Kudurumalla },
85*58fbbccaSRakesh Kudurumalla };
86*58fbbccaSRakesh Kudurumalla
87*58fbbccaSRakesh Kudurumalla RTE_NODE_REGISTER(ip4_local_node);
88