xref: /dpdk/examples/ip_pipeline/thread.c (revision 5ac1abdd37aa43692603cd8670111c354014766f)
1c0b668e0SJasvinder Singh /* SPDX-License-Identifier: BSD-3-Clause
2c0b668e0SJasvinder Singh  * Copyright(c) 2010-2018 Intel Corporation
3c0b668e0SJasvinder Singh  */
4c0b668e0SJasvinder Singh 
5c0b668e0SJasvinder Singh #include <stdlib.h>
6c0b668e0SJasvinder Singh 
7c0b668e0SJasvinder Singh #include <rte_common.h>
8c0b668e0SJasvinder Singh #include <rte_cycles.h>
9c0b668e0SJasvinder Singh #include <rte_lcore.h>
10c0b668e0SJasvinder Singh #include <rte_ring.h>
11c0b668e0SJasvinder Singh 
12c0b668e0SJasvinder Singh #include <rte_table_acl.h>
13c0b668e0SJasvinder Singh #include <rte_table_array.h>
14c0b668e0SJasvinder Singh #include <rte_table_hash.h>
15c0b668e0SJasvinder Singh #include <rte_table_lpm.h>
16c0b668e0SJasvinder Singh #include <rte_table_lpm_ipv6.h>
17c0b668e0SJasvinder Singh 
18c0b668e0SJasvinder Singh #include "common.h"
19c0b668e0SJasvinder Singh #include "thread.h"
20c0b668e0SJasvinder Singh #include "pipeline.h"
21c0b668e0SJasvinder Singh 
22c0b668e0SJasvinder Singh #ifndef THREAD_PIPELINES_MAX
23c0b668e0SJasvinder Singh #define THREAD_PIPELINES_MAX                               256
24c0b668e0SJasvinder Singh #endif
25c0b668e0SJasvinder Singh 
26c0b668e0SJasvinder Singh #ifndef THREAD_MSGQ_SIZE
27c0b668e0SJasvinder Singh #define THREAD_MSGQ_SIZE                                   64
28c0b668e0SJasvinder Singh #endif
29c0b668e0SJasvinder Singh 
30c0b668e0SJasvinder Singh #ifndef THREAD_TIMER_PERIOD_MS
31c0b668e0SJasvinder Singh #define THREAD_TIMER_PERIOD_MS                             100
32c0b668e0SJasvinder Singh #endif
33c0b668e0SJasvinder Singh 
34c0b668e0SJasvinder Singh /**
35cb056611SStephen Hemminger  * Main thread: data plane thread context
36c0b668e0SJasvinder Singh  */
37c0b668e0SJasvinder Singh struct thread {
38c0b668e0SJasvinder Singh 	struct rte_ring *msgq_req;
39c0b668e0SJasvinder Singh 	struct rte_ring *msgq_rsp;
40c0b668e0SJasvinder Singh 
41c0b668e0SJasvinder Singh 	uint32_t enabled;
42c0b668e0SJasvinder Singh };
43c0b668e0SJasvinder Singh 
44c0b668e0SJasvinder Singh static struct thread thread[RTE_MAX_LCORE];
45c0b668e0SJasvinder Singh 
46c0b668e0SJasvinder Singh /**
47c0b668e0SJasvinder Singh  * Data plane threads: context
48c0b668e0SJasvinder Singh  */
49c0b668e0SJasvinder Singh struct table_data {
50c0b668e0SJasvinder Singh 	struct rte_table_action *a;
51c0b668e0SJasvinder Singh };
52c0b668e0SJasvinder Singh 
53c0b668e0SJasvinder Singh struct pipeline_data {
54c0b668e0SJasvinder Singh 	struct rte_pipeline *p;
55c0b668e0SJasvinder Singh 	struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
56c0b668e0SJasvinder Singh 	uint32_t n_tables;
57c0b668e0SJasvinder Singh 
58c0b668e0SJasvinder Singh 	struct rte_ring *msgq_req;
59c0b668e0SJasvinder Singh 	struct rte_ring *msgq_rsp;
60c0b668e0SJasvinder Singh 	uint64_t timer_period; /* Measured in CPU cycles. */
61c0b668e0SJasvinder Singh 	uint64_t time_next;
62c0b668e0SJasvinder Singh 
63c0b668e0SJasvinder Singh 	uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
64c0b668e0SJasvinder Singh };
65c0b668e0SJasvinder Singh 
667e06c0deSTyler Retzlaff struct __rte_cache_aligned thread_data {
67c0b668e0SJasvinder Singh 	struct rte_pipeline *p[THREAD_PIPELINES_MAX];
68c0b668e0SJasvinder Singh 	uint32_t n_pipelines;
69c0b668e0SJasvinder Singh 
70c0b668e0SJasvinder Singh 	struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
71c0b668e0SJasvinder Singh 	struct rte_ring *msgq_req;
72c0b668e0SJasvinder Singh 	struct rte_ring *msgq_rsp;
73c0b668e0SJasvinder Singh 	uint64_t timer_period; /* Measured in CPU cycles. */
74c0b668e0SJasvinder Singh 	uint64_t time_next;
75c0b668e0SJasvinder Singh 	uint64_t time_next_min;
767e06c0deSTyler Retzlaff };
77c0b668e0SJasvinder Singh 
78c0b668e0SJasvinder Singh static struct thread_data thread_data[RTE_MAX_LCORE];
79c0b668e0SJasvinder Singh 
80c0b668e0SJasvinder Singh /**
81cb056611SStephen Hemminger  * Main thread: data plane thread init
82c0b668e0SJasvinder Singh  */
83c0b668e0SJasvinder Singh static void
84c0b668e0SJasvinder Singh thread_free(void)
85c0b668e0SJasvinder Singh {
86c0b668e0SJasvinder Singh 	uint32_t i;
87c0b668e0SJasvinder Singh 
88c0b668e0SJasvinder Singh 	for (i = 0; i < RTE_MAX_LCORE; i++) {
89c0b668e0SJasvinder Singh 		struct thread *t = &thread[i];
90c0b668e0SJasvinder Singh 
91c0b668e0SJasvinder Singh 		if (!rte_lcore_is_enabled(i))
92c0b668e0SJasvinder Singh 			continue;
93c0b668e0SJasvinder Singh 
94c0b668e0SJasvinder Singh 		/* MSGQs */
95c0b668e0SJasvinder Singh 		rte_ring_free(t->msgq_req);
96c0b668e0SJasvinder Singh 
97c0b668e0SJasvinder Singh 		rte_ring_free(t->msgq_rsp);
98c0b668e0SJasvinder Singh 	}
99c0b668e0SJasvinder Singh }
100c0b668e0SJasvinder Singh 
101c0b668e0SJasvinder Singh int
102c0b668e0SJasvinder Singh thread_init(void)
103c0b668e0SJasvinder Singh {
104c0b668e0SJasvinder Singh 	uint32_t i;
105c0b668e0SJasvinder Singh 
106cb056611SStephen Hemminger 	RTE_LCORE_FOREACH_WORKER(i) {
107c0b668e0SJasvinder Singh 		char name[NAME_MAX];
108c0b668e0SJasvinder Singh 		struct rte_ring *msgq_req, *msgq_rsp;
109c0b668e0SJasvinder Singh 		struct thread *t = &thread[i];
110c0b668e0SJasvinder Singh 		struct thread_data *t_data = &thread_data[i];
111c0b668e0SJasvinder Singh 		uint32_t cpu_id = rte_lcore_to_socket_id(i);
112c0b668e0SJasvinder Singh 
113c0b668e0SJasvinder Singh 		/* MSGQs */
114c0b668e0SJasvinder Singh 		snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i);
115c0b668e0SJasvinder Singh 
116c0b668e0SJasvinder Singh 		msgq_req = rte_ring_create(name,
117c0b668e0SJasvinder Singh 			THREAD_MSGQ_SIZE,
118c0b668e0SJasvinder Singh 			cpu_id,
119c0b668e0SJasvinder Singh 			RING_F_SP_ENQ | RING_F_SC_DEQ);
120c0b668e0SJasvinder Singh 
121c0b668e0SJasvinder Singh 		if (msgq_req == NULL) {
122c0b668e0SJasvinder Singh 			thread_free();
123c0b668e0SJasvinder Singh 			return -1;
124c0b668e0SJasvinder Singh 		}
125c0b668e0SJasvinder Singh 
126c0b668e0SJasvinder Singh 		snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i);
127c0b668e0SJasvinder Singh 
128c0b668e0SJasvinder Singh 		msgq_rsp = rte_ring_create(name,
129c0b668e0SJasvinder Singh 			THREAD_MSGQ_SIZE,
130c0b668e0SJasvinder Singh 			cpu_id,
131c0b668e0SJasvinder Singh 			RING_F_SP_ENQ | RING_F_SC_DEQ);
132c0b668e0SJasvinder Singh 
133c0b668e0SJasvinder Singh 		if (msgq_rsp == NULL) {
134c0b668e0SJasvinder Singh 			thread_free();
135c0b668e0SJasvinder Singh 			return -1;
136c0b668e0SJasvinder Singh 		}
137c0b668e0SJasvinder Singh 
138cb056611SStephen Hemminger 		/* Main thread records */
139c0b668e0SJasvinder Singh 		t->msgq_req = msgq_req;
140c0b668e0SJasvinder Singh 		t->msgq_rsp = msgq_rsp;
141c0b668e0SJasvinder Singh 		t->enabled = 1;
142c0b668e0SJasvinder Singh 
143c0b668e0SJasvinder Singh 		/* Data plane thread records */
144c0b668e0SJasvinder Singh 		t_data->n_pipelines = 0;
145c0b668e0SJasvinder Singh 		t_data->msgq_req = msgq_req;
146c0b668e0SJasvinder Singh 		t_data->msgq_rsp = msgq_rsp;
147c0b668e0SJasvinder Singh 		t_data->timer_period =
148c0b668e0SJasvinder Singh 			(rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
149c0b668e0SJasvinder Singh 		t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
150c0b668e0SJasvinder Singh 		t_data->time_next_min = t_data->time_next;
151c0b668e0SJasvinder Singh 	}
152c0b668e0SJasvinder Singh 
153c0b668e0SJasvinder Singh 	return 0;
154c0b668e0SJasvinder Singh }
155a8bd581dSJasvinder Singh 
156f68a1d3fSJasvinder Singh static inline int
157f68a1d3fSJasvinder Singh thread_is_running(uint32_t thread_id)
158f68a1d3fSJasvinder Singh {
159f68a1d3fSJasvinder Singh 	enum rte_lcore_state_t thread_state;
160f68a1d3fSJasvinder Singh 
161f68a1d3fSJasvinder Singh 	thread_state = rte_eal_get_lcore_state(thread_id);
162f68a1d3fSJasvinder Singh 	return (thread_state == RUNNING) ? 1 : 0;
163f68a1d3fSJasvinder Singh }
164f68a1d3fSJasvinder Singh 
165f68a1d3fSJasvinder Singh /**
166f68a1d3fSJasvinder Singh  * Pipeline is running when:
167f68a1d3fSJasvinder Singh  *    (A) Pipeline is mapped to a data plane thread AND
168f68a1d3fSJasvinder Singh  *    (B) Its data plane thread is in RUNNING state.
169f68a1d3fSJasvinder Singh  */
170f68a1d3fSJasvinder Singh static inline int
171f68a1d3fSJasvinder Singh pipeline_is_running(struct pipeline *p)
172f68a1d3fSJasvinder Singh {
173f68a1d3fSJasvinder Singh 	if (p->enabled == 0)
174f68a1d3fSJasvinder Singh 		return 0;
175f68a1d3fSJasvinder Singh 
176f68a1d3fSJasvinder Singh 	return thread_is_running(p->thread_id);
177f68a1d3fSJasvinder Singh }
178f68a1d3fSJasvinder Singh 
179a8bd581dSJasvinder Singh /**
180cb056611SStephen Hemminger  * Main thread & data plane threads: message passing
181a8bd581dSJasvinder Singh  */
182a8bd581dSJasvinder Singh enum thread_req_type {
18332e5d9b1SJasvinder Singh 	THREAD_REQ_PIPELINE_ENABLE = 0,
18432e5d9b1SJasvinder Singh 	THREAD_REQ_PIPELINE_DISABLE,
185a8bd581dSJasvinder Singh 	THREAD_REQ_MAX
186a8bd581dSJasvinder Singh };
187a8bd581dSJasvinder Singh 
188a8bd581dSJasvinder Singh struct thread_msg_req {
189a8bd581dSJasvinder Singh 	enum thread_req_type type;
19032e5d9b1SJasvinder Singh 
19132e5d9b1SJasvinder Singh 	union {
19232e5d9b1SJasvinder Singh 		struct {
19332e5d9b1SJasvinder Singh 			struct rte_pipeline *p;
19432e5d9b1SJasvinder Singh 			struct {
19532e5d9b1SJasvinder Singh 				struct rte_table_action *a;
19632e5d9b1SJasvinder Singh 			} table[RTE_PIPELINE_TABLE_MAX];
19732e5d9b1SJasvinder Singh 			struct rte_ring *msgq_req;
19832e5d9b1SJasvinder Singh 			struct rte_ring *msgq_rsp;
19932e5d9b1SJasvinder Singh 			uint32_t timer_period_ms;
20032e5d9b1SJasvinder Singh 			uint32_t n_tables;
20132e5d9b1SJasvinder Singh 		} pipeline_enable;
20232e5d9b1SJasvinder Singh 
20332e5d9b1SJasvinder Singh 		struct {
20432e5d9b1SJasvinder Singh 			struct rte_pipeline *p;
20532e5d9b1SJasvinder Singh 		} pipeline_disable;
20632e5d9b1SJasvinder Singh 	};
207a8bd581dSJasvinder Singh };
208a8bd581dSJasvinder Singh 
209a8bd581dSJasvinder Singh struct thread_msg_rsp {
210a8bd581dSJasvinder Singh 	int status;
211a8bd581dSJasvinder Singh };
212a8bd581dSJasvinder Singh 
213a8bd581dSJasvinder Singh /**
214cb056611SStephen Hemminger  * Main thread
21532e5d9b1SJasvinder Singh  */
21632e5d9b1SJasvinder Singh static struct thread_msg_req *
21732e5d9b1SJasvinder Singh thread_msg_alloc(void)
21832e5d9b1SJasvinder Singh {
21932e5d9b1SJasvinder Singh 	size_t size = RTE_MAX(sizeof(struct thread_msg_req),
22032e5d9b1SJasvinder Singh 		sizeof(struct thread_msg_rsp));
22132e5d9b1SJasvinder Singh 
22232e5d9b1SJasvinder Singh 	return calloc(1, size);
22332e5d9b1SJasvinder Singh }
22432e5d9b1SJasvinder Singh 
22532e5d9b1SJasvinder Singh static void
22632e5d9b1SJasvinder Singh thread_msg_free(struct thread_msg_rsp *rsp)
22732e5d9b1SJasvinder Singh {
22832e5d9b1SJasvinder Singh 	free(rsp);
22932e5d9b1SJasvinder Singh }
23032e5d9b1SJasvinder Singh 
23132e5d9b1SJasvinder Singh static struct thread_msg_rsp *
23232e5d9b1SJasvinder Singh thread_msg_send_recv(uint32_t thread_id,
23332e5d9b1SJasvinder Singh 	struct thread_msg_req *req)
23432e5d9b1SJasvinder Singh {
23532e5d9b1SJasvinder Singh 	struct thread *t = &thread[thread_id];
23632e5d9b1SJasvinder Singh 	struct rte_ring *msgq_req = t->msgq_req;
23732e5d9b1SJasvinder Singh 	struct rte_ring *msgq_rsp = t->msgq_rsp;
23832e5d9b1SJasvinder Singh 	struct thread_msg_rsp *rsp;
23932e5d9b1SJasvinder Singh 	int status;
24032e5d9b1SJasvinder Singh 
24132e5d9b1SJasvinder Singh 	/* send */
24232e5d9b1SJasvinder Singh 	do {
24332e5d9b1SJasvinder Singh 		status = rte_ring_sp_enqueue(msgq_req, req);
24432e5d9b1SJasvinder Singh 	} while (status == -ENOBUFS);
24532e5d9b1SJasvinder Singh 
24632e5d9b1SJasvinder Singh 	/* recv */
24732e5d9b1SJasvinder Singh 	do {
24832e5d9b1SJasvinder Singh 		status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
24932e5d9b1SJasvinder Singh 	} while (status != 0);
25032e5d9b1SJasvinder Singh 
25132e5d9b1SJasvinder Singh 	return rsp;
25232e5d9b1SJasvinder Singh }
25332e5d9b1SJasvinder Singh 
25432e5d9b1SJasvinder Singh int
25532e5d9b1SJasvinder Singh thread_pipeline_enable(uint32_t thread_id,
25632e5d9b1SJasvinder Singh 	const char *pipeline_name)
25732e5d9b1SJasvinder Singh {
25832e5d9b1SJasvinder Singh 	struct pipeline *p = pipeline_find(pipeline_name);
25932e5d9b1SJasvinder Singh 	struct thread *t;
26032e5d9b1SJasvinder Singh 	struct thread_msg_req *req;
26132e5d9b1SJasvinder Singh 	struct thread_msg_rsp *rsp;
26232e5d9b1SJasvinder Singh 	uint32_t i;
26332e5d9b1SJasvinder Singh 	int status;
26432e5d9b1SJasvinder Singh 
26532e5d9b1SJasvinder Singh 	/* Check input params */
26632e5d9b1SJasvinder Singh 	if ((thread_id >= RTE_MAX_LCORE) ||
26732e5d9b1SJasvinder Singh 		(p == NULL) ||
26832e5d9b1SJasvinder Singh 		(p->n_ports_in == 0) ||
26932e5d9b1SJasvinder Singh 		(p->n_ports_out == 0) ||
27032e5d9b1SJasvinder Singh 		(p->n_tables == 0))
27132e5d9b1SJasvinder Singh 		return -1;
27232e5d9b1SJasvinder Singh 
27332e5d9b1SJasvinder Singh 	t = &thread[thread_id];
27432e5d9b1SJasvinder Singh 	if ((t->enabled == 0) ||
27532e5d9b1SJasvinder Singh 		p->enabled)
27632e5d9b1SJasvinder Singh 		return -1;
27732e5d9b1SJasvinder Singh 
278f68a1d3fSJasvinder Singh 	if (!thread_is_running(thread_id)) {
279f68a1d3fSJasvinder Singh 		struct thread_data *td = &thread_data[thread_id];
280f68a1d3fSJasvinder Singh 		struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
281f68a1d3fSJasvinder Singh 
282f68a1d3fSJasvinder Singh 		if (td->n_pipelines >= THREAD_PIPELINES_MAX)
283f68a1d3fSJasvinder Singh 			return -1;
284f68a1d3fSJasvinder Singh 
285f68a1d3fSJasvinder Singh 		/* Data plane thread */
286f68a1d3fSJasvinder Singh 		td->p[td->n_pipelines] = p->p;
287f68a1d3fSJasvinder Singh 
288f68a1d3fSJasvinder Singh 		tdp->p = p->p;
289f68a1d3fSJasvinder Singh 		for (i = 0; i < p->n_tables; i++)
290f68a1d3fSJasvinder Singh 			tdp->table_data[i].a = p->table[i].a;
291f68a1d3fSJasvinder Singh 
292f68a1d3fSJasvinder Singh 		tdp->n_tables = p->n_tables;
293f68a1d3fSJasvinder Singh 
294f68a1d3fSJasvinder Singh 		tdp->msgq_req = p->msgq_req;
295f68a1d3fSJasvinder Singh 		tdp->msgq_rsp = p->msgq_rsp;
296f68a1d3fSJasvinder Singh 		tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
297f68a1d3fSJasvinder Singh 		tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
298f68a1d3fSJasvinder Singh 
299f68a1d3fSJasvinder Singh 		td->n_pipelines++;
300f68a1d3fSJasvinder Singh 
301f68a1d3fSJasvinder Singh 		/* Pipeline */
302f68a1d3fSJasvinder Singh 		p->thread_id = thread_id;
303f68a1d3fSJasvinder Singh 		p->enabled = 1;
304f68a1d3fSJasvinder Singh 
305f68a1d3fSJasvinder Singh 		return 0;
306f68a1d3fSJasvinder Singh 	}
307f68a1d3fSJasvinder Singh 
30832e5d9b1SJasvinder Singh 	/* Allocate request */
30932e5d9b1SJasvinder Singh 	req = thread_msg_alloc();
31032e5d9b1SJasvinder Singh 	if (req == NULL)
31132e5d9b1SJasvinder Singh 		return -1;
31232e5d9b1SJasvinder Singh 
31332e5d9b1SJasvinder Singh 	/* Write request */
31432e5d9b1SJasvinder Singh 	req->type = THREAD_REQ_PIPELINE_ENABLE;
31532e5d9b1SJasvinder Singh 	req->pipeline_enable.p = p->p;
31632e5d9b1SJasvinder Singh 	for (i = 0; i < p->n_tables; i++)
31732e5d9b1SJasvinder Singh 		req->pipeline_enable.table[i].a =
31832e5d9b1SJasvinder Singh 			p->table[i].a;
31932e5d9b1SJasvinder Singh 	req->pipeline_enable.msgq_req = p->msgq_req;
32032e5d9b1SJasvinder Singh 	req->pipeline_enable.msgq_rsp = p->msgq_rsp;
32132e5d9b1SJasvinder Singh 	req->pipeline_enable.timer_period_ms = p->timer_period_ms;
32232e5d9b1SJasvinder Singh 	req->pipeline_enable.n_tables = p->n_tables;
32332e5d9b1SJasvinder Singh 
32432e5d9b1SJasvinder Singh 	/* Send request and wait for response */
32532e5d9b1SJasvinder Singh 	rsp = thread_msg_send_recv(thread_id, req);
32632e5d9b1SJasvinder Singh 
32732e5d9b1SJasvinder Singh 	/* Read response */
32832e5d9b1SJasvinder Singh 	status = rsp->status;
32932e5d9b1SJasvinder Singh 
33032e5d9b1SJasvinder Singh 	/* Free response */
33132e5d9b1SJasvinder Singh 	thread_msg_free(rsp);
33232e5d9b1SJasvinder Singh 
33332e5d9b1SJasvinder Singh 	/* Request completion */
33432e5d9b1SJasvinder Singh 	if (status)
33532e5d9b1SJasvinder Singh 		return status;
33632e5d9b1SJasvinder Singh 
33732e5d9b1SJasvinder Singh 	p->thread_id = thread_id;
33832e5d9b1SJasvinder Singh 	p->enabled = 1;
33932e5d9b1SJasvinder Singh 
34032e5d9b1SJasvinder Singh 	return 0;
34132e5d9b1SJasvinder Singh }
34232e5d9b1SJasvinder Singh 
34332e5d9b1SJasvinder Singh int
34432e5d9b1SJasvinder Singh thread_pipeline_disable(uint32_t thread_id,
34532e5d9b1SJasvinder Singh 	const char *pipeline_name)
34632e5d9b1SJasvinder Singh {
34732e5d9b1SJasvinder Singh 	struct pipeline *p = pipeline_find(pipeline_name);
34832e5d9b1SJasvinder Singh 	struct thread *t;
34932e5d9b1SJasvinder Singh 	struct thread_msg_req *req;
35032e5d9b1SJasvinder Singh 	struct thread_msg_rsp *rsp;
35132e5d9b1SJasvinder Singh 	int status;
35232e5d9b1SJasvinder Singh 
35332e5d9b1SJasvinder Singh 	/* Check input params */
35432e5d9b1SJasvinder Singh 	if ((thread_id >= RTE_MAX_LCORE) ||
35532e5d9b1SJasvinder Singh 		(p == NULL))
35632e5d9b1SJasvinder Singh 		return -1;
35732e5d9b1SJasvinder Singh 
35832e5d9b1SJasvinder Singh 	t = &thread[thread_id];
35932e5d9b1SJasvinder Singh 	if (t->enabled == 0)
36032e5d9b1SJasvinder Singh 		return -1;
36132e5d9b1SJasvinder Singh 
36232e5d9b1SJasvinder Singh 	if (p->enabled == 0)
36332e5d9b1SJasvinder Singh 		return 0;
36432e5d9b1SJasvinder Singh 
36532e5d9b1SJasvinder Singh 	if (p->thread_id != thread_id)
36632e5d9b1SJasvinder Singh 		return -1;
36732e5d9b1SJasvinder Singh 
368f68a1d3fSJasvinder Singh 	if (!thread_is_running(thread_id)) {
369f68a1d3fSJasvinder Singh 		struct thread_data *td = &thread_data[thread_id];
370f68a1d3fSJasvinder Singh 		uint32_t i;
371f68a1d3fSJasvinder Singh 
372f68a1d3fSJasvinder Singh 		for (i = 0; i < td->n_pipelines; i++) {
373f68a1d3fSJasvinder Singh 			struct pipeline_data *tdp = &td->pipeline_data[i];
374f68a1d3fSJasvinder Singh 
375f68a1d3fSJasvinder Singh 			if (tdp->p != p->p)
376f68a1d3fSJasvinder Singh 				continue;
377f68a1d3fSJasvinder Singh 
378f68a1d3fSJasvinder Singh 			/* Data plane thread */
379f68a1d3fSJasvinder Singh 			if (i < td->n_pipelines - 1) {
380f68a1d3fSJasvinder Singh 				struct rte_pipeline *pipeline_last =
381f68a1d3fSJasvinder Singh 					td->p[td->n_pipelines - 1];
382f68a1d3fSJasvinder Singh 				struct pipeline_data *tdp_last =
383f68a1d3fSJasvinder Singh 					&td->pipeline_data[td->n_pipelines - 1];
384f68a1d3fSJasvinder Singh 
385f68a1d3fSJasvinder Singh 				td->p[i] = pipeline_last;
386f68a1d3fSJasvinder Singh 				memcpy(tdp, tdp_last, sizeof(*tdp));
387f68a1d3fSJasvinder Singh 			}
388f68a1d3fSJasvinder Singh 
389f68a1d3fSJasvinder Singh 			td->n_pipelines--;
390f68a1d3fSJasvinder Singh 
391f68a1d3fSJasvinder Singh 			/* Pipeline */
392f68a1d3fSJasvinder Singh 			p->enabled = 0;
393f68a1d3fSJasvinder Singh 
394f68a1d3fSJasvinder Singh 			break;
395f68a1d3fSJasvinder Singh 		}
396f68a1d3fSJasvinder Singh 
397f68a1d3fSJasvinder Singh 		return 0;
398f68a1d3fSJasvinder Singh 	}
399f68a1d3fSJasvinder Singh 
40032e5d9b1SJasvinder Singh 	/* Allocate request */
40132e5d9b1SJasvinder Singh 	req = thread_msg_alloc();
40232e5d9b1SJasvinder Singh 	if (req == NULL)
40332e5d9b1SJasvinder Singh 		return -1;
40432e5d9b1SJasvinder Singh 
40532e5d9b1SJasvinder Singh 	/* Write request */
40632e5d9b1SJasvinder Singh 	req->type = THREAD_REQ_PIPELINE_DISABLE;
40732e5d9b1SJasvinder Singh 	req->pipeline_disable.p = p->p;
40832e5d9b1SJasvinder Singh 
40932e5d9b1SJasvinder Singh 	/* Send request and wait for response */
41032e5d9b1SJasvinder Singh 	rsp = thread_msg_send_recv(thread_id, req);
41132e5d9b1SJasvinder Singh 
41232e5d9b1SJasvinder Singh 	/* Read response */
41332e5d9b1SJasvinder Singh 	status = rsp->status;
41432e5d9b1SJasvinder Singh 
41532e5d9b1SJasvinder Singh 	/* Free response */
41632e5d9b1SJasvinder Singh 	thread_msg_free(rsp);
41732e5d9b1SJasvinder Singh 
41832e5d9b1SJasvinder Singh 	/* Request completion */
41932e5d9b1SJasvinder Singh 	if (status)
42032e5d9b1SJasvinder Singh 		return status;
42132e5d9b1SJasvinder Singh 
42232e5d9b1SJasvinder Singh 	p->enabled = 0;
42332e5d9b1SJasvinder Singh 
42432e5d9b1SJasvinder Singh 	return 0;
42532e5d9b1SJasvinder Singh }
42632e5d9b1SJasvinder Singh 
42732e5d9b1SJasvinder Singh /**
428a8bd581dSJasvinder Singh  * Data plane threads: message handling
429a8bd581dSJasvinder Singh  */
430a8bd581dSJasvinder Singh static inline struct thread_msg_req *
431a8bd581dSJasvinder Singh thread_msg_recv(struct rte_ring *msgq_req)
432a8bd581dSJasvinder Singh {
433aae10e97SJerin Jacob 	struct thread_msg_req *req = NULL;
434a8bd581dSJasvinder Singh 
435a8bd581dSJasvinder Singh 	int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
436a8bd581dSJasvinder Singh 
437a8bd581dSJasvinder Singh 	if (status != 0)
438a8bd581dSJasvinder Singh 		return NULL;
439a8bd581dSJasvinder Singh 
440a8bd581dSJasvinder Singh 	return req;
441a8bd581dSJasvinder Singh }
442a8bd581dSJasvinder Singh 
443a8bd581dSJasvinder Singh static inline void
444a8bd581dSJasvinder Singh thread_msg_send(struct rte_ring *msgq_rsp,
445a8bd581dSJasvinder Singh 	struct thread_msg_rsp *rsp)
446a8bd581dSJasvinder Singh {
447a8bd581dSJasvinder Singh 	int status;
448a8bd581dSJasvinder Singh 
449a8bd581dSJasvinder Singh 	do {
450a8bd581dSJasvinder Singh 		status = rte_ring_sp_enqueue(msgq_rsp, rsp);
451a8bd581dSJasvinder Singh 	} while (status == -ENOBUFS);
452a8bd581dSJasvinder Singh }
453a8bd581dSJasvinder Singh 
45432e5d9b1SJasvinder Singh static struct thread_msg_rsp *
45532e5d9b1SJasvinder Singh thread_msg_handle_pipeline_enable(struct thread_data *t,
45632e5d9b1SJasvinder Singh 	struct thread_msg_req *req)
45732e5d9b1SJasvinder Singh {
45832e5d9b1SJasvinder Singh 	struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
45932e5d9b1SJasvinder Singh 	struct pipeline_data *p = &t->pipeline_data[t->n_pipelines];
46032e5d9b1SJasvinder Singh 	uint32_t i;
46132e5d9b1SJasvinder Singh 
46232e5d9b1SJasvinder Singh 	/* Request */
46332e5d9b1SJasvinder Singh 	if (t->n_pipelines >= THREAD_PIPELINES_MAX) {
46432e5d9b1SJasvinder Singh 		rsp->status = -1;
46532e5d9b1SJasvinder Singh 		return rsp;
46632e5d9b1SJasvinder Singh 	}
46732e5d9b1SJasvinder Singh 
46832e5d9b1SJasvinder Singh 	t->p[t->n_pipelines] = req->pipeline_enable.p;
46932e5d9b1SJasvinder Singh 
47032e5d9b1SJasvinder Singh 	p->p = req->pipeline_enable.p;
47132e5d9b1SJasvinder Singh 	for (i = 0; i < req->pipeline_enable.n_tables; i++)
47232e5d9b1SJasvinder Singh 		p->table_data[i].a =
47332e5d9b1SJasvinder Singh 			req->pipeline_enable.table[i].a;
47432e5d9b1SJasvinder Singh 
47532e5d9b1SJasvinder Singh 	p->n_tables = req->pipeline_enable.n_tables;
47632e5d9b1SJasvinder Singh 
47732e5d9b1SJasvinder Singh 	p->msgq_req = req->pipeline_enable.msgq_req;
47832e5d9b1SJasvinder Singh 	p->msgq_rsp = req->pipeline_enable.msgq_rsp;
47932e5d9b1SJasvinder Singh 	p->timer_period =
48032e5d9b1SJasvinder Singh 		(rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;
48132e5d9b1SJasvinder Singh 	p->time_next = rte_get_tsc_cycles() + p->timer_period;
48232e5d9b1SJasvinder Singh 
48332e5d9b1SJasvinder Singh 	t->n_pipelines++;
48432e5d9b1SJasvinder Singh 
48532e5d9b1SJasvinder Singh 	/* Response */
48632e5d9b1SJasvinder Singh 	rsp->status = 0;
48732e5d9b1SJasvinder Singh 	return rsp;
48832e5d9b1SJasvinder Singh }
48932e5d9b1SJasvinder Singh 
49032e5d9b1SJasvinder Singh static struct thread_msg_rsp *
49132e5d9b1SJasvinder Singh thread_msg_handle_pipeline_disable(struct thread_data *t,
49232e5d9b1SJasvinder Singh 	struct thread_msg_req *req)
49332e5d9b1SJasvinder Singh {
49432e5d9b1SJasvinder Singh 	struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
49532e5d9b1SJasvinder Singh 	uint32_t n_pipelines = t->n_pipelines;
49632e5d9b1SJasvinder Singh 	struct rte_pipeline *pipeline = req->pipeline_disable.p;
49732e5d9b1SJasvinder Singh 	uint32_t i;
49832e5d9b1SJasvinder Singh 
49932e5d9b1SJasvinder Singh 	/* find pipeline */
50032e5d9b1SJasvinder Singh 	for (i = 0; i < n_pipelines; i++) {
50132e5d9b1SJasvinder Singh 		struct pipeline_data *p = &t->pipeline_data[i];
50232e5d9b1SJasvinder Singh 
50332e5d9b1SJasvinder Singh 		if (p->p != pipeline)
50432e5d9b1SJasvinder Singh 			continue;
50532e5d9b1SJasvinder Singh 
50632e5d9b1SJasvinder Singh 		if (i < n_pipelines - 1) {
50732e5d9b1SJasvinder Singh 			struct rte_pipeline *pipeline_last =
50832e5d9b1SJasvinder Singh 				t->p[n_pipelines - 1];
50932e5d9b1SJasvinder Singh 			struct pipeline_data *p_last =
51032e5d9b1SJasvinder Singh 				&t->pipeline_data[n_pipelines - 1];
51132e5d9b1SJasvinder Singh 
51232e5d9b1SJasvinder Singh 			t->p[i] = pipeline_last;
51332e5d9b1SJasvinder Singh 			memcpy(p, p_last, sizeof(*p));
51432e5d9b1SJasvinder Singh 		}
51532e5d9b1SJasvinder Singh 
51632e5d9b1SJasvinder Singh 		t->n_pipelines--;
51732e5d9b1SJasvinder Singh 
51832e5d9b1SJasvinder Singh 		rsp->status = 0;
51932e5d9b1SJasvinder Singh 		return rsp;
52032e5d9b1SJasvinder Singh 	}
52132e5d9b1SJasvinder Singh 
52232e5d9b1SJasvinder Singh 	/* should not get here */
52332e5d9b1SJasvinder Singh 	rsp->status = 0;
52432e5d9b1SJasvinder Singh 	return rsp;
52532e5d9b1SJasvinder Singh }
52632e5d9b1SJasvinder Singh 
527a8bd581dSJasvinder Singh static void
528a8bd581dSJasvinder Singh thread_msg_handle(struct thread_data *t)
529a8bd581dSJasvinder Singh {
530a8bd581dSJasvinder Singh 	for ( ; ; ) {
531a8bd581dSJasvinder Singh 		struct thread_msg_req *req;
532a8bd581dSJasvinder Singh 		struct thread_msg_rsp *rsp;
533a8bd581dSJasvinder Singh 
534a8bd581dSJasvinder Singh 		req = thread_msg_recv(t->msgq_req);
535a8bd581dSJasvinder Singh 		if (req == NULL)
536a8bd581dSJasvinder Singh 			break;
537a8bd581dSJasvinder Singh 
538a8bd581dSJasvinder Singh 		switch (req->type) {
53932e5d9b1SJasvinder Singh 		case THREAD_REQ_PIPELINE_ENABLE:
54032e5d9b1SJasvinder Singh 			rsp = thread_msg_handle_pipeline_enable(t, req);
54132e5d9b1SJasvinder Singh 			break;
54232e5d9b1SJasvinder Singh 
54332e5d9b1SJasvinder Singh 		case THREAD_REQ_PIPELINE_DISABLE:
54432e5d9b1SJasvinder Singh 			rsp = thread_msg_handle_pipeline_disable(t, req);
54532e5d9b1SJasvinder Singh 			break;
54632e5d9b1SJasvinder Singh 
547a8bd581dSJasvinder Singh 		default:
548a8bd581dSJasvinder Singh 			rsp = (struct thread_msg_rsp *) req;
549a8bd581dSJasvinder Singh 			rsp->status = -1;
550a8bd581dSJasvinder Singh 		}
551a8bd581dSJasvinder Singh 
552a8bd581dSJasvinder Singh 		thread_msg_send(t->msgq_rsp, rsp);
553a8bd581dSJasvinder Singh 	}
554a8bd581dSJasvinder Singh }
555a8bd581dSJasvinder Singh 
556a8bd581dSJasvinder Singh /**
557cb056611SStephen Hemminger  * Main thread & data plane threads: message passing
558a8bd581dSJasvinder Singh  */
559a8bd581dSJasvinder Singh enum pipeline_req_type {
5606b1b3c3cSJasvinder Singh 	/* Port IN */
56150e73d05SJasvinder Singh 	PIPELINE_REQ_PORT_IN_STATS_READ,
5626b1b3c3cSJasvinder Singh 	PIPELINE_REQ_PORT_IN_ENABLE,
5636b1b3c3cSJasvinder Singh 	PIPELINE_REQ_PORT_IN_DISABLE,
5646b1b3c3cSJasvinder Singh 
56550e73d05SJasvinder Singh 	/* Port OUT */
56650e73d05SJasvinder Singh 	PIPELINE_REQ_PORT_OUT_STATS_READ,
56750e73d05SJasvinder Singh 
56850e73d05SJasvinder Singh 	/* Table */
56950e73d05SJasvinder Singh 	PIPELINE_REQ_TABLE_STATS_READ,
570a3a95b7dSJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_ADD,
571a3a95b7dSJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
5723186282fSJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_ADD_BULK,
573f634e4c5SJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_DELETE,
574f634e4c5SJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
575c64b9121SJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_STATS_READ,
5767e11393eSJasvinder Singh 	PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
5777e11393eSJasvinder Singh 	PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
578e92058d6SJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_MTR_READ,
5792b82ef48SJasvinder Singh 	PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
580d0d306c7SJasvinder Singh 	PIPELINE_REQ_TABLE_RULE_TTL_READ,
581a3169ee5SCristian Dumitrescu 	PIPELINE_REQ_TABLE_RULE_TIME_READ,
582a8bd581dSJasvinder Singh 	PIPELINE_REQ_MAX
583a8bd581dSJasvinder Singh };
584a8bd581dSJasvinder Singh 
58550e73d05SJasvinder Singh struct pipeline_msg_req_port_in_stats_read {
58650e73d05SJasvinder Singh 	int clear;
58750e73d05SJasvinder Singh };
58850e73d05SJasvinder Singh 
58950e73d05SJasvinder Singh struct pipeline_msg_req_port_out_stats_read {
59050e73d05SJasvinder Singh 	int clear;
59150e73d05SJasvinder Singh };
59250e73d05SJasvinder Singh 
59350e73d05SJasvinder Singh struct pipeline_msg_req_table_stats_read {
59450e73d05SJasvinder Singh 	int clear;
59550e73d05SJasvinder Singh };
59650e73d05SJasvinder Singh 
597a3a95b7dSJasvinder Singh struct pipeline_msg_req_table_rule_add {
598a3a95b7dSJasvinder Singh 	struct table_rule_match match;
599a3a95b7dSJasvinder Singh 	struct table_rule_action action;
600a3a95b7dSJasvinder Singh };
601a3a95b7dSJasvinder Singh 
602a3a95b7dSJasvinder Singh struct pipeline_msg_req_table_rule_add_default {
603a3a95b7dSJasvinder Singh 	struct table_rule_action action;
604a3a95b7dSJasvinder Singh };
605a3a95b7dSJasvinder Singh 
6063186282fSJasvinder Singh struct pipeline_msg_req_table_rule_add_bulk {
60727b333b2SCristian Dumitrescu 	struct table_rule_list *list;
6083186282fSJasvinder Singh 	int bulk;
6093186282fSJasvinder Singh };
6103186282fSJasvinder Singh 
611f634e4c5SJasvinder Singh struct pipeline_msg_req_table_rule_delete {
612f634e4c5SJasvinder Singh 	struct table_rule_match match;
613f634e4c5SJasvinder Singh };
614f634e4c5SJasvinder Singh 
615c64b9121SJasvinder Singh struct pipeline_msg_req_table_rule_stats_read {
616c64b9121SJasvinder Singh 	void *data;
617c64b9121SJasvinder Singh 	int clear;
618c64b9121SJasvinder Singh };
619c64b9121SJasvinder Singh 
6207e11393eSJasvinder Singh struct pipeline_msg_req_table_mtr_profile_add {
6217e11393eSJasvinder Singh 	uint32_t meter_profile_id;
6227e11393eSJasvinder Singh 	struct rte_table_action_meter_profile profile;
6237e11393eSJasvinder Singh };
6247e11393eSJasvinder Singh 
6257e11393eSJasvinder Singh struct pipeline_msg_req_table_mtr_profile_delete {
6267e11393eSJasvinder Singh 	uint32_t meter_profile_id;
6277e11393eSJasvinder Singh };
6287e11393eSJasvinder Singh 
629e92058d6SJasvinder Singh struct pipeline_msg_req_table_rule_mtr_read {
630e92058d6SJasvinder Singh 	void *data;
631e92058d6SJasvinder Singh 	uint32_t tc_mask;
632e92058d6SJasvinder Singh 	int clear;
633e92058d6SJasvinder Singh };
6342b82ef48SJasvinder Singh 
6352b82ef48SJasvinder Singh struct pipeline_msg_req_table_dscp_table_update {
6362b82ef48SJasvinder Singh 	uint64_t dscp_mask;
6372b82ef48SJasvinder Singh 	struct rte_table_action_dscp_table dscp_table;
6382b82ef48SJasvinder Singh };
6392b82ef48SJasvinder Singh 
640d0d306c7SJasvinder Singh struct pipeline_msg_req_table_rule_ttl_read {
641d0d306c7SJasvinder Singh 	void *data;
642d0d306c7SJasvinder Singh 	int clear;
643d0d306c7SJasvinder Singh };
644d0d306c7SJasvinder Singh 
645a3169ee5SCristian Dumitrescu struct pipeline_msg_req_table_rule_time_read {
646a3169ee5SCristian Dumitrescu 	void *data;
647a3169ee5SCristian Dumitrescu };
648a3169ee5SCristian Dumitrescu 
649a8bd581dSJasvinder Singh struct pipeline_msg_req {
650a8bd581dSJasvinder Singh 	enum pipeline_req_type type;
6516b1b3c3cSJasvinder Singh 	uint32_t id; /* Port IN, port OUT or table ID */
65250e73d05SJasvinder Singh 
65350e73d05SJasvinder Singh 	union {
65450e73d05SJasvinder Singh 		struct pipeline_msg_req_port_in_stats_read port_in_stats_read;
65550e73d05SJasvinder Singh 		struct pipeline_msg_req_port_out_stats_read port_out_stats_read;
65650e73d05SJasvinder Singh 		struct pipeline_msg_req_table_stats_read table_stats_read;
657a3a95b7dSJasvinder Singh 		struct pipeline_msg_req_table_rule_add table_rule_add;
658a3a95b7dSJasvinder Singh 		struct pipeline_msg_req_table_rule_add_default table_rule_add_default;
6593186282fSJasvinder Singh 		struct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;
660f634e4c5SJasvinder Singh 		struct pipeline_msg_req_table_rule_delete table_rule_delete;
661c64b9121SJasvinder Singh 		struct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;
6627e11393eSJasvinder Singh 		struct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;
6637e11393eSJasvinder Singh 		struct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;
664e92058d6SJasvinder Singh 		struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
6652b82ef48SJasvinder Singh 		struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
666d0d306c7SJasvinder Singh 		struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
667a3169ee5SCristian Dumitrescu 		struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
66850e73d05SJasvinder Singh 	};
66950e73d05SJasvinder Singh };
67050e73d05SJasvinder Singh 
67150e73d05SJasvinder Singh struct pipeline_msg_rsp_port_in_stats_read {
67250e73d05SJasvinder Singh 	struct rte_pipeline_port_in_stats stats;
67350e73d05SJasvinder Singh };
67450e73d05SJasvinder Singh 
67550e73d05SJasvinder Singh struct pipeline_msg_rsp_port_out_stats_read {
67650e73d05SJasvinder Singh 	struct rte_pipeline_port_out_stats stats;
67750e73d05SJasvinder Singh };
67850e73d05SJasvinder Singh 
67950e73d05SJasvinder Singh struct pipeline_msg_rsp_table_stats_read {
68050e73d05SJasvinder Singh 	struct rte_pipeline_table_stats stats;
681a8bd581dSJasvinder Singh };
682a8bd581dSJasvinder Singh 
683a3a95b7dSJasvinder Singh struct pipeline_msg_rsp_table_rule_add {
684a3a95b7dSJasvinder Singh 	void *data;
685a3a95b7dSJasvinder Singh };
686a3a95b7dSJasvinder Singh 
687a3a95b7dSJasvinder Singh struct pipeline_msg_rsp_table_rule_add_default {
688a3a95b7dSJasvinder Singh 	void *data;
689a3a95b7dSJasvinder Singh };
690a3a95b7dSJasvinder Singh 
6913186282fSJasvinder Singh struct pipeline_msg_rsp_table_rule_add_bulk {
6923186282fSJasvinder Singh 	uint32_t n_rules;
6933186282fSJasvinder Singh };
6943186282fSJasvinder Singh 
695c64b9121SJasvinder Singh struct pipeline_msg_rsp_table_rule_stats_read {
696c64b9121SJasvinder Singh 	struct rte_table_action_stats_counters stats;
697c64b9121SJasvinder Singh };
698c64b9121SJasvinder Singh 
699e92058d6SJasvinder Singh struct pipeline_msg_rsp_table_rule_mtr_read {
700e92058d6SJasvinder Singh 	struct rte_table_action_mtr_counters stats;
701e92058d6SJasvinder Singh };
702e92058d6SJasvinder Singh 
703d0d306c7SJasvinder Singh struct pipeline_msg_rsp_table_rule_ttl_read {
704d0d306c7SJasvinder Singh 	struct rte_table_action_ttl_counters stats;
705d0d306c7SJasvinder Singh };
706d0d306c7SJasvinder Singh 
707a3169ee5SCristian Dumitrescu struct pipeline_msg_rsp_table_rule_time_read {
708a3169ee5SCristian Dumitrescu 	uint64_t timestamp;
709a3169ee5SCristian Dumitrescu };
710a3169ee5SCristian Dumitrescu 
711a8bd581dSJasvinder Singh struct pipeline_msg_rsp {
712a8bd581dSJasvinder Singh 	int status;
71350e73d05SJasvinder Singh 
71450e73d05SJasvinder Singh 	union {
71550e73d05SJasvinder Singh 		struct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;
71650e73d05SJasvinder Singh 		struct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;
71750e73d05SJasvinder Singh 		struct pipeline_msg_rsp_table_stats_read table_stats_read;
718a3a95b7dSJasvinder Singh 		struct pipeline_msg_rsp_table_rule_add table_rule_add;
719a3a95b7dSJasvinder Singh 		struct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;
7203186282fSJasvinder Singh 		struct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;
721c64b9121SJasvinder Singh 		struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
722e92058d6SJasvinder Singh 		struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
723d0d306c7SJasvinder Singh 		struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
724a3169ee5SCristian Dumitrescu 		struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
72550e73d05SJasvinder Singh 	};
726a8bd581dSJasvinder Singh };
727a8bd581dSJasvinder Singh 
728a8bd581dSJasvinder Singh /**
729cb056611SStephen Hemminger  * Main thread
7306b1b3c3cSJasvinder Singh  */
7316b1b3c3cSJasvinder Singh static struct pipeline_msg_req *
7326b1b3c3cSJasvinder Singh pipeline_msg_alloc(void)
7336b1b3c3cSJasvinder Singh {
7346b1b3c3cSJasvinder Singh 	size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
7356b1b3c3cSJasvinder Singh 		sizeof(struct pipeline_msg_rsp));
7366b1b3c3cSJasvinder Singh 
7376b1b3c3cSJasvinder Singh 	return calloc(1, size);
7386b1b3c3cSJasvinder Singh }
7396b1b3c3cSJasvinder Singh 
7406b1b3c3cSJasvinder Singh static void
7416b1b3c3cSJasvinder Singh pipeline_msg_free(struct pipeline_msg_rsp *rsp)
7426b1b3c3cSJasvinder Singh {
7436b1b3c3cSJasvinder Singh 	free(rsp);
7446b1b3c3cSJasvinder Singh }
7456b1b3c3cSJasvinder Singh 
7466b1b3c3cSJasvinder Singh static struct pipeline_msg_rsp *
7476b1b3c3cSJasvinder Singh pipeline_msg_send_recv(struct pipeline *p,
7486b1b3c3cSJasvinder Singh 	struct pipeline_msg_req *req)
7496b1b3c3cSJasvinder Singh {
7506b1b3c3cSJasvinder Singh 	struct rte_ring *msgq_req = p->msgq_req;
7516b1b3c3cSJasvinder Singh 	struct rte_ring *msgq_rsp = p->msgq_rsp;
7526b1b3c3cSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
7536b1b3c3cSJasvinder Singh 	int status;
7546b1b3c3cSJasvinder Singh 
7556b1b3c3cSJasvinder Singh 	/* send */
7566b1b3c3cSJasvinder Singh 	do {
7576b1b3c3cSJasvinder Singh 		status = rte_ring_sp_enqueue(msgq_req, req);
7586b1b3c3cSJasvinder Singh 	} while (status == -ENOBUFS);
7596b1b3c3cSJasvinder Singh 
7606b1b3c3cSJasvinder Singh 	/* recv */
7616b1b3c3cSJasvinder Singh 	do {
7626b1b3c3cSJasvinder Singh 		status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
7636b1b3c3cSJasvinder Singh 	} while (status != 0);
7646b1b3c3cSJasvinder Singh 
7656b1b3c3cSJasvinder Singh 	return rsp;
7666b1b3c3cSJasvinder Singh }
7676b1b3c3cSJasvinder Singh 
7686b1b3c3cSJasvinder Singh int
76950e73d05SJasvinder Singh pipeline_port_in_stats_read(const char *pipeline_name,
77050e73d05SJasvinder Singh 	uint32_t port_id,
77150e73d05SJasvinder Singh 	struct rte_pipeline_port_in_stats *stats,
77250e73d05SJasvinder Singh 	int clear)
77350e73d05SJasvinder Singh {
77450e73d05SJasvinder Singh 	struct pipeline *p;
77550e73d05SJasvinder Singh 	struct pipeline_msg_req *req;
77650e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
77750e73d05SJasvinder Singh 	int status;
77850e73d05SJasvinder Singh 
77950e73d05SJasvinder Singh 	/* Check input params */
78050e73d05SJasvinder Singh 	if ((pipeline_name == NULL) ||
78150e73d05SJasvinder Singh 		(stats == NULL))
78250e73d05SJasvinder Singh 		return -1;
78350e73d05SJasvinder Singh 
78450e73d05SJasvinder Singh 	p = pipeline_find(pipeline_name);
78550e73d05SJasvinder Singh 	if ((p == NULL) ||
78650e73d05SJasvinder Singh 		(port_id >= p->n_ports_in))
78750e73d05SJasvinder Singh 		return -1;
78850e73d05SJasvinder Singh 
789f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
790f68a1d3fSJasvinder Singh 		status = rte_pipeline_port_in_stats_read(p->p,
791f68a1d3fSJasvinder Singh 			port_id,
792f68a1d3fSJasvinder Singh 			stats,
793f68a1d3fSJasvinder Singh 			clear);
794f68a1d3fSJasvinder Singh 
795f68a1d3fSJasvinder Singh 		return status;
796f68a1d3fSJasvinder Singh 	}
797f68a1d3fSJasvinder Singh 
79850e73d05SJasvinder Singh 	/* Allocate request */
79950e73d05SJasvinder Singh 	req = pipeline_msg_alloc();
80050e73d05SJasvinder Singh 	if (req == NULL)
80150e73d05SJasvinder Singh 		return -1;
80250e73d05SJasvinder Singh 
80350e73d05SJasvinder Singh 	/* Write request */
80450e73d05SJasvinder Singh 	req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
80550e73d05SJasvinder Singh 	req->id = port_id;
80650e73d05SJasvinder Singh 	req->port_in_stats_read.clear = clear;
80750e73d05SJasvinder Singh 
80850e73d05SJasvinder Singh 	/* Send request and wait for response */
80950e73d05SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
81050e73d05SJasvinder Singh 
81150e73d05SJasvinder Singh 	/* Read response */
81250e73d05SJasvinder Singh 	status = rsp->status;
813c4160d30SCristian Dumitrescu 	if (status == 0)
81450e73d05SJasvinder Singh 		memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
81550e73d05SJasvinder Singh 
81650e73d05SJasvinder Singh 	/* Free response */
81750e73d05SJasvinder Singh 	pipeline_msg_free(rsp);
81850e73d05SJasvinder Singh 
81950e73d05SJasvinder Singh 	return status;
82050e73d05SJasvinder Singh }
82150e73d05SJasvinder Singh 
82250e73d05SJasvinder Singh int
8236b1b3c3cSJasvinder Singh pipeline_port_in_enable(const char *pipeline_name,
8246b1b3c3cSJasvinder Singh 	uint32_t port_id)
8256b1b3c3cSJasvinder Singh {
8266b1b3c3cSJasvinder Singh 	struct pipeline *p;
8276b1b3c3cSJasvinder Singh 	struct pipeline_msg_req *req;
8286b1b3c3cSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
8296b1b3c3cSJasvinder Singh 	int status;
8306b1b3c3cSJasvinder Singh 
8316b1b3c3cSJasvinder Singh 	/* Check input params */
8326b1b3c3cSJasvinder Singh 	if (pipeline_name == NULL)
8336b1b3c3cSJasvinder Singh 		return -1;
8346b1b3c3cSJasvinder Singh 
8356b1b3c3cSJasvinder Singh 	p = pipeline_find(pipeline_name);
8366b1b3c3cSJasvinder Singh 	if ((p == NULL) ||
8376b1b3c3cSJasvinder Singh 		(port_id >= p->n_ports_in))
8386b1b3c3cSJasvinder Singh 		return -1;
8396b1b3c3cSJasvinder Singh 
840f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
841f68a1d3fSJasvinder Singh 		status = rte_pipeline_port_in_enable(p->p, port_id);
842f68a1d3fSJasvinder Singh 		return status;
843f68a1d3fSJasvinder Singh 	}
844f68a1d3fSJasvinder Singh 
8456b1b3c3cSJasvinder Singh 	/* Allocate request */
8466b1b3c3cSJasvinder Singh 	req = pipeline_msg_alloc();
8476b1b3c3cSJasvinder Singh 	if (req == NULL)
8486b1b3c3cSJasvinder Singh 		return -1;
8496b1b3c3cSJasvinder Singh 
8506b1b3c3cSJasvinder Singh 	/* Write request */
8516b1b3c3cSJasvinder Singh 	req->type = PIPELINE_REQ_PORT_IN_ENABLE;
8526b1b3c3cSJasvinder Singh 	req->id = port_id;
8536b1b3c3cSJasvinder Singh 
8546b1b3c3cSJasvinder Singh 	/* Send request and wait for response */
8556b1b3c3cSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
8566b1b3c3cSJasvinder Singh 
8576b1b3c3cSJasvinder Singh 	/* Read response */
8586b1b3c3cSJasvinder Singh 	status = rsp->status;
8596b1b3c3cSJasvinder Singh 
8606b1b3c3cSJasvinder Singh 	/* Free response */
8616b1b3c3cSJasvinder Singh 	pipeline_msg_free(rsp);
8626b1b3c3cSJasvinder Singh 
8636b1b3c3cSJasvinder Singh 	return status;
8646b1b3c3cSJasvinder Singh }
8656b1b3c3cSJasvinder Singh 
8666b1b3c3cSJasvinder Singh int
8676b1b3c3cSJasvinder Singh pipeline_port_in_disable(const char *pipeline_name,
8686b1b3c3cSJasvinder Singh 	uint32_t port_id)
8696b1b3c3cSJasvinder Singh {
8706b1b3c3cSJasvinder Singh 	struct pipeline *p;
8716b1b3c3cSJasvinder Singh 	struct pipeline_msg_req *req;
8726b1b3c3cSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
8736b1b3c3cSJasvinder Singh 	int status;
8746b1b3c3cSJasvinder Singh 
8756b1b3c3cSJasvinder Singh 	/* Check input params */
8766b1b3c3cSJasvinder Singh 	if (pipeline_name == NULL)
8776b1b3c3cSJasvinder Singh 		return -1;
8786b1b3c3cSJasvinder Singh 
8796b1b3c3cSJasvinder Singh 	p = pipeline_find(pipeline_name);
8806b1b3c3cSJasvinder Singh 	if ((p == NULL) ||
8816b1b3c3cSJasvinder Singh 		(port_id >= p->n_ports_in))
8826b1b3c3cSJasvinder Singh 		return -1;
8836b1b3c3cSJasvinder Singh 
884f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
885f68a1d3fSJasvinder Singh 		status = rte_pipeline_port_in_disable(p->p, port_id);
886f68a1d3fSJasvinder Singh 		return status;
887f68a1d3fSJasvinder Singh 	}
888f68a1d3fSJasvinder Singh 
8896b1b3c3cSJasvinder Singh 	/* Allocate request */
8906b1b3c3cSJasvinder Singh 	req = pipeline_msg_alloc();
8916b1b3c3cSJasvinder Singh 	if (req == NULL)
8926b1b3c3cSJasvinder Singh 		return -1;
8936b1b3c3cSJasvinder Singh 
8946b1b3c3cSJasvinder Singh 	/* Write request */
8956b1b3c3cSJasvinder Singh 	req->type = PIPELINE_REQ_PORT_IN_DISABLE;
8966b1b3c3cSJasvinder Singh 	req->id = port_id;
8976b1b3c3cSJasvinder Singh 
8986b1b3c3cSJasvinder Singh 	/* Send request and wait for response */
8996b1b3c3cSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
9006b1b3c3cSJasvinder Singh 
9016b1b3c3cSJasvinder Singh 	/* Read response */
9026b1b3c3cSJasvinder Singh 	status = rsp->status;
9036b1b3c3cSJasvinder Singh 
9046b1b3c3cSJasvinder Singh 	/* Free response */
9056b1b3c3cSJasvinder Singh 	pipeline_msg_free(rsp);
9066b1b3c3cSJasvinder Singh 
9076b1b3c3cSJasvinder Singh 	return status;
9086b1b3c3cSJasvinder Singh }
9096b1b3c3cSJasvinder Singh 
91050e73d05SJasvinder Singh int
91150e73d05SJasvinder Singh pipeline_port_out_stats_read(const char *pipeline_name,
91250e73d05SJasvinder Singh 	uint32_t port_id,
91350e73d05SJasvinder Singh 	struct rte_pipeline_port_out_stats *stats,
91450e73d05SJasvinder Singh 	int clear)
91550e73d05SJasvinder Singh {
91650e73d05SJasvinder Singh 	struct pipeline *p;
91750e73d05SJasvinder Singh 	struct pipeline_msg_req *req;
91850e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
91950e73d05SJasvinder Singh 	int status;
92050e73d05SJasvinder Singh 
92150e73d05SJasvinder Singh 	/* Check input params */
92250e73d05SJasvinder Singh 	if ((pipeline_name == NULL) ||
92350e73d05SJasvinder Singh 		(stats == NULL))
92450e73d05SJasvinder Singh 		return -1;
92550e73d05SJasvinder Singh 
92650e73d05SJasvinder Singh 	p = pipeline_find(pipeline_name);
92750e73d05SJasvinder Singh 	if ((p == NULL) ||
92850e73d05SJasvinder Singh 		(port_id >= p->n_ports_out))
92950e73d05SJasvinder Singh 		return -1;
93050e73d05SJasvinder Singh 
931f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
932f68a1d3fSJasvinder Singh 		status = rte_pipeline_port_out_stats_read(p->p,
933f68a1d3fSJasvinder Singh 			port_id,
934f68a1d3fSJasvinder Singh 			stats,
935f68a1d3fSJasvinder Singh 			clear);
936f68a1d3fSJasvinder Singh 
937f68a1d3fSJasvinder Singh 		return status;
938f68a1d3fSJasvinder Singh 	}
939f68a1d3fSJasvinder Singh 
94050e73d05SJasvinder Singh 	/* Allocate request */
94150e73d05SJasvinder Singh 	req = pipeline_msg_alloc();
94250e73d05SJasvinder Singh 	if (req == NULL)
94350e73d05SJasvinder Singh 		return -1;
94450e73d05SJasvinder Singh 
94550e73d05SJasvinder Singh 	/* Write request */
94650e73d05SJasvinder Singh 	req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
94750e73d05SJasvinder Singh 	req->id = port_id;
94850e73d05SJasvinder Singh 	req->port_out_stats_read.clear = clear;
94950e73d05SJasvinder Singh 
95050e73d05SJasvinder Singh 	/* Send request and wait for response */
95150e73d05SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
95250e73d05SJasvinder Singh 
95350e73d05SJasvinder Singh 	/* Read response */
95450e73d05SJasvinder Singh 	status = rsp->status;
955c4160d30SCristian Dumitrescu 	if (status == 0)
95650e73d05SJasvinder Singh 		memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
95750e73d05SJasvinder Singh 
95850e73d05SJasvinder Singh 	/* Free response */
95950e73d05SJasvinder Singh 	pipeline_msg_free(rsp);
96050e73d05SJasvinder Singh 
96150e73d05SJasvinder Singh 	return status;
96250e73d05SJasvinder Singh }
96350e73d05SJasvinder Singh 
96450e73d05SJasvinder Singh int
96550e73d05SJasvinder Singh pipeline_table_stats_read(const char *pipeline_name,
96650e73d05SJasvinder Singh 	uint32_t table_id,
96750e73d05SJasvinder Singh 	struct rte_pipeline_table_stats *stats,
96850e73d05SJasvinder Singh 	int clear)
96950e73d05SJasvinder Singh {
97050e73d05SJasvinder Singh 	struct pipeline *p;
97150e73d05SJasvinder Singh 	struct pipeline_msg_req *req;
97250e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
97350e73d05SJasvinder Singh 	int status;
97450e73d05SJasvinder Singh 
97550e73d05SJasvinder Singh 	/* Check input params */
97650e73d05SJasvinder Singh 	if ((pipeline_name == NULL) ||
97750e73d05SJasvinder Singh 		(stats == NULL))
97850e73d05SJasvinder Singh 		return -1;
97950e73d05SJasvinder Singh 
98050e73d05SJasvinder Singh 	p = pipeline_find(pipeline_name);
98150e73d05SJasvinder Singh 	if ((p == NULL) ||
98250e73d05SJasvinder Singh 		(table_id >= p->n_tables))
98350e73d05SJasvinder Singh 		return -1;
98450e73d05SJasvinder Singh 
985f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
986f68a1d3fSJasvinder Singh 		status = rte_pipeline_table_stats_read(p->p,
987f68a1d3fSJasvinder Singh 			table_id,
988f68a1d3fSJasvinder Singh 			stats,
989f68a1d3fSJasvinder Singh 			clear);
990f68a1d3fSJasvinder Singh 
991f68a1d3fSJasvinder Singh 		return status;
992f68a1d3fSJasvinder Singh 	}
993f68a1d3fSJasvinder Singh 
99450e73d05SJasvinder Singh 	/* Allocate request */
99550e73d05SJasvinder Singh 	req = pipeline_msg_alloc();
99650e73d05SJasvinder Singh 	if (req == NULL)
99750e73d05SJasvinder Singh 		return -1;
99850e73d05SJasvinder Singh 
99950e73d05SJasvinder Singh 	/* Write request */
100050e73d05SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_STATS_READ;
100150e73d05SJasvinder Singh 	req->id = table_id;
100250e73d05SJasvinder Singh 	req->table_stats_read.clear = clear;
100350e73d05SJasvinder Singh 
100450e73d05SJasvinder Singh 	/* Send request and wait for response */
100550e73d05SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
100650e73d05SJasvinder Singh 
100750e73d05SJasvinder Singh 	/* Read response */
100850e73d05SJasvinder Singh 	status = rsp->status;
1009c4160d30SCristian Dumitrescu 	if (status == 0)
101050e73d05SJasvinder Singh 		memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
101150e73d05SJasvinder Singh 
101250e73d05SJasvinder Singh 	/* Free response */
101350e73d05SJasvinder Singh 	pipeline_msg_free(rsp);
101450e73d05SJasvinder Singh 
101550e73d05SJasvinder Singh 	return status;
101650e73d05SJasvinder Singh }
10176b1b3c3cSJasvinder Singh 
1018a3a95b7dSJasvinder Singh static int
1019a3a95b7dSJasvinder Singh match_check(struct table_rule_match *match,
1020a3a95b7dSJasvinder Singh 	struct pipeline *p,
1021a3a95b7dSJasvinder Singh 	uint32_t table_id)
1022a3a95b7dSJasvinder Singh {
1023a3a95b7dSJasvinder Singh 	struct table *table;
1024a3a95b7dSJasvinder Singh 
1025a3a95b7dSJasvinder Singh 	if ((match == NULL) ||
1026a3a95b7dSJasvinder Singh 		(p == NULL) ||
1027a3a95b7dSJasvinder Singh 		(table_id >= p->n_tables))
1028a3a95b7dSJasvinder Singh 		return -1;
1029a3a95b7dSJasvinder Singh 
1030a3a95b7dSJasvinder Singh 	table = &p->table[table_id];
1031a3a95b7dSJasvinder Singh 	if (match->match_type != table->params.match_type)
1032a3a95b7dSJasvinder Singh 		return -1;
1033a3a95b7dSJasvinder Singh 
1034a3a95b7dSJasvinder Singh 	switch (match->match_type) {
1035a3a95b7dSJasvinder Singh 	case TABLE_ACL:
1036a3a95b7dSJasvinder Singh 	{
1037a3a95b7dSJasvinder Singh 		struct table_acl_params *t = &table->params.match.acl;
1038a3a95b7dSJasvinder Singh 		struct table_rule_match_acl *r = &match->match.acl;
1039a3a95b7dSJasvinder Singh 
1040a3a95b7dSJasvinder Singh 		if ((r->ip_version && (t->ip_version == 0)) ||
1041a3a95b7dSJasvinder Singh 			((r->ip_version == 0) && t->ip_version))
1042a3a95b7dSJasvinder Singh 			return -1;
1043a3a95b7dSJasvinder Singh 
1044a3a95b7dSJasvinder Singh 		if (r->ip_version) {
1045a3a95b7dSJasvinder Singh 			if ((r->sa_depth > 32) ||
1046a3a95b7dSJasvinder Singh 				(r->da_depth > 32))
1047a3a95b7dSJasvinder Singh 				return -1;
1048a3a95b7dSJasvinder Singh 		} else {
1049a3a95b7dSJasvinder Singh 			if ((r->sa_depth > 128) ||
1050a3a95b7dSJasvinder Singh 				(r->da_depth > 128))
1051a3a95b7dSJasvinder Singh 				return -1;
1052a3a95b7dSJasvinder Singh 		}
1053a3a95b7dSJasvinder Singh 		return 0;
1054a3a95b7dSJasvinder Singh 	}
1055a3a95b7dSJasvinder Singh 
1056a3a95b7dSJasvinder Singh 	case TABLE_ARRAY:
1057a3a95b7dSJasvinder Singh 		return 0;
1058a3a95b7dSJasvinder Singh 
1059a3a95b7dSJasvinder Singh 	case TABLE_HASH:
1060a3a95b7dSJasvinder Singh 		return 0;
1061a3a95b7dSJasvinder Singh 
1062a3a95b7dSJasvinder Singh 	case TABLE_LPM:
1063a3a95b7dSJasvinder Singh 	{
1064a3a95b7dSJasvinder Singh 		struct table_lpm_params *t = &table->params.match.lpm;
1065a3a95b7dSJasvinder Singh 		struct table_rule_match_lpm *r = &match->match.lpm;
1066a3a95b7dSJasvinder Singh 
1067a3a95b7dSJasvinder Singh 		if ((r->ip_version && (t->key_size != 4)) ||
1068a3a95b7dSJasvinder Singh 			((r->ip_version == 0) && (t->key_size != 16)))
1069a3a95b7dSJasvinder Singh 			return -1;
1070a3a95b7dSJasvinder Singh 
1071a3a95b7dSJasvinder Singh 		if (r->ip_version) {
1072a3a95b7dSJasvinder Singh 			if (r->depth > 32)
1073a3a95b7dSJasvinder Singh 				return -1;
1074a3a95b7dSJasvinder Singh 		} else {
1075a3a95b7dSJasvinder Singh 			if (r->depth > 128)
1076a3a95b7dSJasvinder Singh 				return -1;
1077a3a95b7dSJasvinder Singh 		}
1078a3a95b7dSJasvinder Singh 		return 0;
1079a3a95b7dSJasvinder Singh 	}
1080a3a95b7dSJasvinder Singh 
1081a3a95b7dSJasvinder Singh 	case TABLE_STUB:
1082a3a95b7dSJasvinder Singh 		return -1;
1083a3a95b7dSJasvinder Singh 
1084a3a95b7dSJasvinder Singh 	default:
1085a3a95b7dSJasvinder Singh 		return -1;
1086a3a95b7dSJasvinder Singh 	}
1087a3a95b7dSJasvinder Singh }
1088a3a95b7dSJasvinder Singh 
1089a3a95b7dSJasvinder Singh static int
1090a3a95b7dSJasvinder Singh action_check(struct table_rule_action *action,
1091a3a95b7dSJasvinder Singh 	struct pipeline *p,
1092a3a95b7dSJasvinder Singh 	uint32_t table_id)
1093a3a95b7dSJasvinder Singh {
1094a3a95b7dSJasvinder Singh 	struct table_action_profile *ap;
1095a3a95b7dSJasvinder Singh 
1096a3a95b7dSJasvinder Singh 	if ((action == NULL) ||
1097a3a95b7dSJasvinder Singh 		(p == NULL) ||
1098a3a95b7dSJasvinder Singh 		(table_id >= p->n_tables))
1099a3a95b7dSJasvinder Singh 		return -1;
1100a3a95b7dSJasvinder Singh 
1101a3a95b7dSJasvinder Singh 	ap = p->table[table_id].ap;
1102a3a95b7dSJasvinder Singh 	if (action->action_mask != ap->params.action_mask)
1103a3a95b7dSJasvinder Singh 		return -1;
1104a3a95b7dSJasvinder Singh 
1105a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
1106a3a95b7dSJasvinder Singh 		if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
1107a3a95b7dSJasvinder Singh 			(action->fwd.id >= p->n_ports_out))
1108a3a95b7dSJasvinder Singh 			return -1;
1109a3a95b7dSJasvinder Singh 
1110a3a95b7dSJasvinder Singh 		if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
1111a3a95b7dSJasvinder Singh 			(action->fwd.id >= p->n_tables))
1112a3a95b7dSJasvinder Singh 			return -1;
1113a3a95b7dSJasvinder Singh 	}
1114a3a95b7dSJasvinder Singh 
1115a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
1116a3a95b7dSJasvinder Singh 		uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
1117a3a95b7dSJasvinder Singh 		uint32_t tc_mask1 = action->mtr.tc_mask;
1118a3a95b7dSJasvinder Singh 
1119a3a95b7dSJasvinder Singh 		if (tc_mask1 != tc_mask0)
1120a3a95b7dSJasvinder Singh 			return -1;
1121a3a95b7dSJasvinder Singh 	}
1122a3a95b7dSJasvinder Singh 
1123a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
1124a3a95b7dSJasvinder Singh 		uint32_t n_subports_per_port =
1125a3a95b7dSJasvinder Singh 			ap->params.tm.n_subports_per_port;
1126a3a95b7dSJasvinder Singh 		uint32_t n_pipes_per_subport =
1127a3a95b7dSJasvinder Singh 			ap->params.tm.n_pipes_per_subport;
1128a3a95b7dSJasvinder Singh 		uint32_t subport_id = action->tm.subport_id;
1129a3a95b7dSJasvinder Singh 		uint32_t pipe_id = action->tm.pipe_id;
1130a3a95b7dSJasvinder Singh 
1131a3a95b7dSJasvinder Singh 		if ((subport_id >= n_subports_per_port) ||
1132a3a95b7dSJasvinder Singh 			(pipe_id >= n_pipes_per_subport))
1133a3a95b7dSJasvinder Singh 			return -1;
1134a3a95b7dSJasvinder Singh 	}
1135a3a95b7dSJasvinder Singh 
1136a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
1137a3a95b7dSJasvinder Singh 		uint64_t encap_mask = ap->params.encap.encap_mask;
1138a3a95b7dSJasvinder Singh 		enum rte_table_action_encap_type type = action->encap.type;
1139a3a95b7dSJasvinder Singh 
1140a3a95b7dSJasvinder Singh 		if ((encap_mask & (1LLU << type)) == 0)
1141a3a95b7dSJasvinder Singh 			return -1;
1142a3a95b7dSJasvinder Singh 	}
1143a3a95b7dSJasvinder Singh 
1144a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
1145a3a95b7dSJasvinder Singh 		int ip_version0 = ap->params.common.ip_version;
1146a3a95b7dSJasvinder Singh 		int ip_version1 = action->nat.ip_version;
1147a3a95b7dSJasvinder Singh 
1148a3a95b7dSJasvinder Singh 		if ((ip_version1 && (ip_version0 == 0)) ||
1149a3a95b7dSJasvinder Singh 			((ip_version1 == 0) && ip_version0))
1150a3a95b7dSJasvinder Singh 			return -1;
1151a3a95b7dSJasvinder Singh 	}
1152a3a95b7dSJasvinder Singh 
1153a3a95b7dSJasvinder Singh 	return 0;
1154a3a95b7dSJasvinder Singh }
1155a3a95b7dSJasvinder Singh 
1156a3a95b7dSJasvinder Singh static int
1157a3a95b7dSJasvinder Singh action_default_check(struct table_rule_action *action,
1158a3a95b7dSJasvinder Singh 	struct pipeline *p,
1159a3a95b7dSJasvinder Singh 	uint32_t table_id)
1160a3a95b7dSJasvinder Singh {
1161a3a95b7dSJasvinder Singh 	if ((action == NULL) ||
1162a3a95b7dSJasvinder Singh 		(action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
1163a3a95b7dSJasvinder Singh 		(p == NULL) ||
1164a3a95b7dSJasvinder Singh 		(table_id >= p->n_tables))
1165a3a95b7dSJasvinder Singh 		return -1;
1166a3a95b7dSJasvinder Singh 
1167a3a95b7dSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
1168a3a95b7dSJasvinder Singh 		if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
1169a3a95b7dSJasvinder Singh 			(action->fwd.id >= p->n_ports_out))
1170a3a95b7dSJasvinder Singh 			return -1;
1171a3a95b7dSJasvinder Singh 
1172a3a95b7dSJasvinder Singh 		if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
1173a3a95b7dSJasvinder Singh 			(action->fwd.id >= p->n_tables))
1174a3a95b7dSJasvinder Singh 			return -1;
1175a3a95b7dSJasvinder Singh 	}
1176a3a95b7dSJasvinder Singh 
1177a3a95b7dSJasvinder Singh 	return 0;
1178a3a95b7dSJasvinder Singh }
1179a3a95b7dSJasvinder Singh 
1180f68a1d3fSJasvinder Singh union table_rule_match_low_level {
1181f68a1d3fSJasvinder Singh 	struct rte_table_acl_rule_add_params acl_add;
1182f68a1d3fSJasvinder Singh 	struct rte_table_acl_rule_delete_params acl_delete;
1183f68a1d3fSJasvinder Singh 	struct rte_table_array_key array;
1184f68a1d3fSJasvinder Singh 	uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
1185f68a1d3fSJasvinder Singh 	struct rte_table_lpm_key lpm_ipv4;
1186f68a1d3fSJasvinder Singh 	struct rte_table_lpm_ipv6_key lpm_ipv6;
1187f68a1d3fSJasvinder Singh };
1188f68a1d3fSJasvinder Singh 
1189f68a1d3fSJasvinder Singh static int
1190f68a1d3fSJasvinder Singh match_convert(struct table_rule_match *mh,
1191f68a1d3fSJasvinder Singh 	union table_rule_match_low_level *ml,
1192f68a1d3fSJasvinder Singh 	int add);
1193f68a1d3fSJasvinder Singh 
1194f68a1d3fSJasvinder Singh static int
1195f68a1d3fSJasvinder Singh action_convert(struct rte_table_action *a,
1196f68a1d3fSJasvinder Singh 	struct table_rule_action *action,
1197f68a1d3fSJasvinder Singh 	struct rte_pipeline_table_entry *data);
1198f68a1d3fSJasvinder Singh 
119927b333b2SCristian Dumitrescu struct table_ll {
120027b333b2SCristian Dumitrescu 	struct rte_pipeline *p;
120127b333b2SCristian Dumitrescu 	int table_id;
120227b333b2SCristian Dumitrescu 	struct rte_table_action *a;
120327b333b2SCristian Dumitrescu 	int bulk_supported;
120427b333b2SCristian Dumitrescu };
120527b333b2SCristian Dumitrescu 
120627b333b2SCristian Dumitrescu static int
120727b333b2SCristian Dumitrescu table_rule_add_bulk_ll(struct table_ll *table,
120827b333b2SCristian Dumitrescu 	struct table_rule_list *list,
120927b333b2SCristian Dumitrescu 	uint32_t *n_rules)
121027b333b2SCristian Dumitrescu {
121127b333b2SCristian Dumitrescu 	union table_rule_match_low_level *match_ll = NULL;
121227b333b2SCristian Dumitrescu 	uint8_t *action_ll = NULL;
121327b333b2SCristian Dumitrescu 	void **match_ll_ptr = NULL;
121427b333b2SCristian Dumitrescu 	struct rte_pipeline_table_entry **action_ll_ptr = NULL;
121527b333b2SCristian Dumitrescu 	struct rte_pipeline_table_entry **entries_ptr = NULL;
121627b333b2SCristian Dumitrescu 	int *found = NULL;
121727b333b2SCristian Dumitrescu 	struct table_rule *rule;
121827b333b2SCristian Dumitrescu 	uint32_t n, i;
121927b333b2SCristian Dumitrescu 	int status = 0;
122027b333b2SCristian Dumitrescu 
122127b333b2SCristian Dumitrescu 	n = 0;
122227b333b2SCristian Dumitrescu 	TAILQ_FOREACH(rule, list, node)
122327b333b2SCristian Dumitrescu 		n++;
122427b333b2SCristian Dumitrescu 
122527b333b2SCristian Dumitrescu 	/* Memory allocation */
122627b333b2SCristian Dumitrescu 	match_ll = calloc(n, sizeof(union table_rule_match_low_level));
122727b333b2SCristian Dumitrescu 	action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
122827b333b2SCristian Dumitrescu 
122927b333b2SCristian Dumitrescu 	match_ll_ptr = calloc(n, sizeof(void *));
123027b333b2SCristian Dumitrescu 	action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
123127b333b2SCristian Dumitrescu 
123227b333b2SCristian Dumitrescu 	entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
123327b333b2SCristian Dumitrescu 	found = calloc(n, sizeof(int));
123427b333b2SCristian Dumitrescu 
123527b333b2SCristian Dumitrescu 	if (match_ll == NULL ||
123627b333b2SCristian Dumitrescu 		action_ll == NULL ||
123727b333b2SCristian Dumitrescu 		match_ll_ptr == NULL ||
123827b333b2SCristian Dumitrescu 		action_ll_ptr == NULL ||
123927b333b2SCristian Dumitrescu 		entries_ptr == NULL ||
124027b333b2SCristian Dumitrescu 		found == NULL) {
124127b333b2SCristian Dumitrescu 			status = -ENOMEM;
124227b333b2SCristian Dumitrescu 			goto table_rule_add_bulk_ll_free;
124327b333b2SCristian Dumitrescu 	}
124427b333b2SCristian Dumitrescu 
124527b333b2SCristian Dumitrescu 	/* Init */
124627b333b2SCristian Dumitrescu 	for (i = 0; i < n; i++) {
124727b333b2SCristian Dumitrescu 		match_ll_ptr[i] = (void *)&match_ll[i];
124827b333b2SCristian Dumitrescu 		action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
124927b333b2SCristian Dumitrescu 			&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
125027b333b2SCristian Dumitrescu 	}
125127b333b2SCristian Dumitrescu 
125227b333b2SCristian Dumitrescu 	/* Rule (match, action) conversion */
125327b333b2SCristian Dumitrescu 	i = 0;
125427b333b2SCristian Dumitrescu 	TAILQ_FOREACH(rule, list, node) {
125527b333b2SCristian Dumitrescu 		status = match_convert(&rule->match, match_ll_ptr[i], 1);
125627b333b2SCristian Dumitrescu 		if (status)
125727b333b2SCristian Dumitrescu 			goto table_rule_add_bulk_ll_free;
125827b333b2SCristian Dumitrescu 
125927b333b2SCristian Dumitrescu 		status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
126027b333b2SCristian Dumitrescu 		if (status)
126127b333b2SCristian Dumitrescu 			goto table_rule_add_bulk_ll_free;
126227b333b2SCristian Dumitrescu 
126327b333b2SCristian Dumitrescu 		i++;
126427b333b2SCristian Dumitrescu 	}
126527b333b2SCristian Dumitrescu 
126627b333b2SCristian Dumitrescu 	/* Add rule (match, action) to table */
126727b333b2SCristian Dumitrescu 	if (table->bulk_supported) {
126827b333b2SCristian Dumitrescu 		status = rte_pipeline_table_entry_add_bulk(table->p,
126927b333b2SCristian Dumitrescu 			table->table_id,
127027b333b2SCristian Dumitrescu 			match_ll_ptr,
127127b333b2SCristian Dumitrescu 			action_ll_ptr,
127227b333b2SCristian Dumitrescu 			n,
127327b333b2SCristian Dumitrescu 			found,
127427b333b2SCristian Dumitrescu 			entries_ptr);
127527b333b2SCristian Dumitrescu 		if (status)
127627b333b2SCristian Dumitrescu 			goto table_rule_add_bulk_ll_free;
127727b333b2SCristian Dumitrescu 	} else
127827b333b2SCristian Dumitrescu 		for (i = 0; i < n; i++) {
127927b333b2SCristian Dumitrescu 			status = rte_pipeline_table_entry_add(table->p,
128027b333b2SCristian Dumitrescu 				table->table_id,
128127b333b2SCristian Dumitrescu 				match_ll_ptr[i],
128227b333b2SCristian Dumitrescu 				action_ll_ptr[i],
128327b333b2SCristian Dumitrescu 				&found[i],
128427b333b2SCristian Dumitrescu 				&entries_ptr[i]);
128527b333b2SCristian Dumitrescu 			if (status) {
128627b333b2SCristian Dumitrescu 				if (i == 0)
128727b333b2SCristian Dumitrescu 					goto table_rule_add_bulk_ll_free;
128827b333b2SCristian Dumitrescu 
128927b333b2SCristian Dumitrescu 				/* No roll-back. */
129027b333b2SCristian Dumitrescu 				status = 0;
129127b333b2SCristian Dumitrescu 				n = i;
129227b333b2SCristian Dumitrescu 				break;
129327b333b2SCristian Dumitrescu 			}
129427b333b2SCristian Dumitrescu 		}
129527b333b2SCristian Dumitrescu 
129627b333b2SCristian Dumitrescu 	/* Write back to the rule list. */
129727b333b2SCristian Dumitrescu 	i = 0;
129827b333b2SCristian Dumitrescu 	TAILQ_FOREACH(rule, list, node) {
129927b333b2SCristian Dumitrescu 		if (i >= n)
130027b333b2SCristian Dumitrescu 			break;
130127b333b2SCristian Dumitrescu 
130227b333b2SCristian Dumitrescu 		rule->data = entries_ptr[i];
130327b333b2SCristian Dumitrescu 
130427b333b2SCristian Dumitrescu 		i++;
130527b333b2SCristian Dumitrescu 	}
130627b333b2SCristian Dumitrescu 
130727b333b2SCristian Dumitrescu 	*n_rules = n;
130827b333b2SCristian Dumitrescu 
130927b333b2SCristian Dumitrescu 	/* Free */
131027b333b2SCristian Dumitrescu table_rule_add_bulk_ll_free:
131127b333b2SCristian Dumitrescu 	free(found);
131227b333b2SCristian Dumitrescu 	free(entries_ptr);
131327b333b2SCristian Dumitrescu 	free(action_ll_ptr);
131427b333b2SCristian Dumitrescu 	free(match_ll_ptr);
131527b333b2SCristian Dumitrescu 	free(action_ll);
131627b333b2SCristian Dumitrescu 	free(match_ll);
131727b333b2SCristian Dumitrescu 
131827b333b2SCristian Dumitrescu 	return status;
131927b333b2SCristian Dumitrescu }
132027b333b2SCristian Dumitrescu 
1321a3a95b7dSJasvinder Singh int
1322a3a95b7dSJasvinder Singh pipeline_table_rule_add(const char *pipeline_name,
1323a3a95b7dSJasvinder Singh 	uint32_t table_id,
1324a3a95b7dSJasvinder Singh 	struct table_rule_match *match,
13254c65163eSCristian Dumitrescu 	struct table_rule_action *action)
1326a3a95b7dSJasvinder Singh {
1327a3a95b7dSJasvinder Singh 	struct pipeline *p;
13284c65163eSCristian Dumitrescu 	struct table *table;
1329a3a95b7dSJasvinder Singh 	struct pipeline_msg_req *req;
1330a3a95b7dSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
13314c65163eSCristian Dumitrescu 	struct table_rule *rule;
1332a3a95b7dSJasvinder Singh 	int status;
1333a3a95b7dSJasvinder Singh 
1334a3a95b7dSJasvinder Singh 	/* Check input params */
1335a3a95b7dSJasvinder Singh 	if ((pipeline_name == NULL) ||
1336a3a95b7dSJasvinder Singh 		(match == NULL) ||
13374c65163eSCristian Dumitrescu 		(action == NULL))
1338a3a95b7dSJasvinder Singh 		return -1;
1339a3a95b7dSJasvinder Singh 
1340a3a95b7dSJasvinder Singh 	p = pipeline_find(pipeline_name);
1341a3a95b7dSJasvinder Singh 	if ((p == NULL) ||
1342a3a95b7dSJasvinder Singh 		(table_id >= p->n_tables) ||
1343a3a95b7dSJasvinder Singh 		match_check(match, p, table_id) ||
1344a3a95b7dSJasvinder Singh 		action_check(action, p, table_id))
1345a3a95b7dSJasvinder Singh 		return -1;
1346a3a95b7dSJasvinder Singh 
13474c65163eSCristian Dumitrescu 	table = &p->table[table_id];
13484c65163eSCristian Dumitrescu 
13494c65163eSCristian Dumitrescu 	rule = calloc(1, sizeof(struct table_rule));
13504c65163eSCristian Dumitrescu 	if (rule == NULL)
13514c65163eSCristian Dumitrescu 		return -1;
13524c65163eSCristian Dumitrescu 
13534c65163eSCristian Dumitrescu 	memcpy(&rule->match, match, sizeof(*match));
13544c65163eSCristian Dumitrescu 	memcpy(&rule->action, action, sizeof(*action));
13554c65163eSCristian Dumitrescu 
1356f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1357f68a1d3fSJasvinder Singh 		union table_rule_match_low_level match_ll;
1358f68a1d3fSJasvinder Singh 		struct rte_pipeline_table_entry *data_in, *data_out;
1359f68a1d3fSJasvinder Singh 		int key_found;
1360f68a1d3fSJasvinder Singh 		uint8_t *buffer;
1361f68a1d3fSJasvinder Singh 
1362f68a1d3fSJasvinder Singh 		buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
13634c65163eSCristian Dumitrescu 		if (buffer == NULL) {
13644c65163eSCristian Dumitrescu 			free(rule);
1365f68a1d3fSJasvinder Singh 			return -1;
13664c65163eSCristian Dumitrescu 		}
1367f68a1d3fSJasvinder Singh 
1368f68a1d3fSJasvinder Singh 		/* Table match-action rule conversion */
1369f68a1d3fSJasvinder Singh 		data_in = (struct rte_pipeline_table_entry *)buffer;
1370f68a1d3fSJasvinder Singh 
1371f68a1d3fSJasvinder Singh 		status = match_convert(match, &match_ll, 1);
1372f68a1d3fSJasvinder Singh 		if (status) {
1373f68a1d3fSJasvinder Singh 			free(buffer);
13744c65163eSCristian Dumitrescu 			free(rule);
1375f68a1d3fSJasvinder Singh 			return -1;
1376f68a1d3fSJasvinder Singh 		}
1377f68a1d3fSJasvinder Singh 
13784c65163eSCristian Dumitrescu 		status = action_convert(table->a, action, data_in);
1379f68a1d3fSJasvinder Singh 		if (status) {
1380f68a1d3fSJasvinder Singh 			free(buffer);
13814c65163eSCristian Dumitrescu 			free(rule);
1382f68a1d3fSJasvinder Singh 			return -1;
1383f68a1d3fSJasvinder Singh 		}
1384f68a1d3fSJasvinder Singh 
1385f68a1d3fSJasvinder Singh 		/* Add rule (match, action) to table */
1386f68a1d3fSJasvinder Singh 		status = rte_pipeline_table_entry_add(p->p,
1387f68a1d3fSJasvinder Singh 				table_id,
1388f68a1d3fSJasvinder Singh 				&match_ll,
1389f68a1d3fSJasvinder Singh 				data_in,
1390f68a1d3fSJasvinder Singh 				&key_found,
1391f68a1d3fSJasvinder Singh 				&data_out);
1392f68a1d3fSJasvinder Singh 		if (status) {
1393f68a1d3fSJasvinder Singh 			free(buffer);
13944c65163eSCristian Dumitrescu 			free(rule);
1395f68a1d3fSJasvinder Singh 			return -1;
1396f68a1d3fSJasvinder Singh 		}
1397f68a1d3fSJasvinder Singh 
1398f68a1d3fSJasvinder Singh 		/* Write Response */
13994c65163eSCristian Dumitrescu 		rule->data = data_out;
14004c65163eSCristian Dumitrescu 		table_rule_add(table, rule);
1401f68a1d3fSJasvinder Singh 
1402f68a1d3fSJasvinder Singh 		free(buffer);
1403f68a1d3fSJasvinder Singh 		return 0;
1404f68a1d3fSJasvinder Singh 	}
1405f68a1d3fSJasvinder Singh 
1406a3a95b7dSJasvinder Singh 	/* Allocate request */
1407a3a95b7dSJasvinder Singh 	req = pipeline_msg_alloc();
14084c65163eSCristian Dumitrescu 	if (req == NULL) {
14094c65163eSCristian Dumitrescu 		free(rule);
1410a3a95b7dSJasvinder Singh 		return -1;
14114c65163eSCristian Dumitrescu 	}
1412a3a95b7dSJasvinder Singh 
1413a3a95b7dSJasvinder Singh 	/* Write request */
1414a3a95b7dSJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_ADD;
1415a3a95b7dSJasvinder Singh 	req->id = table_id;
1416a3a95b7dSJasvinder Singh 	memcpy(&req->table_rule_add.match, match, sizeof(*match));
1417a3a95b7dSJasvinder Singh 	memcpy(&req->table_rule_add.action, action, sizeof(*action));
1418a3a95b7dSJasvinder Singh 
1419a3a95b7dSJasvinder Singh 	/* Send request and wait for response */
1420a3a95b7dSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
1421a3a95b7dSJasvinder Singh 
1422a3a95b7dSJasvinder Singh 	/* Read response */
1423a3a95b7dSJasvinder Singh 	status = rsp->status;
14244c65163eSCristian Dumitrescu 	if (status == 0) {
14254c65163eSCristian Dumitrescu 		rule->data = rsp->table_rule_add.data;
14264c65163eSCristian Dumitrescu 		table_rule_add(table, rule);
14274c65163eSCristian Dumitrescu 	} else
14284c65163eSCristian Dumitrescu 		free(rule);
1429a3a95b7dSJasvinder Singh 
1430a3a95b7dSJasvinder Singh 	/* Free response */
1431a3a95b7dSJasvinder Singh 	pipeline_msg_free(rsp);
1432a3a95b7dSJasvinder Singh 
1433a3a95b7dSJasvinder Singh 	return status;
1434a3a95b7dSJasvinder Singh }
1435a3a95b7dSJasvinder Singh 
1436a3a95b7dSJasvinder Singh int
1437a3a95b7dSJasvinder Singh pipeline_table_rule_add_default(const char *pipeline_name,
1438a3a95b7dSJasvinder Singh 	uint32_t table_id,
1439c348ec05SCristian Dumitrescu 	struct table_rule_action *action)
1440a3a95b7dSJasvinder Singh {
1441a3a95b7dSJasvinder Singh 	struct pipeline *p;
1442c348ec05SCristian Dumitrescu 	struct table *table;
1443a3a95b7dSJasvinder Singh 	struct pipeline_msg_req *req;
1444a3a95b7dSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
1445c348ec05SCristian Dumitrescu 	struct table_rule *rule;
1446a3a95b7dSJasvinder Singh 	int status;
1447a3a95b7dSJasvinder Singh 
1448a3a95b7dSJasvinder Singh 	/* Check input params */
1449a3a95b7dSJasvinder Singh 	if ((pipeline_name == NULL) ||
1450c348ec05SCristian Dumitrescu 		(action == NULL))
1451a3a95b7dSJasvinder Singh 		return -1;
1452a3a95b7dSJasvinder Singh 
1453a3a95b7dSJasvinder Singh 	p = pipeline_find(pipeline_name);
1454a3a95b7dSJasvinder Singh 	if ((p == NULL) ||
1455a3a95b7dSJasvinder Singh 		(table_id >= p->n_tables) ||
1456a3a95b7dSJasvinder Singh 		action_default_check(action, p, table_id))
1457a3a95b7dSJasvinder Singh 		return -1;
1458a3a95b7dSJasvinder Singh 
1459c348ec05SCristian Dumitrescu 	table = &p->table[table_id];
1460c348ec05SCristian Dumitrescu 
1461c348ec05SCristian Dumitrescu 	rule = calloc(1, sizeof(struct table_rule));
1462c348ec05SCristian Dumitrescu 	if (rule == NULL)
1463c348ec05SCristian Dumitrescu 		return -1;
1464c348ec05SCristian Dumitrescu 
1465c348ec05SCristian Dumitrescu 	memcpy(&rule->action, action, sizeof(*action));
1466c348ec05SCristian Dumitrescu 
1467f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1468f68a1d3fSJasvinder Singh 		struct rte_pipeline_table_entry *data_in, *data_out;
1469f68a1d3fSJasvinder Singh 		uint8_t *buffer;
1470f68a1d3fSJasvinder Singh 
1471f68a1d3fSJasvinder Singh 		buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
1472c348ec05SCristian Dumitrescu 		if (buffer == NULL) {
1473c348ec05SCristian Dumitrescu 			free(rule);
1474f68a1d3fSJasvinder Singh 			return -1;
1475c348ec05SCristian Dumitrescu 		}
1476f68a1d3fSJasvinder Singh 
1477f68a1d3fSJasvinder Singh 		/* Apply actions */
1478f68a1d3fSJasvinder Singh 		data_in = (struct rte_pipeline_table_entry *)buffer;
1479f68a1d3fSJasvinder Singh 
1480f68a1d3fSJasvinder Singh 		data_in->action = action->fwd.action;
1481f68a1d3fSJasvinder Singh 		if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
1482f68a1d3fSJasvinder Singh 			data_in->port_id = action->fwd.id;
1483f68a1d3fSJasvinder Singh 		if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
1484f68a1d3fSJasvinder Singh 			data_in->table_id = action->fwd.id;
1485f68a1d3fSJasvinder Singh 
1486f68a1d3fSJasvinder Singh 		/* Add default rule to table */
1487f68a1d3fSJasvinder Singh 		status = rte_pipeline_table_default_entry_add(p->p,
1488f68a1d3fSJasvinder Singh 				table_id,
1489f68a1d3fSJasvinder Singh 				data_in,
1490f68a1d3fSJasvinder Singh 				&data_out);
1491f68a1d3fSJasvinder Singh 		if (status) {
1492f68a1d3fSJasvinder Singh 			free(buffer);
1493c348ec05SCristian Dumitrescu 			free(rule);
1494f68a1d3fSJasvinder Singh 			return -1;
1495f68a1d3fSJasvinder Singh 		}
1496f68a1d3fSJasvinder Singh 
1497f68a1d3fSJasvinder Singh 		/* Write Response */
1498c348ec05SCristian Dumitrescu 		rule->data = data_out;
1499c348ec05SCristian Dumitrescu 		table_rule_default_add(table, rule);
1500f68a1d3fSJasvinder Singh 
1501f68a1d3fSJasvinder Singh 		free(buffer);
1502f68a1d3fSJasvinder Singh 		return 0;
1503f68a1d3fSJasvinder Singh 	}
1504f68a1d3fSJasvinder Singh 
1505a3a95b7dSJasvinder Singh 	/* Allocate request */
1506a3a95b7dSJasvinder Singh 	req = pipeline_msg_alloc();
1507c348ec05SCristian Dumitrescu 	if (req == NULL) {
1508c348ec05SCristian Dumitrescu 		free(rule);
1509a3a95b7dSJasvinder Singh 		return -1;
1510c348ec05SCristian Dumitrescu 	}
1511a3a95b7dSJasvinder Singh 
1512a3a95b7dSJasvinder Singh 	/* Write request */
1513a3a95b7dSJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
1514a3a95b7dSJasvinder Singh 	req->id = table_id;
1515a3a95b7dSJasvinder Singh 	memcpy(&req->table_rule_add_default.action, action, sizeof(*action));
1516a3a95b7dSJasvinder Singh 
1517a3a95b7dSJasvinder Singh 	/* Send request and wait for response */
1518a3a95b7dSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
1519a3a95b7dSJasvinder Singh 
1520a3a95b7dSJasvinder Singh 	/* Read response */
1521a3a95b7dSJasvinder Singh 	status = rsp->status;
1522c348ec05SCristian Dumitrescu 	if (status == 0) {
1523c348ec05SCristian Dumitrescu 		rule->data = rsp->table_rule_add_default.data;
1524c348ec05SCristian Dumitrescu 		table_rule_default_add(table, rule);
1525c348ec05SCristian Dumitrescu 	} else
1526c348ec05SCristian Dumitrescu 		free(rule);
1527a3a95b7dSJasvinder Singh 
1528a3a95b7dSJasvinder Singh 	/* Free response */
1529a3a95b7dSJasvinder Singh 	pipeline_msg_free(rsp);
1530a3a95b7dSJasvinder Singh 
1531a3a95b7dSJasvinder Singh 	return status;
1532a3a95b7dSJasvinder Singh }
1533a3a95b7dSJasvinder Singh 
153427b333b2SCristian Dumitrescu static uint32_t
153527b333b2SCristian Dumitrescu table_rule_list_free(struct table_rule_list *list)
153627b333b2SCristian Dumitrescu {
153727b333b2SCristian Dumitrescu 	uint32_t n = 0;
153827b333b2SCristian Dumitrescu 
153927b333b2SCristian Dumitrescu 	if (!list)
154027b333b2SCristian Dumitrescu 		return 0;
154127b333b2SCristian Dumitrescu 
154227b333b2SCristian Dumitrescu 	for ( ; ; ) {
154327b333b2SCristian Dumitrescu 		struct table_rule *rule;
154427b333b2SCristian Dumitrescu 
154527b333b2SCristian Dumitrescu 		rule = TAILQ_FIRST(list);
154627b333b2SCristian Dumitrescu 		if (rule == NULL)
154727b333b2SCristian Dumitrescu 			break;
154827b333b2SCristian Dumitrescu 
154927b333b2SCristian Dumitrescu 		TAILQ_REMOVE(list, rule, node);
155027b333b2SCristian Dumitrescu 		free(rule);
155127b333b2SCristian Dumitrescu 		n++;
155227b333b2SCristian Dumitrescu 	}
155327b333b2SCristian Dumitrescu 
155427b333b2SCristian Dumitrescu 	free(list);
155527b333b2SCristian Dumitrescu 	return n;
155627b333b2SCristian Dumitrescu }
155727b333b2SCristian Dumitrescu 
1558f634e4c5SJasvinder Singh int
15593186282fSJasvinder Singh pipeline_table_rule_add_bulk(const char *pipeline_name,
15603186282fSJasvinder Singh 	uint32_t table_id,
156127b333b2SCristian Dumitrescu 	struct table_rule_list *list,
156227b333b2SCristian Dumitrescu 	uint32_t *n_rules_added,
156327b333b2SCristian Dumitrescu 	uint32_t *n_rules_not_added)
15643186282fSJasvinder Singh {
15653186282fSJasvinder Singh 	struct pipeline *p;
156627b333b2SCristian Dumitrescu 	struct table *table;
15673186282fSJasvinder Singh 	struct pipeline_msg_req *req;
15683186282fSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
156927b333b2SCristian Dumitrescu 	struct table_rule *rule;
157027b333b2SCristian Dumitrescu 	int status = 0;
15713186282fSJasvinder Singh 
15723186282fSJasvinder Singh 	/* Check input params */
15733186282fSJasvinder Singh 	if ((pipeline_name == NULL) ||
157427b333b2SCristian Dumitrescu 		(list == NULL) ||
157527b333b2SCristian Dumitrescu 		TAILQ_EMPTY(list) ||
157627b333b2SCristian Dumitrescu 		(n_rules_added == NULL) ||
157727b333b2SCristian Dumitrescu 		(n_rules_not_added == NULL)) {
157827b333b2SCristian Dumitrescu 		table_rule_list_free(list);
157927b333b2SCristian Dumitrescu 		return -EINVAL;
158027b333b2SCristian Dumitrescu 	}
15813186282fSJasvinder Singh 
15823186282fSJasvinder Singh 	p = pipeline_find(pipeline_name);
15833186282fSJasvinder Singh 	if ((p == NULL) ||
158427b333b2SCristian Dumitrescu 		(table_id >= p->n_tables)) {
158527b333b2SCristian Dumitrescu 		table_rule_list_free(list);
158627b333b2SCristian Dumitrescu 		return -EINVAL;
158727b333b2SCristian Dumitrescu 	}
15883186282fSJasvinder Singh 
158927b333b2SCristian Dumitrescu 	table = &p->table[table_id];
159027b333b2SCristian Dumitrescu 
159127b333b2SCristian Dumitrescu 	TAILQ_FOREACH(rule, list, node)
159227b333b2SCristian Dumitrescu 		if (match_check(&rule->match, p, table_id) ||
159327b333b2SCristian Dumitrescu 			action_check(&rule->action, p, table_id)) {
159427b333b2SCristian Dumitrescu 			table_rule_list_free(list);
159527b333b2SCristian Dumitrescu 			return -EINVAL;
159627b333b2SCristian Dumitrescu 		}
15973186282fSJasvinder Singh 
1598f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
159927b333b2SCristian Dumitrescu 		struct table_ll table_ll = {
160027b333b2SCristian Dumitrescu 			.p = p->p,
160127b333b2SCristian Dumitrescu 			.table_id = table_id,
160227b333b2SCristian Dumitrescu 			.a = table->a,
160327b333b2SCristian Dumitrescu 			.bulk_supported = table->params.match_type == TABLE_ACL,
160427b333b2SCristian Dumitrescu 		};
1605f68a1d3fSJasvinder Singh 
160627b333b2SCristian Dumitrescu 		status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
1607f68a1d3fSJasvinder Singh 		if (status) {
160827b333b2SCristian Dumitrescu 			table_rule_list_free(list);
1609f68a1d3fSJasvinder Singh 			return status;
161027b333b2SCristian Dumitrescu 		}
1611f68a1d3fSJasvinder Singh 
161227b333b2SCristian Dumitrescu 		table_rule_add_bulk(table, list, *n_rules_added);
161327b333b2SCristian Dumitrescu 		*n_rules_not_added = table_rule_list_free(list);
161427b333b2SCristian Dumitrescu 		return 0;
1615f68a1d3fSJasvinder Singh 	}
1616f68a1d3fSJasvinder Singh 
16173186282fSJasvinder Singh 	/* Allocate request */
16183186282fSJasvinder Singh 	req = pipeline_msg_alloc();
161927b333b2SCristian Dumitrescu 	if (req == NULL) {
162027b333b2SCristian Dumitrescu 		table_rule_list_free(list);
162127b333b2SCristian Dumitrescu 		return -ENOMEM;
162227b333b2SCristian Dumitrescu 	}
16233186282fSJasvinder Singh 
16243186282fSJasvinder Singh 	/* Write request */
16253186282fSJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
16263186282fSJasvinder Singh 	req->id = table_id;
162727b333b2SCristian Dumitrescu 	req->table_rule_add_bulk.list = list;
162827b333b2SCristian Dumitrescu 	req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
16293186282fSJasvinder Singh 
16303186282fSJasvinder Singh 	/* Send request and wait for response */
16313186282fSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
16323186282fSJasvinder Singh 
16333186282fSJasvinder Singh 	/* Read response */
16343186282fSJasvinder Singh 	status = rsp->status;
163527b333b2SCristian Dumitrescu 	if (status == 0) {
163627b333b2SCristian Dumitrescu 		*n_rules_added = rsp->table_rule_add_bulk.n_rules;
163727b333b2SCristian Dumitrescu 
163827b333b2SCristian Dumitrescu 		table_rule_add_bulk(table, list, *n_rules_added);
163927b333b2SCristian Dumitrescu 		*n_rules_not_added = table_rule_list_free(list);
164027b333b2SCristian Dumitrescu 	} else
164127b333b2SCristian Dumitrescu 		table_rule_list_free(list);
164227b333b2SCristian Dumitrescu 
16433186282fSJasvinder Singh 
16443186282fSJasvinder Singh 	/* Free response */
16453186282fSJasvinder Singh 	pipeline_msg_free(rsp);
16463186282fSJasvinder Singh 
16473186282fSJasvinder Singh 	return status;
16483186282fSJasvinder Singh }
16493186282fSJasvinder Singh 
16503186282fSJasvinder Singh int
1651f634e4c5SJasvinder Singh pipeline_table_rule_delete(const char *pipeline_name,
1652f634e4c5SJasvinder Singh 	uint32_t table_id,
1653f634e4c5SJasvinder Singh 	struct table_rule_match *match)
1654f634e4c5SJasvinder Singh {
1655f634e4c5SJasvinder Singh 	struct pipeline *p;
1656d2cb41c2SCristian Dumitrescu 	struct table *table;
1657f634e4c5SJasvinder Singh 	struct pipeline_msg_req *req;
1658f634e4c5SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
1659f634e4c5SJasvinder Singh 	int status;
1660f634e4c5SJasvinder Singh 
1661f634e4c5SJasvinder Singh 	/* Check input params */
1662f634e4c5SJasvinder Singh 	if ((pipeline_name == NULL) ||
1663f634e4c5SJasvinder Singh 		(match == NULL))
1664f634e4c5SJasvinder Singh 		return -1;
1665f634e4c5SJasvinder Singh 
1666f634e4c5SJasvinder Singh 	p = pipeline_find(pipeline_name);
1667f634e4c5SJasvinder Singh 	if ((p == NULL) ||
1668f634e4c5SJasvinder Singh 		(table_id >= p->n_tables) ||
1669f634e4c5SJasvinder Singh 		match_check(match, p, table_id))
1670f634e4c5SJasvinder Singh 		return -1;
1671f634e4c5SJasvinder Singh 
1672d2cb41c2SCristian Dumitrescu 	table = &p->table[table_id];
1673d2cb41c2SCristian Dumitrescu 
1674f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1675f68a1d3fSJasvinder Singh 		union table_rule_match_low_level match_ll;
1676f68a1d3fSJasvinder Singh 		int key_found;
1677f68a1d3fSJasvinder Singh 
1678f68a1d3fSJasvinder Singh 		status = match_convert(match, &match_ll, 0);
1679f68a1d3fSJasvinder Singh 		if (status)
1680f68a1d3fSJasvinder Singh 			return -1;
1681f68a1d3fSJasvinder Singh 
1682f68a1d3fSJasvinder Singh 		status = rte_pipeline_table_entry_delete(p->p,
1683f68a1d3fSJasvinder Singh 				table_id,
1684f68a1d3fSJasvinder Singh 				&match_ll,
1685f68a1d3fSJasvinder Singh 				&key_found,
1686f68a1d3fSJasvinder Singh 				NULL);
1687f68a1d3fSJasvinder Singh 
1688d2cb41c2SCristian Dumitrescu 		if (status == 0)
1689d2cb41c2SCristian Dumitrescu 			table_rule_delete(table, match);
1690d2cb41c2SCristian Dumitrescu 
1691f68a1d3fSJasvinder Singh 		return status;
1692f68a1d3fSJasvinder Singh 	}
1693f68a1d3fSJasvinder Singh 
1694f634e4c5SJasvinder Singh 	/* Allocate request */
1695f634e4c5SJasvinder Singh 	req = pipeline_msg_alloc();
1696f634e4c5SJasvinder Singh 	if (req == NULL)
1697f634e4c5SJasvinder Singh 		return -1;
1698f634e4c5SJasvinder Singh 
1699f634e4c5SJasvinder Singh 	/* Write request */
1700f634e4c5SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_DELETE;
1701f634e4c5SJasvinder Singh 	req->id = table_id;
1702f634e4c5SJasvinder Singh 	memcpy(&req->table_rule_delete.match, match, sizeof(*match));
1703f634e4c5SJasvinder Singh 
1704f634e4c5SJasvinder Singh 	/* Send request and wait for response */
1705f634e4c5SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
1706f634e4c5SJasvinder Singh 
1707f634e4c5SJasvinder Singh 	/* Read response */
1708f634e4c5SJasvinder Singh 	status = rsp->status;
1709d2cb41c2SCristian Dumitrescu 	if (status == 0)
1710d2cb41c2SCristian Dumitrescu 		table_rule_delete(table, match);
1711f634e4c5SJasvinder Singh 
1712f634e4c5SJasvinder Singh 	/* Free response */
1713f634e4c5SJasvinder Singh 	pipeline_msg_free(rsp);
1714f634e4c5SJasvinder Singh 
1715f634e4c5SJasvinder Singh 	return status;
1716f634e4c5SJasvinder Singh }
1717f634e4c5SJasvinder Singh 
1718f634e4c5SJasvinder Singh int
1719f634e4c5SJasvinder Singh pipeline_table_rule_delete_default(const char *pipeline_name,
1720f634e4c5SJasvinder Singh 	uint32_t table_id)
1721f634e4c5SJasvinder Singh {
1722f634e4c5SJasvinder Singh 	struct pipeline *p;
1723f6df5f53SCristian Dumitrescu 	struct table *table;
1724f634e4c5SJasvinder Singh 	struct pipeline_msg_req *req;
1725f634e4c5SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
1726f634e4c5SJasvinder Singh 	int status;
1727f634e4c5SJasvinder Singh 
1728f634e4c5SJasvinder Singh 	/* Check input params */
1729f634e4c5SJasvinder Singh 	if (pipeline_name == NULL)
1730f634e4c5SJasvinder Singh 		return -1;
1731f634e4c5SJasvinder Singh 
1732f634e4c5SJasvinder Singh 	p = pipeline_find(pipeline_name);
1733f634e4c5SJasvinder Singh 	if ((p == NULL) ||
1734f634e4c5SJasvinder Singh 		(table_id >= p->n_tables))
1735f634e4c5SJasvinder Singh 		return -1;
1736f634e4c5SJasvinder Singh 
1737f6df5f53SCristian Dumitrescu 	table = &p->table[table_id];
1738f6df5f53SCristian Dumitrescu 
1739f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1740f68a1d3fSJasvinder Singh 		status = rte_pipeline_table_default_entry_delete(p->p,
1741f68a1d3fSJasvinder Singh 			table_id,
1742f68a1d3fSJasvinder Singh 			NULL);
1743f68a1d3fSJasvinder Singh 
1744f6df5f53SCristian Dumitrescu 		if (status == 0)
1745f6df5f53SCristian Dumitrescu 			table_rule_default_delete(table);
1746f6df5f53SCristian Dumitrescu 
1747f68a1d3fSJasvinder Singh 		return status;
1748f68a1d3fSJasvinder Singh 	}
1749f68a1d3fSJasvinder Singh 
1750f634e4c5SJasvinder Singh 	/* Allocate request */
1751f634e4c5SJasvinder Singh 	req = pipeline_msg_alloc();
1752f634e4c5SJasvinder Singh 	if (req == NULL)
1753f634e4c5SJasvinder Singh 		return -1;
1754f634e4c5SJasvinder Singh 
1755f634e4c5SJasvinder Singh 	/* Write request */
1756f634e4c5SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;
1757f634e4c5SJasvinder Singh 	req->id = table_id;
1758f634e4c5SJasvinder Singh 
1759f634e4c5SJasvinder Singh 	/* Send request and wait for response */
1760f634e4c5SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
1761f634e4c5SJasvinder Singh 
1762f634e4c5SJasvinder Singh 	/* Read response */
1763f634e4c5SJasvinder Singh 	status = rsp->status;
1764f6df5f53SCristian Dumitrescu 	if (status == 0)
1765f6df5f53SCristian Dumitrescu 		table_rule_default_delete(table);
1766f634e4c5SJasvinder Singh 
1767f634e4c5SJasvinder Singh 	/* Free response */
1768f634e4c5SJasvinder Singh 	pipeline_msg_free(rsp);
1769f634e4c5SJasvinder Singh 
1770f634e4c5SJasvinder Singh 	return status;
1771f634e4c5SJasvinder Singh }
1772f634e4c5SJasvinder Singh 
1773c64b9121SJasvinder Singh int
1774c64b9121SJasvinder Singh pipeline_table_rule_stats_read(const char *pipeline_name,
1775c64b9121SJasvinder Singh 	uint32_t table_id,
177687b36dcdSCristian Dumitrescu 	struct table_rule_match *match,
1777c64b9121SJasvinder Singh 	struct rte_table_action_stats_counters *stats,
1778c64b9121SJasvinder Singh 	int clear)
1779c64b9121SJasvinder Singh {
1780c64b9121SJasvinder Singh 	struct pipeline *p;
178187b36dcdSCristian Dumitrescu 	struct table *table;
1782c64b9121SJasvinder Singh 	struct pipeline_msg_req *req;
1783c64b9121SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
178487b36dcdSCristian Dumitrescu 	struct table_rule *rule;
1785c64b9121SJasvinder Singh 	int status;
1786c64b9121SJasvinder Singh 
1787c64b9121SJasvinder Singh 	/* Check input params */
1788c64b9121SJasvinder Singh 	if ((pipeline_name == NULL) ||
178987b36dcdSCristian Dumitrescu 		(match == NULL) ||
1790c64b9121SJasvinder Singh 		(stats == NULL))
1791c64b9121SJasvinder Singh 		return -1;
1792c64b9121SJasvinder Singh 
1793c64b9121SJasvinder Singh 	p = pipeline_find(pipeline_name);
1794c64b9121SJasvinder Singh 	if ((p == NULL) ||
179587b36dcdSCristian Dumitrescu 		(table_id >= p->n_tables) ||
179687b36dcdSCristian Dumitrescu 		match_check(match, p, table_id))
179787b36dcdSCristian Dumitrescu 		return -1;
179887b36dcdSCristian Dumitrescu 
179987b36dcdSCristian Dumitrescu 	table = &p->table[table_id];
180087b36dcdSCristian Dumitrescu 	rule = table_rule_find(table, match);
180187b36dcdSCristian Dumitrescu 	if (rule == NULL)
1802c64b9121SJasvinder Singh 		return -1;
1803c64b9121SJasvinder Singh 
1804f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
180587b36dcdSCristian Dumitrescu 		status = rte_table_action_stats_read(table->a,
180687b36dcdSCristian Dumitrescu 			rule->data,
1807f68a1d3fSJasvinder Singh 			stats,
1808f68a1d3fSJasvinder Singh 			clear);
1809f68a1d3fSJasvinder Singh 
1810f68a1d3fSJasvinder Singh 		return status;
1811f68a1d3fSJasvinder Singh 	}
1812f68a1d3fSJasvinder Singh 
1813c64b9121SJasvinder Singh 	/* Allocate request */
1814c64b9121SJasvinder Singh 	req = pipeline_msg_alloc();
1815c64b9121SJasvinder Singh 	if (req == NULL)
1816c64b9121SJasvinder Singh 		return -1;
1817c64b9121SJasvinder Singh 
1818c64b9121SJasvinder Singh 	/* Write request */
1819c64b9121SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
1820c64b9121SJasvinder Singh 	req->id = table_id;
182187b36dcdSCristian Dumitrescu 	req->table_rule_stats_read.data = rule->data;
1822c64b9121SJasvinder Singh 	req->table_rule_stats_read.clear = clear;
1823c64b9121SJasvinder Singh 
1824c64b9121SJasvinder Singh 	/* Send request and wait for response */
1825c64b9121SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
1826c64b9121SJasvinder Singh 
1827c64b9121SJasvinder Singh 	/* Read response */
1828c64b9121SJasvinder Singh 	status = rsp->status;
182987b36dcdSCristian Dumitrescu 	if (status == 0)
1830c64b9121SJasvinder Singh 		memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
1831c64b9121SJasvinder Singh 
1832c64b9121SJasvinder Singh 	/* Free response */
1833c64b9121SJasvinder Singh 	pipeline_msg_free(rsp);
1834c64b9121SJasvinder Singh 
1835c64b9121SJasvinder Singh 	return status;
1836c64b9121SJasvinder Singh }
1837c64b9121SJasvinder Singh 
18387e11393eSJasvinder Singh int
18397e11393eSJasvinder Singh pipeline_table_mtr_profile_add(const char *pipeline_name,
18407e11393eSJasvinder Singh 	uint32_t table_id,
18417e11393eSJasvinder Singh 	uint32_t meter_profile_id,
18427e11393eSJasvinder Singh 	struct rte_table_action_meter_profile *profile)
18437e11393eSJasvinder Singh {
18447e11393eSJasvinder Singh 	struct pipeline *p;
18457e11393eSJasvinder Singh 	struct pipeline_msg_req *req;
18467e11393eSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
18477e11393eSJasvinder Singh 	int status;
18487e11393eSJasvinder Singh 
18497e11393eSJasvinder Singh 	/* Check input params */
18507e11393eSJasvinder Singh 	if ((pipeline_name == NULL) ||
18517e11393eSJasvinder Singh 		(profile == NULL))
18527e11393eSJasvinder Singh 		return -1;
18537e11393eSJasvinder Singh 
18547e11393eSJasvinder Singh 	p = pipeline_find(pipeline_name);
18557e11393eSJasvinder Singh 	if ((p == NULL) ||
18567e11393eSJasvinder Singh 		(table_id >= p->n_tables))
18577e11393eSJasvinder Singh 		return -1;
18587e11393eSJasvinder Singh 
1859f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1860f68a1d3fSJasvinder Singh 		struct rte_table_action *a = p->table[table_id].a;
1861f68a1d3fSJasvinder Singh 
1862f68a1d3fSJasvinder Singh 		status = rte_table_action_meter_profile_add(a,
1863f68a1d3fSJasvinder Singh 			meter_profile_id,
1864f68a1d3fSJasvinder Singh 			profile);
1865f68a1d3fSJasvinder Singh 
1866f68a1d3fSJasvinder Singh 		return status;
1867f68a1d3fSJasvinder Singh 	}
1868f68a1d3fSJasvinder Singh 
18697e11393eSJasvinder Singh 	/* Allocate request */
18707e11393eSJasvinder Singh 	req = pipeline_msg_alloc();
18717e11393eSJasvinder Singh 	if (req == NULL)
18727e11393eSJasvinder Singh 		return -1;
18737e11393eSJasvinder Singh 
18747e11393eSJasvinder Singh 	/* Write request */
18757e11393eSJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
18767e11393eSJasvinder Singh 	req->id = table_id;
18777e11393eSJasvinder Singh 	req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
18787e11393eSJasvinder Singh 	memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
18797e11393eSJasvinder Singh 
18807e11393eSJasvinder Singh 	/* Send request and wait for response */
18817e11393eSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
18827e11393eSJasvinder Singh 
18837e11393eSJasvinder Singh 	/* Read response */
18847e11393eSJasvinder Singh 	status = rsp->status;
18857e11393eSJasvinder Singh 
18867e11393eSJasvinder Singh 	/* Free response */
18877e11393eSJasvinder Singh 	pipeline_msg_free(rsp);
18887e11393eSJasvinder Singh 
18897e11393eSJasvinder Singh 	return status;
18907e11393eSJasvinder Singh }
18917e11393eSJasvinder Singh 
18927e11393eSJasvinder Singh int
18937e11393eSJasvinder Singh pipeline_table_mtr_profile_delete(const char *pipeline_name,
18947e11393eSJasvinder Singh 	uint32_t table_id,
18957e11393eSJasvinder Singh 	uint32_t meter_profile_id)
18967e11393eSJasvinder Singh {
18977e11393eSJasvinder Singh 	struct pipeline *p;
18987e11393eSJasvinder Singh 	struct pipeline_msg_req *req;
18997e11393eSJasvinder Singh 	struct pipeline_msg_rsp *rsp;
19007e11393eSJasvinder Singh 	int status;
19017e11393eSJasvinder Singh 
19027e11393eSJasvinder Singh 	/* Check input params */
19037e11393eSJasvinder Singh 	if (pipeline_name == NULL)
19047e11393eSJasvinder Singh 		return -1;
19057e11393eSJasvinder Singh 
19067e11393eSJasvinder Singh 	p = pipeline_find(pipeline_name);
19077e11393eSJasvinder Singh 	if ((p == NULL) ||
19087e11393eSJasvinder Singh 		(table_id >= p->n_tables))
19097e11393eSJasvinder Singh 		return -1;
19107e11393eSJasvinder Singh 
1911f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
1912f68a1d3fSJasvinder Singh 		struct rte_table_action *a = p->table[table_id].a;
1913f68a1d3fSJasvinder Singh 
1914f68a1d3fSJasvinder Singh 		status = rte_table_action_meter_profile_delete(a,
1915f68a1d3fSJasvinder Singh 				meter_profile_id);
1916f68a1d3fSJasvinder Singh 
1917f68a1d3fSJasvinder Singh 		return status;
1918f68a1d3fSJasvinder Singh 	}
1919f68a1d3fSJasvinder Singh 
19207e11393eSJasvinder Singh 	/* Allocate request */
19217e11393eSJasvinder Singh 	req = pipeline_msg_alloc();
19227e11393eSJasvinder Singh 	if (req == NULL)
19237e11393eSJasvinder Singh 		return -1;
19247e11393eSJasvinder Singh 
19257e11393eSJasvinder Singh 	/* Write request */
19267e11393eSJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
19277e11393eSJasvinder Singh 	req->id = table_id;
19287e11393eSJasvinder Singh 	req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
19297e11393eSJasvinder Singh 
19307e11393eSJasvinder Singh 	/* Send request and wait for response */
19317e11393eSJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
19327e11393eSJasvinder Singh 
19337e11393eSJasvinder Singh 	/* Read response */
19347e11393eSJasvinder Singh 	status = rsp->status;
19357e11393eSJasvinder Singh 
19367e11393eSJasvinder Singh 	/* Free response */
19377e11393eSJasvinder Singh 	pipeline_msg_free(rsp);
19387e11393eSJasvinder Singh 
19397e11393eSJasvinder Singh 	return status;
19407e11393eSJasvinder Singh }
19417e11393eSJasvinder Singh 
1942e92058d6SJasvinder Singh int
1943e92058d6SJasvinder Singh pipeline_table_rule_mtr_read(const char *pipeline_name,
1944e92058d6SJasvinder Singh 	uint32_t table_id,
19458c6dc647SCristian Dumitrescu 	struct table_rule_match *match,
1946e92058d6SJasvinder Singh 	struct rte_table_action_mtr_counters *stats,
1947e92058d6SJasvinder Singh 	int clear)
1948e92058d6SJasvinder Singh {
1949e92058d6SJasvinder Singh 	struct pipeline *p;
19508c6dc647SCristian Dumitrescu 	struct table *table;
1951e92058d6SJasvinder Singh 	struct pipeline_msg_req *req;
1952e92058d6SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
19538c6dc647SCristian Dumitrescu 	struct table_rule *rule;
19548c6dc647SCristian Dumitrescu 	uint32_t tc_mask;
1955e92058d6SJasvinder Singh 	int status;
1956e92058d6SJasvinder Singh 
1957e92058d6SJasvinder Singh 	/* Check input params */
1958e92058d6SJasvinder Singh 	if ((pipeline_name == NULL) ||
19598c6dc647SCristian Dumitrescu 		(match == NULL) ||
1960e92058d6SJasvinder Singh 		(stats == NULL))
1961e92058d6SJasvinder Singh 		return -1;
1962e92058d6SJasvinder Singh 
1963e92058d6SJasvinder Singh 	p = pipeline_find(pipeline_name);
1964e92058d6SJasvinder Singh 	if ((p == NULL) ||
19658c6dc647SCristian Dumitrescu 		(table_id >= p->n_tables) ||
19668c6dc647SCristian Dumitrescu 		match_check(match, p, table_id))
19678c6dc647SCristian Dumitrescu 		return -1;
19688c6dc647SCristian Dumitrescu 
19698c6dc647SCristian Dumitrescu 	table = &p->table[table_id];
19708c6dc647SCristian Dumitrescu 	tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
19718c6dc647SCristian Dumitrescu 
19728c6dc647SCristian Dumitrescu 	rule = table_rule_find(table, match);
19738c6dc647SCristian Dumitrescu 	if (rule == NULL)
1974e92058d6SJasvinder Singh 		return -1;
1975e92058d6SJasvinder Singh 
1976f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
19778c6dc647SCristian Dumitrescu 		status = rte_table_action_meter_read(table->a,
19788c6dc647SCristian Dumitrescu 				rule->data,
1979f68a1d3fSJasvinder Singh 				tc_mask,
1980f68a1d3fSJasvinder Singh 				stats,
1981f68a1d3fSJasvinder Singh 				clear);
1982f68a1d3fSJasvinder Singh 
1983f68a1d3fSJasvinder Singh 		return status;
1984f68a1d3fSJasvinder Singh 	}
1985f68a1d3fSJasvinder Singh 
1986e92058d6SJasvinder Singh 	/* Allocate request */
1987e92058d6SJasvinder Singh 	req = pipeline_msg_alloc();
1988e92058d6SJasvinder Singh 	if (req == NULL)
1989e92058d6SJasvinder Singh 		return -1;
1990e92058d6SJasvinder Singh 
1991e92058d6SJasvinder Singh 	/* Write request */
1992e92058d6SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
1993e92058d6SJasvinder Singh 	req->id = table_id;
19948c6dc647SCristian Dumitrescu 	req->table_rule_mtr_read.data = rule->data;
1995e92058d6SJasvinder Singh 	req->table_rule_mtr_read.tc_mask = tc_mask;
1996e92058d6SJasvinder Singh 	req->table_rule_mtr_read.clear = clear;
1997e92058d6SJasvinder Singh 
1998e92058d6SJasvinder Singh 	/* Send request and wait for response */
1999e92058d6SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
2000e92058d6SJasvinder Singh 
2001e92058d6SJasvinder Singh 	/* Read response */
2002e92058d6SJasvinder Singh 	status = rsp->status;
20038c6dc647SCristian Dumitrescu 	if (status == 0)
2004e92058d6SJasvinder Singh 		memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
2005e92058d6SJasvinder Singh 
2006e92058d6SJasvinder Singh 	/* Free response */
2007e92058d6SJasvinder Singh 	pipeline_msg_free(rsp);
2008e92058d6SJasvinder Singh 
2009e92058d6SJasvinder Singh 	return status;
2010e92058d6SJasvinder Singh }
2011e92058d6SJasvinder Singh 
20122b82ef48SJasvinder Singh int
20132b82ef48SJasvinder Singh pipeline_table_dscp_table_update(const char *pipeline_name,
20142b82ef48SJasvinder Singh 	uint32_t table_id,
20152b82ef48SJasvinder Singh 	uint64_t dscp_mask,
20162b82ef48SJasvinder Singh 	struct rte_table_action_dscp_table *dscp_table)
20172b82ef48SJasvinder Singh {
20182b82ef48SJasvinder Singh 	struct pipeline *p;
20192b82ef48SJasvinder Singh 	struct pipeline_msg_req *req;
20202b82ef48SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
20212b82ef48SJasvinder Singh 	int status;
20222b82ef48SJasvinder Singh 
20232b82ef48SJasvinder Singh 	/* Check input params */
20242b82ef48SJasvinder Singh 	if ((pipeline_name == NULL) ||
20252b82ef48SJasvinder Singh 		(dscp_table == NULL))
20262b82ef48SJasvinder Singh 		return -1;
20272b82ef48SJasvinder Singh 
20282b82ef48SJasvinder Singh 	p = pipeline_find(pipeline_name);
20292b82ef48SJasvinder Singh 	if ((p == NULL) ||
20302b82ef48SJasvinder Singh 		(table_id >= p->n_tables))
20312b82ef48SJasvinder Singh 		return -1;
20322b82ef48SJasvinder Singh 
2033f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
2034f68a1d3fSJasvinder Singh 		struct rte_table_action *a = p->table[table_id].a;
2035f68a1d3fSJasvinder Singh 
2036f68a1d3fSJasvinder Singh 		status = rte_table_action_dscp_table_update(a,
2037f68a1d3fSJasvinder Singh 				dscp_mask,
2038f68a1d3fSJasvinder Singh 				dscp_table);
2039f68a1d3fSJasvinder Singh 
2040f68a1d3fSJasvinder Singh 		return status;
2041f68a1d3fSJasvinder Singh 	}
2042f68a1d3fSJasvinder Singh 
20432b82ef48SJasvinder Singh 	/* Allocate request */
20442b82ef48SJasvinder Singh 	req = pipeline_msg_alloc();
20452b82ef48SJasvinder Singh 	if (req == NULL)
20462b82ef48SJasvinder Singh 		return -1;
20472b82ef48SJasvinder Singh 
20482b82ef48SJasvinder Singh 	/* Write request */
20492b82ef48SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
20502b82ef48SJasvinder Singh 	req->id = table_id;
20512b82ef48SJasvinder Singh 	req->table_dscp_table_update.dscp_mask = dscp_mask;
20522b82ef48SJasvinder Singh 	memcpy(&req->table_dscp_table_update.dscp_table,
20532b82ef48SJasvinder Singh 		dscp_table, sizeof(*dscp_table));
20542b82ef48SJasvinder Singh 
20552b82ef48SJasvinder Singh 	/* Send request and wait for response */
20562b82ef48SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
20572b82ef48SJasvinder Singh 
20582b82ef48SJasvinder Singh 	/* Read response */
20592b82ef48SJasvinder Singh 	status = rsp->status;
20602b82ef48SJasvinder Singh 
20612b82ef48SJasvinder Singh 	/* Free response */
20622b82ef48SJasvinder Singh 	pipeline_msg_free(rsp);
20632b82ef48SJasvinder Singh 
20642b82ef48SJasvinder Singh 	return status;
20652b82ef48SJasvinder Singh }
20662b82ef48SJasvinder Singh 
2067d0d306c7SJasvinder Singh int
2068d0d306c7SJasvinder Singh pipeline_table_rule_ttl_read(const char *pipeline_name,
2069d0d306c7SJasvinder Singh 	uint32_t table_id,
20708bfe22acSCristian Dumitrescu 	struct table_rule_match *match,
2071d0d306c7SJasvinder Singh 	struct rte_table_action_ttl_counters *stats,
2072d0d306c7SJasvinder Singh 	int clear)
2073d0d306c7SJasvinder Singh {
2074d0d306c7SJasvinder Singh 	struct pipeline *p;
20758bfe22acSCristian Dumitrescu 	struct table *table;
2076d0d306c7SJasvinder Singh 	struct pipeline_msg_req *req;
2077d0d306c7SJasvinder Singh 	struct pipeline_msg_rsp *rsp;
20788bfe22acSCristian Dumitrescu 	struct table_rule *rule;
2079d0d306c7SJasvinder Singh 	int status;
2080d0d306c7SJasvinder Singh 
2081d0d306c7SJasvinder Singh 	/* Check input params */
2082d0d306c7SJasvinder Singh 	if ((pipeline_name == NULL) ||
20838bfe22acSCristian Dumitrescu 		(match == NULL) ||
2084d0d306c7SJasvinder Singh 		(stats == NULL))
2085d0d306c7SJasvinder Singh 		return -1;
2086d0d306c7SJasvinder Singh 
2087d0d306c7SJasvinder Singh 	p = pipeline_find(pipeline_name);
2088d0d306c7SJasvinder Singh 	if ((p == NULL) ||
20898bfe22acSCristian Dumitrescu 		(table_id >= p->n_tables) ||
20908bfe22acSCristian Dumitrescu 		match_check(match, p, table_id))
20918bfe22acSCristian Dumitrescu 		return -1;
20928bfe22acSCristian Dumitrescu 
20938bfe22acSCristian Dumitrescu 	table = &p->table[table_id];
20948bfe22acSCristian Dumitrescu 	if (!table->ap->params.ttl.n_packets_enabled)
20958bfe22acSCristian Dumitrescu 		return -1;
20968bfe22acSCristian Dumitrescu 
20978bfe22acSCristian Dumitrescu 	rule = table_rule_find(table, match);
20988bfe22acSCristian Dumitrescu 	if (rule == NULL)
2099d0d306c7SJasvinder Singh 		return -1;
2100d0d306c7SJasvinder Singh 
2101f68a1d3fSJasvinder Singh 	if (!pipeline_is_running(p)) {
21028bfe22acSCristian Dumitrescu 		status = rte_table_action_ttl_read(table->a,
21038bfe22acSCristian Dumitrescu 				rule->data,
2104f68a1d3fSJasvinder Singh 				stats,
2105f68a1d3fSJasvinder Singh 				clear);
2106f68a1d3fSJasvinder Singh 
2107f68a1d3fSJasvinder Singh 		return status;
2108f68a1d3fSJasvinder Singh 	}
2109f68a1d3fSJasvinder Singh 
2110d0d306c7SJasvinder Singh 	/* Allocate request */
2111d0d306c7SJasvinder Singh 	req = pipeline_msg_alloc();
2112d0d306c7SJasvinder Singh 	if (req == NULL)
2113d0d306c7SJasvinder Singh 		return -1;
2114d0d306c7SJasvinder Singh 
2115d0d306c7SJasvinder Singh 	/* Write request */
2116d0d306c7SJasvinder Singh 	req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
2117d0d306c7SJasvinder Singh 	req->id = table_id;
21188bfe22acSCristian Dumitrescu 	req->table_rule_ttl_read.data = rule->data;
2119d0d306c7SJasvinder Singh 	req->table_rule_ttl_read.clear = clear;
2120d0d306c7SJasvinder Singh 
2121d0d306c7SJasvinder Singh 	/* Send request and wait for response */
2122d0d306c7SJasvinder Singh 	rsp = pipeline_msg_send_recv(p, req);
2123d0d306c7SJasvinder Singh 
2124d0d306c7SJasvinder Singh 	/* Read response */
2125d0d306c7SJasvinder Singh 	status = rsp->status;
21268bfe22acSCristian Dumitrescu 	if (status == 0)
2127d0d306c7SJasvinder Singh 		memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
2128d0d306c7SJasvinder Singh 
2129d0d306c7SJasvinder Singh 	/* Free response */
2130d0d306c7SJasvinder Singh 	pipeline_msg_free(rsp);
2131d0d306c7SJasvinder Singh 
2132d0d306c7SJasvinder Singh 	return status;
2133d0d306c7SJasvinder Singh }
2134d0d306c7SJasvinder Singh 
2135a3169ee5SCristian Dumitrescu int
2136a3169ee5SCristian Dumitrescu pipeline_table_rule_time_read(const char *pipeline_name,
2137a3169ee5SCristian Dumitrescu 	uint32_t table_id,
2138a3169ee5SCristian Dumitrescu 	struct table_rule_match *match,
2139a3169ee5SCristian Dumitrescu 	uint64_t *timestamp)
2140a3169ee5SCristian Dumitrescu {
2141a3169ee5SCristian Dumitrescu 	struct pipeline *p;
2142a3169ee5SCristian Dumitrescu 	struct table *table;
2143a3169ee5SCristian Dumitrescu 	struct pipeline_msg_req *req;
2144a3169ee5SCristian Dumitrescu 	struct pipeline_msg_rsp *rsp;
2145a3169ee5SCristian Dumitrescu 	struct table_rule *rule;
2146a3169ee5SCristian Dumitrescu 	int status;
2147a3169ee5SCristian Dumitrescu 
2148a3169ee5SCristian Dumitrescu 	/* Check input params */
2149a3169ee5SCristian Dumitrescu 	if ((pipeline_name == NULL) ||
2150a3169ee5SCristian Dumitrescu 		(match == NULL) ||
2151a3169ee5SCristian Dumitrescu 		(timestamp == NULL))
2152a3169ee5SCristian Dumitrescu 		return -1;
2153a3169ee5SCristian Dumitrescu 
2154a3169ee5SCristian Dumitrescu 	p = pipeline_find(pipeline_name);
2155a3169ee5SCristian Dumitrescu 	if ((p == NULL) ||
2156a3169ee5SCristian Dumitrescu 		(table_id >= p->n_tables) ||
2157a3169ee5SCristian Dumitrescu 		match_check(match, p, table_id))
2158a3169ee5SCristian Dumitrescu 		return -1;
2159a3169ee5SCristian Dumitrescu 
2160a3169ee5SCristian Dumitrescu 	table = &p->table[table_id];
2161a3169ee5SCristian Dumitrescu 
2162a3169ee5SCristian Dumitrescu 	rule = table_rule_find(table, match);
2163a3169ee5SCristian Dumitrescu 	if (rule == NULL)
2164a3169ee5SCristian Dumitrescu 		return -1;
2165a3169ee5SCristian Dumitrescu 
2166a3169ee5SCristian Dumitrescu 	if (!pipeline_is_running(p)) {
2167a3169ee5SCristian Dumitrescu 		status = rte_table_action_time_read(table->a,
2168a3169ee5SCristian Dumitrescu 				rule->data,
2169a3169ee5SCristian Dumitrescu 				timestamp);
2170a3169ee5SCristian Dumitrescu 
2171a3169ee5SCristian Dumitrescu 		return status;
2172a3169ee5SCristian Dumitrescu 	}
2173a3169ee5SCristian Dumitrescu 
2174a3169ee5SCristian Dumitrescu 	/* Allocate request */
2175a3169ee5SCristian Dumitrescu 	req = pipeline_msg_alloc();
2176a3169ee5SCristian Dumitrescu 	if (req == NULL)
2177a3169ee5SCristian Dumitrescu 		return -1;
2178a3169ee5SCristian Dumitrescu 
2179a3169ee5SCristian Dumitrescu 	/* Write request */
2180a3169ee5SCristian Dumitrescu 	req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
2181a3169ee5SCristian Dumitrescu 	req->id = table_id;
2182a3169ee5SCristian Dumitrescu 	req->table_rule_time_read.data = rule->data;
2183a3169ee5SCristian Dumitrescu 
2184a3169ee5SCristian Dumitrescu 	/* Send request and wait for response */
2185a3169ee5SCristian Dumitrescu 	rsp = pipeline_msg_send_recv(p, req);
2186a3169ee5SCristian Dumitrescu 
2187a3169ee5SCristian Dumitrescu 	/* Read response */
2188a3169ee5SCristian Dumitrescu 	status = rsp->status;
2189a3169ee5SCristian Dumitrescu 	if (status == 0)
2190a3169ee5SCristian Dumitrescu 		*timestamp = rsp->table_rule_time_read.timestamp;
2191a3169ee5SCristian Dumitrescu 
2192a3169ee5SCristian Dumitrescu 	/* Free response */
2193a3169ee5SCristian Dumitrescu 	pipeline_msg_free(rsp);
2194a3169ee5SCristian Dumitrescu 
2195a3169ee5SCristian Dumitrescu 	return status;
2196a3169ee5SCristian Dumitrescu }
2197a3169ee5SCristian Dumitrescu 
21986b1b3c3cSJasvinder Singh /**
2199a8bd581dSJasvinder Singh  * Data plane threads: message handling
2200a8bd581dSJasvinder Singh  */
2201a8bd581dSJasvinder Singh static inline struct pipeline_msg_req *
2202a8bd581dSJasvinder Singh pipeline_msg_recv(struct rte_ring *msgq_req)
2203a8bd581dSJasvinder Singh {
2204a8bd581dSJasvinder Singh 	struct pipeline_msg_req *req;
2205a8bd581dSJasvinder Singh 
2206a8bd581dSJasvinder Singh 	int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
2207a8bd581dSJasvinder Singh 
2208a8bd581dSJasvinder Singh 	if (status != 0)
2209a8bd581dSJasvinder Singh 		return NULL;
2210a8bd581dSJasvinder Singh 
2211a8bd581dSJasvinder Singh 	return req;
2212a8bd581dSJasvinder Singh }
2213a8bd581dSJasvinder Singh 
2214a8bd581dSJasvinder Singh static inline void
2215a8bd581dSJasvinder Singh pipeline_msg_send(struct rte_ring *msgq_rsp,
2216a8bd581dSJasvinder Singh 	struct pipeline_msg_rsp *rsp)
2217a8bd581dSJasvinder Singh {
2218a8bd581dSJasvinder Singh 	int status;
2219a8bd581dSJasvinder Singh 
2220a8bd581dSJasvinder Singh 	do {
2221a8bd581dSJasvinder Singh 		status = rte_ring_sp_enqueue(msgq_rsp, rsp);
2222a8bd581dSJasvinder Singh 	} while (status == -ENOBUFS);
2223a8bd581dSJasvinder Singh }
2224a8bd581dSJasvinder Singh 
22256b1b3c3cSJasvinder Singh static struct pipeline_msg_rsp *
222650e73d05SJasvinder Singh pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,
222750e73d05SJasvinder Singh 	struct pipeline_msg_req *req)
222850e73d05SJasvinder Singh {
222950e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
223050e73d05SJasvinder Singh 	uint32_t port_id = req->id;
223150e73d05SJasvinder Singh 	int clear = req->port_in_stats_read.clear;
223250e73d05SJasvinder Singh 
223350e73d05SJasvinder Singh 	rsp->status = rte_pipeline_port_in_stats_read(p->p,
223450e73d05SJasvinder Singh 		port_id,
223550e73d05SJasvinder Singh 		&rsp->port_in_stats_read.stats,
223650e73d05SJasvinder Singh 		clear);
223750e73d05SJasvinder Singh 
223850e73d05SJasvinder Singh 	return rsp;
223950e73d05SJasvinder Singh }
224050e73d05SJasvinder Singh 
224150e73d05SJasvinder Singh static struct pipeline_msg_rsp *
22426b1b3c3cSJasvinder Singh pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
22436b1b3c3cSJasvinder Singh 	struct pipeline_msg_req *req)
22446b1b3c3cSJasvinder Singh {
22456b1b3c3cSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
22466b1b3c3cSJasvinder Singh 	uint32_t port_id = req->id;
22476b1b3c3cSJasvinder Singh 
22486b1b3c3cSJasvinder Singh 	rsp->status = rte_pipeline_port_in_enable(p->p,
22496b1b3c3cSJasvinder Singh 		port_id);
22506b1b3c3cSJasvinder Singh 
22516b1b3c3cSJasvinder Singh 	return rsp;
22526b1b3c3cSJasvinder Singh }
22536b1b3c3cSJasvinder Singh 
22546b1b3c3cSJasvinder Singh static struct pipeline_msg_rsp *
22556b1b3c3cSJasvinder Singh pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
22566b1b3c3cSJasvinder Singh 	struct pipeline_msg_req *req)
22576b1b3c3cSJasvinder Singh {
22586b1b3c3cSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
22596b1b3c3cSJasvinder Singh 	uint32_t port_id = req->id;
22606b1b3c3cSJasvinder Singh 
22616b1b3c3cSJasvinder Singh 	rsp->status = rte_pipeline_port_in_disable(p->p,
22626b1b3c3cSJasvinder Singh 		port_id);
22636b1b3c3cSJasvinder Singh 
22646b1b3c3cSJasvinder Singh 	return rsp;
22656b1b3c3cSJasvinder Singh }
22666b1b3c3cSJasvinder Singh 
226750e73d05SJasvinder Singh static struct pipeline_msg_rsp *
226850e73d05SJasvinder Singh pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,
226950e73d05SJasvinder Singh 	struct pipeline_msg_req *req)
227050e73d05SJasvinder Singh {
227150e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
227250e73d05SJasvinder Singh 	uint32_t port_id = req->id;
227350e73d05SJasvinder Singh 	int clear = req->port_out_stats_read.clear;
227450e73d05SJasvinder Singh 
227550e73d05SJasvinder Singh 	rsp->status = rte_pipeline_port_out_stats_read(p->p,
227650e73d05SJasvinder Singh 		port_id,
227750e73d05SJasvinder Singh 		&rsp->port_out_stats_read.stats,
227850e73d05SJasvinder Singh 		clear);
227950e73d05SJasvinder Singh 
228050e73d05SJasvinder Singh 	return rsp;
228150e73d05SJasvinder Singh }
228250e73d05SJasvinder Singh 
228350e73d05SJasvinder Singh static struct pipeline_msg_rsp *
228450e73d05SJasvinder Singh pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
228550e73d05SJasvinder Singh 	struct pipeline_msg_req *req)
228650e73d05SJasvinder Singh {
228750e73d05SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
228850e73d05SJasvinder Singh 	uint32_t port_id = req->id;
228950e73d05SJasvinder Singh 	int clear = req->table_stats_read.clear;
229050e73d05SJasvinder Singh 
229150e73d05SJasvinder Singh 	rsp->status = rte_pipeline_table_stats_read(p->p,
229250e73d05SJasvinder Singh 		port_id,
229350e73d05SJasvinder Singh 		&rsp->table_stats_read.stats,
229450e73d05SJasvinder Singh 		clear);
229550e73d05SJasvinder Singh 
229650e73d05SJasvinder Singh 	return rsp;
229750e73d05SJasvinder Singh }
229850e73d05SJasvinder Singh 
2299a3a95b7dSJasvinder Singh static int
2300a3a95b7dSJasvinder Singh match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
2301a3a95b7dSJasvinder Singh {
2302a3a95b7dSJasvinder Singh 	if (depth > 128)
2303a3a95b7dSJasvinder Singh 		return -1;
2304a3a95b7dSJasvinder Singh 
2305a3a95b7dSJasvinder Singh 	switch (depth / 32) {
2306a3a95b7dSJasvinder Singh 	case 0:
2307a3a95b7dSJasvinder Singh 		depth32[0] = depth;
2308a3a95b7dSJasvinder Singh 		depth32[1] = 0;
2309a3a95b7dSJasvinder Singh 		depth32[2] = 0;
2310a3a95b7dSJasvinder Singh 		depth32[3] = 0;
2311a3a95b7dSJasvinder Singh 		return 0;
2312a3a95b7dSJasvinder Singh 
2313a3a95b7dSJasvinder Singh 	case 1:
2314a3a95b7dSJasvinder Singh 		depth32[0] = 32;
2315a3a95b7dSJasvinder Singh 		depth32[1] = depth - 32;
2316a3a95b7dSJasvinder Singh 		depth32[2] = 0;
2317a3a95b7dSJasvinder Singh 		depth32[3] = 0;
2318a3a95b7dSJasvinder Singh 		return 0;
2319a3a95b7dSJasvinder Singh 
2320a3a95b7dSJasvinder Singh 	case 2:
2321a3a95b7dSJasvinder Singh 		depth32[0] = 32;
2322a3a95b7dSJasvinder Singh 		depth32[1] = 32;
2323a3a95b7dSJasvinder Singh 		depth32[2] = depth - 64;
2324a3a95b7dSJasvinder Singh 		depth32[3] = 0;
2325a3a95b7dSJasvinder Singh 		return 0;
2326a3a95b7dSJasvinder Singh 
2327a3a95b7dSJasvinder Singh 	case 3:
2328a3a95b7dSJasvinder Singh 		depth32[0] = 32;
2329a3a95b7dSJasvinder Singh 		depth32[1] = 32;
2330a3a95b7dSJasvinder Singh 		depth32[2] = 32;
2331a3a95b7dSJasvinder Singh 		depth32[3] = depth - 96;
2332a3a95b7dSJasvinder Singh 		return 0;
2333a3a95b7dSJasvinder Singh 
2334a3a95b7dSJasvinder Singh 	case 4:
2335a3a95b7dSJasvinder Singh 		depth32[0] = 32;
2336a3a95b7dSJasvinder Singh 		depth32[1] = 32;
2337a3a95b7dSJasvinder Singh 		depth32[2] = 32;
2338a3a95b7dSJasvinder Singh 		depth32[3] = 32;
2339a3a95b7dSJasvinder Singh 		return 0;
2340a3a95b7dSJasvinder Singh 
2341a3a95b7dSJasvinder Singh 	default:
2342a3a95b7dSJasvinder Singh 		return -1;
2343a3a95b7dSJasvinder Singh 	}
2344a3a95b7dSJasvinder Singh }
2345a3a95b7dSJasvinder Singh 
2346a3a95b7dSJasvinder Singh static int
2347a3a95b7dSJasvinder Singh match_convert(struct table_rule_match *mh,
2348a3a95b7dSJasvinder Singh 	union table_rule_match_low_level *ml,
2349a3a95b7dSJasvinder Singh 	int add)
2350a3a95b7dSJasvinder Singh {
2351a3a95b7dSJasvinder Singh 	memset(ml, 0, sizeof(*ml));
2352a3a95b7dSJasvinder Singh 
2353a3a95b7dSJasvinder Singh 	switch (mh->match_type) {
2354a3a95b7dSJasvinder Singh 	case TABLE_ACL:
2355a3a95b7dSJasvinder Singh 		if (mh->match.acl.ip_version)
2356a3a95b7dSJasvinder Singh 			if (add) {
2357a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[0].value.u8 =
2358a3a95b7dSJasvinder Singh 					mh->match.acl.proto;
2359a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[0].mask_range.u8 =
2360a3a95b7dSJasvinder Singh 					mh->match.acl.proto_mask;
2361a3a95b7dSJasvinder Singh 
2362a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[1].value.u32 =
2363a3a95b7dSJasvinder Singh 					mh->match.acl.ipv4.sa;
2364a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[1].mask_range.u32 =
2365a3a95b7dSJasvinder Singh 					mh->match.acl.sa_depth;
2366a3a95b7dSJasvinder Singh 
2367a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[2].value.u32 =
2368a3a95b7dSJasvinder Singh 					mh->match.acl.ipv4.da;
2369a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[2].mask_range.u32 =
2370a3a95b7dSJasvinder Singh 					mh->match.acl.da_depth;
2371a3a95b7dSJasvinder Singh 
2372a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[3].value.u16 =
2373a3a95b7dSJasvinder Singh 					mh->match.acl.sp0;
2374a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[3].mask_range.u16 =
2375a3a95b7dSJasvinder Singh 					mh->match.acl.sp1;
2376a3a95b7dSJasvinder Singh 
2377a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[4].value.u16 =
2378a3a95b7dSJasvinder Singh 					mh->match.acl.dp0;
2379a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[4].mask_range.u16 =
2380a3a95b7dSJasvinder Singh 					mh->match.acl.dp1;
2381a3a95b7dSJasvinder Singh 
2382a3a95b7dSJasvinder Singh 				ml->acl_add.priority =
2383a3a95b7dSJasvinder Singh 					(int32_t) mh->match.acl.priority;
2384a3a95b7dSJasvinder Singh 			} else {
2385a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[0].value.u8 =
2386a3a95b7dSJasvinder Singh 					mh->match.acl.proto;
2387a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[0].mask_range.u8 =
2388a3a95b7dSJasvinder Singh 					mh->match.acl.proto_mask;
2389a3a95b7dSJasvinder Singh 
2390a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[1].value.u32 =
2391a3a95b7dSJasvinder Singh 					mh->match.acl.ipv4.sa;
2392a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[1].mask_range.u32 =
2393a3a95b7dSJasvinder Singh 					mh->match.acl.sa_depth;
2394a3a95b7dSJasvinder Singh 
2395a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[2].value.u32 =
2396a3a95b7dSJasvinder Singh 					mh->match.acl.ipv4.da;
2397a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[2].mask_range.u32 =
2398a3a95b7dSJasvinder Singh 					mh->match.acl.da_depth;
2399a3a95b7dSJasvinder Singh 
2400a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[3].value.u16 =
2401a3a95b7dSJasvinder Singh 					mh->match.acl.sp0;
2402a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[3].mask_range.u16 =
2403a3a95b7dSJasvinder Singh 					mh->match.acl.sp1;
2404a3a95b7dSJasvinder Singh 
2405a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[4].value.u16 =
2406a3a95b7dSJasvinder Singh 					mh->match.acl.dp0;
2407a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[4].mask_range.u16 =
2408a3a95b7dSJasvinder Singh 					mh->match.acl.dp1;
2409a3a95b7dSJasvinder Singh 			}
2410a3a95b7dSJasvinder Singh 		else
2411a3a95b7dSJasvinder Singh 			if (add) {
2412*5ac1abddSRobin Jarry 				uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
2413*5ac1abddSRobin Jarry 				uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
2414a3a95b7dSJasvinder Singh 				uint32_t sa32_depth[4], da32_depth[4];
2415a3a95b7dSJasvinder Singh 				int status;
2416a3a95b7dSJasvinder Singh 
2417a3a95b7dSJasvinder Singh 				status = match_convert_ipv6_depth(
2418a3a95b7dSJasvinder Singh 					mh->match.acl.sa_depth,
2419a3a95b7dSJasvinder Singh 					sa32_depth);
2420a3a95b7dSJasvinder Singh 				if (status)
2421a3a95b7dSJasvinder Singh 					return status;
2422a3a95b7dSJasvinder Singh 
2423a3a95b7dSJasvinder Singh 				status = match_convert_ipv6_depth(
2424a3a95b7dSJasvinder Singh 					mh->match.acl.da_depth,
2425a3a95b7dSJasvinder Singh 					da32_depth);
2426a3a95b7dSJasvinder Singh 				if (status)
2427a3a95b7dSJasvinder Singh 					return status;
2428a3a95b7dSJasvinder Singh 
2429a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[0].value.u8 =
2430a3a95b7dSJasvinder Singh 					mh->match.acl.proto;
2431a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[0].mask_range.u8 =
2432a3a95b7dSJasvinder Singh 					mh->match.acl.proto_mask;
2433a3a95b7dSJasvinder Singh 
2434223be676SReshma Pattan 				ml->acl_add.field_value[1].value.u32 =
2435223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[0]);
2436a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[1].mask_range.u32 =
2437a3a95b7dSJasvinder Singh 					sa32_depth[0];
2438223be676SReshma Pattan 				ml->acl_add.field_value[2].value.u32 =
2439223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[1]);
2440a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[2].mask_range.u32 =
2441a3a95b7dSJasvinder Singh 					sa32_depth[1];
2442223be676SReshma Pattan 				ml->acl_add.field_value[3].value.u32 =
2443223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[2]);
2444a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[3].mask_range.u32 =
2445a3a95b7dSJasvinder Singh 					sa32_depth[2];
2446223be676SReshma Pattan 				ml->acl_add.field_value[4].value.u32 =
2447223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[3]);
2448a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[4].mask_range.u32 =
2449a3a95b7dSJasvinder Singh 					sa32_depth[3];
2450a3a95b7dSJasvinder Singh 
2451223be676SReshma Pattan 				ml->acl_add.field_value[5].value.u32 =
2452223be676SReshma Pattan 					rte_be_to_cpu_32(da32[0]);
2453a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[5].mask_range.u32 =
2454a3a95b7dSJasvinder Singh 					da32_depth[0];
2455223be676SReshma Pattan 				ml->acl_add.field_value[6].value.u32 =
2456223be676SReshma Pattan 					rte_be_to_cpu_32(da32[1]);
2457a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[6].mask_range.u32 =
2458a3a95b7dSJasvinder Singh 					da32_depth[1];
2459223be676SReshma Pattan 				ml->acl_add.field_value[7].value.u32 =
2460223be676SReshma Pattan 					rte_be_to_cpu_32(da32[2]);
2461a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[7].mask_range.u32 =
2462a3a95b7dSJasvinder Singh 					da32_depth[2];
2463223be676SReshma Pattan 				ml->acl_add.field_value[8].value.u32 =
2464223be676SReshma Pattan 					rte_be_to_cpu_32(da32[3]);
2465a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[8].mask_range.u32 =
2466a3a95b7dSJasvinder Singh 					da32_depth[3];
2467a3a95b7dSJasvinder Singh 
2468a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[9].value.u16 =
2469a3a95b7dSJasvinder Singh 					mh->match.acl.sp0;
2470a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[9].mask_range.u16 =
2471a3a95b7dSJasvinder Singh 					mh->match.acl.sp1;
2472a3a95b7dSJasvinder Singh 
2473a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[10].value.u16 =
2474a3a95b7dSJasvinder Singh 					mh->match.acl.dp0;
2475a3a95b7dSJasvinder Singh 				ml->acl_add.field_value[10].mask_range.u16 =
2476a3a95b7dSJasvinder Singh 					mh->match.acl.dp1;
2477a3a95b7dSJasvinder Singh 
2478a3a95b7dSJasvinder Singh 				ml->acl_add.priority =
2479a3a95b7dSJasvinder Singh 					(int32_t) mh->match.acl.priority;
2480a3a95b7dSJasvinder Singh 			} else {
2481*5ac1abddSRobin Jarry 				uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
2482*5ac1abddSRobin Jarry 				uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
2483a3a95b7dSJasvinder Singh 				uint32_t sa32_depth[4], da32_depth[4];
2484a3a95b7dSJasvinder Singh 				int status;
2485a3a95b7dSJasvinder Singh 
2486a3a95b7dSJasvinder Singh 				status = match_convert_ipv6_depth(
2487a3a95b7dSJasvinder Singh 					mh->match.acl.sa_depth,
2488a3a95b7dSJasvinder Singh 					sa32_depth);
2489a3a95b7dSJasvinder Singh 				if (status)
2490a3a95b7dSJasvinder Singh 					return status;
2491a3a95b7dSJasvinder Singh 
2492a3a95b7dSJasvinder Singh 				status = match_convert_ipv6_depth(
2493a3a95b7dSJasvinder Singh 					mh->match.acl.da_depth,
2494a3a95b7dSJasvinder Singh 					da32_depth);
2495a3a95b7dSJasvinder Singh 				if (status)
2496a3a95b7dSJasvinder Singh 					return status;
2497a3a95b7dSJasvinder Singh 
2498a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[0].value.u8 =
2499a3a95b7dSJasvinder Singh 					mh->match.acl.proto;
2500a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[0].mask_range.u8 =
2501a3a95b7dSJasvinder Singh 					mh->match.acl.proto_mask;
2502a3a95b7dSJasvinder Singh 
2503a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[1].value.u32 =
2504223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[0]);
2505a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[1].mask_range.u32 =
2506a3a95b7dSJasvinder Singh 					sa32_depth[0];
2507a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[2].value.u32 =
2508223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[1]);
2509a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[2].mask_range.u32 =
2510a3a95b7dSJasvinder Singh 					sa32_depth[1];
2511a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[3].value.u32 =
2512223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[2]);
2513a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[3].mask_range.u32 =
2514a3a95b7dSJasvinder Singh 					sa32_depth[2];
2515a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[4].value.u32 =
2516223be676SReshma Pattan 					rte_be_to_cpu_32(sa32[3]);
2517a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[4].mask_range.u32 =
2518a3a95b7dSJasvinder Singh 					sa32_depth[3];
2519a3a95b7dSJasvinder Singh 
2520a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[5].value.u32 =
2521223be676SReshma Pattan 					rte_be_to_cpu_32(da32[0]);
2522a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[5].mask_range.u32 =
2523a3a95b7dSJasvinder Singh 					da32_depth[0];
2524a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[6].value.u32 =
2525223be676SReshma Pattan 					rte_be_to_cpu_32(da32[1]);
2526a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[6].mask_range.u32 =
2527a3a95b7dSJasvinder Singh 					da32_depth[1];
2528a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[7].value.u32 =
2529223be676SReshma Pattan 					rte_be_to_cpu_32(da32[2]);
2530a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[7].mask_range.u32 =
2531a3a95b7dSJasvinder Singh 					da32_depth[2];
2532a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[8].value.u32 =
2533223be676SReshma Pattan 					rte_be_to_cpu_32(da32[3]);
2534a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[8].mask_range.u32 =
2535a3a95b7dSJasvinder Singh 					da32_depth[3];
2536a3a95b7dSJasvinder Singh 
2537a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[9].value.u16 =
2538a3a95b7dSJasvinder Singh 					mh->match.acl.sp0;
2539a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[9].mask_range.u16 =
2540a3a95b7dSJasvinder Singh 					mh->match.acl.sp1;
2541a3a95b7dSJasvinder Singh 
2542a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[10].value.u16 =
2543a3a95b7dSJasvinder Singh 					mh->match.acl.dp0;
2544a3a95b7dSJasvinder Singh 				ml->acl_delete.field_value[10].mask_range.u16 =
2545a3a95b7dSJasvinder Singh 					mh->match.acl.dp1;
2546a3a95b7dSJasvinder Singh 			}
2547a3a95b7dSJasvinder Singh 		return 0;
2548a3a95b7dSJasvinder Singh 
2549a3a95b7dSJasvinder Singh 	case TABLE_ARRAY:
2550a3a95b7dSJasvinder Singh 		ml->array.pos = mh->match.array.pos;
2551a3a95b7dSJasvinder Singh 		return 0;
2552a3a95b7dSJasvinder Singh 
2553a3a95b7dSJasvinder Singh 	case TABLE_HASH:
2554a3a95b7dSJasvinder Singh 		memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
2555a3a95b7dSJasvinder Singh 		return 0;
2556a3a95b7dSJasvinder Singh 
2557a3a95b7dSJasvinder Singh 	case TABLE_LPM:
2558a3a95b7dSJasvinder Singh 		if (mh->match.lpm.ip_version) {
2559a3a95b7dSJasvinder Singh 			ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
2560a3a95b7dSJasvinder Singh 			ml->lpm_ipv4.depth = mh->match.lpm.depth;
2561a3a95b7dSJasvinder Singh 		} else {
2562*5ac1abddSRobin Jarry 			ml->lpm_ipv6.ip = mh->match.lpm.ipv6;
2563a3a95b7dSJasvinder Singh 			ml->lpm_ipv6.depth = mh->match.lpm.depth;
2564a3a95b7dSJasvinder Singh 		}
2565a3a95b7dSJasvinder Singh 
2566a3a95b7dSJasvinder Singh 		return 0;
2567a3a95b7dSJasvinder Singh 
2568a3a95b7dSJasvinder Singh 	default:
2569a3a95b7dSJasvinder Singh 		return -1;
2570a3a95b7dSJasvinder Singh 	}
2571a3a95b7dSJasvinder Singh }
2572a3a95b7dSJasvinder Singh 
2573f68a1d3fSJasvinder Singh static int
2574f68a1d3fSJasvinder Singh action_convert(struct rte_table_action *a,
2575f68a1d3fSJasvinder Singh 	struct table_rule_action *action,
2576f68a1d3fSJasvinder Singh 	struct rte_pipeline_table_entry *data)
2577f68a1d3fSJasvinder Singh {
2578f68a1d3fSJasvinder Singh 	int status;
2579f68a1d3fSJasvinder Singh 
2580f68a1d3fSJasvinder Singh 	/* Apply actions */
2581f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
2582f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2583f68a1d3fSJasvinder Singh 			data,
2584f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_FWD,
2585f68a1d3fSJasvinder Singh 			&action->fwd);
2586f68a1d3fSJasvinder Singh 
2587f68a1d3fSJasvinder Singh 		if (status)
2588f68a1d3fSJasvinder Singh 			return status;
2589f68a1d3fSJasvinder Singh 	}
2590f68a1d3fSJasvinder Singh 
2591f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
2592f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2593f68a1d3fSJasvinder Singh 			data,
2594f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_LB,
2595f68a1d3fSJasvinder Singh 			&action->lb);
2596f68a1d3fSJasvinder Singh 
2597f68a1d3fSJasvinder Singh 		if (status)
2598f68a1d3fSJasvinder Singh 			return status;
2599f68a1d3fSJasvinder Singh 	}
2600f68a1d3fSJasvinder Singh 
2601f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
2602f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2603f68a1d3fSJasvinder Singh 			data,
2604f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_MTR,
2605f68a1d3fSJasvinder Singh 			&action->mtr);
2606f68a1d3fSJasvinder Singh 
2607f68a1d3fSJasvinder Singh 		if (status)
2608f68a1d3fSJasvinder Singh 			return status;
2609f68a1d3fSJasvinder Singh 	}
2610f68a1d3fSJasvinder Singh 
2611f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
2612f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2613f68a1d3fSJasvinder Singh 			data,
2614f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_TM,
2615f68a1d3fSJasvinder Singh 			&action->tm);
2616f68a1d3fSJasvinder Singh 
2617f68a1d3fSJasvinder Singh 		if (status)
2618f68a1d3fSJasvinder Singh 			return status;
2619f68a1d3fSJasvinder Singh 	}
2620f68a1d3fSJasvinder Singh 
2621f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
2622f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2623f68a1d3fSJasvinder Singh 			data,
2624f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_ENCAP,
2625f68a1d3fSJasvinder Singh 			&action->encap);
2626f68a1d3fSJasvinder Singh 
2627f68a1d3fSJasvinder Singh 		if (status)
2628f68a1d3fSJasvinder Singh 			return status;
2629f68a1d3fSJasvinder Singh 	}
2630f68a1d3fSJasvinder Singh 
2631f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
2632f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2633f68a1d3fSJasvinder Singh 			data,
2634f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_NAT,
2635f68a1d3fSJasvinder Singh 			&action->nat);
2636f68a1d3fSJasvinder Singh 
2637f68a1d3fSJasvinder Singh 		if (status)
2638f68a1d3fSJasvinder Singh 			return status;
2639f68a1d3fSJasvinder Singh 	}
2640f68a1d3fSJasvinder Singh 
2641f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
2642f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2643f68a1d3fSJasvinder Singh 			data,
2644f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_TTL,
2645f68a1d3fSJasvinder Singh 			&action->ttl);
2646f68a1d3fSJasvinder Singh 
2647f68a1d3fSJasvinder Singh 		if (status)
2648f68a1d3fSJasvinder Singh 			return status;
2649f68a1d3fSJasvinder Singh 	}
2650f68a1d3fSJasvinder Singh 
2651f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
2652f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2653f68a1d3fSJasvinder Singh 			data,
2654f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_STATS,
2655f68a1d3fSJasvinder Singh 			&action->stats);
2656f68a1d3fSJasvinder Singh 
2657f68a1d3fSJasvinder Singh 		if (status)
2658f68a1d3fSJasvinder Singh 			return status;
2659f68a1d3fSJasvinder Singh 	}
2660f68a1d3fSJasvinder Singh 
2661f68a1d3fSJasvinder Singh 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
2662f68a1d3fSJasvinder Singh 		status = rte_table_action_apply(a,
2663f68a1d3fSJasvinder Singh 			data,
2664f68a1d3fSJasvinder Singh 			RTE_TABLE_ACTION_TIME,
2665f68a1d3fSJasvinder Singh 			&action->time);
2666f68a1d3fSJasvinder Singh 
2667f68a1d3fSJasvinder Singh 		if (status)
2668f68a1d3fSJasvinder Singh 			return status;
2669f68a1d3fSJasvinder Singh 	}
2670f68a1d3fSJasvinder Singh 
2671d46fe944SFan Zhang 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
2672d46fe944SFan Zhang 		status = rte_table_action_apply(a,
2673d46fe944SFan Zhang 			data,
2674d46fe944SFan Zhang 			RTE_TABLE_ACTION_SYM_CRYPTO,
2675d46fe944SFan Zhang 			&action->sym_crypto);
2676d46fe944SFan Zhang 
2677d46fe944SFan Zhang 		if (status)
2678d46fe944SFan Zhang 			return status;
2679d46fe944SFan Zhang 	}
2680d46fe944SFan Zhang 
26811bdf2632SCristian Dumitrescu 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
26821bdf2632SCristian Dumitrescu 		status = rte_table_action_apply(a,
26831bdf2632SCristian Dumitrescu 			data,
26841bdf2632SCristian Dumitrescu 			RTE_TABLE_ACTION_TAG,
26851bdf2632SCristian Dumitrescu 			&action->tag);
26861bdf2632SCristian Dumitrescu 
26871bdf2632SCristian Dumitrescu 		if (status)
26881bdf2632SCristian Dumitrescu 			return status;
26891bdf2632SCristian Dumitrescu 	}
26901bdf2632SCristian Dumitrescu 
2691d5ed626fSCristian Dumitrescu 	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
2692d5ed626fSCristian Dumitrescu 		status = rte_table_action_apply(a,
2693d5ed626fSCristian Dumitrescu 			data,
2694d5ed626fSCristian Dumitrescu 			RTE_TABLE_ACTION_DECAP,
2695d5ed626fSCristian Dumitrescu 			&action->decap);
2696d5ed626fSCristian Dumitrescu 
2697d5ed626fSCristian Dumitrescu 		if (status)
2698d5ed626fSCristian Dumitrescu 			return status;
2699d5ed626fSCristian Dumitrescu 	}
2700d5ed626fSCristian Dumitrescu 
2701f68a1d3fSJasvinder Singh 	return 0;
2702f68a1d3fSJasvinder Singh }
2703f68a1d3fSJasvinder Singh 
2704a3a95b7dSJasvinder Singh static struct pipeline_msg_rsp *
2705a3a95b7dSJasvinder Singh pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
2706a3a95b7dSJasvinder Singh 	struct pipeline_msg_req *req)
2707a3a95b7dSJasvinder Singh {
2708a3a95b7dSJasvinder Singh 	union table_rule_match_low_level match_ll;
2709a3a95b7dSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2710a3a95b7dSJasvinder Singh 	struct table_rule_match *match = &req->table_rule_add.match;
2711a3a95b7dSJasvinder Singh 	struct table_rule_action *action = &req->table_rule_add.action;
2712a3a95b7dSJasvinder Singh 	struct rte_pipeline_table_entry *data_in, *data_out;
2713a3a95b7dSJasvinder Singh 	uint32_t table_id = req->id;
2714a3a95b7dSJasvinder Singh 	int key_found, status;
2715a3a95b7dSJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
2716a3a95b7dSJasvinder Singh 
2717a3a95b7dSJasvinder Singh 	/* Apply actions */
2718a3a95b7dSJasvinder Singh 	memset(p->buffer, 0, sizeof(p->buffer));
2719a3a95b7dSJasvinder Singh 	data_in = (struct rte_pipeline_table_entry *) p->buffer;
2720a3a95b7dSJasvinder Singh 
2721a3a95b7dSJasvinder Singh 	status = match_convert(match, &match_ll, 1);
2722a3a95b7dSJasvinder Singh 	if (status) {
2723a3a95b7dSJasvinder Singh 		rsp->status = -1;
2724a3a95b7dSJasvinder Singh 		return rsp;
2725a3a95b7dSJasvinder Singh 	}
2726a3a95b7dSJasvinder Singh 
2727f68a1d3fSJasvinder Singh 	status = action_convert(a, action, data_in);
2728f68a1d3fSJasvinder Singh 	if (status) {
2729f68a1d3fSJasvinder Singh 		rsp->status = -1;
2730f68a1d3fSJasvinder Singh 		return rsp;
2731f68a1d3fSJasvinder Singh 	}
2732f68a1d3fSJasvinder Singh 
2733a3a95b7dSJasvinder Singh 	status = rte_pipeline_table_entry_add(p->p,
2734a3a95b7dSJasvinder Singh 		table_id,
2735a3a95b7dSJasvinder Singh 		&match_ll,
2736a3a95b7dSJasvinder Singh 		data_in,
2737a3a95b7dSJasvinder Singh 		&key_found,
2738a3a95b7dSJasvinder Singh 		&data_out);
2739a3a95b7dSJasvinder Singh 	if (status) {
2740a3a95b7dSJasvinder Singh 		rsp->status = -1;
2741a3a95b7dSJasvinder Singh 		return rsp;
2742a3a95b7dSJasvinder Singh 	}
2743a3a95b7dSJasvinder Singh 
2744a3a95b7dSJasvinder Singh 	/* Write response */
2745a3a95b7dSJasvinder Singh 	rsp->status = 0;
2746a3a95b7dSJasvinder Singh 	rsp->table_rule_add.data = data_out;
2747a3a95b7dSJasvinder Singh 
2748a3a95b7dSJasvinder Singh 	return rsp;
2749a3a95b7dSJasvinder Singh }
2750a3a95b7dSJasvinder Singh 
2751a3a95b7dSJasvinder Singh static struct pipeline_msg_rsp *
2752a3a95b7dSJasvinder Singh pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
2753a3a95b7dSJasvinder Singh 	struct pipeline_msg_req *req)
2754a3a95b7dSJasvinder Singh {
2755a3a95b7dSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2756a3a95b7dSJasvinder Singh 	struct table_rule_action *action = &req->table_rule_add_default.action;
2757a3a95b7dSJasvinder Singh 	struct rte_pipeline_table_entry *data_in, *data_out;
2758a3a95b7dSJasvinder Singh 	uint32_t table_id = req->id;
2759a3a95b7dSJasvinder Singh 	int status;
2760a3a95b7dSJasvinder Singh 
2761a3a95b7dSJasvinder Singh 	/* Apply actions */
2762a3a95b7dSJasvinder Singh 	memset(p->buffer, 0, sizeof(p->buffer));
2763a3a95b7dSJasvinder Singh 	data_in = (struct rte_pipeline_table_entry *) p->buffer;
2764a3a95b7dSJasvinder Singh 
2765a3a95b7dSJasvinder Singh 	data_in->action = action->fwd.action;
2766a3a95b7dSJasvinder Singh 	if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
2767a3a95b7dSJasvinder Singh 		data_in->port_id = action->fwd.id;
2768a3a95b7dSJasvinder Singh 	if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
2769a3a95b7dSJasvinder Singh 		data_in->table_id = action->fwd.id;
2770a3a95b7dSJasvinder Singh 
2771a3a95b7dSJasvinder Singh 	/* Add default rule to table */
2772a3a95b7dSJasvinder Singh 	status = rte_pipeline_table_default_entry_add(p->p,
2773a3a95b7dSJasvinder Singh 		table_id,
2774a3a95b7dSJasvinder Singh 		data_in,
2775a3a95b7dSJasvinder Singh 		&data_out);
2776a3a95b7dSJasvinder Singh 	if (status) {
2777a3a95b7dSJasvinder Singh 		rsp->status = -1;
2778a3a95b7dSJasvinder Singh 		return rsp;
2779a3a95b7dSJasvinder Singh 	}
2780a3a95b7dSJasvinder Singh 
2781a3a95b7dSJasvinder Singh 	/* Write response */
2782a3a95b7dSJasvinder Singh 	rsp->status = 0;
2783a3a95b7dSJasvinder Singh 	rsp->table_rule_add_default.data = data_out;
2784a3a95b7dSJasvinder Singh 
2785a3a95b7dSJasvinder Singh 	return rsp;
2786a3a95b7dSJasvinder Singh }
2787a3a95b7dSJasvinder Singh 
2788f634e4c5SJasvinder Singh static struct pipeline_msg_rsp *
27893186282fSJasvinder Singh pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
27903186282fSJasvinder Singh 	struct pipeline_msg_req *req)
27913186282fSJasvinder Singh {
27923186282fSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
27933186282fSJasvinder Singh 
27943186282fSJasvinder Singh 	uint32_t table_id = req->id;
279527b333b2SCristian Dumitrescu 	struct table_rule_list *list = req->table_rule_add_bulk.list;
27963186282fSJasvinder Singh 	uint32_t bulk = req->table_rule_add_bulk.bulk;
27973186282fSJasvinder Singh 
279827b333b2SCristian Dumitrescu 	uint32_t n_rules_added;
279927b333b2SCristian Dumitrescu 	int status;
28003186282fSJasvinder Singh 
280127b333b2SCristian Dumitrescu 	struct table_ll table_ll = {
280227b333b2SCristian Dumitrescu 		.p = p->p,
280327b333b2SCristian Dumitrescu 		.table_id = table_id,
280427b333b2SCristian Dumitrescu 		.a = p->table_data[table_id].a,
280527b333b2SCristian Dumitrescu 		.bulk_supported = bulk,
280627b333b2SCristian Dumitrescu 	};
28073186282fSJasvinder Singh 
280827b333b2SCristian Dumitrescu 	status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
28093186282fSJasvinder Singh 	if (status) {
281027b333b2SCristian Dumitrescu 		rsp->status = -1;
281127b333b2SCristian Dumitrescu 		rsp->table_rule_add_bulk.n_rules = 0;
281227b333b2SCristian Dumitrescu 		return rsp;
28133186282fSJasvinder Singh 	}
28143186282fSJasvinder Singh 
28153186282fSJasvinder Singh 	/* Write response */
28163186282fSJasvinder Singh 	rsp->status = 0;
281727b333b2SCristian Dumitrescu 	rsp->table_rule_add_bulk.n_rules = n_rules_added;
28183186282fSJasvinder Singh 	return rsp;
28193186282fSJasvinder Singh }
28203186282fSJasvinder Singh 
28213186282fSJasvinder Singh static struct pipeline_msg_rsp *
2822f634e4c5SJasvinder Singh pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,
2823f634e4c5SJasvinder Singh 	struct pipeline_msg_req *req)
2824f634e4c5SJasvinder Singh {
2825f634e4c5SJasvinder Singh 	union table_rule_match_low_level match_ll;
2826f634e4c5SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2827f634e4c5SJasvinder Singh 	struct table_rule_match *match = &req->table_rule_delete.match;
2828f634e4c5SJasvinder Singh 	uint32_t table_id = req->id;
2829f634e4c5SJasvinder Singh 	int key_found, status;
2830f634e4c5SJasvinder Singh 
2831f634e4c5SJasvinder Singh 	status = match_convert(match, &match_ll, 0);
2832f634e4c5SJasvinder Singh 	if (status) {
2833f634e4c5SJasvinder Singh 		rsp->status = -1;
2834f634e4c5SJasvinder Singh 		return rsp;
2835f634e4c5SJasvinder Singh 	}
2836f634e4c5SJasvinder Singh 
2837f634e4c5SJasvinder Singh 	rsp->status = rte_pipeline_table_entry_delete(p->p,
2838f634e4c5SJasvinder Singh 		table_id,
2839f634e4c5SJasvinder Singh 		&match_ll,
2840f634e4c5SJasvinder Singh 		&key_found,
2841f634e4c5SJasvinder Singh 		NULL);
2842f634e4c5SJasvinder Singh 
2843f634e4c5SJasvinder Singh 	return rsp;
2844f634e4c5SJasvinder Singh }
2845f634e4c5SJasvinder Singh 
2846f634e4c5SJasvinder Singh static struct pipeline_msg_rsp *
2847f634e4c5SJasvinder Singh pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,
2848f634e4c5SJasvinder Singh 	struct pipeline_msg_req *req)
2849f634e4c5SJasvinder Singh {
2850f634e4c5SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2851f634e4c5SJasvinder Singh 	uint32_t table_id = req->id;
2852f634e4c5SJasvinder Singh 
2853f634e4c5SJasvinder Singh 	rsp->status = rte_pipeline_table_default_entry_delete(p->p,
2854f634e4c5SJasvinder Singh 		table_id,
2855f634e4c5SJasvinder Singh 		NULL);
2856f634e4c5SJasvinder Singh 
2857f634e4c5SJasvinder Singh 	return rsp;
2858f634e4c5SJasvinder Singh }
2859f634e4c5SJasvinder Singh 
2860c64b9121SJasvinder Singh static struct pipeline_msg_rsp *
2861c64b9121SJasvinder Singh pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,
2862c64b9121SJasvinder Singh 	struct pipeline_msg_req *req)
2863c64b9121SJasvinder Singh {
2864c64b9121SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2865c64b9121SJasvinder Singh 	uint32_t table_id = req->id;
2866c64b9121SJasvinder Singh 	void *data = req->table_rule_stats_read.data;
2867c64b9121SJasvinder Singh 	int clear = req->table_rule_stats_read.clear;
2868c64b9121SJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
2869c64b9121SJasvinder Singh 
2870c64b9121SJasvinder Singh 	rsp->status = rte_table_action_stats_read(a,
2871c64b9121SJasvinder Singh 		data,
2872c64b9121SJasvinder Singh 		&rsp->table_rule_stats_read.stats,
2873c64b9121SJasvinder Singh 		clear);
2874c64b9121SJasvinder Singh 
2875c64b9121SJasvinder Singh 	return rsp;
2876c64b9121SJasvinder Singh }
2877c64b9121SJasvinder Singh 
28787e11393eSJasvinder Singh static struct pipeline_msg_rsp *
28797e11393eSJasvinder Singh pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,
28807e11393eSJasvinder Singh 	struct pipeline_msg_req *req)
28817e11393eSJasvinder Singh {
28827e11393eSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
28837e11393eSJasvinder Singh 	uint32_t table_id = req->id;
28847e11393eSJasvinder Singh 	uint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;
28857e11393eSJasvinder Singh 	struct rte_table_action_meter_profile *profile =
28867e11393eSJasvinder Singh 		&req->table_mtr_profile_add.profile;
28877e11393eSJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
28887e11393eSJasvinder Singh 
28897e11393eSJasvinder Singh 	rsp->status = rte_table_action_meter_profile_add(a,
28907e11393eSJasvinder Singh 		meter_profile_id,
28917e11393eSJasvinder Singh 		profile);
28927e11393eSJasvinder Singh 
28937e11393eSJasvinder Singh 	return rsp;
28947e11393eSJasvinder Singh }
28957e11393eSJasvinder Singh 
28967e11393eSJasvinder Singh static struct pipeline_msg_rsp *
28977e11393eSJasvinder Singh pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,
28987e11393eSJasvinder Singh 	struct pipeline_msg_req *req)
28997e11393eSJasvinder Singh {
29007e11393eSJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
29017e11393eSJasvinder Singh 	uint32_t table_id = req->id;
29027e11393eSJasvinder Singh 	uint32_t meter_profile_id =
29037e11393eSJasvinder Singh 		req->table_mtr_profile_delete.meter_profile_id;
29047e11393eSJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
29057e11393eSJasvinder Singh 
29067e11393eSJasvinder Singh 	rsp->status = rte_table_action_meter_profile_delete(a,
29077e11393eSJasvinder Singh 		meter_profile_id);
29087e11393eSJasvinder Singh 
29097e11393eSJasvinder Singh 	return rsp;
29107e11393eSJasvinder Singh }
29117e11393eSJasvinder Singh 
2912e92058d6SJasvinder Singh static struct pipeline_msg_rsp *
2913e92058d6SJasvinder Singh pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,
2914e92058d6SJasvinder Singh 	struct pipeline_msg_req *req)
2915e92058d6SJasvinder Singh {
2916e92058d6SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2917e92058d6SJasvinder Singh 	uint32_t table_id = req->id;
2918e92058d6SJasvinder Singh 	void *data = req->table_rule_mtr_read.data;
2919e92058d6SJasvinder Singh 	uint32_t tc_mask = req->table_rule_mtr_read.tc_mask;
2920e92058d6SJasvinder Singh 	int clear = req->table_rule_mtr_read.clear;
2921e92058d6SJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
2922e92058d6SJasvinder Singh 
2923e92058d6SJasvinder Singh 	rsp->status = rte_table_action_meter_read(a,
2924e92058d6SJasvinder Singh 		data,
2925e92058d6SJasvinder Singh 		tc_mask,
2926e92058d6SJasvinder Singh 		&rsp->table_rule_mtr_read.stats,
2927e92058d6SJasvinder Singh 		clear);
2928e92058d6SJasvinder Singh 
2929e92058d6SJasvinder Singh 	return rsp;
2930e92058d6SJasvinder Singh }
2931e92058d6SJasvinder Singh 
29322b82ef48SJasvinder Singh static struct pipeline_msg_rsp *
29332b82ef48SJasvinder Singh pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,
29342b82ef48SJasvinder Singh 	struct pipeline_msg_req *req)
29352b82ef48SJasvinder Singh {
29362b82ef48SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
29372b82ef48SJasvinder Singh 	uint32_t table_id = req->id;
29382b82ef48SJasvinder Singh 	uint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;
29392b82ef48SJasvinder Singh 	struct rte_table_action_dscp_table *dscp_table =
29402b82ef48SJasvinder Singh 		&req->table_dscp_table_update.dscp_table;
29412b82ef48SJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
29422b82ef48SJasvinder Singh 
29432b82ef48SJasvinder Singh 	rsp->status = rte_table_action_dscp_table_update(a,
29442b82ef48SJasvinder Singh 		dscp_mask,
29452b82ef48SJasvinder Singh 		dscp_table);
29462b82ef48SJasvinder Singh 
29472b82ef48SJasvinder Singh 	return rsp;
29482b82ef48SJasvinder Singh }
29492b82ef48SJasvinder Singh 
2950d0d306c7SJasvinder Singh static struct pipeline_msg_rsp *
2951d0d306c7SJasvinder Singh pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
2952d0d306c7SJasvinder Singh 	struct pipeline_msg_req *req)
2953d0d306c7SJasvinder Singh {
2954d0d306c7SJasvinder Singh 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2955d0d306c7SJasvinder Singh 	uint32_t table_id = req->id;
2956d0d306c7SJasvinder Singh 	void *data = req->table_rule_ttl_read.data;
2957d0d306c7SJasvinder Singh 	int clear = req->table_rule_ttl_read.clear;
2958d0d306c7SJasvinder Singh 	struct rte_table_action *a = p->table_data[table_id].a;
2959d0d306c7SJasvinder Singh 
2960d0d306c7SJasvinder Singh 	rsp->status = rte_table_action_ttl_read(a,
2961d0d306c7SJasvinder Singh 		data,
2962d0d306c7SJasvinder Singh 		&rsp->table_rule_ttl_read.stats,
2963d0d306c7SJasvinder Singh 		clear);
2964d0d306c7SJasvinder Singh 
2965d0d306c7SJasvinder Singh 	return rsp;
2966d0d306c7SJasvinder Singh }
2967d0d306c7SJasvinder Singh 
2968a3169ee5SCristian Dumitrescu static struct pipeline_msg_rsp *
2969a3169ee5SCristian Dumitrescu pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
2970a3169ee5SCristian Dumitrescu 	struct pipeline_msg_req *req)
2971a3169ee5SCristian Dumitrescu {
2972a3169ee5SCristian Dumitrescu 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
2973a3169ee5SCristian Dumitrescu 	uint32_t table_id = req->id;
2974a3169ee5SCristian Dumitrescu 	void *data = req->table_rule_time_read.data;
2975a3169ee5SCristian Dumitrescu 	struct rte_table_action *a = p->table_data[table_id].a;
2976a3169ee5SCristian Dumitrescu 
2977a3169ee5SCristian Dumitrescu 	rsp->status = rte_table_action_time_read(a,
2978a3169ee5SCristian Dumitrescu 		data,
2979a3169ee5SCristian Dumitrescu 		&rsp->table_rule_time_read.timestamp);
2980a3169ee5SCristian Dumitrescu 
2981a3169ee5SCristian Dumitrescu 	return rsp;
2982a3169ee5SCristian Dumitrescu }
2983a3169ee5SCristian Dumitrescu 
2984a8bd581dSJasvinder Singh static void
2985a8bd581dSJasvinder Singh pipeline_msg_handle(struct pipeline_data *p)
2986a8bd581dSJasvinder Singh {
2987a8bd581dSJasvinder Singh 	for ( ; ; ) {
2988a8bd581dSJasvinder Singh 		struct pipeline_msg_req *req;
2989a8bd581dSJasvinder Singh 		struct pipeline_msg_rsp *rsp;
2990a8bd581dSJasvinder Singh 
2991a8bd581dSJasvinder Singh 		req = pipeline_msg_recv(p->msgq_req);
2992a8bd581dSJasvinder Singh 		if (req == NULL)
2993a8bd581dSJasvinder Singh 			break;
2994a8bd581dSJasvinder Singh 
2995a8bd581dSJasvinder Singh 		switch (req->type) {
299650e73d05SJasvinder Singh 		case PIPELINE_REQ_PORT_IN_STATS_READ:
299750e73d05SJasvinder Singh 			rsp = pipeline_msg_handle_port_in_stats_read(p, req);
299850e73d05SJasvinder Singh 			break;
299950e73d05SJasvinder Singh 
30006b1b3c3cSJasvinder Singh 		case PIPELINE_REQ_PORT_IN_ENABLE:
30016b1b3c3cSJasvinder Singh 			rsp = pipeline_msg_handle_port_in_enable(p, req);
30026b1b3c3cSJasvinder Singh 			break;
30036b1b3c3cSJasvinder Singh 
30046b1b3c3cSJasvinder Singh 		case PIPELINE_REQ_PORT_IN_DISABLE:
30056b1b3c3cSJasvinder Singh 			rsp = pipeline_msg_handle_port_in_disable(p, req);
30066b1b3c3cSJasvinder Singh 			break;
30076b1b3c3cSJasvinder Singh 
300850e73d05SJasvinder Singh 		case PIPELINE_REQ_PORT_OUT_STATS_READ:
300950e73d05SJasvinder Singh 			rsp = pipeline_msg_handle_port_out_stats_read(p, req);
301050e73d05SJasvinder Singh 			break;
301150e73d05SJasvinder Singh 
301250e73d05SJasvinder Singh 		case PIPELINE_REQ_TABLE_STATS_READ:
301350e73d05SJasvinder Singh 			rsp = pipeline_msg_handle_table_stats_read(p, req);
301450e73d05SJasvinder Singh 			break;
301550e73d05SJasvinder Singh 
3016a3a95b7dSJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_ADD:
3017a3a95b7dSJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_add(p, req);
3018a3a95b7dSJasvinder Singh 			break;
3019a3a95b7dSJasvinder Singh 
3020a3a95b7dSJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:
3021a3a95b7dSJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_add_default(p,	req);
3022a3a95b7dSJasvinder Singh 			break;
302350e73d05SJasvinder Singh 
30243186282fSJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_ADD_BULK:
30253186282fSJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_add_bulk(p, req);
30263186282fSJasvinder Singh 			break;
30273186282fSJasvinder Singh 
3028f634e4c5SJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_DELETE:
3029f634e4c5SJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_delete(p, req);
3030f634e4c5SJasvinder Singh 			break;
3031f634e4c5SJasvinder Singh 
3032f634e4c5SJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:
3033f634e4c5SJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_delete_default(p, req);
3034f634e4c5SJasvinder Singh 			break;
3035f634e4c5SJasvinder Singh 
3036c64b9121SJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_STATS_READ:
3037c64b9121SJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_stats_read(p, req);
3038c64b9121SJasvinder Singh 			break;
3039c64b9121SJasvinder Singh 
30407e11393eSJasvinder Singh 		case PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:
30417e11393eSJasvinder Singh 			rsp = pipeline_msg_handle_table_mtr_profile_add(p, req);
30427e11393eSJasvinder Singh 			break;
30437e11393eSJasvinder Singh 
30447e11393eSJasvinder Singh 		case PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:
30457e11393eSJasvinder Singh 			rsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);
30467e11393eSJasvinder Singh 			break;
30477e11393eSJasvinder Singh 
3048e92058d6SJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_MTR_READ:
3049e92058d6SJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_mtr_read(p, req);
3050e92058d6SJasvinder Singh 			break;
3051e92058d6SJasvinder Singh 
30522b82ef48SJasvinder Singh 		case PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:
30532b82ef48SJasvinder Singh 			rsp = pipeline_msg_handle_table_dscp_table_update(p, req);
30542b82ef48SJasvinder Singh 			break;
30552b82ef48SJasvinder Singh 
3056d0d306c7SJasvinder Singh 		case PIPELINE_REQ_TABLE_RULE_TTL_READ:
3057d0d306c7SJasvinder Singh 			rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
3058d0d306c7SJasvinder Singh 			break;
3059d0d306c7SJasvinder Singh 
3060a3169ee5SCristian Dumitrescu 		case PIPELINE_REQ_TABLE_RULE_TIME_READ:
3061a3169ee5SCristian Dumitrescu 			rsp = pipeline_msg_handle_table_rule_time_read(p, req);
3062a3169ee5SCristian Dumitrescu 			break;
3063a3169ee5SCristian Dumitrescu 
3064a8bd581dSJasvinder Singh 		default:
3065a8bd581dSJasvinder Singh 			rsp = (struct pipeline_msg_rsp *) req;
3066a8bd581dSJasvinder Singh 			rsp->status = -1;
3067a8bd581dSJasvinder Singh 		}
3068a8bd581dSJasvinder Singh 
3069a8bd581dSJasvinder Singh 		pipeline_msg_send(p->msgq_rsp, rsp);
3070a8bd581dSJasvinder Singh 	}
3071a8bd581dSJasvinder Singh }
3072a8bd581dSJasvinder Singh 
3073a8bd581dSJasvinder Singh /**
3074a8bd581dSJasvinder Singh  * Data plane threads: main
3075a8bd581dSJasvinder Singh  */
3076a8bd581dSJasvinder Singh int
3077a8bd581dSJasvinder Singh thread_main(void *arg __rte_unused)
3078a8bd581dSJasvinder Singh {
3079a8bd581dSJasvinder Singh 	struct thread_data *t;
3080a8bd581dSJasvinder Singh 	uint32_t thread_id, i;
3081a8bd581dSJasvinder Singh 
3082a8bd581dSJasvinder Singh 	thread_id = rte_lcore_id();
3083a8bd581dSJasvinder Singh 	t = &thread_data[thread_id];
3084a8bd581dSJasvinder Singh 
3085a8bd581dSJasvinder Singh 	/* Dispatch loop */
3086a8bd581dSJasvinder Singh 	for (i = 0; ; i++) {
3087a8bd581dSJasvinder Singh 		uint32_t j;
3088a8bd581dSJasvinder Singh 
3089a8bd581dSJasvinder Singh 		/* Data Plane */
3090a8bd581dSJasvinder Singh 		for (j = 0; j < t->n_pipelines; j++)
3091a8bd581dSJasvinder Singh 			rte_pipeline_run(t->p[j]);
3092a8bd581dSJasvinder Singh 
3093a8bd581dSJasvinder Singh 		/* Control Plane */
3094a8bd581dSJasvinder Singh 		if ((i & 0xF) == 0) {
3095a8bd581dSJasvinder Singh 			uint64_t time = rte_get_tsc_cycles();
3096a8bd581dSJasvinder Singh 			uint64_t time_next_min = UINT64_MAX;
3097a8bd581dSJasvinder Singh 
3098a8bd581dSJasvinder Singh 			if (time < t->time_next_min)
3099a8bd581dSJasvinder Singh 				continue;
3100a8bd581dSJasvinder Singh 
3101a8bd581dSJasvinder Singh 			/* Pipeline message queues */
3102a8bd581dSJasvinder Singh 			for (j = 0; j < t->n_pipelines; j++) {
3103a8bd581dSJasvinder Singh 				struct pipeline_data *p =
3104a8bd581dSJasvinder Singh 					&t->pipeline_data[j];
3105a8bd581dSJasvinder Singh 				uint64_t time_next = p->time_next;
3106a8bd581dSJasvinder Singh 
3107a8bd581dSJasvinder Singh 				if (time_next <= time) {
3108a8bd581dSJasvinder Singh 					pipeline_msg_handle(p);
3109a8bd581dSJasvinder Singh 					rte_pipeline_flush(p->p);
3110a8bd581dSJasvinder Singh 					time_next = time + p->timer_period;
3111a8bd581dSJasvinder Singh 					p->time_next = time_next;
3112a8bd581dSJasvinder Singh 				}
3113a8bd581dSJasvinder Singh 
3114a8bd581dSJasvinder Singh 				if (time_next < time_next_min)
3115a8bd581dSJasvinder Singh 					time_next_min = time_next;
3116a8bd581dSJasvinder Singh 			}
3117a8bd581dSJasvinder Singh 
3118a8bd581dSJasvinder Singh 			/* Thread message queues */
3119a8bd581dSJasvinder Singh 			{
3120a8bd581dSJasvinder Singh 				uint64_t time_next = t->time_next;
3121a8bd581dSJasvinder Singh 
3122a8bd581dSJasvinder Singh 				if (time_next <= time) {
3123a8bd581dSJasvinder Singh 					thread_msg_handle(t);
3124a8bd581dSJasvinder Singh 					time_next = time + t->timer_period;
3125a8bd581dSJasvinder Singh 					t->time_next = time_next;
3126a8bd581dSJasvinder Singh 				}
3127a8bd581dSJasvinder Singh 
3128a8bd581dSJasvinder Singh 				if (time_next < time_next_min)
3129a8bd581dSJasvinder Singh 					time_next_min = time_next;
3130a8bd581dSJasvinder Singh 			}
3131a8bd581dSJasvinder Singh 
3132a8bd581dSJasvinder Singh 			t->time_next_min = time_next_min;
3133a8bd581dSJasvinder Singh 		}
3134a8bd581dSJasvinder Singh 	}
3135a8bd581dSJasvinder Singh 
3136a8bd581dSJasvinder Singh 	return 0;
3137a8bd581dSJasvinder Singh }
3138