4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <rte_common.h>
37 #include <rte_malloc.h>
38 #include <rte_cycles.h>
39 #include <rte_table_array.h>
40 #include <rte_byteorder.h>
43 #include "pipeline_actions_common.h"
44 #include "pipeline_flow_actions_be.h"
46 #include "hash_func.h"
49 pipeline_fa_flow_params_set_default(struct pipeline_fa_flow_params
*params
)
56 for (i
= 0; i
< PIPELINE_FA_N_TC_MAX
; i
++) {
57 struct rte_meter_trtcm_params
*m
= ¶ms
->m
[i
];
65 for (i
= 0; i
< PIPELINE_FA_N_TC_MAX
; i
++) {
66 struct pipeline_fa_policer_params
*p
= ¶ms
->p
[i
];
69 for (j
= 0; j
< e_RTE_METER_COLORS
; j
++) {
70 struct pipeline_fa_policer_action
*a
= &p
->action
[j
];
73 a
->color
= (enum rte_meter_color
) j
;
83 uint32_t traffic_class
;
84 enum rte_meter_color color
;
87 struct pipeline_flow_actions
{
89 struct pipeline_fa_params params
;
90 pipeline_msg_req_handler custom_handlers
[PIPELINE_FA_MSG_REQS
];
92 struct dscp_entry dscp
[PIPELINE_FA_N_DSCP
];
93 } __rte_cache_aligned
;
96 pipeline_fa_msg_req_custom_handler(struct pipeline
*p
, void *msg
);
98 static pipeline_msg_req_handler handlers
[] = {
99 [PIPELINE_MSG_REQ_PING
] =
100 pipeline_msg_req_ping_handler
,
101 [PIPELINE_MSG_REQ_STATS_PORT_IN
] =
102 pipeline_msg_req_stats_port_in_handler
,
103 [PIPELINE_MSG_REQ_STATS_PORT_OUT
] =
104 pipeline_msg_req_stats_port_out_handler
,
105 [PIPELINE_MSG_REQ_STATS_TABLE
] =
106 pipeline_msg_req_stats_table_handler
,
107 [PIPELINE_MSG_REQ_PORT_IN_ENABLE
] =
108 pipeline_msg_req_port_in_enable_handler
,
109 [PIPELINE_MSG_REQ_PORT_IN_DISABLE
] =
110 pipeline_msg_req_port_in_disable_handler
,
111 [PIPELINE_MSG_REQ_CUSTOM
] =
112 pipeline_fa_msg_req_custom_handler
,
116 pipeline_fa_msg_req_flow_config_handler(struct pipeline
*p
, void *msg
);
119 pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline
*p
, void *msg
);
122 pipeline_fa_msg_req_dscp_config_handler(struct pipeline
*p
, void *msg
);
125 pipeline_fa_msg_req_policer_stats_read_handler(struct pipeline
*p
, void *msg
);
127 static pipeline_msg_req_handler custom_handlers
[] = {
128 [PIPELINE_FA_MSG_REQ_FLOW_CONFIG
] =
129 pipeline_fa_msg_req_flow_config_handler
,
130 [PIPELINE_FA_MSG_REQ_FLOW_CONFIG_BULK
] =
131 pipeline_fa_msg_req_flow_config_bulk_handler
,
132 [PIPELINE_FA_MSG_REQ_DSCP_CONFIG
] =
133 pipeline_fa_msg_req_dscp_config_handler
,
134 [PIPELINE_FA_MSG_REQ_POLICER_STATS_READ
] =
135 pipeline_fa_msg_req_policer_stats_read_handler
,
141 struct meter_policer
{
142 struct rte_meter_trtcm meter
;
143 struct pipeline_fa_policer_params policer
;
144 struct pipeline_fa_policer_stats stats
;
147 struct flow_table_entry
{
148 struct rte_pipeline_table_entry head
;
149 struct meter_policer mp
[PIPELINE_FA_N_TC_MAX
];
153 flow_table_entry_set_meter(struct flow_table_entry
*entry
,
155 struct pipeline_fa_flow_params
*params
)
157 struct rte_meter_trtcm
*meter
= &entry
->mp
[meter_id
].meter
;
158 struct rte_meter_trtcm_params
*meter_params
= ¶ms
->m
[meter_id
];
160 return rte_meter_trtcm_config(meter
, meter_params
);
164 flow_table_entry_set_policer(struct flow_table_entry
*entry
,
166 struct pipeline_fa_flow_params
*params
)
168 struct pipeline_fa_policer_params
*p0
= &entry
->mp
[policer_id
].policer
;
169 struct pipeline_fa_policer_params
*p1
= ¶ms
->p
[policer_id
];
171 memcpy(p0
, p1
, sizeof(*p0
));
175 flow_table_entry_set_port_id(struct pipeline_flow_actions
*p
,
176 struct flow_table_entry
*entry
,
177 struct pipeline_fa_flow_params
*params
)
179 entry
->head
.action
= RTE_PIPELINE_ACTION_PORT
;
180 entry
->head
.port_id
= p
->p
.port_out_id
[params
->port_id
];
184 flow_table_entry_set_default(struct pipeline_flow_actions
*p
,
185 struct flow_table_entry
*entry
)
187 struct pipeline_fa_flow_params params
;
190 pipeline_fa_flow_params_set_default(¶ms
);
192 memset(entry
, 0, sizeof(*entry
));
194 flow_table_entry_set_port_id(p
, entry
, ¶ms
);
196 for (i
= 0; i
< PIPELINE_FA_N_TC_MAX
; i
++) {
199 status
= flow_table_entry_set_meter(entry
, i
, ¶ms
);
204 for (i
= 0; i
< PIPELINE_FA_N_TC_MAX
; i
++)
205 flow_table_entry_set_policer(entry
, i
, ¶ms
);
210 static inline uint64_t
212 struct rte_mbuf
*pkt
,
213 struct rte_pipeline_table_entry
*table_entry
,
217 struct pipeline_flow_actions
*p
= arg
;
218 struct flow_table_entry
*entry
=
219 (struct flow_table_entry
*) table_entry
;
221 struct ipv4_hdr
*pkt_ip
= (struct ipv4_hdr
*)
222 RTE_MBUF_METADATA_UINT32_PTR(pkt
, p
->params
.ip_hdr_offset
);
223 enum rte_meter_color
*pkt_color
= (enum rte_meter_color
*)
224 RTE_MBUF_METADATA_UINT32_PTR(pkt
, p
->params
.color_offset
);
226 /* Read (IP header) */
227 uint32_t total_length
= rte_bswap16(pkt_ip
->total_length
);
228 uint32_t dscp
= pkt_ip
->type_of_service
>> 2;
230 uint32_t tc
= p
->dscp
[dscp
].traffic_class
;
231 enum rte_meter_color color
= p
->dscp
[dscp
].color
;
233 struct rte_meter_trtcm
*meter
= &entry
->mp
[tc
].meter
;
234 struct pipeline_fa_policer_params
*policer
= &entry
->mp
[tc
].policer
;
235 struct pipeline_fa_policer_stats
*stats
= &entry
->mp
[tc
].stats
;
237 /* Read (entry), compute */
238 enum rte_meter_color color2
= rte_meter_trtcm_color_aware_check(meter
,
243 enum rte_meter_color color3
= policer
->action
[color2
].color
;
244 uint64_t drop
= policer
->action
[color2
].drop
;
246 /* Read (entry), write (entry, color) */
247 stats
->n_pkts
[color3
] += drop
^ 1LLU;
248 stats
->n_pkts_drop
+= drop
;
254 static inline uint64_t
256 struct rte_mbuf
**pkts
,
257 struct rte_pipeline_table_entry
**table_entries
,
261 struct pipeline_flow_actions
*p
= arg
;
263 struct flow_table_entry
*entry0
=
264 (struct flow_table_entry
*) table_entries
[0];
265 struct flow_table_entry
*entry1
=
266 (struct flow_table_entry
*) table_entries
[1];
267 struct flow_table_entry
*entry2
=
268 (struct flow_table_entry
*) table_entries
[2];
269 struct flow_table_entry
*entry3
=
270 (struct flow_table_entry
*) table_entries
[3];
272 struct ipv4_hdr
*pkt0_ip
= (struct ipv4_hdr
*)
273 RTE_MBUF_METADATA_UINT32_PTR(pkts
[0], p
->params
.ip_hdr_offset
);
274 struct ipv4_hdr
*pkt1_ip
= (struct ipv4_hdr
*)
275 RTE_MBUF_METADATA_UINT32_PTR(pkts
[1], p
->params
.ip_hdr_offset
);
276 struct ipv4_hdr
*pkt2_ip
= (struct ipv4_hdr
*)
277 RTE_MBUF_METADATA_UINT32_PTR(pkts
[2], p
->params
.ip_hdr_offset
);
278 struct ipv4_hdr
*pkt3_ip
= (struct ipv4_hdr
*)
279 RTE_MBUF_METADATA_UINT32_PTR(pkts
[3], p
->params
.ip_hdr_offset
);
281 enum rte_meter_color
*pkt0_color
= (enum rte_meter_color
*)
282 RTE_MBUF_METADATA_UINT32_PTR(pkts
[0], p
->params
.color_offset
);
283 enum rte_meter_color
*pkt1_color
= (enum rte_meter_color
*)
284 RTE_MBUF_METADATA_UINT32_PTR(pkts
[1], p
->params
.color_offset
);
285 enum rte_meter_color
*pkt2_color
= (enum rte_meter_color
*)
286 RTE_MBUF_METADATA_UINT32_PTR(pkts
[2], p
->params
.color_offset
);
287 enum rte_meter_color
*pkt3_color
= (enum rte_meter_color
*)
288 RTE_MBUF_METADATA_UINT32_PTR(pkts
[3], p
->params
.color_offset
);
290 /* Read (IP header) */
291 uint32_t total_length0
= rte_bswap16(pkt0_ip
->total_length
);
292 uint32_t dscp0
= pkt0_ip
->type_of_service
>> 2;
294 uint32_t total_length1
= rte_bswap16(pkt1_ip
->total_length
);
295 uint32_t dscp1
= pkt1_ip
->type_of_service
>> 2;
297 uint32_t total_length2
= rte_bswap16(pkt2_ip
->total_length
);
298 uint32_t dscp2
= pkt2_ip
->type_of_service
>> 2;
300 uint32_t total_length3
= rte_bswap16(pkt3_ip
->total_length
);
301 uint32_t dscp3
= pkt3_ip
->type_of_service
>> 2;
303 uint32_t tc0
= p
->dscp
[dscp0
].traffic_class
;
304 enum rte_meter_color color0
= p
->dscp
[dscp0
].color
;
306 uint32_t tc1
= p
->dscp
[dscp1
].traffic_class
;
307 enum rte_meter_color color1
= p
->dscp
[dscp1
].color
;
309 uint32_t tc2
= p
->dscp
[dscp2
].traffic_class
;
310 enum rte_meter_color color2
= p
->dscp
[dscp2
].color
;
312 uint32_t tc3
= p
->dscp
[dscp3
].traffic_class
;
313 enum rte_meter_color color3
= p
->dscp
[dscp3
].color
;
315 struct rte_meter_trtcm
*meter0
= &entry0
->mp
[tc0
].meter
;
316 struct pipeline_fa_policer_params
*policer0
= &entry0
->mp
[tc0
].policer
;
317 struct pipeline_fa_policer_stats
*stats0
= &entry0
->mp
[tc0
].stats
;
319 struct rte_meter_trtcm
*meter1
= &entry1
->mp
[tc1
].meter
;
320 struct pipeline_fa_policer_params
*policer1
= &entry1
->mp
[tc1
].policer
;
321 struct pipeline_fa_policer_stats
*stats1
= &entry1
->mp
[tc1
].stats
;
323 struct rte_meter_trtcm
*meter2
= &entry2
->mp
[tc2
].meter
;
324 struct pipeline_fa_policer_params
*policer2
= &entry2
->mp
[tc2
].policer
;
325 struct pipeline_fa_policer_stats
*stats2
= &entry2
->mp
[tc2
].stats
;
327 struct rte_meter_trtcm
*meter3
= &entry3
->mp
[tc3
].meter
;
328 struct pipeline_fa_policer_params
*policer3
= &entry3
->mp
[tc3
].policer
;
329 struct pipeline_fa_policer_stats
*stats3
= &entry3
->mp
[tc3
].stats
;
331 /* Read (entry), compute, write (entry) */
332 enum rte_meter_color color2_0
= rte_meter_trtcm_color_aware_check(
338 enum rte_meter_color color2_1
= rte_meter_trtcm_color_aware_check(
344 enum rte_meter_color color2_2
= rte_meter_trtcm_color_aware_check(
350 enum rte_meter_color color2_3
= rte_meter_trtcm_color_aware_check(
356 enum rte_meter_color color3_0
= policer0
->action
[color2_0
].color
;
357 enum rte_meter_color color3_1
= policer1
->action
[color2_1
].color
;
358 enum rte_meter_color color3_2
= policer2
->action
[color2_2
].color
;
359 enum rte_meter_color color3_3
= policer3
->action
[color2_3
].color
;
361 uint64_t drop0
= policer0
->action
[color2_0
].drop
;
362 uint64_t drop1
= policer1
->action
[color2_1
].drop
;
363 uint64_t drop2
= policer2
->action
[color2_2
].drop
;
364 uint64_t drop3
= policer3
->action
[color2_3
].drop
;
366 /* Read (entry), write (entry, color) */
367 stats0
->n_pkts
[color3_0
] += drop0
^ 1LLU;
368 stats0
->n_pkts_drop
+= drop0
;
370 stats1
->n_pkts
[color3_1
] += drop1
^ 1LLU;
371 stats1
->n_pkts_drop
+= drop1
;
373 stats2
->n_pkts
[color3_2
] += drop2
^ 1LLU;
374 stats2
->n_pkts_drop
+= drop2
;
376 stats3
->n_pkts
[color3_3
] += drop3
^ 1LLU;
377 stats3
->n_pkts_drop
+= drop3
;
379 *pkt0_color
= color3_0
;
380 *pkt1_color
= color3_1
;
381 *pkt2_color
= color3_2
;
382 *pkt3_color
= color3_3
;
384 return drop0
| (drop1
<< 1) | (drop2
<< 2) | (drop3
<< 3);
387 PIPELINE_TABLE_AH_HIT_DROP_TIME(fa_table_ah_hit
, pkt_work
, pkt4_work
);
389 static rte_pipeline_table_action_handler_hit
390 get_fa_table_ah_hit(__rte_unused
struct pipeline_flow_actions
*p
)
392 return fa_table_ah_hit
;
399 pipeline_fa_parse_args(struct pipeline_fa_params
*p
,
400 struct pipeline_params
*params
)
402 uint32_t n_flows_present
= 0;
403 uint32_t n_meters_per_flow_present
= 0;
404 uint32_t flow_id_offset_present
= 0;
405 uint32_t ip_hdr_offset_present
= 0;
406 uint32_t color_offset_present
= 0;
410 p
->n_meters_per_flow
= 1;
413 for (i
= 0; i
< params
->n_args
; i
++) {
414 char *arg_name
= params
->args_name
[i
];
415 char *arg_value
= params
->args_value
[i
];
418 if (strcmp(arg_name
, "n_flows") == 0) {
421 PIPELINE_PARSE_ERR_DUPLICATE(
422 n_flows_present
== 0, params
->name
,
426 status
= parser_read_uint32(&p
->n_flows
,
428 PIPELINE_PARSE_ERR_INV_VAL(((status
!= -EINVAL
) &&
429 (p
->n_flows
!= 0)), params
->name
,
430 arg_name
, arg_value
);
431 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
432 params
->name
, arg_name
, arg_value
);
437 /* n_meters_per_flow */
438 if (strcmp(arg_name
, "n_meters_per_flow") == 0) {
441 PIPELINE_PARSE_ERR_DUPLICATE(
442 n_meters_per_flow_present
== 0,
443 params
->name
, arg_name
);
444 n_meters_per_flow_present
= 1;
446 status
= parser_read_uint32(&p
->n_meters_per_flow
,
448 PIPELINE_PARSE_ERR_INV_VAL(((status
!= -EINVAL
) &&
449 (p
->n_meters_per_flow
!= 0)),
450 params
->name
, arg_name
, arg_value
);
451 PIPELINE_PARSE_ERR_OUT_RNG(((status
!= -ERANGE
) &&
452 (p
->n_meters_per_flow
<=
453 PIPELINE_FA_N_TC_MAX
)), params
->name
,
454 arg_name
, arg_value
);
460 if (strcmp(arg_name
, "flow_id_offset") == 0) {
463 PIPELINE_PARSE_ERR_DUPLICATE(
464 flow_id_offset_present
== 0,
465 params
->name
, arg_name
);
466 flow_id_offset_present
= 1;
468 status
= parser_read_uint32(&p
->flow_id_offset
,
470 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
471 params
->name
, arg_name
, arg_value
);
472 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
473 params
->name
, arg_name
, arg_value
);
479 if (strcmp(arg_name
, "ip_hdr_offset") == 0) {
482 PIPELINE_PARSE_ERR_DUPLICATE(
483 ip_hdr_offset_present
== 0,
484 params
->name
, arg_name
);
485 ip_hdr_offset_present
= 1;
487 status
= parser_read_uint32(&p
->ip_hdr_offset
,
489 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
490 params
->name
, arg_name
, arg_value
);
491 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
492 params
->name
, arg_name
, arg_value
);
498 if (strcmp(arg_name
, "color_offset") == 0) {
501 PIPELINE_PARSE_ERR_DUPLICATE(
502 color_offset_present
== 0, params
->name
,
504 color_offset_present
= 1;
506 status
= parser_read_uint32(&p
->color_offset
,
508 PIPELINE_PARSE_ERR_INV_VAL((status
!= -EINVAL
),
509 params
->name
, arg_name
, arg_value
);
510 PIPELINE_PARSE_ERR_OUT_RNG((status
!= -ERANGE
),
511 params
->name
, arg_name
, arg_value
);
518 /* Unknown argument */
519 PIPELINE_PARSE_ERR_INV_ENT(0, params
->name
, arg_name
);
522 /* Check that mandatory arguments are present */
523 PIPELINE_PARSE_ERR_MANDATORY((n_flows_present
), params
->name
,
525 PIPELINE_PARSE_ERR_MANDATORY((flow_id_offset_present
),
526 params
->name
, "flow_id_offset");
527 PIPELINE_PARSE_ERR_MANDATORY((ip_hdr_offset_present
),
528 params
->name
, "ip_hdr_offset");
529 PIPELINE_PARSE_ERR_MANDATORY((color_offset_present
), params
->name
,
536 dscp_init(struct pipeline_flow_actions
*p
)
540 for (i
= 0; i
< PIPELINE_FA_N_DSCP
; i
++) {
541 p
->dscp
[i
].traffic_class
= 0;
542 p
->dscp
[i
].color
= e_RTE_METER_GREEN
;
546 static void *pipeline_fa_init(struct pipeline_params
*params
,
547 __rte_unused
void *arg
)
550 struct pipeline_flow_actions
*p_fa
;
553 /* Check input arguments */
557 if (params
->n_ports_in
!= params
->n_ports_out
)
560 /* Memory allocation */
561 size
= RTE_CACHE_LINE_ROUNDUP(
562 sizeof(struct pipeline_flow_actions
));
563 p
= rte_zmalloc(NULL
, size
, RTE_CACHE_LINE_SIZE
);
566 p_fa
= (struct pipeline_flow_actions
*) p
;
568 strcpy(p
->name
, params
->name
);
569 p
->log_level
= params
->log_level
;
571 PLOG(p
, HIGH
, "Flow actions");
573 /* Parse arguments */
574 if (pipeline_fa_parse_args(&p_fa
->params
, params
))
581 struct rte_pipeline_params pipeline_params
= {
582 .name
= params
->name
,
583 .socket_id
= params
->socket_id
,
587 p
->p
= rte_pipeline_create(&pipeline_params
);
595 p
->n_ports_in
= params
->n_ports_in
;
596 for (i
= 0; i
< p
->n_ports_in
; i
++) {
597 struct rte_pipeline_port_in_params port_params
= {
598 .ops
= pipeline_port_in_params_get_ops(
599 ¶ms
->port_in
[i
]),
600 .arg_create
= pipeline_port_in_params_convert(
601 ¶ms
->port_in
[i
]),
604 .burst_size
= params
->port_in
[i
].burst_size
,
607 int status
= rte_pipeline_port_in_create(p
->p
,
612 rte_pipeline_free(p
->p
);
619 p
->n_ports_out
= params
->n_ports_out
;
620 for (i
= 0; i
< p
->n_ports_out
; i
++) {
621 struct rte_pipeline_port_out_params port_params
= {
622 .ops
= pipeline_port_out_params_get_ops(
623 ¶ms
->port_out
[i
]),
624 .arg_create
= pipeline_port_out_params_convert(
625 ¶ms
->port_out
[i
]),
630 int status
= rte_pipeline_port_out_create(p
->p
,
635 rte_pipeline_free(p
->p
);
644 struct rte_table_array_params table_array_params
= {
645 .n_entries
= p_fa
->params
.n_flows
,
646 .offset
= p_fa
->params
.flow_id_offset
,
649 struct rte_pipeline_table_params table_params
= {
650 .ops
= &rte_table_array_ops
,
651 .arg_create
= &table_array_params
,
652 .f_action_hit
= get_fa_table_ah_hit(p_fa
),
653 .f_action_miss
= NULL
,
656 sizeof(struct flow_table_entry
) -
657 sizeof(struct rte_pipeline_table_entry
),
662 status
= rte_pipeline_table_create(p
->p
,
667 rte_pipeline_free(p
->p
);
673 /* Connecting input ports to tables */
674 for (i
= 0; i
< p
->n_ports_in
; i
++) {
675 int status
= rte_pipeline_port_in_connect_to_table(p
->p
,
680 rte_pipeline_free(p
->p
);
686 /* Enable input ports */
687 for (i
= 0; i
< p
->n_ports_in
; i
++) {
688 int status
= rte_pipeline_port_in_enable(p
->p
,
692 rte_pipeline_free(p
->p
);
698 /* Initialize table entries */
699 for (i
= 0; i
< p_fa
->params
.n_flows
; i
++) {
700 struct rte_table_array_key key
= {
704 struct flow_table_entry entry
;
705 struct rte_pipeline_table_entry
*entry_ptr
;
706 int key_found
, status
;
708 flow_table_entry_set_default(p_fa
, &entry
);
710 status
= rte_pipeline_table_entry_add(p
->p
,
713 (struct rte_pipeline_table_entry
*) &entry
,
718 rte_pipeline_free(p
->p
);
724 /* Check pipeline consistency */
725 if (rte_pipeline_check(p
->p
) < 0) {
726 rte_pipeline_free(p
->p
);
732 p
->n_msgq
= params
->n_msgq
;
733 for (i
= 0; i
< p
->n_msgq
; i
++)
734 p
->msgq_in
[i
] = params
->msgq_in
[i
];
735 for (i
= 0; i
< p
->n_msgq
; i
++)
736 p
->msgq_out
[i
] = params
->msgq_out
[i
];
738 /* Message handlers */
739 memcpy(p
->handlers
, handlers
, sizeof(p
->handlers
));
740 memcpy(p_fa
->custom_handlers
,
742 sizeof(p_fa
->custom_handlers
));
748 pipeline_fa_free(void *pipeline
)
750 struct pipeline
*p
= (struct pipeline
*) pipeline
;
752 /* Check input arguments */
757 rte_pipeline_free(p
->p
);
763 pipeline_fa_timer(void *pipeline
)
765 struct pipeline
*p
= (struct pipeline
*) pipeline
;
767 pipeline_msg_req_handle(p
);
768 rte_pipeline_flush(p
->p
);
774 pipeline_fa_msg_req_custom_handler(struct pipeline
*p
, void *msg
)
776 struct pipeline_flow_actions
*p_fa
=
777 (struct pipeline_flow_actions
*) p
;
778 struct pipeline_custom_msg_req
*req
= msg
;
779 pipeline_msg_req_handler f_handle
;
781 f_handle
= (req
->subtype
< PIPELINE_FA_MSG_REQS
) ?
782 p_fa
->custom_handlers
[req
->subtype
] :
783 pipeline_msg_req_invalid_handler
;
785 if (f_handle
== NULL
)
786 f_handle
= pipeline_msg_req_invalid_handler
;
788 return f_handle(p
, req
);
792 pipeline_fa_msg_req_flow_config_handler(struct pipeline
*p
, void *msg
)
794 struct pipeline_flow_actions
*p_fa
= (struct pipeline_flow_actions
*) p
;
795 struct pipeline_fa_flow_config_msg_req
*req
= msg
;
796 struct pipeline_fa_flow_config_msg_rsp
*rsp
= msg
;
797 struct flow_table_entry
*entry
;
800 /* Set flow table entry to default if not configured before */
801 if (req
->entry_ptr
== NULL
) {
802 struct rte_table_array_key key
= {
803 .pos
= req
->flow_id
% p_fa
->params
.n_flows
,
806 struct flow_table_entry default_entry
;
808 int key_found
, status
;
810 flow_table_entry_set_default(p_fa
, &default_entry
);
812 status
= rte_pipeline_table_entry_add(p
->p
,
815 (struct rte_pipeline_table_entry
*) &default_entry
,
817 (struct rte_pipeline_table_entry
**) &entry
);
823 entry
= (struct flow_table_entry
*) req
->entry_ptr
;
826 for (i
= 0, mask
= 1; i
< PIPELINE_FA_N_TC_MAX
; i
++, mask
<<= 1) {
829 if ((mask
& req
->meter_update_mask
) == 0)
832 status
= flow_table_entry_set_meter(entry
, i
, &req
->params
);
840 for (i
= 0, mask
= 1; i
< PIPELINE_FA_N_TC_MAX
; i
++, mask
<<= 1) {
841 if ((mask
& req
->policer_update_mask
) == 0)
844 flow_table_entry_set_policer(entry
, i
, &req
->params
);
848 if (req
->port_update
)
849 flow_table_entry_set_port_id(p_fa
, entry
, &req
->params
);
853 rsp
->entry_ptr
= (void *) entry
;
858 pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline
*p
, void *msg
)
860 struct pipeline_flow_actions
*p_fa
= (struct pipeline_flow_actions
*) p
;
861 struct pipeline_fa_flow_config_bulk_msg_req
*req
= msg
;
862 struct pipeline_fa_flow_config_bulk_msg_rsp
*rsp
= msg
;
865 for (i
= 0; i
< req
->n_flows
; i
++) {
866 struct flow_table_entry
*entry
;
869 /* Set flow table entry to default if not configured before */
870 if (req
->entry_ptr
[i
] == NULL
) {
871 struct rte_table_array_key key
= {
872 .pos
= req
->flow_id
[i
] % p_fa
->params
.n_flows
,
875 struct flow_table_entry entry_to_add
;
877 int key_found
, status
;
879 flow_table_entry_set_default(p_fa
, &entry_to_add
);
881 status
= rte_pipeline_table_entry_add(p
->p
,
884 (struct rte_pipeline_table_entry
*) &entry_to_add
,
886 (struct rte_pipeline_table_entry
**) &entry
);
892 req
->entry_ptr
[i
] = (void *) entry
;
894 entry
= (struct flow_table_entry
*) req
->entry_ptr
[i
];
897 for (j
= 0, mask
= 1;
898 j
< PIPELINE_FA_N_TC_MAX
;
902 if ((mask
& req
->meter_update_mask
) == 0)
905 status
= flow_table_entry_set_meter(entry
,
914 for (j
= 0, mask
= 1;
915 j
< PIPELINE_FA_N_TC_MAX
;
917 if ((mask
& req
->policer_update_mask
) == 0)
920 flow_table_entry_set_policer(entry
,
925 if (req
->port_update
)
926 flow_table_entry_set_port_id(p_fa
,
927 entry
, &req
->params
[i
]);
936 pipeline_fa_msg_req_dscp_config_handler(struct pipeline
*p
, void *msg
)
938 struct pipeline_flow_actions
*p_fa
= (struct pipeline_flow_actions
*) p
;
939 struct pipeline_fa_dscp_config_msg_req
*req
= msg
;
940 struct pipeline_fa_dscp_config_msg_rsp
*rsp
= msg
;
943 if ((req
->dscp
>= PIPELINE_FA_N_DSCP
) ||
944 (req
->traffic_class
>= PIPELINE_FA_N_TC_MAX
) ||
945 (req
->color
>= e_RTE_METER_COLORS
)) {
950 p_fa
->dscp
[req
->dscp
].traffic_class
= req
->traffic_class
;
951 p_fa
->dscp
[req
->dscp
].color
= req
->color
;
957 pipeline_fa_msg_req_policer_stats_read_handler(__rte_unused
struct pipeline
*p
,
960 struct pipeline_fa_policer_stats_msg_req
*req
= msg
;
961 struct pipeline_fa_policer_stats_msg_rsp
*rsp
= msg
;
963 struct flow_table_entry
*entry
= req
->entry_ptr
;
964 uint32_t policer_id
= req
->policer_id
;
965 int clear
= req
->clear
;
968 if ((req
->entry_ptr
== NULL
) ||
969 (req
->policer_id
>= PIPELINE_FA_N_TC_MAX
)) {
975 &entry
->mp
[policer_id
].stats
,
978 memset(&entry
->mp
[policer_id
].stats
,
979 0, sizeof(entry
->mp
[policer_id
].stats
));
984 struct pipeline_be_ops pipeline_flow_actions_be_ops
= {
985 .f_init
= pipeline_fa_init
,
986 .f_free
= pipeline_fa_free
,
988 .f_timer
= pipeline_fa_timer
,