1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2016 Intel Corporation
7 #include <rte_common.h>
8 #include <rte_malloc.h>
9 #include <rte_cycles.h>
10 #include <rte_table_array.h>
11 #include <rte_byteorder.h>
14 #include "pipeline_actions_common.h"
15 #include "pipeline_flow_actions_be.h"
17 #include "hash_func.h"
20 pipeline_fa_flow_params_set_default(struct pipeline_fa_flow_params *params)
27 for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
28 struct rte_meter_trtcm_params *m = ¶ms->m[i];
36 for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
37 struct pipeline_fa_policer_params *p = ¶ms->p[i];
40 for (j = 0; j < e_RTE_METER_COLORS; j++) {
41 struct pipeline_fa_policer_action *a = &p->action[j];
44 a->color = (enum rte_meter_color) j;
54 uint32_t traffic_class;
55 enum rte_meter_color color;
58 struct pipeline_flow_actions {
60 struct pipeline_fa_params params;
61 pipeline_msg_req_handler custom_handlers[PIPELINE_FA_MSG_REQS];
63 struct dscp_entry dscp[PIPELINE_FA_N_DSCP];
64 } __rte_cache_aligned;
67 pipeline_fa_msg_req_custom_handler(struct pipeline *p, void *msg);
69 static pipeline_msg_req_handler handlers[] = {
70 [PIPELINE_MSG_REQ_PING] =
71 pipeline_msg_req_ping_handler,
72 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
73 pipeline_msg_req_stats_port_in_handler,
74 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
75 pipeline_msg_req_stats_port_out_handler,
76 [PIPELINE_MSG_REQ_STATS_TABLE] =
77 pipeline_msg_req_stats_table_handler,
78 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
79 pipeline_msg_req_port_in_enable_handler,
80 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
81 pipeline_msg_req_port_in_disable_handler,
82 [PIPELINE_MSG_REQ_CUSTOM] =
83 pipeline_fa_msg_req_custom_handler,
87 pipeline_fa_msg_req_flow_config_handler(struct pipeline *p, void *msg);
90 pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline *p, void *msg);
93 pipeline_fa_msg_req_dscp_config_handler(struct pipeline *p, void *msg);
96 pipeline_fa_msg_req_policer_stats_read_handler(struct pipeline *p, void *msg);
98 static pipeline_msg_req_handler custom_handlers[] = {
99 [PIPELINE_FA_MSG_REQ_FLOW_CONFIG] =
100 pipeline_fa_msg_req_flow_config_handler,
101 [PIPELINE_FA_MSG_REQ_FLOW_CONFIG_BULK] =
102 pipeline_fa_msg_req_flow_config_bulk_handler,
103 [PIPELINE_FA_MSG_REQ_DSCP_CONFIG] =
104 pipeline_fa_msg_req_dscp_config_handler,
105 [PIPELINE_FA_MSG_REQ_POLICER_STATS_READ] =
106 pipeline_fa_msg_req_policer_stats_read_handler,
112 struct meter_policer {
113 struct rte_meter_trtcm meter;
114 struct pipeline_fa_policer_params policer;
115 struct pipeline_fa_policer_stats stats;
118 struct flow_table_entry {
119 struct rte_pipeline_table_entry head;
120 struct meter_policer mp[PIPELINE_FA_N_TC_MAX];
124 flow_table_entry_set_meter(struct flow_table_entry *entry,
126 struct pipeline_fa_flow_params *params)
128 struct rte_meter_trtcm *meter = &entry->mp[meter_id].meter;
129 struct rte_meter_trtcm_params *meter_params = ¶ms->m[meter_id];
131 return rte_meter_trtcm_config(meter, meter_params);
135 flow_table_entry_set_policer(struct flow_table_entry *entry,
137 struct pipeline_fa_flow_params *params)
139 struct pipeline_fa_policer_params *p0 = &entry->mp[policer_id].policer;
140 struct pipeline_fa_policer_params *p1 = ¶ms->p[policer_id];
142 memcpy(p0, p1, sizeof(*p0));
146 flow_table_entry_set_port_id(struct pipeline_flow_actions *p,
147 struct flow_table_entry *entry,
148 struct pipeline_fa_flow_params *params)
150 entry->head.action = RTE_PIPELINE_ACTION_PORT;
151 entry->head.port_id = p->p.port_out_id[params->port_id];
155 flow_table_entry_set_default(struct pipeline_flow_actions *p,
156 struct flow_table_entry *entry)
158 struct pipeline_fa_flow_params params;
161 pipeline_fa_flow_params_set_default(¶ms);
163 memset(entry, 0, sizeof(*entry));
165 flow_table_entry_set_port_id(p, entry, ¶ms);
167 for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
170 status = flow_table_entry_set_meter(entry, i, ¶ms);
175 for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++)
176 flow_table_entry_set_policer(entry, i, ¶ms);
181 static inline uint64_t
183 struct rte_mbuf *pkt,
184 struct rte_pipeline_table_entry *table_entry,
188 struct pipeline_flow_actions *p = arg;
189 struct flow_table_entry *entry =
190 (struct flow_table_entry *) table_entry;
192 struct ipv4_hdr *pkt_ip = (struct ipv4_hdr *)
193 RTE_MBUF_METADATA_UINT32_PTR(pkt, p->params.ip_hdr_offset);
194 enum rte_meter_color *pkt_color = (enum rte_meter_color *)
195 RTE_MBUF_METADATA_UINT32_PTR(pkt, p->params.color_offset);
197 /* Read (IP header) */
198 uint32_t total_length = rte_bswap16(pkt_ip->total_length);
199 uint32_t dscp = pkt_ip->type_of_service >> 2;
201 uint32_t tc = p->dscp[dscp].traffic_class;
202 enum rte_meter_color color = p->dscp[dscp].color;
204 struct rte_meter_trtcm *meter = &entry->mp[tc].meter;
205 struct pipeline_fa_policer_params *policer = &entry->mp[tc].policer;
206 struct pipeline_fa_policer_stats *stats = &entry->mp[tc].stats;
208 /* Read (entry), compute */
209 enum rte_meter_color color2 = rte_meter_trtcm_color_aware_check(meter,
214 enum rte_meter_color color3 = policer->action[color2].color;
215 uint64_t drop = policer->action[color2].drop;
217 /* Read (entry), write (entry, color) */
218 stats->n_pkts[color3] += drop ^ 1LLU;
219 stats->n_pkts_drop += drop;
225 static inline uint64_t
227 struct rte_mbuf **pkts,
228 struct rte_pipeline_table_entry **table_entries,
232 struct pipeline_flow_actions *p = arg;
234 struct flow_table_entry *entry0 =
235 (struct flow_table_entry *) table_entries[0];
236 struct flow_table_entry *entry1 =
237 (struct flow_table_entry *) table_entries[1];
238 struct flow_table_entry *entry2 =
239 (struct flow_table_entry *) table_entries[2];
240 struct flow_table_entry *entry3 =
241 (struct flow_table_entry *) table_entries[3];
243 struct ipv4_hdr *pkt0_ip = (struct ipv4_hdr *)
244 RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p->params.ip_hdr_offset);
245 struct ipv4_hdr *pkt1_ip = (struct ipv4_hdr *)
246 RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p->params.ip_hdr_offset);
247 struct ipv4_hdr *pkt2_ip = (struct ipv4_hdr *)
248 RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p->params.ip_hdr_offset);
249 struct ipv4_hdr *pkt3_ip = (struct ipv4_hdr *)
250 RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p->params.ip_hdr_offset);
252 enum rte_meter_color *pkt0_color = (enum rte_meter_color *)
253 RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p->params.color_offset);
254 enum rte_meter_color *pkt1_color = (enum rte_meter_color *)
255 RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p->params.color_offset);
256 enum rte_meter_color *pkt2_color = (enum rte_meter_color *)
257 RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p->params.color_offset);
258 enum rte_meter_color *pkt3_color = (enum rte_meter_color *)
259 RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p->params.color_offset);
261 /* Read (IP header) */
262 uint32_t total_length0 = rte_bswap16(pkt0_ip->total_length);
263 uint32_t dscp0 = pkt0_ip->type_of_service >> 2;
265 uint32_t total_length1 = rte_bswap16(pkt1_ip->total_length);
266 uint32_t dscp1 = pkt1_ip->type_of_service >> 2;
268 uint32_t total_length2 = rte_bswap16(pkt2_ip->total_length);
269 uint32_t dscp2 = pkt2_ip->type_of_service >> 2;
271 uint32_t total_length3 = rte_bswap16(pkt3_ip->total_length);
272 uint32_t dscp3 = pkt3_ip->type_of_service >> 2;
274 uint32_t tc0 = p->dscp[dscp0].traffic_class;
275 enum rte_meter_color color0 = p->dscp[dscp0].color;
277 uint32_t tc1 = p->dscp[dscp1].traffic_class;
278 enum rte_meter_color color1 = p->dscp[dscp1].color;
280 uint32_t tc2 = p->dscp[dscp2].traffic_class;
281 enum rte_meter_color color2 = p->dscp[dscp2].color;
283 uint32_t tc3 = p->dscp[dscp3].traffic_class;
284 enum rte_meter_color color3 = p->dscp[dscp3].color;
286 struct rte_meter_trtcm *meter0 = &entry0->mp[tc0].meter;
287 struct pipeline_fa_policer_params *policer0 = &entry0->mp[tc0].policer;
288 struct pipeline_fa_policer_stats *stats0 = &entry0->mp[tc0].stats;
290 struct rte_meter_trtcm *meter1 = &entry1->mp[tc1].meter;
291 struct pipeline_fa_policer_params *policer1 = &entry1->mp[tc1].policer;
292 struct pipeline_fa_policer_stats *stats1 = &entry1->mp[tc1].stats;
294 struct rte_meter_trtcm *meter2 = &entry2->mp[tc2].meter;
295 struct pipeline_fa_policer_params *policer2 = &entry2->mp[tc2].policer;
296 struct pipeline_fa_policer_stats *stats2 = &entry2->mp[tc2].stats;
298 struct rte_meter_trtcm *meter3 = &entry3->mp[tc3].meter;
299 struct pipeline_fa_policer_params *policer3 = &entry3->mp[tc3].policer;
300 struct pipeline_fa_policer_stats *stats3 = &entry3->mp[tc3].stats;
302 /* Read (entry), compute, write (entry) */
303 enum rte_meter_color color2_0 = rte_meter_trtcm_color_aware_check(
309 enum rte_meter_color color2_1 = rte_meter_trtcm_color_aware_check(
315 enum rte_meter_color color2_2 = rte_meter_trtcm_color_aware_check(
321 enum rte_meter_color color2_3 = rte_meter_trtcm_color_aware_check(
327 enum rte_meter_color color3_0 = policer0->action[color2_0].color;
328 enum rte_meter_color color3_1 = policer1->action[color2_1].color;
329 enum rte_meter_color color3_2 = policer2->action[color2_2].color;
330 enum rte_meter_color color3_3 = policer3->action[color2_3].color;
332 uint64_t drop0 = policer0->action[color2_0].drop;
333 uint64_t drop1 = policer1->action[color2_1].drop;
334 uint64_t drop2 = policer2->action[color2_2].drop;
335 uint64_t drop3 = policer3->action[color2_3].drop;
337 /* Read (entry), write (entry, color) */
338 stats0->n_pkts[color3_0] += drop0 ^ 1LLU;
339 stats0->n_pkts_drop += drop0;
341 stats1->n_pkts[color3_1] += drop1 ^ 1LLU;
342 stats1->n_pkts_drop += drop1;
344 stats2->n_pkts[color3_2] += drop2 ^ 1LLU;
345 stats2->n_pkts_drop += drop2;
347 stats3->n_pkts[color3_3] += drop3 ^ 1LLU;
348 stats3->n_pkts_drop += drop3;
350 *pkt0_color = color3_0;
351 *pkt1_color = color3_1;
352 *pkt2_color = color3_2;
353 *pkt3_color = color3_3;
355 return drop0 | (drop1 << 1) | (drop2 << 2) | (drop3 << 3);
358 PIPELINE_TABLE_AH_HIT_DROP_TIME(fa_table_ah_hit, pkt_work, pkt4_work);
360 static rte_pipeline_table_action_handler_hit
361 get_fa_table_ah_hit(__rte_unused struct pipeline_flow_actions *p)
363 return fa_table_ah_hit;
370 pipeline_fa_parse_args(struct pipeline_fa_params *p,
371 struct pipeline_params *params)
373 uint32_t n_flows_present = 0;
374 uint32_t n_meters_per_flow_present = 0;
375 uint32_t flow_id_offset_present = 0;
376 uint32_t ip_hdr_offset_present = 0;
377 uint32_t color_offset_present = 0;
381 p->n_meters_per_flow = 1;
384 for (i = 0; i < params->n_args; i++) {
385 char *arg_name = params->args_name[i];
386 char *arg_value = params->args_value[i];
389 if (strcmp(arg_name, "n_flows") == 0) {
392 PIPELINE_PARSE_ERR_DUPLICATE(
393 n_flows_present == 0, params->name,
397 status = parser_read_uint32(&p->n_flows,
399 PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
400 (p->n_flows != 0)), params->name,
401 arg_name, arg_value);
402 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
403 params->name, arg_name, arg_value);
408 /* n_meters_per_flow */
409 if (strcmp(arg_name, "n_meters_per_flow") == 0) {
412 PIPELINE_PARSE_ERR_DUPLICATE(
413 n_meters_per_flow_present == 0,
414 params->name, arg_name);
415 n_meters_per_flow_present = 1;
417 status = parser_read_uint32(&p->n_meters_per_flow,
419 PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
420 (p->n_meters_per_flow != 0)),
421 params->name, arg_name, arg_value);
422 PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
423 (p->n_meters_per_flow <=
424 PIPELINE_FA_N_TC_MAX)), params->name,
425 arg_name, arg_value);
431 if (strcmp(arg_name, "flow_id_offset") == 0) {
434 PIPELINE_PARSE_ERR_DUPLICATE(
435 flow_id_offset_present == 0,
436 params->name, arg_name);
437 flow_id_offset_present = 1;
439 status = parser_read_uint32(&p->flow_id_offset,
441 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
442 params->name, arg_name, arg_value);
443 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
444 params->name, arg_name, arg_value);
450 if (strcmp(arg_name, "ip_hdr_offset") == 0) {
453 PIPELINE_PARSE_ERR_DUPLICATE(
454 ip_hdr_offset_present == 0,
455 params->name, arg_name);
456 ip_hdr_offset_present = 1;
458 status = parser_read_uint32(&p->ip_hdr_offset,
460 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
461 params->name, arg_name, arg_value);
462 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
463 params->name, arg_name, arg_value);
469 if (strcmp(arg_name, "color_offset") == 0) {
472 PIPELINE_PARSE_ERR_DUPLICATE(
473 color_offset_present == 0, params->name,
475 color_offset_present = 1;
477 status = parser_read_uint32(&p->color_offset,
479 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
480 params->name, arg_name, arg_value);
481 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
482 params->name, arg_name, arg_value);
489 /* Unknown argument */
490 PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
493 /* Check that mandatory arguments are present */
494 PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name,
496 PIPELINE_PARSE_ERR_MANDATORY((flow_id_offset_present),
497 params->name, "flow_id_offset");
498 PIPELINE_PARSE_ERR_MANDATORY((ip_hdr_offset_present),
499 params->name, "ip_hdr_offset");
500 PIPELINE_PARSE_ERR_MANDATORY((color_offset_present), params->name,
507 dscp_init(struct pipeline_flow_actions *p)
511 for (i = 0; i < PIPELINE_FA_N_DSCP; i++) {
512 p->dscp[i].traffic_class = 0;
513 p->dscp[i].color = e_RTE_METER_GREEN;
517 static void *pipeline_fa_init(struct pipeline_params *params,
518 __rte_unused void *arg)
521 struct pipeline_flow_actions *p_fa;
524 /* Check input arguments */
528 if (params->n_ports_in != params->n_ports_out)
531 /* Memory allocation */
532 size = RTE_CACHE_LINE_ROUNDUP(
533 sizeof(struct pipeline_flow_actions));
534 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
537 p_fa = (struct pipeline_flow_actions *) p;
539 strcpy(p->name, params->name);
540 p->log_level = params->log_level;
542 PLOG(p, HIGH, "Flow actions");
544 /* Parse arguments */
545 if (pipeline_fa_parse_args(&p_fa->params, params))
552 struct rte_pipeline_params pipeline_params = {
553 .name = params->name,
554 .socket_id = params->socket_id,
558 p->p = rte_pipeline_create(&pipeline_params);
566 p->n_ports_in = params->n_ports_in;
567 for (i = 0; i < p->n_ports_in; i++) {
568 struct rte_pipeline_port_in_params port_params = {
569 .ops = pipeline_port_in_params_get_ops(
570 ¶ms->port_in[i]),
571 .arg_create = pipeline_port_in_params_convert(
572 ¶ms->port_in[i]),
575 .burst_size = params->port_in[i].burst_size,
578 int status = rte_pipeline_port_in_create(p->p,
583 rte_pipeline_free(p->p);
590 p->n_ports_out = params->n_ports_out;
591 for (i = 0; i < p->n_ports_out; i++) {
592 struct rte_pipeline_port_out_params port_params = {
593 .ops = pipeline_port_out_params_get_ops(
594 ¶ms->port_out[i]),
595 .arg_create = pipeline_port_out_params_convert(
596 ¶ms->port_out[i]),
601 int status = rte_pipeline_port_out_create(p->p,
606 rte_pipeline_free(p->p);
615 struct rte_table_array_params table_array_params = {
616 .n_entries = p_fa->params.n_flows,
617 .offset = p_fa->params.flow_id_offset,
620 struct rte_pipeline_table_params table_params = {
621 .ops = &rte_table_array_ops,
622 .arg_create = &table_array_params,
623 .f_action_hit = get_fa_table_ah_hit(p_fa),
624 .f_action_miss = NULL,
627 sizeof(struct flow_table_entry) -
628 sizeof(struct rte_pipeline_table_entry),
633 status = rte_pipeline_table_create(p->p,
638 rte_pipeline_free(p->p);
644 /* Connecting input ports to tables */
645 for (i = 0; i < p->n_ports_in; i++) {
646 int status = rte_pipeline_port_in_connect_to_table(p->p,
651 rte_pipeline_free(p->p);
657 /* Enable input ports */
658 for (i = 0; i < p->n_ports_in; i++) {
659 int status = rte_pipeline_port_in_enable(p->p,
663 rte_pipeline_free(p->p);
669 /* Initialize table entries */
670 for (i = 0; i < p_fa->params.n_flows; i++) {
671 struct rte_table_array_key key = {
675 struct flow_table_entry entry;
676 struct rte_pipeline_table_entry *entry_ptr;
677 int key_found, status;
679 flow_table_entry_set_default(p_fa, &entry);
681 status = rte_pipeline_table_entry_add(p->p,
684 (struct rte_pipeline_table_entry *) &entry,
689 rte_pipeline_free(p->p);
695 /* Check pipeline consistency */
696 if (rte_pipeline_check(p->p) < 0) {
697 rte_pipeline_free(p->p);
703 p->n_msgq = params->n_msgq;
704 for (i = 0; i < p->n_msgq; i++)
705 p->msgq_in[i] = params->msgq_in[i];
706 for (i = 0; i < p->n_msgq; i++)
707 p->msgq_out[i] = params->msgq_out[i];
709 /* Message handlers */
710 memcpy(p->handlers, handlers, sizeof(p->handlers));
711 memcpy(p_fa->custom_handlers,
713 sizeof(p_fa->custom_handlers));
719 pipeline_fa_free(void *pipeline)
721 struct pipeline *p = (struct pipeline *) pipeline;
723 /* Check input arguments */
728 rte_pipeline_free(p->p);
734 pipeline_fa_timer(void *pipeline)
736 struct pipeline *p = (struct pipeline *) pipeline;
738 pipeline_msg_req_handle(p);
739 rte_pipeline_flush(p->p);
745 pipeline_fa_msg_req_custom_handler(struct pipeline *p, void *msg)
747 struct pipeline_flow_actions *p_fa =
748 (struct pipeline_flow_actions *) p;
749 struct pipeline_custom_msg_req *req = msg;
750 pipeline_msg_req_handler f_handle;
752 f_handle = (req->subtype < PIPELINE_FA_MSG_REQS) ?
753 p_fa->custom_handlers[req->subtype] :
754 pipeline_msg_req_invalid_handler;
756 if (f_handle == NULL)
757 f_handle = pipeline_msg_req_invalid_handler;
759 return f_handle(p, req);
763 pipeline_fa_msg_req_flow_config_handler(struct pipeline *p, void *msg)
765 struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
766 struct pipeline_fa_flow_config_msg_req *req = msg;
767 struct pipeline_fa_flow_config_msg_rsp *rsp = msg;
768 struct flow_table_entry *entry;
771 /* Set flow table entry to default if not configured before */
772 if (req->entry_ptr == NULL) {
773 struct rte_table_array_key key = {
774 .pos = req->flow_id % p_fa->params.n_flows,
777 struct flow_table_entry default_entry;
779 int key_found, status;
781 flow_table_entry_set_default(p_fa, &default_entry);
783 status = rte_pipeline_table_entry_add(p->p,
786 (struct rte_pipeline_table_entry *) &default_entry,
788 (struct rte_pipeline_table_entry **) &entry);
794 entry = (struct flow_table_entry *) req->entry_ptr;
797 for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
800 if ((mask & req->meter_update_mask) == 0)
803 status = flow_table_entry_set_meter(entry, i, &req->params);
811 for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
812 if ((mask & req->policer_update_mask) == 0)
815 flow_table_entry_set_policer(entry, i, &req->params);
819 if (req->port_update)
820 flow_table_entry_set_port_id(p_fa, entry, &req->params);
824 rsp->entry_ptr = (void *) entry;
829 pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline *p, void *msg)
831 struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
832 struct pipeline_fa_flow_config_bulk_msg_req *req = msg;
833 struct pipeline_fa_flow_config_bulk_msg_rsp *rsp = msg;
836 for (i = 0; i < req->n_flows; i++) {
837 struct flow_table_entry *entry;
840 /* Set flow table entry to default if not configured before */
841 if (req->entry_ptr[i] == NULL) {
842 struct rte_table_array_key key = {
843 .pos = req->flow_id[i] % p_fa->params.n_flows,
846 struct flow_table_entry entry_to_add;
848 int key_found, status;
850 flow_table_entry_set_default(p_fa, &entry_to_add);
852 status = rte_pipeline_table_entry_add(p->p,
855 (struct rte_pipeline_table_entry *) &entry_to_add,
857 (struct rte_pipeline_table_entry **) &entry);
863 req->entry_ptr[i] = (void *) entry;
865 entry = (struct flow_table_entry *) req->entry_ptr[i];
868 for (j = 0, mask = 1;
869 j < PIPELINE_FA_N_TC_MAX;
873 if ((mask & req->meter_update_mask) == 0)
876 status = flow_table_entry_set_meter(entry,
885 for (j = 0, mask = 1;
886 j < PIPELINE_FA_N_TC_MAX;
888 if ((mask & req->policer_update_mask) == 0)
891 flow_table_entry_set_policer(entry,
896 if (req->port_update)
897 flow_table_entry_set_port_id(p_fa,
898 entry, &req->params[i]);
907 pipeline_fa_msg_req_dscp_config_handler(struct pipeline *p, void *msg)
909 struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
910 struct pipeline_fa_dscp_config_msg_req *req = msg;
911 struct pipeline_fa_dscp_config_msg_rsp *rsp = msg;
914 if ((req->dscp >= PIPELINE_FA_N_DSCP) ||
915 (req->traffic_class >= PIPELINE_FA_N_TC_MAX) ||
916 (req->color >= e_RTE_METER_COLORS)) {
921 p_fa->dscp[req->dscp].traffic_class = req->traffic_class;
922 p_fa->dscp[req->dscp].color = req->color;
928 pipeline_fa_msg_req_policer_stats_read_handler(__rte_unused struct pipeline *p,
931 struct pipeline_fa_policer_stats_msg_req *req = msg;
932 struct pipeline_fa_policer_stats_msg_rsp *rsp = msg;
934 struct flow_table_entry *entry = req->entry_ptr;
935 uint32_t policer_id = req->policer_id;
936 int clear = req->clear;
939 if ((req->entry_ptr == NULL) ||
940 (req->policer_id >= PIPELINE_FA_N_TC_MAX)) {
946 &entry->mp[policer_id].stats,
949 memset(&entry->mp[policer_id].stats,
950 0, sizeof(entry->mp[policer_id].stats));
955 struct pipeline_be_ops pipeline_flow_actions_be_ops = {
956 .f_init = pipeline_fa_init,
957 .f_free = pipeline_fa_free,
959 .f_timer = pipeline_fa_timer,