xref: /dpdk/lib/node/pkt_cls.c (revision e9fd1ebf981f361844aea9ec94e17f4bda5e1479)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright (C) 2020 Marvell.
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
5*e9fd1ebfSTyler Retzlaff #include <stdalign.h>
6*e9fd1ebfSTyler Retzlaff 
799a2dd95SBruce Richardson #include <rte_graph.h>
8a2bc0584SZhirun Yan #include <rte_graph_worker.h>
999a2dd95SBruce Richardson 
1099a2dd95SBruce Richardson #include "pkt_cls_priv.h"
1199a2dd95SBruce Richardson #include "node_private.h"
1299a2dd95SBruce Richardson 
1399a2dd95SBruce Richardson /* Next node for each ptype, default is '0' is "pkt_drop" */
14*e9fd1ebfSTyler Retzlaff static const alignas(RTE_CACHE_LINE_SIZE) uint8_t p_nxt[256] = {
1599a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4] = PKT_CLS_NEXT_IP4_LOOKUP,
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4_EXT] = PKT_CLS_NEXT_IP4_LOOKUP,
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4_EXT_UNKNOWN] = PKT_CLS_NEXT_IP4_LOOKUP,
2099a2dd95SBruce Richardson 
2199a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L2_ETHER] =
2299a2dd95SBruce Richardson 		PKT_CLS_NEXT_IP4_LOOKUP,
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L2_ETHER] =
2599a2dd95SBruce Richardson 		PKT_CLS_NEXT_IP4_LOOKUP,
2699a2dd95SBruce Richardson 
2799a2dd95SBruce Richardson 	[RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
2899a2dd95SBruce Richardson 		PKT_CLS_NEXT_IP4_LOOKUP,
2920365d79SSunil Kumar Kori 
3020365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6] = PKT_CLS_NEXT_IP6_LOOKUP,
3120365d79SSunil Kumar Kori 
3220365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6_EXT] = PKT_CLS_NEXT_IP6_LOOKUP,
3320365d79SSunil Kumar Kori 
3420365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6_EXT_UNKNOWN] = PKT_CLS_NEXT_IP6_LOOKUP,
3520365d79SSunil Kumar Kori 
3620365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L2_ETHER] = PKT_CLS_NEXT_IP6_LOOKUP,
3720365d79SSunil Kumar Kori 
3820365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L2_ETHER] = PKT_CLS_NEXT_IP6_LOOKUP,
3920365d79SSunil Kumar Kori 
4020365d79SSunil Kumar Kori 	[RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
4120365d79SSunil Kumar Kori 		PKT_CLS_NEXT_IP6_LOOKUP,
4299a2dd95SBruce Richardson };
4399a2dd95SBruce Richardson 
4499a2dd95SBruce Richardson static uint16_t
pkt_cls_node_process(struct rte_graph * graph,struct rte_node * node,void ** objs,uint16_t nb_objs)4599a2dd95SBruce Richardson pkt_cls_node_process(struct rte_graph *graph, struct rte_node *node,
4699a2dd95SBruce Richardson 		     void **objs, uint16_t nb_objs)
4799a2dd95SBruce Richardson {
4899a2dd95SBruce Richardson 	struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts;
4999a2dd95SBruce Richardson 	uint8_t l0, l1, l2, l3, last_type;
5099a2dd95SBruce Richardson 	uint16_t next_index, n_left_from;
5199a2dd95SBruce Richardson 	uint16_t held = 0, last_spec = 0;
5299a2dd95SBruce Richardson 	struct pkt_cls_node_ctx *ctx;
5399a2dd95SBruce Richardson 	void **to_next, **from;
5499a2dd95SBruce Richardson 	uint32_t i;
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson 	pkts = (struct rte_mbuf **)objs;
5799a2dd95SBruce Richardson 	from = objs;
5899a2dd95SBruce Richardson 	n_left_from = nb_objs;
5999a2dd95SBruce Richardson 
6099a2dd95SBruce Richardson 	for (i = OBJS_PER_CLINE; i < RTE_GRAPH_BURST_SIZE; i += OBJS_PER_CLINE)
6199a2dd95SBruce Richardson 		rte_prefetch0(&objs[i]);
6299a2dd95SBruce Richardson 
6399a2dd95SBruce Richardson #if RTE_GRAPH_BURST_SIZE > 64
6499a2dd95SBruce Richardson 	for (i = 0; i < 4 && i < n_left_from; i++)
6599a2dd95SBruce Richardson 		rte_prefetch0(pkts[i]);
6699a2dd95SBruce Richardson #endif
6799a2dd95SBruce Richardson 
6899a2dd95SBruce Richardson 	ctx = (struct pkt_cls_node_ctx *)node->ctx;
6999a2dd95SBruce Richardson 	last_type = ctx->l2l3_type;
7099a2dd95SBruce Richardson 	next_index = p_nxt[last_type];
7199a2dd95SBruce Richardson 
7299a2dd95SBruce Richardson 	/* Get stream for the speculated next node */
7399a2dd95SBruce Richardson 	to_next = rte_node_next_stream_get(graph, node,
7499a2dd95SBruce Richardson 					   next_index, nb_objs);
7599a2dd95SBruce Richardson 	while (n_left_from >= 4) {
7699a2dd95SBruce Richardson #if RTE_GRAPH_BURST_SIZE > 64
7799a2dd95SBruce Richardson 		if (likely(n_left_from > 7)) {
7899a2dd95SBruce Richardson 			rte_prefetch0(pkts[4]);
7999a2dd95SBruce Richardson 			rte_prefetch0(pkts[5]);
8099a2dd95SBruce Richardson 			rte_prefetch0(pkts[6]);
8199a2dd95SBruce Richardson 			rte_prefetch0(pkts[7]);
8299a2dd95SBruce Richardson 		}
8399a2dd95SBruce Richardson #endif
8499a2dd95SBruce Richardson 
8599a2dd95SBruce Richardson 		mbuf0 = pkts[0];
8699a2dd95SBruce Richardson 		mbuf1 = pkts[1];
8799a2dd95SBruce Richardson 		mbuf2 = pkts[2];
8899a2dd95SBruce Richardson 		mbuf3 = pkts[3];
8999a2dd95SBruce Richardson 		pkts += 4;
9099a2dd95SBruce Richardson 		n_left_from -= 4;
9199a2dd95SBruce Richardson 
9299a2dd95SBruce Richardson 		l0 = mbuf0->packet_type &
9399a2dd95SBruce Richardson 			(RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
9499a2dd95SBruce Richardson 		l1 = mbuf1->packet_type &
9599a2dd95SBruce Richardson 			(RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
9699a2dd95SBruce Richardson 		l2 = mbuf2->packet_type &
9799a2dd95SBruce Richardson 			(RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
9899a2dd95SBruce Richardson 		l3 = mbuf3->packet_type &
9999a2dd95SBruce Richardson 			(RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
10099a2dd95SBruce Richardson 
10199a2dd95SBruce Richardson 		/* Check if they are destined to same
10299a2dd95SBruce Richardson 		 * next node based on l2l3 packet type.
10399a2dd95SBruce Richardson 		 */
10499a2dd95SBruce Richardson 		uint8_t fix_spec = (last_type ^ l0) | (last_type ^ l1) |
10599a2dd95SBruce Richardson 			(last_type ^ l2) | (last_type ^ l3);
10699a2dd95SBruce Richardson 
10799a2dd95SBruce Richardson 		if (unlikely(fix_spec)) {
10899a2dd95SBruce Richardson 			/* Copy things successfully speculated till now */
10999a2dd95SBruce Richardson 			rte_memcpy(to_next, from,
11099a2dd95SBruce Richardson 				   last_spec * sizeof(from[0]));
11199a2dd95SBruce Richardson 			from += last_spec;
11299a2dd95SBruce Richardson 			to_next += last_spec;
11399a2dd95SBruce Richardson 			held += last_spec;
11499a2dd95SBruce Richardson 			last_spec = 0;
11599a2dd95SBruce Richardson 
11699a2dd95SBruce Richardson 			/* l0 */
11799a2dd95SBruce Richardson 			if (p_nxt[l0] == next_index) {
11899a2dd95SBruce Richardson 				to_next[0] = from[0];
11999a2dd95SBruce Richardson 				to_next++;
12099a2dd95SBruce Richardson 				held++;
12199a2dd95SBruce Richardson 			} else {
12299a2dd95SBruce Richardson 				rte_node_enqueue_x1(graph, node,
12399a2dd95SBruce Richardson 						    p_nxt[l0], from[0]);
12499a2dd95SBruce Richardson 			}
12599a2dd95SBruce Richardson 
12699a2dd95SBruce Richardson 			/* l1 */
12799a2dd95SBruce Richardson 			if (p_nxt[l1] == next_index) {
12899a2dd95SBruce Richardson 				to_next[0] = from[1];
12999a2dd95SBruce Richardson 				to_next++;
13099a2dd95SBruce Richardson 				held++;
13199a2dd95SBruce Richardson 			} else {
13299a2dd95SBruce Richardson 				rte_node_enqueue_x1(graph, node,
13399a2dd95SBruce Richardson 						    p_nxt[l1], from[1]);
13499a2dd95SBruce Richardson 			}
13599a2dd95SBruce Richardson 
13699a2dd95SBruce Richardson 			/* l2 */
13799a2dd95SBruce Richardson 			if (p_nxt[l2] == next_index) {
13899a2dd95SBruce Richardson 				to_next[0] = from[2];
13999a2dd95SBruce Richardson 				to_next++;
14099a2dd95SBruce Richardson 				held++;
14199a2dd95SBruce Richardson 			} else {
14299a2dd95SBruce Richardson 				rte_node_enqueue_x1(graph, node,
14399a2dd95SBruce Richardson 						    p_nxt[l2], from[2]);
14499a2dd95SBruce Richardson 			}
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson 			/* l3 */
14799a2dd95SBruce Richardson 			if (p_nxt[l3] == next_index) {
14899a2dd95SBruce Richardson 				to_next[0] = from[3];
14999a2dd95SBruce Richardson 				to_next++;
15099a2dd95SBruce Richardson 				held++;
15199a2dd95SBruce Richardson 			} else {
15299a2dd95SBruce Richardson 				rte_node_enqueue_x1(graph, node,
15399a2dd95SBruce Richardson 						    p_nxt[l3], from[3]);
15499a2dd95SBruce Richardson 			}
15599a2dd95SBruce Richardson 
15699a2dd95SBruce Richardson 			/* Update speculated ptype */
15799a2dd95SBruce Richardson 			if ((last_type != l3) && (l2 == l3) &&
15899a2dd95SBruce Richardson 			    (next_index != p_nxt[l3])) {
15999a2dd95SBruce Richardson 				/* Put the current stream for
16099a2dd95SBruce Richardson 				 * speculated ltype.
16199a2dd95SBruce Richardson 				 */
16299a2dd95SBruce Richardson 				rte_node_next_stream_put(graph, node,
16399a2dd95SBruce Richardson 							 next_index, held);
16499a2dd95SBruce Richardson 
16599a2dd95SBruce Richardson 				held = 0;
16699a2dd95SBruce Richardson 
16799a2dd95SBruce Richardson 				/* Get next stream for new ltype */
16899a2dd95SBruce Richardson 				next_index = p_nxt[l3];
16999a2dd95SBruce Richardson 				last_type = l3;
17099a2dd95SBruce Richardson 				to_next = rte_node_next_stream_get(graph, node,
17199a2dd95SBruce Richardson 								   next_index,
17299a2dd95SBruce Richardson 								   nb_objs);
17399a2dd95SBruce Richardson 			} else if (next_index == p_nxt[l3]) {
17499a2dd95SBruce Richardson 				last_type = l3;
17599a2dd95SBruce Richardson 			}
17699a2dd95SBruce Richardson 
17799a2dd95SBruce Richardson 			from += 4;
17899a2dd95SBruce Richardson 		} else {
17999a2dd95SBruce Richardson 			last_spec += 4;
18099a2dd95SBruce Richardson 		}
18199a2dd95SBruce Richardson 	}
18299a2dd95SBruce Richardson 
18399a2dd95SBruce Richardson 	while (n_left_from > 0) {
18499a2dd95SBruce Richardson 		mbuf0 = pkts[0];
18599a2dd95SBruce Richardson 
18699a2dd95SBruce Richardson 		pkts += 1;
18799a2dd95SBruce Richardson 		n_left_from -= 1;
18899a2dd95SBruce Richardson 
18999a2dd95SBruce Richardson 		l0 = mbuf0->packet_type &
19099a2dd95SBruce Richardson 			(RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
19199a2dd95SBruce Richardson 		if (unlikely((l0 != last_type) &&
19299a2dd95SBruce Richardson 			     (p_nxt[l0] != next_index))) {
19399a2dd95SBruce Richardson 			/* Copy things successfully speculated till now */
19499a2dd95SBruce Richardson 			rte_memcpy(to_next, from,
19599a2dd95SBruce Richardson 				   last_spec * sizeof(from[0]));
19699a2dd95SBruce Richardson 			from += last_spec;
19799a2dd95SBruce Richardson 			to_next += last_spec;
19899a2dd95SBruce Richardson 			held += last_spec;
19999a2dd95SBruce Richardson 			last_spec = 0;
20099a2dd95SBruce Richardson 
20199a2dd95SBruce Richardson 			rte_node_enqueue_x1(graph, node,
20299a2dd95SBruce Richardson 					    p_nxt[l0], from[0]);
20399a2dd95SBruce Richardson 			from += 1;
20499a2dd95SBruce Richardson 		} else {
20599a2dd95SBruce Richardson 			last_spec += 1;
20699a2dd95SBruce Richardson 		}
20799a2dd95SBruce Richardson 	}
20899a2dd95SBruce Richardson 
20999a2dd95SBruce Richardson 	/* !!! Home run !!! */
21099a2dd95SBruce Richardson 	if (likely(last_spec == nb_objs)) {
21199a2dd95SBruce Richardson 		rte_node_next_stream_move(graph, node, next_index);
21299a2dd95SBruce Richardson 		return nb_objs;
21399a2dd95SBruce Richardson 	}
21499a2dd95SBruce Richardson 
21599a2dd95SBruce Richardson 	held += last_spec;
21699a2dd95SBruce Richardson 	/* Copy things successfully speculated till now */
21799a2dd95SBruce Richardson 	rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
21899a2dd95SBruce Richardson 	rte_node_next_stream_put(graph, node, next_index, held);
21999a2dd95SBruce Richardson 
22099a2dd95SBruce Richardson 	ctx->l2l3_type = last_type;
22199a2dd95SBruce Richardson 	return nb_objs;
22299a2dd95SBruce Richardson }
22399a2dd95SBruce Richardson 
22499a2dd95SBruce Richardson /* Packet Classification Node */
22599a2dd95SBruce Richardson struct rte_node_register pkt_cls_node = {
22699a2dd95SBruce Richardson 	.process = pkt_cls_node_process,
22799a2dd95SBruce Richardson 	.name = "pkt_cls",
22899a2dd95SBruce Richardson 
22999a2dd95SBruce Richardson 	.nb_edges = PKT_CLS_NEXT_MAX,
23099a2dd95SBruce Richardson 	.next_nodes = {
23199a2dd95SBruce Richardson 		/* Pkt drop node starts at '0' */
23299a2dd95SBruce Richardson 		[PKT_CLS_NEXT_PKT_DROP] = "pkt_drop",
23399a2dd95SBruce Richardson 		[PKT_CLS_NEXT_IP4_LOOKUP] = "ip4_lookup",
23420365d79SSunil Kumar Kori 		[PKT_CLS_NEXT_IP6_LOOKUP] = "ip6_lookup",
23599a2dd95SBruce Richardson 	},
23699a2dd95SBruce Richardson };
23799a2dd95SBruce Richardson RTE_NODE_REGISTER(pkt_cls_node);
238