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