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"
33 #elif defined(RTE_ARCH_X86)
34 #include "ip4_lookup_sse.h"
38 ip4_lookup_node_process(struct rte_graph *graph, struct rte_node *node,
39 void **objs, uint16_t nb_objs)
41 struct rte_ipv4_hdr *ipv4_hdr;
42 void **to_next, **from;
43 uint16_t last_spec = 0;
44 struct rte_mbuf *mbuf;
45 rte_edge_t next_index;
51 /* Speculative next */
52 next_index = RTE_NODE_IP4_LOOKUP_NEXT_REWRITE;
54 drop_nh = ((uint32_t)RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP) << 16;
56 /* Get socket specific LPM from ctx */
57 lpm = *((struct rte_lpm **)node->ctx);
60 /* Get stream for the speculated next node */
61 to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
62 for (i = 0; i < nb_objs; i++) {
66 mbuf = (struct rte_mbuf *)objs[i];
68 /* Extract DIP of mbuf0 */
69 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *,
70 sizeof(struct rte_ether_hdr));
71 /* Extract cksum, ttl as ipv4 hdr is in cache */
72 node_mbuf_priv1(mbuf)->cksum = ipv4_hdr->hdr_checksum;
73 node_mbuf_priv1(mbuf)->ttl = ipv4_hdr->time_to_live;
75 rc = rte_lpm_lookup(lpm, rte_be_to_cpu_32(ipv4_hdr->dst_addr),
77 next_hop = (rc == 0) ? next_hop : drop_nh;
79 node_mbuf_priv1(mbuf)->nh = (uint16_t)next_hop;
80 next_hop = next_hop >> 16;
81 next = (uint16_t)next_hop;
83 if (unlikely(next_index != next)) {
84 /* Copy things successfully speculated till now */
85 rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
91 rte_node_enqueue_x1(graph, node, next, from[0]);
98 /* !!! Home run !!! */
99 if (likely(last_spec == nb_objs)) {
100 rte_node_next_stream_move(graph, node, next_index);
104 rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
105 rte_node_next_stream_put(graph, node, next_index, held);
113 ip4_lookup_node_init(const struct rte_graph *graph, struct rte_node *node)
118 node_dbg("ip4_lookup", "Initialized ip4_lookup node");
123 static struct rte_node_register ip4_lookup_node = {
124 .process = ip4_lookup_node_process,
125 .name = "ip4_lookup",
127 .init = ip4_lookup_node_init,
129 .nb_edges = RTE_NODE_IP4_LOOKUP_NEXT_MAX,
131 [RTE_NODE_IP4_LOOKUP_NEXT_REWRITE] = "ip4_rewrite",
132 [RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP] = "pkt_drop",
136 RTE_NODE_REGISTER(ip4_lookup_node);