Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2020 Marvell.
3 : : */
4 : :
5 : : #include <rte_graph.h>
6 : : #include <rte_graph_worker.h>
7 : :
8 : : #include "pkt_cls_priv.h"
9 : : #include "node_private.h"
10 : :
11 : : /* Next node for each ptype, default is '0' is "pkt_drop" */
12 : : static const uint8_t p_nxt[256] __rte_cache_aligned = {
13 : : [RTE_PTYPE_L3_IPV4] = PKT_CLS_NEXT_IP4_LOOKUP,
14 : :
15 : : [RTE_PTYPE_L3_IPV4_EXT] = PKT_CLS_NEXT_IP4_LOOKUP,
16 : :
17 : : [RTE_PTYPE_L3_IPV4_EXT_UNKNOWN] = PKT_CLS_NEXT_IP4_LOOKUP,
18 : :
19 : : [RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L2_ETHER] =
20 : : PKT_CLS_NEXT_IP4_LOOKUP,
21 : :
22 : : [RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L2_ETHER] =
23 : : PKT_CLS_NEXT_IP4_LOOKUP,
24 : :
25 : : [RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
26 : : PKT_CLS_NEXT_IP4_LOOKUP,
27 : :
28 : : [RTE_PTYPE_L3_IPV6] = PKT_CLS_NEXT_IP6_LOOKUP,
29 : :
30 : : [RTE_PTYPE_L3_IPV6_EXT] = PKT_CLS_NEXT_IP6_LOOKUP,
31 : :
32 : : [RTE_PTYPE_L3_IPV6_EXT_UNKNOWN] = PKT_CLS_NEXT_IP6_LOOKUP,
33 : :
34 : : [RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L2_ETHER] = PKT_CLS_NEXT_IP6_LOOKUP,
35 : :
36 : : [RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L2_ETHER] = PKT_CLS_NEXT_IP6_LOOKUP,
37 : :
38 : : [RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
39 : : PKT_CLS_NEXT_IP6_LOOKUP,
40 : : };
41 : :
42 : : static uint16_t
43 : 0 : pkt_cls_node_process(struct rte_graph *graph, struct rte_node *node,
44 : : void **objs, uint16_t nb_objs)
45 : : {
46 : : struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts;
47 : : uint8_t l0, l1, l2, l3, last_type;
48 : : uint16_t next_index, n_left_from;
49 : : uint16_t held = 0, last_spec = 0;
50 : : struct pkt_cls_node_ctx *ctx;
51 : : void **to_next, **from;
52 : : uint32_t i;
53 : :
54 : : pkts = (struct rte_mbuf **)objs;
55 : : from = objs;
56 : : n_left_from = nb_objs;
57 : :
58 [ # # ]: 0 : for (i = OBJS_PER_CLINE; i < RTE_GRAPH_BURST_SIZE; i += OBJS_PER_CLINE)
59 : 0 : rte_prefetch0(&objs[i]);
60 : :
61 : : #if RTE_GRAPH_BURST_SIZE > 64
62 [ # # # # ]: 0 : for (i = 0; i < 4 && i < n_left_from; i++)
63 : 0 : rte_prefetch0(pkts[i]);
64 : : #endif
65 : :
66 : : ctx = (struct pkt_cls_node_ctx *)node->ctx;
67 : 0 : last_type = ctx->l2l3_type;
68 : 0 : next_index = p_nxt[last_type];
69 : :
70 : : /* Get stream for the speculated next node */
71 : 0 : to_next = rte_node_next_stream_get(graph, node,
72 : : next_index, nb_objs);
73 [ # # ]: 0 : while (n_left_from >= 4) {
74 : : #if RTE_GRAPH_BURST_SIZE > 64
75 [ # # ]: 0 : if (likely(n_left_from > 7)) {
76 : 0 : rte_prefetch0(pkts[4]);
77 : 0 : rte_prefetch0(pkts[5]);
78 : 0 : rte_prefetch0(pkts[6]);
79 : 0 : rte_prefetch0(pkts[7]);
80 : : }
81 : : #endif
82 : :
83 : 0 : mbuf0 = pkts[0];
84 : 0 : mbuf1 = pkts[1];
85 : 0 : mbuf2 = pkts[2];
86 : 0 : mbuf3 = pkts[3];
87 : 0 : pkts += 4;
88 : 0 : n_left_from -= 4;
89 : :
90 : 0 : l0 = mbuf0->packet_type &
91 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
92 : 0 : l1 = mbuf1->packet_type &
93 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
94 : 0 : l2 = mbuf2->packet_type &
95 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
96 : 0 : l3 = mbuf3->packet_type &
97 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
98 : :
99 : : /* Check if they are destined to same
100 : : * next node based on l2l3 packet type.
101 : : */
102 : 0 : uint8_t fix_spec = (last_type ^ l0) | (last_type ^ l1) |
103 : : (last_type ^ l2) | (last_type ^ l3);
104 : :
105 [ # # ]: 0 : if (unlikely(fix_spec)) {
106 : : /* Copy things successfully speculated till now */
107 [ # # ]: 0 : rte_memcpy(to_next, from,
108 : : last_spec * sizeof(from[0]));
109 : 0 : from += last_spec;
110 : 0 : to_next += last_spec;
111 : 0 : held += last_spec;
112 : : last_spec = 0;
113 : :
114 : : /* l0 */
115 [ # # ]: 0 : if (p_nxt[l0] == next_index) {
116 : 0 : to_next[0] = from[0];
117 : 0 : to_next++;
118 : 0 : held++;
119 : : } else {
120 : 0 : rte_node_enqueue_x1(graph, node,
121 : : p_nxt[l0], from[0]);
122 : : }
123 : :
124 : : /* l1 */
125 [ # # ]: 0 : if (p_nxt[l1] == next_index) {
126 : 0 : to_next[0] = from[1];
127 : 0 : to_next++;
128 : 0 : held++;
129 : : } else {
130 : 0 : rte_node_enqueue_x1(graph, node,
131 : : p_nxt[l1], from[1]);
132 : : }
133 : :
134 : : /* l2 */
135 [ # # ]: 0 : if (p_nxt[l2] == next_index) {
136 : 0 : to_next[0] = from[2];
137 : 0 : to_next++;
138 : 0 : held++;
139 : : } else {
140 : 0 : rte_node_enqueue_x1(graph, node,
141 : : p_nxt[l2], from[2]);
142 : : }
143 : :
144 : : /* l3 */
145 [ # # ]: 0 : if (p_nxt[l3] == next_index) {
146 : 0 : to_next[0] = from[3];
147 : 0 : to_next++;
148 : 0 : held++;
149 : : } else {
150 : 0 : rte_node_enqueue_x1(graph, node,
151 : : p_nxt[l3], from[3]);
152 : : }
153 : :
154 : : /* Update speculated ptype */
155 [ # # # # ]: 0 : if ((last_type != l3) && (l2 == l3) &&
156 : : (next_index != p_nxt[l3])) {
157 : : /* Put the current stream for
158 : : * speculated ltype.
159 : : */
160 [ # # ]: 0 : rte_node_next_stream_put(graph, node,
161 : : next_index, held);
162 : :
163 : : held = 0;
164 : :
165 : : /* Get next stream for new ltype */
166 : : next_index = p_nxt[l3];
167 : : last_type = l3;
168 : 0 : to_next = rte_node_next_stream_get(graph, node,
169 : : next_index,
170 : : nb_objs);
171 [ # # ]: 0 : } else if (next_index == p_nxt[l3]) {
172 : : last_type = l3;
173 : : }
174 : :
175 : 0 : from += 4;
176 : : } else {
177 : 0 : last_spec += 4;
178 : : }
179 : : }
180 : :
181 [ # # ]: 0 : while (n_left_from > 0) {
182 : 0 : mbuf0 = pkts[0];
183 : :
184 : 0 : pkts += 1;
185 : 0 : n_left_from -= 1;
186 : :
187 : 0 : l0 = mbuf0->packet_type &
188 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
189 [ # # # # ]: 0 : if (unlikely((l0 != last_type) &&
190 : : (p_nxt[l0] != next_index))) {
191 : : /* Copy things successfully speculated till now */
192 [ # # ]: 0 : rte_memcpy(to_next, from,
193 : : last_spec * sizeof(from[0]));
194 : 0 : from += last_spec;
195 : 0 : to_next += last_spec;
196 : 0 : held += last_spec;
197 : : last_spec = 0;
198 : :
199 : 0 : rte_node_enqueue_x1(graph, node,
200 : : p_nxt[l0], from[0]);
201 : 0 : from += 1;
202 : : } else {
203 : 0 : last_spec += 1;
204 : : }
205 : : }
206 : :
207 : : /* !!! Home run !!! */
208 [ # # ]: 0 : if (likely(last_spec == nb_objs)) {
209 : 0 : rte_node_next_stream_move(graph, node, next_index);
210 : 0 : return nb_objs;
211 : : }
212 : :
213 : 0 : held += last_spec;
214 : : /* Copy things successfully speculated till now */
215 [ # # ]: 0 : rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
216 [ # # ]: 0 : rte_node_next_stream_put(graph, node, next_index, held);
217 : :
218 : 0 : ctx->l2l3_type = last_type;
219 : 0 : return nb_objs;
220 : : }
221 : :
222 : : /* Packet Classification Node */
223 : : struct rte_node_register pkt_cls_node = {
224 : : .process = pkt_cls_node_process,
225 : : .name = "pkt_cls",
226 : :
227 : : .nb_edges = PKT_CLS_NEXT_MAX,
228 : : .next_nodes = {
229 : : /* Pkt drop node starts at '0' */
230 : : [PKT_CLS_NEXT_PKT_DROP] = "pkt_drop",
231 : : [PKT_CLS_NEXT_IP4_LOOKUP] = "ip4_lookup",
232 : : [PKT_CLS_NEXT_IP6_LOOKUP] = "ip6_lookup",
233 : : },
234 : : };
235 : 235 : RTE_NODE_REGISTER(pkt_cls_node);
|