xref: /dpdk/examples/ip_pipeline/pipeline.c (revision d75c371e9b46565bab99e40f74973bda73e315e1)
1*d75c371eSJasvinder Singh /* SPDX-License-Identifier: BSD-3-Clause
2*d75c371eSJasvinder Singh  * Copyright(c) 2010-2018 Intel Corporation
3*d75c371eSJasvinder Singh  */
4*d75c371eSJasvinder Singh 
5*d75c371eSJasvinder Singh #include <stdlib.h>
6*d75c371eSJasvinder Singh #include <string.h>
7*d75c371eSJasvinder Singh 
8*d75c371eSJasvinder Singh #include <rte_common.h>
9*d75c371eSJasvinder Singh #include <rte_ip.h>
10*d75c371eSJasvinder Singh #include <rte_tcp.h>
11*d75c371eSJasvinder Singh 
12*d75c371eSJasvinder Singh #include <rte_port_ethdev.h>
13*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
14*d75c371eSJasvinder Singh #include <rte_port_kni.h>
15*d75c371eSJasvinder Singh #endif
16*d75c371eSJasvinder Singh #include <rte_port_ring.h>
17*d75c371eSJasvinder Singh #include <rte_port_source_sink.h>
18*d75c371eSJasvinder Singh #include <rte_port_fd.h>
19*d75c371eSJasvinder Singh #include <rte_port_sched.h>
20*d75c371eSJasvinder Singh 
21*d75c371eSJasvinder Singh #include <rte_table_acl.h>
22*d75c371eSJasvinder Singh #include <rte_table_array.h>
23*d75c371eSJasvinder Singh #include <rte_table_hash.h>
24*d75c371eSJasvinder Singh #include <rte_table_lpm.h>
25*d75c371eSJasvinder Singh #include <rte_table_lpm_ipv6.h>
26*d75c371eSJasvinder Singh #include <rte_table_stub.h>
27*d75c371eSJasvinder Singh 
28*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
29*d75c371eSJasvinder Singh #include "kni.h"
30*d75c371eSJasvinder Singh #endif
31*d75c371eSJasvinder Singh #include "link.h"
32*d75c371eSJasvinder Singh #include "mempool.h"
33*d75c371eSJasvinder Singh #include "pipeline.h"
34*d75c371eSJasvinder Singh #include "tap.h"
35*d75c371eSJasvinder Singh #include "tmgr.h"
36*d75c371eSJasvinder Singh #include "swq.h"
37*d75c371eSJasvinder Singh 
38*d75c371eSJasvinder Singh #include "hash_func.h"
39*d75c371eSJasvinder Singh 
40*d75c371eSJasvinder Singh #ifndef PIPELINE_MSGQ_SIZE
41*d75c371eSJasvinder Singh #define PIPELINE_MSGQ_SIZE                                 64
42*d75c371eSJasvinder Singh #endif
43*d75c371eSJasvinder Singh 
44*d75c371eSJasvinder Singh #ifndef TABLE_LPM_NUMBER_TBL8
45*d75c371eSJasvinder Singh #define TABLE_LPM_NUMBER_TBL8                              256
46*d75c371eSJasvinder Singh #endif
47*d75c371eSJasvinder Singh 
48*d75c371eSJasvinder Singh static struct pipeline_list pipeline_list;
49*d75c371eSJasvinder Singh 
50*d75c371eSJasvinder Singh int
51*d75c371eSJasvinder Singh pipeline_init(void)
52*d75c371eSJasvinder Singh {
53*d75c371eSJasvinder Singh 	TAILQ_INIT(&pipeline_list);
54*d75c371eSJasvinder Singh 
55*d75c371eSJasvinder Singh 	return 0;
56*d75c371eSJasvinder Singh }
57*d75c371eSJasvinder Singh 
58*d75c371eSJasvinder Singh struct pipeline *
59*d75c371eSJasvinder Singh pipeline_find(const char *name)
60*d75c371eSJasvinder Singh {
61*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
62*d75c371eSJasvinder Singh 
63*d75c371eSJasvinder Singh 	if (name == NULL)
64*d75c371eSJasvinder Singh 		return NULL;
65*d75c371eSJasvinder Singh 
66*d75c371eSJasvinder Singh 	TAILQ_FOREACH(pipeline, &pipeline_list, node)
67*d75c371eSJasvinder Singh 		if (strcmp(name, pipeline->name) == 0)
68*d75c371eSJasvinder Singh 			return pipeline;
69*d75c371eSJasvinder Singh 
70*d75c371eSJasvinder Singh 	return NULL;
71*d75c371eSJasvinder Singh }
72*d75c371eSJasvinder Singh 
73*d75c371eSJasvinder Singh struct pipeline *
74*d75c371eSJasvinder Singh pipeline_create(const char *name, struct pipeline_params *params)
75*d75c371eSJasvinder Singh {
76*d75c371eSJasvinder Singh 	char msgq_name[NAME_MAX];
77*d75c371eSJasvinder Singh 	struct rte_pipeline_params pp;
78*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
79*d75c371eSJasvinder Singh 	struct rte_pipeline *p;
80*d75c371eSJasvinder Singh 	struct rte_ring *msgq_req;
81*d75c371eSJasvinder Singh 	struct rte_ring *msgq_rsp;
82*d75c371eSJasvinder Singh 
83*d75c371eSJasvinder Singh 	/* Check input params */
84*d75c371eSJasvinder Singh 	if ((name == NULL) ||
85*d75c371eSJasvinder Singh 		pipeline_find(name) ||
86*d75c371eSJasvinder Singh 		(params == NULL) ||
87*d75c371eSJasvinder Singh 		(params->timer_period_ms == 0))
88*d75c371eSJasvinder Singh 		return NULL;
89*d75c371eSJasvinder Singh 
90*d75c371eSJasvinder Singh 	/* Resource create */
91*d75c371eSJasvinder Singh 	snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-REQ", name);
92*d75c371eSJasvinder Singh 
93*d75c371eSJasvinder Singh 	msgq_req = rte_ring_create(msgq_name,
94*d75c371eSJasvinder Singh 		PIPELINE_MSGQ_SIZE,
95*d75c371eSJasvinder Singh 		params->cpu_id,
96*d75c371eSJasvinder Singh 		RING_F_SP_ENQ | RING_F_SC_DEQ);
97*d75c371eSJasvinder Singh 	if (msgq_req == NULL)
98*d75c371eSJasvinder Singh 		return NULL;
99*d75c371eSJasvinder Singh 
100*d75c371eSJasvinder Singh 	snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-RSP", name);
101*d75c371eSJasvinder Singh 
102*d75c371eSJasvinder Singh 	msgq_rsp = rte_ring_create(msgq_name,
103*d75c371eSJasvinder Singh 		PIPELINE_MSGQ_SIZE,
104*d75c371eSJasvinder Singh 		params->cpu_id,
105*d75c371eSJasvinder Singh 		RING_F_SP_ENQ | RING_F_SC_DEQ);
106*d75c371eSJasvinder Singh 	if (msgq_rsp == NULL) {
107*d75c371eSJasvinder Singh 		rte_ring_free(msgq_req);
108*d75c371eSJasvinder Singh 		return NULL;
109*d75c371eSJasvinder Singh 	}
110*d75c371eSJasvinder Singh 
111*d75c371eSJasvinder Singh 	pp.name = name;
112*d75c371eSJasvinder Singh 	pp.socket_id = (int) params->cpu_id;
113*d75c371eSJasvinder Singh 	pp.offset_port_id = params->offset_port_id;
114*d75c371eSJasvinder Singh 
115*d75c371eSJasvinder Singh 	p = rte_pipeline_create(&pp);
116*d75c371eSJasvinder Singh 	if (p == NULL) {
117*d75c371eSJasvinder Singh 		rte_ring_free(msgq_rsp);
118*d75c371eSJasvinder Singh 		rte_ring_free(msgq_req);
119*d75c371eSJasvinder Singh 		return NULL;
120*d75c371eSJasvinder Singh 	}
121*d75c371eSJasvinder Singh 
122*d75c371eSJasvinder Singh 	/* Node allocation */
123*d75c371eSJasvinder Singh 	pipeline = calloc(1, sizeof(struct pipeline));
124*d75c371eSJasvinder Singh 	if (pipeline == NULL) {
125*d75c371eSJasvinder Singh 		rte_pipeline_free(p);
126*d75c371eSJasvinder Singh 		rte_ring_free(msgq_rsp);
127*d75c371eSJasvinder Singh 		rte_ring_free(msgq_req);
128*d75c371eSJasvinder Singh 		return NULL;
129*d75c371eSJasvinder Singh 	}
130*d75c371eSJasvinder Singh 
131*d75c371eSJasvinder Singh 	/* Node fill in */
132*d75c371eSJasvinder Singh 	strncpy(pipeline->name, name, sizeof(pipeline->name));
133*d75c371eSJasvinder Singh 	pipeline->p = p;
134*d75c371eSJasvinder Singh 	pipeline->n_ports_in = 0;
135*d75c371eSJasvinder Singh 	pipeline->n_ports_out = 0;
136*d75c371eSJasvinder Singh 	pipeline->n_tables = 0;
137*d75c371eSJasvinder Singh 	pipeline->msgq_req = msgq_req;
138*d75c371eSJasvinder Singh 	pipeline->msgq_rsp = msgq_rsp;
139*d75c371eSJasvinder Singh 	pipeline->timer_period_ms = params->timer_period_ms;
140*d75c371eSJasvinder Singh 	pipeline->enabled = 0;
141*d75c371eSJasvinder Singh 	pipeline->cpu_id = params->cpu_id;
142*d75c371eSJasvinder Singh 
143*d75c371eSJasvinder Singh 	/* Node add to list */
144*d75c371eSJasvinder Singh 	TAILQ_INSERT_TAIL(&pipeline_list, pipeline, node);
145*d75c371eSJasvinder Singh 
146*d75c371eSJasvinder Singh 	return pipeline;
147*d75c371eSJasvinder Singh }
148*d75c371eSJasvinder Singh 
149*d75c371eSJasvinder Singh int
150*d75c371eSJasvinder Singh pipeline_port_in_create(const char *pipeline_name,
151*d75c371eSJasvinder Singh 	struct port_in_params *params,
152*d75c371eSJasvinder Singh 	int enabled)
153*d75c371eSJasvinder Singh {
154*d75c371eSJasvinder Singh 	struct rte_pipeline_port_in_params p;
155*d75c371eSJasvinder Singh 
156*d75c371eSJasvinder Singh 	union {
157*d75c371eSJasvinder Singh 		struct rte_port_ethdev_reader_params ethdev;
158*d75c371eSJasvinder Singh 		struct rte_port_ring_reader_params ring;
159*d75c371eSJasvinder Singh 		struct rte_port_sched_reader_params sched;
160*d75c371eSJasvinder Singh 		struct rte_port_fd_reader_params fd;
161*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
162*d75c371eSJasvinder Singh 		struct rte_port_kni_reader_params kni;
163*d75c371eSJasvinder Singh #endif
164*d75c371eSJasvinder Singh 		struct rte_port_source_params source;
165*d75c371eSJasvinder Singh 	} pp;
166*d75c371eSJasvinder Singh 
167*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
168*d75c371eSJasvinder Singh 	struct port_in *port_in;
169*d75c371eSJasvinder Singh 	struct port_in_action_profile *ap;
170*d75c371eSJasvinder Singh 	struct rte_port_in_action *action;
171*d75c371eSJasvinder Singh 	uint32_t port_id;
172*d75c371eSJasvinder Singh 	int status;
173*d75c371eSJasvinder Singh 
174*d75c371eSJasvinder Singh 	memset(&p, 0, sizeof(p));
175*d75c371eSJasvinder Singh 	memset(&pp, 0, sizeof(pp));
176*d75c371eSJasvinder Singh 
177*d75c371eSJasvinder Singh 	/* Check input params */
178*d75c371eSJasvinder Singh 	if ((pipeline_name == NULL) ||
179*d75c371eSJasvinder Singh 		(params == NULL) ||
180*d75c371eSJasvinder Singh 		(params->burst_size == 0) ||
181*d75c371eSJasvinder Singh 		(params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
182*d75c371eSJasvinder Singh 		return -1;
183*d75c371eSJasvinder Singh 
184*d75c371eSJasvinder Singh 	pipeline = pipeline_find(pipeline_name);
185*d75c371eSJasvinder Singh 	if (pipeline == NULL)
186*d75c371eSJasvinder Singh 		return -1;
187*d75c371eSJasvinder Singh 
188*d75c371eSJasvinder Singh 	ap = NULL;
189*d75c371eSJasvinder Singh 	if (params->action_profile_name) {
190*d75c371eSJasvinder Singh 		ap = port_in_action_profile_find(params->action_profile_name);
191*d75c371eSJasvinder Singh 		if (ap == NULL)
192*d75c371eSJasvinder Singh 			return -1;
193*d75c371eSJasvinder Singh 	}
194*d75c371eSJasvinder Singh 
195*d75c371eSJasvinder Singh 	switch (params->type) {
196*d75c371eSJasvinder Singh 	case PORT_IN_RXQ:
197*d75c371eSJasvinder Singh 	{
198*d75c371eSJasvinder Singh 		struct link *link;
199*d75c371eSJasvinder Singh 
200*d75c371eSJasvinder Singh 		link = link_find(params->dev_name);
201*d75c371eSJasvinder Singh 		if (link == NULL)
202*d75c371eSJasvinder Singh 			return -1;
203*d75c371eSJasvinder Singh 
204*d75c371eSJasvinder Singh 		if (params->rxq.queue_id >= link->n_rxq)
205*d75c371eSJasvinder Singh 			return -1;
206*d75c371eSJasvinder Singh 
207*d75c371eSJasvinder Singh 		pp.ethdev.port_id = link->port_id;
208*d75c371eSJasvinder Singh 		pp.ethdev.queue_id = params->rxq.queue_id;
209*d75c371eSJasvinder Singh 
210*d75c371eSJasvinder Singh 		p.ops = &rte_port_ethdev_reader_ops;
211*d75c371eSJasvinder Singh 		p.arg_create = &pp.ethdev;
212*d75c371eSJasvinder Singh 		break;
213*d75c371eSJasvinder Singh 	}
214*d75c371eSJasvinder Singh 
215*d75c371eSJasvinder Singh 	case PORT_IN_SWQ:
216*d75c371eSJasvinder Singh 	{
217*d75c371eSJasvinder Singh 		struct swq *swq;
218*d75c371eSJasvinder Singh 
219*d75c371eSJasvinder Singh 		swq = swq_find(params->dev_name);
220*d75c371eSJasvinder Singh 		if (swq == NULL)
221*d75c371eSJasvinder Singh 			return -1;
222*d75c371eSJasvinder Singh 
223*d75c371eSJasvinder Singh 		pp.ring.ring = swq->r;
224*d75c371eSJasvinder Singh 
225*d75c371eSJasvinder Singh 		p.ops = &rte_port_ring_reader_ops;
226*d75c371eSJasvinder Singh 		p.arg_create = &pp.ring;
227*d75c371eSJasvinder Singh 		break;
228*d75c371eSJasvinder Singh 	}
229*d75c371eSJasvinder Singh 
230*d75c371eSJasvinder Singh 	case PORT_IN_TMGR:
231*d75c371eSJasvinder Singh 	{
232*d75c371eSJasvinder Singh 		struct tmgr_port *tmgr_port;
233*d75c371eSJasvinder Singh 
234*d75c371eSJasvinder Singh 		tmgr_port = tmgr_port_find(params->dev_name);
235*d75c371eSJasvinder Singh 		if (tmgr_port == NULL)
236*d75c371eSJasvinder Singh 			return -1;
237*d75c371eSJasvinder Singh 
238*d75c371eSJasvinder Singh 		pp.sched.sched = tmgr_port->s;
239*d75c371eSJasvinder Singh 
240*d75c371eSJasvinder Singh 		p.ops = &rte_port_sched_reader_ops;
241*d75c371eSJasvinder Singh 		p.arg_create = &pp.sched;
242*d75c371eSJasvinder Singh 		break;
243*d75c371eSJasvinder Singh 	}
244*d75c371eSJasvinder Singh 
245*d75c371eSJasvinder Singh 	case PORT_IN_TAP:
246*d75c371eSJasvinder Singh 	{
247*d75c371eSJasvinder Singh 		struct tap *tap;
248*d75c371eSJasvinder Singh 		struct mempool *mempool;
249*d75c371eSJasvinder Singh 
250*d75c371eSJasvinder Singh 		tap = tap_find(params->dev_name);
251*d75c371eSJasvinder Singh 		mempool = mempool_find(params->tap.mempool_name);
252*d75c371eSJasvinder Singh 		if ((tap == NULL) || (mempool == NULL))
253*d75c371eSJasvinder Singh 			return -1;
254*d75c371eSJasvinder Singh 
255*d75c371eSJasvinder Singh 		pp.fd.fd = tap->fd;
256*d75c371eSJasvinder Singh 		pp.fd.mempool = mempool->m;
257*d75c371eSJasvinder Singh 		pp.fd.mtu = params->tap.mtu;
258*d75c371eSJasvinder Singh 
259*d75c371eSJasvinder Singh 		p.ops = &rte_port_fd_reader_ops;
260*d75c371eSJasvinder Singh 		p.arg_create = &pp.fd;
261*d75c371eSJasvinder Singh 		break;
262*d75c371eSJasvinder Singh 	}
263*d75c371eSJasvinder Singh 
264*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
265*d75c371eSJasvinder Singh 	case PORT_IN_KNI:
266*d75c371eSJasvinder Singh 	{
267*d75c371eSJasvinder Singh 		struct kni *kni;
268*d75c371eSJasvinder Singh 
269*d75c371eSJasvinder Singh 		kni = kni_find(params->dev_name);
270*d75c371eSJasvinder Singh 		if (kni == NULL)
271*d75c371eSJasvinder Singh 			return -1;
272*d75c371eSJasvinder Singh 
273*d75c371eSJasvinder Singh 		pp.kni.kni = kni->k;
274*d75c371eSJasvinder Singh 
275*d75c371eSJasvinder Singh 		p.ops = &rte_port_kni_reader_ops;
276*d75c371eSJasvinder Singh 		p.arg_create = &pp.kni;
277*d75c371eSJasvinder Singh 		break;
278*d75c371eSJasvinder Singh 	}
279*d75c371eSJasvinder Singh #endif
280*d75c371eSJasvinder Singh 
281*d75c371eSJasvinder Singh 	case PORT_IN_SOURCE:
282*d75c371eSJasvinder Singh 	{
283*d75c371eSJasvinder Singh 		struct mempool *mempool;
284*d75c371eSJasvinder Singh 
285*d75c371eSJasvinder Singh 		mempool = mempool_find(params->source.mempool_name);
286*d75c371eSJasvinder Singh 		if (mempool == NULL)
287*d75c371eSJasvinder Singh 			return -1;
288*d75c371eSJasvinder Singh 
289*d75c371eSJasvinder Singh 		pp.source.mempool = mempool->m;
290*d75c371eSJasvinder Singh 		pp.source.file_name = params->source.file_name;
291*d75c371eSJasvinder Singh 		pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
292*d75c371eSJasvinder Singh 
293*d75c371eSJasvinder Singh 		p.ops = &rte_port_source_ops;
294*d75c371eSJasvinder Singh 		p.arg_create = &pp.source;
295*d75c371eSJasvinder Singh 		break;
296*d75c371eSJasvinder Singh 	}
297*d75c371eSJasvinder Singh 
298*d75c371eSJasvinder Singh 	default:
299*d75c371eSJasvinder Singh 		return -1;
300*d75c371eSJasvinder Singh 	}
301*d75c371eSJasvinder Singh 
302*d75c371eSJasvinder Singh 	p.burst_size = params->burst_size;
303*d75c371eSJasvinder Singh 
304*d75c371eSJasvinder Singh 	/* Resource create */
305*d75c371eSJasvinder Singh 	action = NULL;
306*d75c371eSJasvinder Singh 	p.f_action = NULL;
307*d75c371eSJasvinder Singh 	p.arg_ah = NULL;
308*d75c371eSJasvinder Singh 
309*d75c371eSJasvinder Singh 	if (ap) {
310*d75c371eSJasvinder Singh 		action = rte_port_in_action_create(ap->ap,
311*d75c371eSJasvinder Singh 			pipeline->cpu_id);
312*d75c371eSJasvinder Singh 		if (action == NULL)
313*d75c371eSJasvinder Singh 			return -1;
314*d75c371eSJasvinder Singh 
315*d75c371eSJasvinder Singh 		status = rte_port_in_action_params_get(
316*d75c371eSJasvinder Singh 			action,
317*d75c371eSJasvinder Singh 			&p);
318*d75c371eSJasvinder Singh 		if (status) {
319*d75c371eSJasvinder Singh 			rte_port_in_action_free(action);
320*d75c371eSJasvinder Singh 			return -1;
321*d75c371eSJasvinder Singh 		}
322*d75c371eSJasvinder Singh 	}
323*d75c371eSJasvinder Singh 
324*d75c371eSJasvinder Singh 	status = rte_pipeline_port_in_create(pipeline->p,
325*d75c371eSJasvinder Singh 		&p,
326*d75c371eSJasvinder Singh 		&port_id);
327*d75c371eSJasvinder Singh 	if (status) {
328*d75c371eSJasvinder Singh 		rte_port_in_action_free(action);
329*d75c371eSJasvinder Singh 		return -1;
330*d75c371eSJasvinder Singh 	}
331*d75c371eSJasvinder Singh 
332*d75c371eSJasvinder Singh 	if (enabled)
333*d75c371eSJasvinder Singh 		rte_pipeline_port_in_enable(pipeline->p, port_id);
334*d75c371eSJasvinder Singh 
335*d75c371eSJasvinder Singh 	/* Pipeline */
336*d75c371eSJasvinder Singh 	port_in = &pipeline->port_in[pipeline->n_ports_in];
337*d75c371eSJasvinder Singh 	memcpy(&port_in->params, params, sizeof(*params));
338*d75c371eSJasvinder Singh 	port_in->ap = ap;
339*d75c371eSJasvinder Singh 	port_in->a = action;
340*d75c371eSJasvinder Singh 	pipeline->n_ports_in++;
341*d75c371eSJasvinder Singh 
342*d75c371eSJasvinder Singh 	return 0;
343*d75c371eSJasvinder Singh }
344*d75c371eSJasvinder Singh 
345*d75c371eSJasvinder Singh int
346*d75c371eSJasvinder Singh pipeline_port_in_connect_to_table(const char *pipeline_name,
347*d75c371eSJasvinder Singh 	uint32_t port_id,
348*d75c371eSJasvinder Singh 	uint32_t table_id)
349*d75c371eSJasvinder Singh {
350*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
351*d75c371eSJasvinder Singh 	int status;
352*d75c371eSJasvinder Singh 
353*d75c371eSJasvinder Singh 	/* Check input params */
354*d75c371eSJasvinder Singh 	if (pipeline_name == NULL)
355*d75c371eSJasvinder Singh 		return -1;
356*d75c371eSJasvinder Singh 
357*d75c371eSJasvinder Singh 	pipeline = pipeline_find(pipeline_name);
358*d75c371eSJasvinder Singh 	if ((pipeline == NULL) ||
359*d75c371eSJasvinder Singh 		(port_id >= pipeline->n_ports_in) ||
360*d75c371eSJasvinder Singh 		(table_id >= pipeline->n_tables))
361*d75c371eSJasvinder Singh 		return -1;
362*d75c371eSJasvinder Singh 
363*d75c371eSJasvinder Singh 	/* Resource */
364*d75c371eSJasvinder Singh 	status = rte_pipeline_port_in_connect_to_table(pipeline->p,
365*d75c371eSJasvinder Singh 		port_id,
366*d75c371eSJasvinder Singh 		table_id);
367*d75c371eSJasvinder Singh 
368*d75c371eSJasvinder Singh 	return status;
369*d75c371eSJasvinder Singh 
370*d75c371eSJasvinder Singh }
371*d75c371eSJasvinder Singh 
372*d75c371eSJasvinder Singh int
373*d75c371eSJasvinder Singh pipeline_port_out_create(const char *pipeline_name,
374*d75c371eSJasvinder Singh 	struct port_out_params *params)
375*d75c371eSJasvinder Singh {
376*d75c371eSJasvinder Singh 	struct rte_pipeline_port_out_params p;
377*d75c371eSJasvinder Singh 
378*d75c371eSJasvinder Singh 	union {
379*d75c371eSJasvinder Singh 		struct rte_port_ethdev_writer_params ethdev;
380*d75c371eSJasvinder Singh 		struct rte_port_ring_writer_params ring;
381*d75c371eSJasvinder Singh 		struct rte_port_sched_writer_params sched;
382*d75c371eSJasvinder Singh 		struct rte_port_fd_writer_params fd;
383*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
384*d75c371eSJasvinder Singh 		struct rte_port_kni_writer_params kni;
385*d75c371eSJasvinder Singh #endif
386*d75c371eSJasvinder Singh 		struct rte_port_sink_params sink;
387*d75c371eSJasvinder Singh 	} pp;
388*d75c371eSJasvinder Singh 
389*d75c371eSJasvinder Singh 	union {
390*d75c371eSJasvinder Singh 		struct rte_port_ethdev_writer_nodrop_params ethdev;
391*d75c371eSJasvinder Singh 		struct rte_port_ring_writer_nodrop_params ring;
392*d75c371eSJasvinder Singh 		struct rte_port_fd_writer_nodrop_params fd;
393*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
394*d75c371eSJasvinder Singh 		struct rte_port_kni_writer_nodrop_params kni;
395*d75c371eSJasvinder Singh #endif
396*d75c371eSJasvinder Singh 	} pp_nodrop;
397*d75c371eSJasvinder Singh 
398*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
399*d75c371eSJasvinder Singh 	uint32_t port_id;
400*d75c371eSJasvinder Singh 	int status;
401*d75c371eSJasvinder Singh 
402*d75c371eSJasvinder Singh 	memset(&p, 0, sizeof(p));
403*d75c371eSJasvinder Singh 	memset(&pp, 0, sizeof(pp));
404*d75c371eSJasvinder Singh 	memset(&pp_nodrop, 0, sizeof(pp_nodrop));
405*d75c371eSJasvinder Singh 
406*d75c371eSJasvinder Singh 	/* Check input params */
407*d75c371eSJasvinder Singh 	if ((pipeline_name == NULL) ||
408*d75c371eSJasvinder Singh 		(params == NULL) ||
409*d75c371eSJasvinder Singh 		(params->burst_size == 0) ||
410*d75c371eSJasvinder Singh 		(params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
411*d75c371eSJasvinder Singh 		return -1;
412*d75c371eSJasvinder Singh 
413*d75c371eSJasvinder Singh 	pipeline = pipeline_find(pipeline_name);
414*d75c371eSJasvinder Singh 	if (pipeline == NULL)
415*d75c371eSJasvinder Singh 		return -1;
416*d75c371eSJasvinder Singh 
417*d75c371eSJasvinder Singh 	switch (params->type) {
418*d75c371eSJasvinder Singh 	case PORT_OUT_TXQ:
419*d75c371eSJasvinder Singh 	{
420*d75c371eSJasvinder Singh 		struct link *link;
421*d75c371eSJasvinder Singh 
422*d75c371eSJasvinder Singh 		link = link_find(params->dev_name);
423*d75c371eSJasvinder Singh 		if (link == NULL)
424*d75c371eSJasvinder Singh 			return -1;
425*d75c371eSJasvinder Singh 
426*d75c371eSJasvinder Singh 		if (params->txq.queue_id >= link->n_txq)
427*d75c371eSJasvinder Singh 			return -1;
428*d75c371eSJasvinder Singh 
429*d75c371eSJasvinder Singh 		pp.ethdev.port_id = link->port_id;
430*d75c371eSJasvinder Singh 		pp.ethdev.queue_id = params->txq.queue_id;
431*d75c371eSJasvinder Singh 		pp.ethdev.tx_burst_sz = params->burst_size;
432*d75c371eSJasvinder Singh 
433*d75c371eSJasvinder Singh 		pp_nodrop.ethdev.port_id = link->port_id;
434*d75c371eSJasvinder Singh 		pp_nodrop.ethdev.queue_id = params->txq.queue_id;
435*d75c371eSJasvinder Singh 		pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
436*d75c371eSJasvinder Singh 		pp_nodrop.ethdev.n_retries = params->n_retries;
437*d75c371eSJasvinder Singh 
438*d75c371eSJasvinder Singh 		if (params->retry == 0) {
439*d75c371eSJasvinder Singh 			p.ops = &rte_port_ethdev_writer_ops;
440*d75c371eSJasvinder Singh 			p.arg_create = &pp.ethdev;
441*d75c371eSJasvinder Singh 		} else {
442*d75c371eSJasvinder Singh 			p.ops = &rte_port_ethdev_writer_nodrop_ops;
443*d75c371eSJasvinder Singh 			p.arg_create = &pp_nodrop.ethdev;
444*d75c371eSJasvinder Singh 		}
445*d75c371eSJasvinder Singh 		break;
446*d75c371eSJasvinder Singh 	}
447*d75c371eSJasvinder Singh 
448*d75c371eSJasvinder Singh 	case PORT_OUT_SWQ:
449*d75c371eSJasvinder Singh 	{
450*d75c371eSJasvinder Singh 		struct swq *swq;
451*d75c371eSJasvinder Singh 
452*d75c371eSJasvinder Singh 		swq = swq_find(params->dev_name);
453*d75c371eSJasvinder Singh 		if (swq == NULL)
454*d75c371eSJasvinder Singh 			return -1;
455*d75c371eSJasvinder Singh 
456*d75c371eSJasvinder Singh 		pp.ring.ring = swq->r;
457*d75c371eSJasvinder Singh 		pp.ring.tx_burst_sz = params->burst_size;
458*d75c371eSJasvinder Singh 
459*d75c371eSJasvinder Singh 		pp_nodrop.ring.ring = swq->r;
460*d75c371eSJasvinder Singh 		pp_nodrop.ring.tx_burst_sz = params->burst_size;
461*d75c371eSJasvinder Singh 		pp_nodrop.ring.n_retries = params->n_retries;
462*d75c371eSJasvinder Singh 
463*d75c371eSJasvinder Singh 		if (params->retry == 0) {
464*d75c371eSJasvinder Singh 			p.ops = &rte_port_ring_writer_ops;
465*d75c371eSJasvinder Singh 			p.arg_create = &pp.ring;
466*d75c371eSJasvinder Singh 		} else {
467*d75c371eSJasvinder Singh 			p.ops = &rte_port_ring_writer_nodrop_ops;
468*d75c371eSJasvinder Singh 			p.arg_create = &pp_nodrop.ring;
469*d75c371eSJasvinder Singh 		}
470*d75c371eSJasvinder Singh 		break;
471*d75c371eSJasvinder Singh 	}
472*d75c371eSJasvinder Singh 
473*d75c371eSJasvinder Singh 	case PORT_OUT_TMGR:
474*d75c371eSJasvinder Singh 	{
475*d75c371eSJasvinder Singh 		struct tmgr_port *tmgr_port;
476*d75c371eSJasvinder Singh 
477*d75c371eSJasvinder Singh 		tmgr_port = tmgr_port_find(params->dev_name);
478*d75c371eSJasvinder Singh 		if (tmgr_port == NULL)
479*d75c371eSJasvinder Singh 			return -1;
480*d75c371eSJasvinder Singh 
481*d75c371eSJasvinder Singh 		pp.sched.sched = tmgr_port->s;
482*d75c371eSJasvinder Singh 		pp.sched.tx_burst_sz = params->burst_size;
483*d75c371eSJasvinder Singh 
484*d75c371eSJasvinder Singh 		p.ops = &rte_port_sched_writer_ops;
485*d75c371eSJasvinder Singh 		p.arg_create = &pp.sched;
486*d75c371eSJasvinder Singh 		break;
487*d75c371eSJasvinder Singh 	}
488*d75c371eSJasvinder Singh 
489*d75c371eSJasvinder Singh 	case PORT_OUT_TAP:
490*d75c371eSJasvinder Singh 	{
491*d75c371eSJasvinder Singh 		struct tap *tap;
492*d75c371eSJasvinder Singh 
493*d75c371eSJasvinder Singh 		tap = tap_find(params->dev_name);
494*d75c371eSJasvinder Singh 		if (tap == NULL)
495*d75c371eSJasvinder Singh 			return -1;
496*d75c371eSJasvinder Singh 
497*d75c371eSJasvinder Singh 		pp.fd.fd = tap->fd;
498*d75c371eSJasvinder Singh 		pp.fd.tx_burst_sz = params->burst_size;
499*d75c371eSJasvinder Singh 
500*d75c371eSJasvinder Singh 		pp_nodrop.fd.fd = tap->fd;
501*d75c371eSJasvinder Singh 		pp_nodrop.fd.tx_burst_sz = params->burst_size;
502*d75c371eSJasvinder Singh 		pp_nodrop.fd.n_retries = params->n_retries;
503*d75c371eSJasvinder Singh 
504*d75c371eSJasvinder Singh 		if (params->retry == 0) {
505*d75c371eSJasvinder Singh 			p.ops = &rte_port_fd_writer_ops;
506*d75c371eSJasvinder Singh 			p.arg_create = &pp.fd;
507*d75c371eSJasvinder Singh 		} else {
508*d75c371eSJasvinder Singh 			p.ops = &rte_port_fd_writer_nodrop_ops;
509*d75c371eSJasvinder Singh 			p.arg_create = &pp_nodrop.fd;
510*d75c371eSJasvinder Singh 		}
511*d75c371eSJasvinder Singh 		break;
512*d75c371eSJasvinder Singh 	}
513*d75c371eSJasvinder Singh 
514*d75c371eSJasvinder Singh #ifdef RTE_LIBRTE_KNI
515*d75c371eSJasvinder Singh 	case PORT_OUT_KNI:
516*d75c371eSJasvinder Singh 	{
517*d75c371eSJasvinder Singh 		struct kni *kni;
518*d75c371eSJasvinder Singh 
519*d75c371eSJasvinder Singh 		kni = kni_find(params->dev_name);
520*d75c371eSJasvinder Singh 		if (kni == NULL)
521*d75c371eSJasvinder Singh 			return -1;
522*d75c371eSJasvinder Singh 
523*d75c371eSJasvinder Singh 		pp.kni.kni = kni->k;
524*d75c371eSJasvinder Singh 		pp.kni.tx_burst_sz = params->burst_size;
525*d75c371eSJasvinder Singh 
526*d75c371eSJasvinder Singh 		pp_nodrop.kni.kni = kni->k;
527*d75c371eSJasvinder Singh 		pp_nodrop.kni.tx_burst_sz = params->burst_size;
528*d75c371eSJasvinder Singh 		pp_nodrop.kni.n_retries = params->n_retries;
529*d75c371eSJasvinder Singh 
530*d75c371eSJasvinder Singh 		if (params->retry == 0) {
531*d75c371eSJasvinder Singh 			p.ops = &rte_port_kni_writer_ops;
532*d75c371eSJasvinder Singh 			p.arg_create = &pp.kni;
533*d75c371eSJasvinder Singh 		} else {
534*d75c371eSJasvinder Singh 			p.ops = &rte_port_kni_writer_nodrop_ops;
535*d75c371eSJasvinder Singh 			p.arg_create = &pp_nodrop.kni;
536*d75c371eSJasvinder Singh 		}
537*d75c371eSJasvinder Singh 		break;
538*d75c371eSJasvinder Singh 	}
539*d75c371eSJasvinder Singh #endif
540*d75c371eSJasvinder Singh 
541*d75c371eSJasvinder Singh 	case PORT_OUT_SINK:
542*d75c371eSJasvinder Singh 	{
543*d75c371eSJasvinder Singh 		pp.sink.file_name = params->sink.file_name;
544*d75c371eSJasvinder Singh 		pp.sink.max_n_pkts = params->sink.max_n_pkts;
545*d75c371eSJasvinder Singh 
546*d75c371eSJasvinder Singh 		p.ops = &rte_port_sink_ops;
547*d75c371eSJasvinder Singh 		p.arg_create = &pp.sink;
548*d75c371eSJasvinder Singh 		break;
549*d75c371eSJasvinder Singh 	}
550*d75c371eSJasvinder Singh 
551*d75c371eSJasvinder Singh 	default:
552*d75c371eSJasvinder Singh 		return -1;
553*d75c371eSJasvinder Singh 	}
554*d75c371eSJasvinder Singh 
555*d75c371eSJasvinder Singh 	p.f_action = NULL;
556*d75c371eSJasvinder Singh 	p.arg_ah = NULL;
557*d75c371eSJasvinder Singh 
558*d75c371eSJasvinder Singh 	/* Resource create */
559*d75c371eSJasvinder Singh 	status = rte_pipeline_port_out_create(pipeline->p,
560*d75c371eSJasvinder Singh 		&p,
561*d75c371eSJasvinder Singh 		&port_id);
562*d75c371eSJasvinder Singh 
563*d75c371eSJasvinder Singh 	if (status)
564*d75c371eSJasvinder Singh 		return -1;
565*d75c371eSJasvinder Singh 
566*d75c371eSJasvinder Singh 	/* Pipeline */
567*d75c371eSJasvinder Singh 	pipeline->n_ports_out++;
568*d75c371eSJasvinder Singh 
569*d75c371eSJasvinder Singh 	return 0;
570*d75c371eSJasvinder Singh }
571*d75c371eSJasvinder Singh 
572*d75c371eSJasvinder Singh static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
573*d75c371eSJasvinder Singh 	/* Protocol */
574*d75c371eSJasvinder Singh 	[0] = {
575*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_BITMASK,
576*d75c371eSJasvinder Singh 		.size = sizeof(uint8_t),
577*d75c371eSJasvinder Singh 		.field_index = 0,
578*d75c371eSJasvinder Singh 		.input_index = 0,
579*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv4_hdr, next_proto_id),
580*d75c371eSJasvinder Singh 	},
581*d75c371eSJasvinder Singh 
582*d75c371eSJasvinder Singh 	/* Source IP address (IPv4) */
583*d75c371eSJasvinder Singh 	[1] = {
584*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
585*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
586*d75c371eSJasvinder Singh 		.field_index = 1,
587*d75c371eSJasvinder Singh 		.input_index = 1,
588*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv4_hdr, src_addr),
589*d75c371eSJasvinder Singh 	},
590*d75c371eSJasvinder Singh 
591*d75c371eSJasvinder Singh 	/* Destination IP address (IPv4) */
592*d75c371eSJasvinder Singh 	[2] = {
593*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
594*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
595*d75c371eSJasvinder Singh 		.field_index = 2,
596*d75c371eSJasvinder Singh 		.input_index = 2,
597*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv4_hdr, dst_addr),
598*d75c371eSJasvinder Singh 	},
599*d75c371eSJasvinder Singh 
600*d75c371eSJasvinder Singh 	/* Source Port */
601*d75c371eSJasvinder Singh 	[3] = {
602*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_RANGE,
603*d75c371eSJasvinder Singh 		.size = sizeof(uint16_t),
604*d75c371eSJasvinder Singh 		.field_index = 3,
605*d75c371eSJasvinder Singh 		.input_index = 3,
606*d75c371eSJasvinder Singh 		.offset = sizeof(struct ipv4_hdr) +
607*d75c371eSJasvinder Singh 			offsetof(struct tcp_hdr, src_port),
608*d75c371eSJasvinder Singh 	},
609*d75c371eSJasvinder Singh 
610*d75c371eSJasvinder Singh 	/* Destination Port */
611*d75c371eSJasvinder Singh 	[4] = {
612*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_RANGE,
613*d75c371eSJasvinder Singh 		.size = sizeof(uint16_t),
614*d75c371eSJasvinder Singh 		.field_index = 4,
615*d75c371eSJasvinder Singh 		.input_index = 3,
616*d75c371eSJasvinder Singh 		.offset = sizeof(struct ipv4_hdr) +
617*d75c371eSJasvinder Singh 			offsetof(struct tcp_hdr, dst_port),
618*d75c371eSJasvinder Singh 	},
619*d75c371eSJasvinder Singh };
620*d75c371eSJasvinder Singh 
621*d75c371eSJasvinder Singh static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
622*d75c371eSJasvinder Singh 	/* Protocol */
623*d75c371eSJasvinder Singh 	[0] = {
624*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_BITMASK,
625*d75c371eSJasvinder Singh 		.size = sizeof(uint8_t),
626*d75c371eSJasvinder Singh 		.field_index = 0,
627*d75c371eSJasvinder Singh 		.input_index = 0,
628*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, proto),
629*d75c371eSJasvinder Singh 	},
630*d75c371eSJasvinder Singh 
631*d75c371eSJasvinder Singh 	/* Source IP address (IPv6) */
632*d75c371eSJasvinder Singh 	[1] = {
633*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
634*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
635*d75c371eSJasvinder Singh 		.field_index = 1,
636*d75c371eSJasvinder Singh 		.input_index = 1,
637*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, src_addr[0]),
638*d75c371eSJasvinder Singh 	},
639*d75c371eSJasvinder Singh 
640*d75c371eSJasvinder Singh 	[2] = {
641*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
642*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
643*d75c371eSJasvinder Singh 		.field_index = 2,
644*d75c371eSJasvinder Singh 		.input_index = 2,
645*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, src_addr[4]),
646*d75c371eSJasvinder Singh 	},
647*d75c371eSJasvinder Singh 
648*d75c371eSJasvinder Singh 	[3] = {
649*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
650*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
651*d75c371eSJasvinder Singh 		.field_index = 3,
652*d75c371eSJasvinder Singh 		.input_index = 3,
653*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, src_addr[8]),
654*d75c371eSJasvinder Singh 	},
655*d75c371eSJasvinder Singh 
656*d75c371eSJasvinder Singh 	[4] = {
657*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
658*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
659*d75c371eSJasvinder Singh 		.field_index = 4,
660*d75c371eSJasvinder Singh 		.input_index = 4,
661*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, src_addr[12]),
662*d75c371eSJasvinder Singh 	},
663*d75c371eSJasvinder Singh 
664*d75c371eSJasvinder Singh 	/* Destination IP address (IPv6) */
665*d75c371eSJasvinder Singh 	[5] = {
666*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
667*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
668*d75c371eSJasvinder Singh 		.field_index = 5,
669*d75c371eSJasvinder Singh 		.input_index = 5,
670*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, dst_addr[0]),
671*d75c371eSJasvinder Singh 	},
672*d75c371eSJasvinder Singh 
673*d75c371eSJasvinder Singh 	[6] = {
674*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
675*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
676*d75c371eSJasvinder Singh 		.field_index = 6,
677*d75c371eSJasvinder Singh 		.input_index = 6,
678*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, dst_addr[4]),
679*d75c371eSJasvinder Singh 	},
680*d75c371eSJasvinder Singh 
681*d75c371eSJasvinder Singh 	[7] = {
682*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
683*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
684*d75c371eSJasvinder Singh 		.field_index = 7,
685*d75c371eSJasvinder Singh 		.input_index = 7,
686*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, dst_addr[8]),
687*d75c371eSJasvinder Singh 	},
688*d75c371eSJasvinder Singh 
689*d75c371eSJasvinder Singh 	[8] = {
690*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_MASK,
691*d75c371eSJasvinder Singh 		.size = sizeof(uint32_t),
692*d75c371eSJasvinder Singh 		.field_index = 8,
693*d75c371eSJasvinder Singh 		.input_index = 8,
694*d75c371eSJasvinder Singh 		.offset = offsetof(struct ipv6_hdr, dst_addr[12]),
695*d75c371eSJasvinder Singh 	},
696*d75c371eSJasvinder Singh 
697*d75c371eSJasvinder Singh 	/* Source Port */
698*d75c371eSJasvinder Singh 	[9] = {
699*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_RANGE,
700*d75c371eSJasvinder Singh 		.size = sizeof(uint16_t),
701*d75c371eSJasvinder Singh 		.field_index = 9,
702*d75c371eSJasvinder Singh 		.input_index = 9,
703*d75c371eSJasvinder Singh 		.offset = sizeof(struct ipv6_hdr) +
704*d75c371eSJasvinder Singh 			offsetof(struct tcp_hdr, src_port),
705*d75c371eSJasvinder Singh 	},
706*d75c371eSJasvinder Singh 
707*d75c371eSJasvinder Singh 	/* Destination Port */
708*d75c371eSJasvinder Singh 	[10] = {
709*d75c371eSJasvinder Singh 		.type = RTE_ACL_FIELD_TYPE_RANGE,
710*d75c371eSJasvinder Singh 		.size = sizeof(uint16_t),
711*d75c371eSJasvinder Singh 		.field_index = 10,
712*d75c371eSJasvinder Singh 		.input_index = 9,
713*d75c371eSJasvinder Singh 		.offset = sizeof(struct ipv6_hdr) +
714*d75c371eSJasvinder Singh 			offsetof(struct tcp_hdr, dst_port),
715*d75c371eSJasvinder Singh 	},
716*d75c371eSJasvinder Singh };
717*d75c371eSJasvinder Singh 
718*d75c371eSJasvinder Singh int
719*d75c371eSJasvinder Singh pipeline_table_create(const char *pipeline_name,
720*d75c371eSJasvinder Singh 	struct table_params *params)
721*d75c371eSJasvinder Singh {
722*d75c371eSJasvinder Singh 	char name[NAME_MAX];
723*d75c371eSJasvinder Singh 	struct rte_pipeline_table_params p;
724*d75c371eSJasvinder Singh 
725*d75c371eSJasvinder Singh 	union {
726*d75c371eSJasvinder Singh 		struct rte_table_acl_params acl;
727*d75c371eSJasvinder Singh 		struct rte_table_array_params array;
728*d75c371eSJasvinder Singh 		struct rte_table_hash_params hash;
729*d75c371eSJasvinder Singh 		struct rte_table_lpm_params lpm;
730*d75c371eSJasvinder Singh 		struct rte_table_lpm_ipv6_params lpm_ipv6;
731*d75c371eSJasvinder Singh 	} pp;
732*d75c371eSJasvinder Singh 
733*d75c371eSJasvinder Singh 	struct pipeline *pipeline;
734*d75c371eSJasvinder Singh 	struct table *table;
735*d75c371eSJasvinder Singh 	struct table_action_profile *ap;
736*d75c371eSJasvinder Singh 	struct rte_table_action *action;
737*d75c371eSJasvinder Singh 	uint32_t table_id;
738*d75c371eSJasvinder Singh 	int status;
739*d75c371eSJasvinder Singh 
740*d75c371eSJasvinder Singh 	memset(&p, 0, sizeof(p));
741*d75c371eSJasvinder Singh 	memset(&pp, 0, sizeof(pp));
742*d75c371eSJasvinder Singh 
743*d75c371eSJasvinder Singh 	/* Check input params */
744*d75c371eSJasvinder Singh 	if ((pipeline_name == NULL) ||
745*d75c371eSJasvinder Singh 		(params == NULL))
746*d75c371eSJasvinder Singh 		return -1;
747*d75c371eSJasvinder Singh 
748*d75c371eSJasvinder Singh 	pipeline = pipeline_find(pipeline_name);
749*d75c371eSJasvinder Singh 	if ((pipeline == NULL) ||
750*d75c371eSJasvinder Singh 		(pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX))
751*d75c371eSJasvinder Singh 		return -1;
752*d75c371eSJasvinder Singh 
753*d75c371eSJasvinder Singh 	ap = NULL;
754*d75c371eSJasvinder Singh 	if (params->action_profile_name) {
755*d75c371eSJasvinder Singh 		ap = table_action_profile_find(params->action_profile_name);
756*d75c371eSJasvinder Singh 		if (ap == NULL)
757*d75c371eSJasvinder Singh 			return -1;
758*d75c371eSJasvinder Singh 	}
759*d75c371eSJasvinder Singh 
760*d75c371eSJasvinder Singh 	snprintf(name, NAME_MAX, "%s_table%u",
761*d75c371eSJasvinder Singh 		pipeline_name, pipeline->n_tables);
762*d75c371eSJasvinder Singh 
763*d75c371eSJasvinder Singh 	switch (params->match_type) {
764*d75c371eSJasvinder Singh 	case TABLE_ACL:
765*d75c371eSJasvinder Singh 	{
766*d75c371eSJasvinder Singh 		uint32_t ip_header_offset = params->match.acl.ip_header_offset -
767*d75c371eSJasvinder Singh 			(sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
768*d75c371eSJasvinder Singh 		uint32_t i;
769*d75c371eSJasvinder Singh 
770*d75c371eSJasvinder Singh 		if (params->match.acl.n_rules == 0)
771*d75c371eSJasvinder Singh 			return -1;
772*d75c371eSJasvinder Singh 
773*d75c371eSJasvinder Singh 		pp.acl.name = name;
774*d75c371eSJasvinder Singh 		pp.acl.n_rules = params->match.acl.n_rules;
775*d75c371eSJasvinder Singh 		if (params->match.acl.ip_version) {
776*d75c371eSJasvinder Singh 			memcpy(&pp.acl.field_format,
777*d75c371eSJasvinder Singh 				&table_acl_field_format_ipv4,
778*d75c371eSJasvinder Singh 				sizeof(table_acl_field_format_ipv4));
779*d75c371eSJasvinder Singh 			pp.acl.n_rule_fields =
780*d75c371eSJasvinder Singh 				RTE_DIM(table_acl_field_format_ipv4);
781*d75c371eSJasvinder Singh 		} else {
782*d75c371eSJasvinder Singh 			memcpy(&pp.acl.field_format,
783*d75c371eSJasvinder Singh 				&table_acl_field_format_ipv6,
784*d75c371eSJasvinder Singh 				sizeof(table_acl_field_format_ipv6));
785*d75c371eSJasvinder Singh 			pp.acl.n_rule_fields =
786*d75c371eSJasvinder Singh 				RTE_DIM(table_acl_field_format_ipv6);
787*d75c371eSJasvinder Singh 		}
788*d75c371eSJasvinder Singh 
789*d75c371eSJasvinder Singh 		for (i = 0; i < pp.acl.n_rule_fields; i++)
790*d75c371eSJasvinder Singh 			pp.acl.field_format[i].offset += ip_header_offset;
791*d75c371eSJasvinder Singh 
792*d75c371eSJasvinder Singh 		p.ops = &rte_table_acl_ops;
793*d75c371eSJasvinder Singh 		p.arg_create = &pp.acl;
794*d75c371eSJasvinder Singh 		break;
795*d75c371eSJasvinder Singh 	}
796*d75c371eSJasvinder Singh 
797*d75c371eSJasvinder Singh 	case TABLE_ARRAY:
798*d75c371eSJasvinder Singh 	{
799*d75c371eSJasvinder Singh 		if (params->match.array.n_keys == 0)
800*d75c371eSJasvinder Singh 			return -1;
801*d75c371eSJasvinder Singh 
802*d75c371eSJasvinder Singh 		pp.array.n_entries = params->match.array.n_keys;
803*d75c371eSJasvinder Singh 		pp.array.offset = params->match.array.key_offset;
804*d75c371eSJasvinder Singh 
805*d75c371eSJasvinder Singh 		p.ops = &rte_table_array_ops;
806*d75c371eSJasvinder Singh 		p.arg_create = &pp.array;
807*d75c371eSJasvinder Singh 		break;
808*d75c371eSJasvinder Singh 	}
809*d75c371eSJasvinder Singh 
810*d75c371eSJasvinder Singh 	case TABLE_HASH:
811*d75c371eSJasvinder Singh 	{
812*d75c371eSJasvinder Singh 		struct rte_table_ops *ops;
813*d75c371eSJasvinder Singh 		rte_table_hash_op_hash f_hash;
814*d75c371eSJasvinder Singh 
815*d75c371eSJasvinder Singh 		if (params->match.hash.n_keys == 0)
816*d75c371eSJasvinder Singh 			return -1;
817*d75c371eSJasvinder Singh 
818*d75c371eSJasvinder Singh 		switch (params->match.hash.key_size) {
819*d75c371eSJasvinder Singh 		case  8:
820*d75c371eSJasvinder Singh 			f_hash = hash_default_key8;
821*d75c371eSJasvinder Singh 			break;
822*d75c371eSJasvinder Singh 		case 16:
823*d75c371eSJasvinder Singh 			f_hash = hash_default_key16;
824*d75c371eSJasvinder Singh 			break;
825*d75c371eSJasvinder Singh 		case 24:
826*d75c371eSJasvinder Singh 			f_hash = hash_default_key24;
827*d75c371eSJasvinder Singh 			break;
828*d75c371eSJasvinder Singh 		case 32:
829*d75c371eSJasvinder Singh 			f_hash = hash_default_key32;
830*d75c371eSJasvinder Singh 			break;
831*d75c371eSJasvinder Singh 		case 40:
832*d75c371eSJasvinder Singh 			f_hash = hash_default_key40;
833*d75c371eSJasvinder Singh 			break;
834*d75c371eSJasvinder Singh 		case 48:
835*d75c371eSJasvinder Singh 			f_hash = hash_default_key48;
836*d75c371eSJasvinder Singh 			break;
837*d75c371eSJasvinder Singh 		case 56:
838*d75c371eSJasvinder Singh 			f_hash = hash_default_key56;
839*d75c371eSJasvinder Singh 			break;
840*d75c371eSJasvinder Singh 		case 64:
841*d75c371eSJasvinder Singh 			f_hash = hash_default_key64;
842*d75c371eSJasvinder Singh 			break;
843*d75c371eSJasvinder Singh 		default:
844*d75c371eSJasvinder Singh 			return -1;
845*d75c371eSJasvinder Singh 		}
846*d75c371eSJasvinder Singh 
847*d75c371eSJasvinder Singh 		pp.hash.name = name;
848*d75c371eSJasvinder Singh 		pp.hash.key_size = params->match.hash.key_size;
849*d75c371eSJasvinder Singh 		pp.hash.key_offset = params->match.hash.key_offset;
850*d75c371eSJasvinder Singh 		pp.hash.key_mask = params->match.hash.key_mask;
851*d75c371eSJasvinder Singh 		pp.hash.n_keys = params->match.hash.n_keys;
852*d75c371eSJasvinder Singh 		pp.hash.n_buckets = params->match.hash.n_buckets;
853*d75c371eSJasvinder Singh 		pp.hash.f_hash = f_hash;
854*d75c371eSJasvinder Singh 		pp.hash.seed = 0;
855*d75c371eSJasvinder Singh 
856*d75c371eSJasvinder Singh 		if (params->match.hash.extendable_bucket)
857*d75c371eSJasvinder Singh 			switch (params->match.hash.key_size) {
858*d75c371eSJasvinder Singh 			case  8:
859*d75c371eSJasvinder Singh 				ops = &rte_table_hash_key8_ext_ops;
860*d75c371eSJasvinder Singh 				break;
861*d75c371eSJasvinder Singh 			case 16:
862*d75c371eSJasvinder Singh 				ops = &rte_table_hash_key16_ext_ops;
863*d75c371eSJasvinder Singh 				break;
864*d75c371eSJasvinder Singh 			default:
865*d75c371eSJasvinder Singh 				ops = &rte_table_hash_ext_ops;
866*d75c371eSJasvinder Singh 			}
867*d75c371eSJasvinder Singh 		else
868*d75c371eSJasvinder Singh 			switch (params->match.hash.key_size) {
869*d75c371eSJasvinder Singh 			case  8:
870*d75c371eSJasvinder Singh 				ops = &rte_table_hash_key8_lru_ops;
871*d75c371eSJasvinder Singh 				break;
872*d75c371eSJasvinder Singh 			case 16:
873*d75c371eSJasvinder Singh 				ops = &rte_table_hash_key16_lru_ops;
874*d75c371eSJasvinder Singh 				break;
875*d75c371eSJasvinder Singh 			default:
876*d75c371eSJasvinder Singh 				ops = &rte_table_hash_lru_ops;
877*d75c371eSJasvinder Singh 			}
878*d75c371eSJasvinder Singh 
879*d75c371eSJasvinder Singh 		p.ops = ops;
880*d75c371eSJasvinder Singh 		p.arg_create = &pp.hash;
881*d75c371eSJasvinder Singh 		break;
882*d75c371eSJasvinder Singh 	}
883*d75c371eSJasvinder Singh 
884*d75c371eSJasvinder Singh 	case TABLE_LPM:
885*d75c371eSJasvinder Singh 	{
886*d75c371eSJasvinder Singh 		if (params->match.lpm.n_rules == 0)
887*d75c371eSJasvinder Singh 			return -1;
888*d75c371eSJasvinder Singh 
889*d75c371eSJasvinder Singh 		switch (params->match.lpm.key_size) {
890*d75c371eSJasvinder Singh 		case 4:
891*d75c371eSJasvinder Singh 		{
892*d75c371eSJasvinder Singh 			pp.lpm.name = name;
893*d75c371eSJasvinder Singh 			pp.lpm.n_rules = params->match.lpm.n_rules;
894*d75c371eSJasvinder Singh 			pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
895*d75c371eSJasvinder Singh 			pp.lpm.flags = 0;
896*d75c371eSJasvinder Singh 			pp.lpm.entry_unique_size = p.action_data_size +
897*d75c371eSJasvinder Singh 				sizeof(struct rte_pipeline_table_entry);
898*d75c371eSJasvinder Singh 			pp.lpm.offset = params->match.lpm.key_offset;
899*d75c371eSJasvinder Singh 
900*d75c371eSJasvinder Singh 			p.ops = &rte_table_lpm_ops;
901*d75c371eSJasvinder Singh 			p.arg_create = &pp.lpm;
902*d75c371eSJasvinder Singh 			break;
903*d75c371eSJasvinder Singh 		}
904*d75c371eSJasvinder Singh 
905*d75c371eSJasvinder Singh 		case 16:
906*d75c371eSJasvinder Singh 		{
907*d75c371eSJasvinder Singh 			pp.lpm_ipv6.name = name;
908*d75c371eSJasvinder Singh 			pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
909*d75c371eSJasvinder Singh 			pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
910*d75c371eSJasvinder Singh 			pp.lpm_ipv6.entry_unique_size = p.action_data_size +
911*d75c371eSJasvinder Singh 				sizeof(struct rte_pipeline_table_entry);
912*d75c371eSJasvinder Singh 			pp.lpm_ipv6.offset = params->match.lpm.key_offset;
913*d75c371eSJasvinder Singh 
914*d75c371eSJasvinder Singh 			p.ops = &rte_table_lpm_ipv6_ops;
915*d75c371eSJasvinder Singh 			p.arg_create = &pp.lpm_ipv6;
916*d75c371eSJasvinder Singh 			break;
917*d75c371eSJasvinder Singh 		}
918*d75c371eSJasvinder Singh 
919*d75c371eSJasvinder Singh 		default:
920*d75c371eSJasvinder Singh 			return -1;
921*d75c371eSJasvinder Singh 		}
922*d75c371eSJasvinder Singh 
923*d75c371eSJasvinder Singh 		break;
924*d75c371eSJasvinder Singh 	}
925*d75c371eSJasvinder Singh 
926*d75c371eSJasvinder Singh 	case TABLE_STUB:
927*d75c371eSJasvinder Singh 	{
928*d75c371eSJasvinder Singh 		p.ops = &rte_table_stub_ops;
929*d75c371eSJasvinder Singh 		p.arg_create = NULL;
930*d75c371eSJasvinder Singh 		break;
931*d75c371eSJasvinder Singh 	}
932*d75c371eSJasvinder Singh 
933*d75c371eSJasvinder Singh 	default:
934*d75c371eSJasvinder Singh 		return -1;
935*d75c371eSJasvinder Singh 	}
936*d75c371eSJasvinder Singh 
937*d75c371eSJasvinder Singh 	/* Resource create */
938*d75c371eSJasvinder Singh 	action = NULL;
939*d75c371eSJasvinder Singh 	p.f_action_hit = NULL;
940*d75c371eSJasvinder Singh 	p.f_action_miss = NULL;
941*d75c371eSJasvinder Singh 	p.arg_ah = NULL;
942*d75c371eSJasvinder Singh 
943*d75c371eSJasvinder Singh 	if (ap) {
944*d75c371eSJasvinder Singh 		action = rte_table_action_create(ap->ap,
945*d75c371eSJasvinder Singh 			pipeline->cpu_id);
946*d75c371eSJasvinder Singh 		if (action == NULL)
947*d75c371eSJasvinder Singh 			return -1;
948*d75c371eSJasvinder Singh 
949*d75c371eSJasvinder Singh 		status = rte_table_action_table_params_get(
950*d75c371eSJasvinder Singh 			action,
951*d75c371eSJasvinder Singh 			&p);
952*d75c371eSJasvinder Singh 		if (status ||
953*d75c371eSJasvinder Singh 			((p.action_data_size +
954*d75c371eSJasvinder Singh 			sizeof(struct rte_pipeline_table_entry)) >
955*d75c371eSJasvinder Singh 			TABLE_RULE_ACTION_SIZE_MAX)) {
956*d75c371eSJasvinder Singh 			rte_table_action_free(action);
957*d75c371eSJasvinder Singh 			return -1;
958*d75c371eSJasvinder Singh 		}
959*d75c371eSJasvinder Singh 	}
960*d75c371eSJasvinder Singh 
961*d75c371eSJasvinder Singh 	if (params->match_type == TABLE_LPM) {
962*d75c371eSJasvinder Singh 		if (params->match.lpm.key_size == 4)
963*d75c371eSJasvinder Singh 			pp.lpm.entry_unique_size = p.action_data_size +
964*d75c371eSJasvinder Singh 				sizeof(struct rte_pipeline_table_entry);
965*d75c371eSJasvinder Singh 
966*d75c371eSJasvinder Singh 		if (params->match.lpm.key_size == 16)
967*d75c371eSJasvinder Singh 			pp.lpm_ipv6.entry_unique_size = p.action_data_size +
968*d75c371eSJasvinder Singh 				sizeof(struct rte_pipeline_table_entry);
969*d75c371eSJasvinder Singh 	}
970*d75c371eSJasvinder Singh 
971*d75c371eSJasvinder Singh 	status = rte_pipeline_table_create(pipeline->p,
972*d75c371eSJasvinder Singh 		&p,
973*d75c371eSJasvinder Singh 		&table_id);
974*d75c371eSJasvinder Singh 	if (status) {
975*d75c371eSJasvinder Singh 		rte_table_action_free(action);
976*d75c371eSJasvinder Singh 		return -1;
977*d75c371eSJasvinder Singh 	}
978*d75c371eSJasvinder Singh 
979*d75c371eSJasvinder Singh 	/* Pipeline */
980*d75c371eSJasvinder Singh 	table = &pipeline->table[pipeline->n_tables];
981*d75c371eSJasvinder Singh 	memcpy(&table->params, params, sizeof(*params));
982*d75c371eSJasvinder Singh 	table->ap = ap;
983*d75c371eSJasvinder Singh 	table->a = action;
984*d75c371eSJasvinder Singh 	pipeline->n_tables++;
985*d75c371eSJasvinder Singh 
986*d75c371eSJasvinder Singh 	return 0;
987*d75c371eSJasvinder Singh }
988