1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
8 #include <rte_common.h>
12 #include <rte_string_fns.h>
13 #include <rte_port_ethdev.h>
14 #include <rte_port_ring.h>
15 #include <rte_port_source_sink.h>
16 #include <rte_port_fd.h>
17 #include <rte_port_sched.h>
18 #include <rte_port_sym_crypto.h>
20 #include <rte_table_acl.h>
21 #include <rte_table_array.h>
22 #include <rte_table_hash.h>
23 #include <rte_table_hash_func.h>
24 #include <rte_table_lpm.h>
25 #include <rte_table_lpm_ipv6.h>
26 #include <rte_table_stub.h>
28 #include "rte_eth_softnic_internals.h"
30 #ifndef PIPELINE_MSGQ_SIZE
31 #define PIPELINE_MSGQ_SIZE 64
34 #ifndef TABLE_LPM_NUMBER_TBL8
35 #define TABLE_LPM_NUMBER_TBL8 256
39 softnic_pipeline_init(struct pmd_internals *p)
41 TAILQ_INIT(&p->pipeline_list);
47 softnic_pipeline_table_free(struct softnic_table *table)
50 struct rte_flow *flow;
52 flow = TAILQ_FIRST(&table->flows);
56 TAILQ_REMOVE(&table->flows, flow, node);
61 struct softnic_table_meter_profile *mp;
63 mp = TAILQ_FIRST(&table->meter_profiles);
67 TAILQ_REMOVE(&table->meter_profiles, mp, node);
73 softnic_pipeline_free(struct pmd_internals *p)
76 struct pipeline *pipeline;
79 pipeline = TAILQ_FIRST(&p->pipeline_list);
83 TAILQ_REMOVE(&p->pipeline_list, pipeline, node);
85 for (table_id = 0; table_id < pipeline->n_tables; table_id++) {
86 struct softnic_table *table =
87 &pipeline->table[table_id];
89 softnic_pipeline_table_free(table);
92 rte_ring_free(pipeline->msgq_req);
93 rte_ring_free(pipeline->msgq_rsp);
94 rte_pipeline_free(pipeline->p);
100 softnic_pipeline_disable_all(struct pmd_internals *p)
102 struct pipeline *pipeline;
104 TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
105 if (pipeline->enabled)
106 softnic_thread_pipeline_disable(p,
112 softnic_pipeline_find(struct pmd_internals *p,
115 struct pipeline *pipeline;
120 TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
121 if (strcmp(name, pipeline->name) == 0)
128 softnic_pipeline_create(struct pmd_internals *softnic,
130 struct pipeline_params *params)
132 char resource_name[NAME_MAX];
133 struct rte_pipeline_params pp;
134 struct pipeline *pipeline;
135 struct rte_pipeline *p;
136 struct rte_ring *msgq_req;
137 struct rte_ring *msgq_rsp;
139 /* Check input params */
141 softnic_pipeline_find(softnic, name) ||
143 params->timer_period_ms == 0)
146 /* Resource create */
147 snprintf(resource_name, sizeof(resource_name), "%s-%s-REQ",
148 softnic->params.name,
151 msgq_req = rte_ring_create(resource_name,
153 softnic->params.cpu_id,
154 RING_F_SP_ENQ | RING_F_SC_DEQ);
155 if (msgq_req == NULL)
158 snprintf(resource_name, sizeof(resource_name), "%s-%s-RSP",
159 softnic->params.name,
162 msgq_rsp = rte_ring_create(resource_name,
164 softnic->params.cpu_id,
165 RING_F_SP_ENQ | RING_F_SC_DEQ);
166 if (msgq_rsp == NULL) {
167 rte_ring_free(msgq_req);
171 snprintf(resource_name, sizeof(resource_name), "%s_%s",
172 softnic->params.name,
175 pp.name = resource_name;
176 pp.socket_id = (int)softnic->params.cpu_id;
177 pp.offset_port_id = params->offset_port_id;
179 p = rte_pipeline_create(&pp);
181 rte_ring_free(msgq_rsp);
182 rte_ring_free(msgq_req);
186 /* Node allocation */
187 pipeline = calloc(1, sizeof(struct pipeline));
188 if (pipeline == NULL) {
189 rte_pipeline_free(p);
190 rte_ring_free(msgq_rsp);
191 rte_ring_free(msgq_req);
196 strlcpy(pipeline->name, name, sizeof(pipeline->name));
198 memcpy(&pipeline->params, params, sizeof(*params));
199 pipeline->n_ports_in = 0;
200 pipeline->n_ports_out = 0;
201 pipeline->n_tables = 0;
202 pipeline->msgq_req = msgq_req;
203 pipeline->msgq_rsp = msgq_rsp;
204 pipeline->timer_period_ms = params->timer_period_ms;
205 pipeline->enabled = 0;
206 pipeline->cpu_id = softnic->params.cpu_id;
208 /* Node add to list */
209 TAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);
215 softnic_pipeline_port_in_create(struct pmd_internals *softnic,
216 const char *pipeline_name,
217 struct softnic_port_in_params *params,
220 struct rte_pipeline_port_in_params p;
223 struct rte_port_ethdev_reader_params ethdev;
224 struct rte_port_ring_reader_params ring;
225 struct rte_port_sched_reader_params sched;
226 struct rte_port_fd_reader_params fd;
227 struct rte_port_source_params source;
228 struct rte_port_sym_crypto_reader_params cryptodev;
231 struct pipeline *pipeline;
232 struct softnic_port_in *port_in;
233 struct softnic_port_in_action_profile *ap;
234 struct rte_port_in_action *action;
238 memset(&p, 0, sizeof(p));
239 memset(&pp, 0, sizeof(pp));
241 /* Check input params */
242 if (pipeline_name == NULL ||
244 params->burst_size == 0 ||
245 params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)
248 pipeline = softnic_pipeline_find(softnic, pipeline_name);
249 if (pipeline == NULL)
253 if (strlen(params->action_profile_name)) {
254 ap = softnic_port_in_action_profile_find(softnic,
255 params->action_profile_name);
260 switch (params->type) {
263 struct softnic_link *link;
265 link = softnic_link_find(softnic, params->dev_name);
269 if (params->rxq.queue_id >= link->n_rxq)
272 pp.ethdev.port_id = link->port_id;
273 pp.ethdev.queue_id = params->rxq.queue_id;
275 p.ops = &rte_port_ethdev_reader_ops;
276 p.arg_create = &pp.ethdev;
282 struct softnic_swq *swq;
284 swq = softnic_swq_find(softnic, params->dev_name);
288 pp.ring.ring = swq->r;
290 p.ops = &rte_port_ring_reader_ops;
291 p.arg_create = &pp.ring;
297 struct softnic_tmgr_port *tmgr_port;
299 tmgr_port = softnic_tmgr_port_find(softnic, params->dev_name);
300 if (tmgr_port == NULL)
303 pp.sched.sched = tmgr_port->s;
305 p.ops = &rte_port_sched_reader_ops;
306 p.arg_create = &pp.sched;
312 struct softnic_tap *tap;
313 struct softnic_mempool *mempool;
315 tap = softnic_tap_find(softnic, params->dev_name);
316 mempool = softnic_mempool_find(softnic, params->tap.mempool_name);
317 if (tap == NULL || mempool == NULL)
321 pp.fd.mempool = mempool->m;
322 pp.fd.mtu = params->tap.mtu;
324 p.ops = &rte_port_fd_reader_ops;
325 p.arg_create = &pp.fd;
331 struct softnic_mempool *mempool;
333 mempool = softnic_mempool_find(softnic, params->source.mempool_name);
337 pp.source.mempool = mempool->m;
338 pp.source.file_name = params->source.file_name;
339 pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
341 p.ops = &rte_port_source_ops;
342 p.arg_create = &pp.source;
346 case PORT_IN_CRYPTODEV:
348 struct softnic_cryptodev *cryptodev;
350 cryptodev = softnic_cryptodev_find(softnic, params->dev_name);
351 if (cryptodev == NULL)
354 pp.cryptodev.cryptodev_id = cryptodev->dev_id;
355 pp.cryptodev.queue_id = params->cryptodev.queue_id;
356 pp.cryptodev.f_callback = params->cryptodev.f_callback;
357 pp.cryptodev.arg_callback = params->cryptodev.arg_callback;
358 p.ops = &rte_port_sym_crypto_reader_ops;
359 p.arg_create = &pp.cryptodev;
367 p.burst_size = params->burst_size;
369 /* Resource create */
375 action = rte_port_in_action_create(ap->ap,
376 softnic->params.cpu_id);
380 status = rte_port_in_action_params_get(action,
383 rte_port_in_action_free(action);
388 status = rte_pipeline_port_in_create(pipeline->p,
392 rte_port_in_action_free(action);
397 rte_pipeline_port_in_enable(pipeline->p, port_id);
400 port_in = &pipeline->port_in[pipeline->n_ports_in];
401 memcpy(&port_in->params, params, sizeof(*params));
404 pipeline->n_ports_in++;
410 softnic_pipeline_port_in_connect_to_table(struct pmd_internals *softnic,
411 const char *pipeline_name,
415 struct pipeline *pipeline;
418 /* Check input params */
419 if (pipeline_name == NULL)
422 pipeline = softnic_pipeline_find(softnic, pipeline_name);
423 if (pipeline == NULL ||
424 port_id >= pipeline->n_ports_in ||
425 table_id >= pipeline->n_tables)
429 status = rte_pipeline_port_in_connect_to_table(pipeline->p,
437 softnic_pipeline_port_out_create(struct pmd_internals *softnic,
438 const char *pipeline_name,
439 struct softnic_port_out_params *params)
441 struct rte_pipeline_port_out_params p;
444 struct rte_port_ethdev_writer_params ethdev;
445 struct rte_port_ring_writer_params ring;
446 struct rte_port_sched_writer_params sched;
447 struct rte_port_fd_writer_params fd;
448 struct rte_port_sink_params sink;
449 struct rte_port_sym_crypto_writer_params cryptodev;
453 struct rte_port_ethdev_writer_nodrop_params ethdev;
454 struct rte_port_ring_writer_nodrop_params ring;
455 struct rte_port_fd_writer_nodrop_params fd;
456 struct rte_port_sym_crypto_writer_nodrop_params cryptodev;
459 struct pipeline *pipeline;
460 struct softnic_port_out *port_out;
464 memset(&p, 0, sizeof(p));
465 memset(&pp, 0, sizeof(pp));
466 memset(&pp_nodrop, 0, sizeof(pp_nodrop));
468 /* Check input params */
469 if (pipeline_name == NULL ||
471 params->burst_size == 0 ||
472 params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)
475 pipeline = softnic_pipeline_find(softnic, pipeline_name);
476 if (pipeline == NULL)
479 switch (params->type) {
482 struct softnic_link *link;
484 link = softnic_link_find(softnic, params->dev_name);
488 if (params->txq.queue_id >= link->n_txq)
491 pp.ethdev.port_id = link->port_id;
492 pp.ethdev.queue_id = params->txq.queue_id;
493 pp.ethdev.tx_burst_sz = params->burst_size;
495 pp_nodrop.ethdev.port_id = link->port_id;
496 pp_nodrop.ethdev.queue_id = params->txq.queue_id;
497 pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
498 pp_nodrop.ethdev.n_retries = params->n_retries;
500 if (params->retry == 0) {
501 p.ops = &rte_port_ethdev_writer_ops;
502 p.arg_create = &pp.ethdev;
504 p.ops = &rte_port_ethdev_writer_nodrop_ops;
505 p.arg_create = &pp_nodrop.ethdev;
512 struct softnic_swq *swq;
514 swq = softnic_swq_find(softnic, params->dev_name);
518 pp.ring.ring = swq->r;
519 pp.ring.tx_burst_sz = params->burst_size;
521 pp_nodrop.ring.ring = swq->r;
522 pp_nodrop.ring.tx_burst_sz = params->burst_size;
523 pp_nodrop.ring.n_retries = params->n_retries;
525 if (params->retry == 0) {
526 p.ops = &rte_port_ring_writer_ops;
527 p.arg_create = &pp.ring;
529 p.ops = &rte_port_ring_writer_nodrop_ops;
530 p.arg_create = &pp_nodrop.ring;
537 struct softnic_tmgr_port *tmgr_port;
539 tmgr_port = softnic_tmgr_port_find(softnic, params->dev_name);
540 if (tmgr_port == NULL)
543 pp.sched.sched = tmgr_port->s;
544 pp.sched.tx_burst_sz = params->burst_size;
546 p.ops = &rte_port_sched_writer_ops;
547 p.arg_create = &pp.sched;
553 struct softnic_tap *tap;
555 tap = softnic_tap_find(softnic, params->dev_name);
560 pp.fd.tx_burst_sz = params->burst_size;
562 pp_nodrop.fd.fd = tap->fd;
563 pp_nodrop.fd.tx_burst_sz = params->burst_size;
564 pp_nodrop.fd.n_retries = params->n_retries;
566 if (params->retry == 0) {
567 p.ops = &rte_port_fd_writer_ops;
568 p.arg_create = &pp.fd;
570 p.ops = &rte_port_fd_writer_nodrop_ops;
571 p.arg_create = &pp_nodrop.fd;
578 pp.sink.file_name = params->sink.file_name;
579 pp.sink.max_n_pkts = params->sink.max_n_pkts;
581 p.ops = &rte_port_sink_ops;
582 p.arg_create = &pp.sink;
586 case PORT_OUT_CRYPTODEV:
588 struct softnic_cryptodev *cryptodev;
590 cryptodev = softnic_cryptodev_find(softnic, params->dev_name);
591 if (cryptodev == NULL)
594 if (params->cryptodev.queue_id >= cryptodev->n_queues)
597 pp.cryptodev.cryptodev_id = cryptodev->dev_id;
598 pp.cryptodev.queue_id = params->cryptodev.queue_id;
599 pp.cryptodev.tx_burst_sz = params->burst_size;
600 pp.cryptodev.crypto_op_offset = params->cryptodev.op_offset;
602 pp_nodrop.cryptodev.cryptodev_id = cryptodev->dev_id;
603 pp_nodrop.cryptodev.queue_id = params->cryptodev.queue_id;
604 pp_nodrop.cryptodev.tx_burst_sz = params->burst_size;
605 pp_nodrop.cryptodev.n_retries = params->retry;
606 pp_nodrop.cryptodev.crypto_op_offset =
607 params->cryptodev.op_offset;
609 if (params->retry == 0) {
610 p.ops = &rte_port_sym_crypto_writer_ops;
611 p.arg_create = &pp.cryptodev;
613 p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
614 p.arg_create = &pp_nodrop.cryptodev;
627 /* Resource create */
628 status = rte_pipeline_port_out_create(pipeline->p,
636 port_out = &pipeline->port_out[pipeline->n_ports_out];
637 memcpy(&port_out->params, params, sizeof(*params));
638 pipeline->n_ports_out++;
643 static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
646 .type = RTE_ACL_FIELD_TYPE_BITMASK,
647 .size = sizeof(uint8_t),
650 .offset = offsetof(struct ipv4_hdr, next_proto_id),
653 /* Source IP address (IPv4) */
655 .type = RTE_ACL_FIELD_TYPE_MASK,
656 .size = sizeof(uint32_t),
659 .offset = offsetof(struct ipv4_hdr, src_addr),
662 /* Destination IP address (IPv4) */
664 .type = RTE_ACL_FIELD_TYPE_MASK,
665 .size = sizeof(uint32_t),
668 .offset = offsetof(struct ipv4_hdr, dst_addr),
673 .type = RTE_ACL_FIELD_TYPE_RANGE,
674 .size = sizeof(uint16_t),
677 .offset = sizeof(struct ipv4_hdr) +
678 offsetof(struct tcp_hdr, src_port),
681 /* Destination Port */
683 .type = RTE_ACL_FIELD_TYPE_RANGE,
684 .size = sizeof(uint16_t),
687 .offset = sizeof(struct ipv4_hdr) +
688 offsetof(struct tcp_hdr, dst_port),
692 static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
695 .type = RTE_ACL_FIELD_TYPE_BITMASK,
696 .size = sizeof(uint8_t),
699 .offset = offsetof(struct ipv6_hdr, proto),
702 /* Source IP address (IPv6) */
704 .type = RTE_ACL_FIELD_TYPE_MASK,
705 .size = sizeof(uint32_t),
708 .offset = offsetof(struct ipv6_hdr, src_addr[0]),
712 .type = RTE_ACL_FIELD_TYPE_MASK,
713 .size = sizeof(uint32_t),
716 .offset = offsetof(struct ipv6_hdr, src_addr[4]),
720 .type = RTE_ACL_FIELD_TYPE_MASK,
721 .size = sizeof(uint32_t),
724 .offset = offsetof(struct ipv6_hdr, src_addr[8]),
728 .type = RTE_ACL_FIELD_TYPE_MASK,
729 .size = sizeof(uint32_t),
732 .offset = offsetof(struct ipv6_hdr, src_addr[12]),
735 /* Destination IP address (IPv6) */
737 .type = RTE_ACL_FIELD_TYPE_MASK,
738 .size = sizeof(uint32_t),
741 .offset = offsetof(struct ipv6_hdr, dst_addr[0]),
745 .type = RTE_ACL_FIELD_TYPE_MASK,
746 .size = sizeof(uint32_t),
749 .offset = offsetof(struct ipv6_hdr, dst_addr[4]),
753 .type = RTE_ACL_FIELD_TYPE_MASK,
754 .size = sizeof(uint32_t),
757 .offset = offsetof(struct ipv6_hdr, dst_addr[8]),
761 .type = RTE_ACL_FIELD_TYPE_MASK,
762 .size = sizeof(uint32_t),
765 .offset = offsetof(struct ipv6_hdr, dst_addr[12]),
770 .type = RTE_ACL_FIELD_TYPE_RANGE,
771 .size = sizeof(uint16_t),
774 .offset = sizeof(struct ipv6_hdr) +
775 offsetof(struct tcp_hdr, src_port),
778 /* Destination Port */
780 .type = RTE_ACL_FIELD_TYPE_RANGE,
781 .size = sizeof(uint16_t),
784 .offset = sizeof(struct ipv6_hdr) +
785 offsetof(struct tcp_hdr, dst_port),
790 softnic_pipeline_table_create(struct pmd_internals *softnic,
791 const char *pipeline_name,
792 struct softnic_table_params *params)
795 struct rte_pipeline_table_params p;
798 struct rte_table_acl_params acl;
799 struct rte_table_array_params array;
800 struct rte_table_hash_params hash;
801 struct rte_table_lpm_params lpm;
802 struct rte_table_lpm_ipv6_params lpm_ipv6;
805 struct pipeline *pipeline;
806 struct softnic_table *table;
807 struct softnic_table_action_profile *ap;
808 struct rte_table_action *action;
812 memset(&p, 0, sizeof(p));
813 memset(&pp, 0, sizeof(pp));
815 /* Check input params */
816 if (pipeline_name == NULL ||
820 pipeline = softnic_pipeline_find(softnic, pipeline_name);
821 if (pipeline == NULL ||
822 pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX)
826 if (strlen(params->action_profile_name)) {
827 ap = softnic_table_action_profile_find(softnic,
828 params->action_profile_name);
833 snprintf(name, NAME_MAX, "%s_%s_table%u",
834 softnic->params.name, pipeline_name, pipeline->n_tables);
836 switch (params->match_type) {
839 uint32_t ip_header_offset = params->match.acl.ip_header_offset -
840 (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
843 if (params->match.acl.n_rules == 0)
847 pp.acl.n_rules = params->match.acl.n_rules;
848 if (params->match.acl.ip_version) {
849 memcpy(&pp.acl.field_format,
850 &table_acl_field_format_ipv4,
851 sizeof(table_acl_field_format_ipv4));
852 pp.acl.n_rule_fields =
853 RTE_DIM(table_acl_field_format_ipv4);
855 memcpy(&pp.acl.field_format,
856 &table_acl_field_format_ipv6,
857 sizeof(table_acl_field_format_ipv6));
858 pp.acl.n_rule_fields =
859 RTE_DIM(table_acl_field_format_ipv6);
862 for (i = 0; i < pp.acl.n_rule_fields; i++)
863 pp.acl.field_format[i].offset += ip_header_offset;
865 p.ops = &rte_table_acl_ops;
866 p.arg_create = &pp.acl;
872 if (params->match.array.n_keys == 0)
875 pp.array.n_entries = params->match.array.n_keys;
876 pp.array.offset = params->match.array.key_offset;
878 p.ops = &rte_table_array_ops;
879 p.arg_create = &pp.array;
885 struct rte_table_ops *ops;
886 rte_table_hash_op_hash f_hash;
888 if (params->match.hash.n_keys == 0)
891 switch (params->match.hash.key_size) {
893 f_hash = rte_table_hash_crc_key8;
896 f_hash = rte_table_hash_crc_key16;
899 f_hash = rte_table_hash_crc_key24;
902 f_hash = rte_table_hash_crc_key32;
905 f_hash = rte_table_hash_crc_key40;
908 f_hash = rte_table_hash_crc_key48;
911 f_hash = rte_table_hash_crc_key56;
914 f_hash = rte_table_hash_crc_key64;
921 pp.hash.key_size = params->match.hash.key_size;
922 pp.hash.key_offset = params->match.hash.key_offset;
923 pp.hash.key_mask = params->match.hash.key_mask;
924 pp.hash.n_keys = params->match.hash.n_keys;
925 pp.hash.n_buckets = params->match.hash.n_buckets;
926 pp.hash.f_hash = f_hash;
929 if (params->match.hash.extendable_bucket)
930 switch (params->match.hash.key_size) {
932 ops = &rte_table_hash_key8_ext_ops;
935 ops = &rte_table_hash_key16_ext_ops;
938 ops = &rte_table_hash_ext_ops;
941 switch (params->match.hash.key_size) {
943 ops = &rte_table_hash_key8_lru_ops;
946 ops = &rte_table_hash_key16_lru_ops;
949 ops = &rte_table_hash_lru_ops;
953 p.arg_create = &pp.hash;
959 if (params->match.lpm.n_rules == 0)
962 switch (params->match.lpm.key_size) {
966 pp.lpm.n_rules = params->match.lpm.n_rules;
967 pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
969 pp.lpm.entry_unique_size = p.action_data_size +
970 sizeof(struct rte_pipeline_table_entry);
971 pp.lpm.offset = params->match.lpm.key_offset;
973 p.ops = &rte_table_lpm_ops;
974 p.arg_create = &pp.lpm;
980 pp.lpm_ipv6.name = name;
981 pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
982 pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
983 pp.lpm_ipv6.entry_unique_size = p.action_data_size +
984 sizeof(struct rte_pipeline_table_entry);
985 pp.lpm_ipv6.offset = params->match.lpm.key_offset;
987 p.ops = &rte_table_lpm_ipv6_ops;
988 p.arg_create = &pp.lpm_ipv6;
1001 p.ops = &rte_table_stub_ops;
1002 p.arg_create = NULL;
1010 /* Resource create */
1012 p.f_action_hit = NULL;
1013 p.f_action_miss = NULL;
1017 action = rte_table_action_create(ap->ap,
1018 softnic->params.cpu_id);
1022 status = rte_table_action_table_params_get(action,
1025 ((p.action_data_size +
1026 sizeof(struct rte_pipeline_table_entry)) >
1027 TABLE_RULE_ACTION_SIZE_MAX)) {
1028 rte_table_action_free(action);
1033 if (params->match_type == TABLE_LPM) {
1034 if (params->match.lpm.key_size == 4)
1035 pp.lpm.entry_unique_size = p.action_data_size +
1036 sizeof(struct rte_pipeline_table_entry);
1038 if (params->match.lpm.key_size == 16)
1039 pp.lpm_ipv6.entry_unique_size = p.action_data_size +
1040 sizeof(struct rte_pipeline_table_entry);
1043 status = rte_pipeline_table_create(pipeline->p,
1047 rte_table_action_free(action);
1052 table = &pipeline->table[pipeline->n_tables];
1053 memcpy(&table->params, params, sizeof(*params));
1056 TAILQ_INIT(&table->flows);
1057 TAILQ_INIT(&table->meter_profiles);
1058 memset(&table->dscp_table, 0, sizeof(table->dscp_table));
1059 pipeline->n_tables++;
1065 softnic_pipeline_port_out_find(struct pmd_internals *softnic,
1066 const char *pipeline_name,
1070 struct pipeline *pipeline;
1073 if (softnic == NULL ||
1074 pipeline_name == NULL ||
1079 pipeline = softnic_pipeline_find(softnic, pipeline_name);
1080 if (pipeline == NULL)
1083 for (i = 0; i < pipeline->n_ports_out; i++)
1084 if (strcmp(pipeline->port_out[i].params.dev_name, name) == 0) {
1092 struct softnic_table_meter_profile *
1093 softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
1094 uint32_t meter_profile_id)
1096 struct softnic_table_meter_profile *mp;
1098 TAILQ_FOREACH(mp, &table->meter_profiles, node)
1099 if (mp->meter_profile_id == meter_profile_id)