1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
6 #include <sys/socket.h>
9 #include <rte_ethdev.h>
10 #include <rte_ether.h>
11 #include <rte_graph.h>
12 #include <rte_graph_worker.h>
19 #include "rte_node_ip4_api.h"
21 #include "node_private.h"
23 #define IPV4_L3FWD_LPM_MAX_RULES 1024
24 #define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8)
26 /* IP4 Lookup global data struct */
27 struct ip4_lookup_node_main {
28 struct rte_lpm *lpm_tbl[RTE_MAX_NUMA_NODES];
31 #if defined(RTE_MACHINE_CPUFLAG_NEON)
32 #include "ip4_lookup_neon.h"
36 ip4_lookup_node_process(struct rte_graph *graph, struct rte_node *node,
37 void **objs, uint16_t nb_objs)
39 struct rte_ipv4_hdr *ipv4_hdr;
40 void **to_next, **from;
41 uint16_t last_spec = 0;
42 struct rte_mbuf *mbuf;
43 rte_edge_t next_index;
49 /* Speculative next */
50 next_index = RTE_NODE_IP4_LOOKUP_NEXT_REWRITE;
52 drop_nh = ((uint32_t)RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP) << 16;
54 /* Get socket specific LPM from ctx */
55 lpm = *((struct rte_lpm **)node->ctx);
58 /* Get stream for the speculated next node */
59 to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
60 for (i = 0; i < nb_objs; i++) {
64 mbuf = (struct rte_mbuf *)objs[i];
66 /* Extract DIP of mbuf0 */
67 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *,
68 sizeof(struct rte_ether_hdr));
69 /* Extract cksum, ttl as ipv4 hdr is in cache */
70 node_mbuf_priv1(mbuf)->cksum = ipv4_hdr->hdr_checksum;
71 node_mbuf_priv1(mbuf)->ttl = ipv4_hdr->time_to_live;
73 rc = rte_lpm_lookup(lpm, rte_be_to_cpu_32(ipv4_hdr->dst_addr),
75 next_hop = (rc == 0) ? next_hop : drop_nh;
77 node_mbuf_priv1(mbuf)->nh = (uint16_t)next_hop;
78 next_hop = next_hop >> 16;
79 next = (uint16_t)next_hop;
81 if (unlikely(next_index != next)) {
82 /* Copy things successfully speculated till now */
83 rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
89 rte_node_enqueue_x1(graph, node, next, from[0]);
96 /* !!! Home run !!! */
97 if (likely(last_spec == nb_objs)) {
98 rte_node_next_stream_move(graph, node, next_index);
102 rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
103 rte_node_next_stream_put(graph, node, next_index, held);
111 ip4_lookup_node_init(const struct rte_graph *graph, struct rte_node *node)
116 node_dbg("ip4_lookup", "Initialized ip4_lookup node");
121 static struct rte_node_register ip4_lookup_node = {
122 .process = ip4_lookup_node_process,
123 .name = "ip4_lookup",
125 .init = ip4_lookup_node_init,
127 .nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
129 [RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
130 [RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
134 RTE_NODE_REGISTER(ip4_lookup_node);