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