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_thread_count(struct pmd_internals *p, uint32_t thread_id)
114 struct pipeline *pipeline;
117 TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
118 if ((pipeline->enabled) && (pipeline->thread_id == thread_id))
125 softnic_pipeline_find(struct pmd_internals *p,
128 struct pipeline *pipeline;
133 TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
134 if (strcmp(name, pipeline->name) == 0)
141 softnic_pipeline_create(struct pmd_internals *softnic,
143 struct pipeline_params *params)
145 char resource_name[NAME_MAX];
146 struct rte_pipeline_params pp;
147 struct pipeline *pipeline;
148 struct rte_pipeline *p;
149 struct rte_ring *msgq_req;
150 struct rte_ring *msgq_rsp;
152 /* Check input params */
154 softnic_pipeline_find(softnic, name) ||
156 params->timer_period_ms == 0)
159 /* Resource create */
160 snprintf(resource_name, sizeof(resource_name), "%s-%s-REQ",
161 softnic->params.name,
164 msgq_req = rte_ring_create(resource_name,
166 softnic->params.cpu_id,
167 RING_F_SP_ENQ | RING_F_SC_DEQ);
168 if (msgq_req == NULL)
171 snprintf(resource_name, sizeof(resource_name), "%s-%s-RSP",
172 softnic->params.name,
175 msgq_rsp = rte_ring_create(resource_name,
177 softnic->params.cpu_id,
178 RING_F_SP_ENQ | RING_F_SC_DEQ);
179 if (msgq_rsp == NULL) {
180 rte_ring_free(msgq_req);
184 snprintf(resource_name, sizeof(resource_name), "%s_%s",
185 softnic->params.name,
188 pp.name = resource_name;
189 pp.socket_id = (int)softnic->params.cpu_id;
190 pp.offset_port_id = params->offset_port_id;
192 p = rte_pipeline_create(&pp);
194 rte_ring_free(msgq_rsp);
195 rte_ring_free(msgq_req);
199 /* Node allocation */
200 pipeline = calloc(1, sizeof(struct pipeline));
201 if (pipeline == NULL) {
202 rte_pipeline_free(p);
203 rte_ring_free(msgq_rsp);
204 rte_ring_free(msgq_req);
209 strlcpy(pipeline->name, name, sizeof(pipeline->name));
211 memcpy(&pipeline->params, params, sizeof(*params));
212 pipeline->n_ports_in = 0;
213 pipeline->n_ports_out = 0;
214 pipeline->n_tables = 0;
215 pipeline->msgq_req = msgq_req;
216 pipeline->msgq_rsp = msgq_rsp;
217 pipeline->timer_period_ms = params->timer_period_ms;
218 pipeline->enabled = 0;
219 pipeline->cpu_id = softnic->params.cpu_id;
221 /* Node add to list */
222 TAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);
228 softnic_pipeline_port_in_create(struct pmd_internals *softnic,
229 const char *pipeline_name,
230 struct softnic_port_in_params *params,
233 struct rte_pipeline_port_in_params p;
236 struct rte_port_ethdev_reader_params ethdev;
237 struct rte_port_ring_reader_params ring;
238 struct rte_port_sched_reader_params sched;
239 struct rte_port_fd_reader_params fd;
240 struct rte_port_source_params source;
241 struct rte_port_sym_crypto_reader_params cryptodev;
244 struct pipeline *pipeline;
245 struct softnic_port_in *port_in;
246 struct softnic_port_in_action_profile *ap;
247 struct rte_port_in_action *action;
251 memset(&p, 0, sizeof(p));
252 memset(&pp, 0, sizeof(pp));
254 /* Check input params */
255 if (pipeline_name == NULL ||
257 params->burst_size == 0 ||
258 params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)
261 pipeline = softnic_pipeline_find(softnic, pipeline_name);
262 if (pipeline == NULL)
266 if (strlen(params->action_profile_name)) {
267 ap = softnic_port_in_action_profile_find(softnic,
268 params->action_profile_name);
273 switch (params->type) {
276 struct softnic_link *link;
278 link = softnic_link_find(softnic, params->dev_name);
282 if (params->rxq.queue_id >= link->n_rxq)
285 pp.ethdev.port_id = link->port_id;
286 pp.ethdev.queue_id = params->rxq.queue_id;
288 p.ops = &rte_port_ethdev_reader_ops;
289 p.arg_create = &pp.ethdev;
295 struct softnic_swq *swq;
297 swq = softnic_swq_find(softnic, params->dev_name);
301 pp.ring.ring = swq->r;
303 p.ops = &rte_port_ring_reader_ops;
304 p.arg_create = &pp.ring;
310 struct softnic_tmgr_port *tmgr_port;
312 tmgr_port = softnic_tmgr_port_find(softnic, params->dev_name);
313 if (tmgr_port == NULL)
316 pp.sched.sched = tmgr_port->s;
318 p.ops = &rte_port_sched_reader_ops;
319 p.arg_create = &pp.sched;
325 struct softnic_tap *tap;
326 struct softnic_mempool *mempool;
328 tap = softnic_tap_find(softnic, params->dev_name);
329 mempool = softnic_mempool_find(softnic, params->tap.mempool_name);
330 if (tap == NULL || mempool == NULL)
334 pp.fd.mempool = mempool->m;
335 pp.fd.mtu = params->tap.mtu;
337 p.ops = &rte_port_fd_reader_ops;
338 p.arg_create = &pp.fd;
344 struct softnic_mempool *mempool;
346 mempool = softnic_mempool_find(softnic, params->source.mempool_name);
350 pp.source.mempool = mempool->m;
351 pp.source.file_name = params->source.file_name;
352 pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
354 p.ops = &rte_port_source_ops;
355 p.arg_create = &pp.source;
359 case PORT_IN_CRYPTODEV:
361 struct softnic_cryptodev *cryptodev;
363 cryptodev = softnic_cryptodev_find(softnic, params->dev_name);
364 if (cryptodev == NULL)
367 pp.cryptodev.cryptodev_id = cryptodev->dev_id;
368 pp.cryptodev.queue_id = params->cryptodev.queue_id;
369 pp.cryptodev.f_callback = params->cryptodev.f_callback;
370 pp.cryptodev.arg_callback = params->cryptodev.arg_callback;
371 p.ops = &rte_port_sym_crypto_reader_ops;
372 p.arg_create = &pp.cryptodev;
380 p.burst_size = params->burst_size;
382 /* Resource create */
388 action = rte_port_in_action_create(ap->ap,
389 softnic->params.cpu_id);
393 status = rte_port_in_action_params_get(action,
396 rte_port_in_action_free(action);
401 status = rte_pipeline_port_in_create(pipeline->p,
405 rte_port_in_action_free(action);
410 rte_pipeline_port_in_enable(pipeline->p, port_id);
413 port_in = &pipeline->port_in[pipeline->n_ports_in];
414 memcpy(&port_in->params, params, sizeof(*params));
417 pipeline->n_ports_in++;
423 softnic_pipeline_port_in_connect_to_table(struct pmd_internals *softnic,
424 const char *pipeline_name,
428 struct pipeline *pipeline;
431 /* Check input params */
432 if (pipeline_name == NULL)
435 pipeline = softnic_pipeline_find(softnic, pipeline_name);
436 if (pipeline == NULL ||
437 port_id >= pipeline->n_ports_in ||
438 table_id >= pipeline->n_tables)
442 status = rte_pipeline_port_in_connect_to_table(pipeline->p,
450 softnic_pipeline_port_out_create(struct pmd_internals *softnic,
451 const char *pipeline_name,
452 struct softnic_port_out_params *params)
454 struct rte_pipeline_port_out_params p;
457 struct rte_port_ethdev_writer_params ethdev;
458 struct rte_port_ring_writer_params ring;
459 struct rte_port_sched_writer_params sched;
460 struct rte_port_fd_writer_params fd;
461 struct rte_port_sink_params sink;
462 struct rte_port_sym_crypto_writer_params cryptodev;
466 struct rte_port_ethdev_writer_nodrop_params ethdev;
467 struct rte_port_ring_writer_nodrop_params ring;
468 struct rte_port_fd_writer_nodrop_params fd;
469 struct rte_port_sym_crypto_writer_nodrop_params cryptodev;
472 struct pipeline *pipeline;
473 struct softnic_port_out *port_out;
477 memset(&p, 0, sizeof(p));
478 memset(&pp, 0, sizeof(pp));
479 memset(&pp_nodrop, 0, sizeof(pp_nodrop));
481 /* Check input params */
482 if (pipeline_name == NULL ||
484 params->burst_size == 0 ||
485 params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)
488 pipeline = softnic_pipeline_find(softnic, pipeline_name);
489 if (pipeline == NULL)
492 switch (params->type) {
495 struct softnic_link *link;
497 link = softnic_link_find(softnic, params->dev_name);
501 if (params->txq.queue_id >= link->n_txq)
504 pp.ethdev.port_id = link->port_id;
505 pp.ethdev.queue_id = params->txq.queue_id;
506 pp.ethdev.tx_burst_sz = params->burst_size;
508 pp_nodrop.ethdev.port_id = link->port_id;
509 pp_nodrop.ethdev.queue_id = params->txq.queue_id;
510 pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
511 pp_nodrop.ethdev.n_retries = params->n_retries;
513 if (params->retry == 0) {
514 p.ops = &rte_port_ethdev_writer_ops;
515 p.arg_create = &pp.ethdev;
517 p.ops = &rte_port_ethdev_writer_nodrop_ops;
518 p.arg_create = &pp_nodrop.ethdev;
525 struct softnic_swq *swq;
527 swq = softnic_swq_find(softnic, params->dev_name);
531 pp.ring.ring = swq->r;
532 pp.ring.tx_burst_sz = params->burst_size;
534 pp_nodrop.ring.ring = swq->r;
535 pp_nodrop.ring.tx_burst_sz = params->burst_size;
536 pp_nodrop.ring.n_retries = params->n_retries;
538 if (params->retry == 0) {
539 p.ops = &rte_port_ring_writer_ops;
540 p.arg_create = &pp.ring;
542 p.ops = &rte_port_ring_writer_nodrop_ops;
543 p.arg_create = &pp_nodrop.ring;
550 struct softnic_tmgr_port *tmgr_port;
552 tmgr_port = softnic_tmgr_port_find(softnic, params->dev_name);
553 if (tmgr_port == NULL)
556 pp.sched.sched = tmgr_port->s;
557 pp.sched.tx_burst_sz = params->burst_size;
559 p.ops = &rte_port_sched_writer_ops;
560 p.arg_create = &pp.sched;
566 struct softnic_tap *tap;
568 tap = softnic_tap_find(softnic, params->dev_name);
573 pp.fd.tx_burst_sz = params->burst_size;
575 pp_nodrop.fd.fd = tap->fd;
576 pp_nodrop.fd.tx_burst_sz = params->burst_size;
577 pp_nodrop.fd.n_retries = params->n_retries;
579 if (params->retry == 0) {
580 p.ops = &rte_port_fd_writer_ops;
581 p.arg_create = &pp.fd;
583 p.ops = &rte_port_fd_writer_nodrop_ops;
584 p.arg_create = &pp_nodrop.fd;
591 pp.sink.file_name = params->sink.file_name;
592 pp.sink.max_n_pkts = params->sink.max_n_pkts;
594 p.ops = &rte_port_sink_ops;
595 p.arg_create = &pp.sink;
599 case PORT_OUT_CRYPTODEV:
601 struct softnic_cryptodev *cryptodev;
603 cryptodev = softnic_cryptodev_find(softnic, params->dev_name);
604 if (cryptodev == NULL)
607 if (params->cryptodev.queue_id >= cryptodev->n_queues)
610 pp.cryptodev.cryptodev_id = cryptodev->dev_id;
611 pp.cryptodev.queue_id = params->cryptodev.queue_id;
612 pp.cryptodev.tx_burst_sz = params->burst_size;
613 pp.cryptodev.crypto_op_offset = params->cryptodev.op_offset;
615 pp_nodrop.cryptodev.cryptodev_id = cryptodev->dev_id;
616 pp_nodrop.cryptodev.queue_id = params->cryptodev.queue_id;
617 pp_nodrop.cryptodev.tx_burst_sz = params->burst_size;
618 pp_nodrop.cryptodev.n_retries = params->retry;
619 pp_nodrop.cryptodev.crypto_op_offset =
620 params->cryptodev.op_offset;
622 if (params->retry == 0) {
623 p.ops = &rte_port_sym_crypto_writer_ops;
624 p.arg_create = &pp.cryptodev;
626 p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
627 p.arg_create = &pp_nodrop.cryptodev;
640 /* Resource create */
641 status = rte_pipeline_port_out_create(pipeline->p,
649 port_out = &pipeline->port_out[pipeline->n_ports_out];
650 memcpy(&port_out->params, params, sizeof(*params));
651 pipeline->n_ports_out++;
656 static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
659 .type = RTE_ACL_FIELD_TYPE_BITMASK,
660 .size = sizeof(uint8_t),
663 .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
666 /* Source IP address (IPv4) */
668 .type = RTE_ACL_FIELD_TYPE_MASK,
669 .size = sizeof(uint32_t),
672 .offset = offsetof(struct rte_ipv4_hdr, src_addr),
675 /* Destination IP address (IPv4) */
677 .type = RTE_ACL_FIELD_TYPE_MASK,
678 .size = sizeof(uint32_t),
681 .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
686 .type = RTE_ACL_FIELD_TYPE_RANGE,
687 .size = sizeof(uint16_t),
690 .offset = sizeof(struct rte_ipv4_hdr) +
691 offsetof(struct rte_tcp_hdr, src_port),
694 /* Destination Port */
696 .type = RTE_ACL_FIELD_TYPE_RANGE,
697 .size = sizeof(uint16_t),
700 .offset = sizeof(struct rte_ipv4_hdr) +
701 offsetof(struct rte_tcp_hdr, dst_port),
705 static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
708 .type = RTE_ACL_FIELD_TYPE_BITMASK,
709 .size = sizeof(uint8_t),
712 .offset = offsetof(struct rte_ipv6_hdr, proto),
715 /* Source IP address (IPv6) */
717 .type = RTE_ACL_FIELD_TYPE_MASK,
718 .size = sizeof(uint32_t),
721 .offset = offsetof(struct rte_ipv6_hdr, src_addr[0]),
725 .type = RTE_ACL_FIELD_TYPE_MASK,
726 .size = sizeof(uint32_t),
729 .offset = offsetof(struct rte_ipv6_hdr, src_addr[4]),
733 .type = RTE_ACL_FIELD_TYPE_MASK,
734 .size = sizeof(uint32_t),
737 .offset = offsetof(struct rte_ipv6_hdr, src_addr[8]),
741 .type = RTE_ACL_FIELD_TYPE_MASK,
742 .size = sizeof(uint32_t),
745 .offset = offsetof(struct rte_ipv6_hdr, src_addr[12]),
748 /* Destination IP address (IPv6) */
750 .type = RTE_ACL_FIELD_TYPE_MASK,
751 .size = sizeof(uint32_t),
754 .offset = offsetof(struct rte_ipv6_hdr, dst_addr[0]),
758 .type = RTE_ACL_FIELD_TYPE_MASK,
759 .size = sizeof(uint32_t),
762 .offset = offsetof(struct rte_ipv6_hdr, dst_addr[4]),
766 .type = RTE_ACL_FIELD_TYPE_MASK,
767 .size = sizeof(uint32_t),
770 .offset = offsetof(struct rte_ipv6_hdr, dst_addr[8]),
774 .type = RTE_ACL_FIELD_TYPE_MASK,
775 .size = sizeof(uint32_t),
778 .offset = offsetof(struct rte_ipv6_hdr, dst_addr[12]),
783 .type = RTE_ACL_FIELD_TYPE_RANGE,
784 .size = sizeof(uint16_t),
787 .offset = sizeof(struct rte_ipv6_hdr) +
788 offsetof(struct rte_tcp_hdr, src_port),
791 /* Destination Port */
793 .type = RTE_ACL_FIELD_TYPE_RANGE,
794 .size = sizeof(uint16_t),
797 .offset = sizeof(struct rte_ipv6_hdr) +
798 offsetof(struct rte_tcp_hdr, dst_port),
803 softnic_pipeline_table_create(struct pmd_internals *softnic,
804 const char *pipeline_name,
805 struct softnic_table_params *params)
808 struct rte_pipeline_table_params p;
811 struct rte_table_acl_params acl;
812 struct rte_table_array_params array;
813 struct rte_table_hash_params hash;
814 struct rte_table_lpm_params lpm;
815 struct rte_table_lpm_ipv6_params lpm_ipv6;
818 struct pipeline *pipeline;
819 struct softnic_table *table;
820 struct softnic_table_action_profile *ap;
821 struct rte_table_action *action;
825 memset(&p, 0, sizeof(p));
826 memset(&pp, 0, sizeof(pp));
828 /* Check input params */
829 if (pipeline_name == NULL ||
833 pipeline = softnic_pipeline_find(softnic, pipeline_name);
834 if (pipeline == NULL ||
835 pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX)
839 if (strlen(params->action_profile_name)) {
840 ap = softnic_table_action_profile_find(softnic,
841 params->action_profile_name);
846 snprintf(name, NAME_MAX, "%s_%s_table%u",
847 softnic->params.name, pipeline_name, pipeline->n_tables);
849 switch (params->match_type) {
852 uint32_t ip_header_offset = params->match.acl.ip_header_offset -
853 (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
856 if (params->match.acl.n_rules == 0)
860 pp.acl.n_rules = params->match.acl.n_rules;
861 if (params->match.acl.ip_version) {
862 memcpy(&pp.acl.field_format,
863 &table_acl_field_format_ipv4,
864 sizeof(table_acl_field_format_ipv4));
865 pp.acl.n_rule_fields =
866 RTE_DIM(table_acl_field_format_ipv4);
868 memcpy(&pp.acl.field_format,
869 &table_acl_field_format_ipv6,
870 sizeof(table_acl_field_format_ipv6));
871 pp.acl.n_rule_fields =
872 RTE_DIM(table_acl_field_format_ipv6);
875 for (i = 0; i < pp.acl.n_rule_fields; i++)
876 pp.acl.field_format[i].offset += ip_header_offset;
878 p.ops = &rte_table_acl_ops;
879 p.arg_create = &pp.acl;
885 if (params->match.array.n_keys == 0)
888 pp.array.n_entries = params->match.array.n_keys;
889 pp.array.offset = params->match.array.key_offset;
891 p.ops = &rte_table_array_ops;
892 p.arg_create = &pp.array;
898 struct rte_table_ops *ops;
899 rte_table_hash_op_hash f_hash;
901 if (params->match.hash.n_keys == 0)
904 switch (params->match.hash.key_size) {
906 f_hash = rte_table_hash_crc_key8;
909 f_hash = rte_table_hash_crc_key16;
912 f_hash = rte_table_hash_crc_key24;
915 f_hash = rte_table_hash_crc_key32;
918 f_hash = rte_table_hash_crc_key40;
921 f_hash = rte_table_hash_crc_key48;
924 f_hash = rte_table_hash_crc_key56;
927 f_hash = rte_table_hash_crc_key64;
934 pp.hash.key_size = params->match.hash.key_size;
935 pp.hash.key_offset = params->match.hash.key_offset;
936 pp.hash.key_mask = params->match.hash.key_mask;
937 pp.hash.n_keys = params->match.hash.n_keys;
938 pp.hash.n_buckets = params->match.hash.n_buckets;
939 pp.hash.f_hash = f_hash;
942 if (params->match.hash.extendable_bucket)
943 switch (params->match.hash.key_size) {
945 ops = &rte_table_hash_key8_ext_ops;
948 ops = &rte_table_hash_key16_ext_ops;
951 ops = &rte_table_hash_ext_ops;
954 switch (params->match.hash.key_size) {
956 ops = &rte_table_hash_key8_lru_ops;
959 ops = &rte_table_hash_key16_lru_ops;
962 ops = &rte_table_hash_lru_ops;
966 p.arg_create = &pp.hash;
972 if (params->match.lpm.n_rules == 0)
975 switch (params->match.lpm.key_size) {
979 pp.lpm.n_rules = params->match.lpm.n_rules;
980 pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
982 pp.lpm.entry_unique_size = p.action_data_size +
983 sizeof(struct rte_pipeline_table_entry);
984 pp.lpm.offset = params->match.lpm.key_offset;
986 p.ops = &rte_table_lpm_ops;
987 p.arg_create = &pp.lpm;
993 pp.lpm_ipv6.name = name;
994 pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
995 pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
996 pp.lpm_ipv6.entry_unique_size = p.action_data_size +
997 sizeof(struct rte_pipeline_table_entry);
998 pp.lpm_ipv6.offset = params->match.lpm.key_offset;
1000 p.ops = &rte_table_lpm_ipv6_ops;
1001 p.arg_create = &pp.lpm_ipv6;
1014 p.ops = &rte_table_stub_ops;
1015 p.arg_create = NULL;
1023 /* Resource create */
1025 p.f_action_hit = NULL;
1026 p.f_action_miss = NULL;
1030 action = rte_table_action_create(ap->ap,
1031 softnic->params.cpu_id);
1035 status = rte_table_action_table_params_get(action,
1038 ((p.action_data_size +
1039 sizeof(struct rte_pipeline_table_entry)) >
1040 TABLE_RULE_ACTION_SIZE_MAX)) {
1041 rte_table_action_free(action);
1046 if (params->match_type == TABLE_LPM) {
1047 if (params->match.lpm.key_size == 4)
1048 pp.lpm.entry_unique_size = p.action_data_size +
1049 sizeof(struct rte_pipeline_table_entry);
1051 if (params->match.lpm.key_size == 16)
1052 pp.lpm_ipv6.entry_unique_size = p.action_data_size +
1053 sizeof(struct rte_pipeline_table_entry);
1056 status = rte_pipeline_table_create(pipeline->p,
1060 rte_table_action_free(action);
1065 table = &pipeline->table[pipeline->n_tables];
1066 memcpy(&table->params, params, sizeof(*params));
1069 TAILQ_INIT(&table->flows);
1070 TAILQ_INIT(&table->meter_profiles);
1071 memset(&table->dscp_table, 0, sizeof(table->dscp_table));
1072 pipeline->n_tables++;
1078 softnic_pipeline_port_out_find(struct pmd_internals *softnic,
1079 const char *pipeline_name,
1083 struct pipeline *pipeline;
1086 if (softnic == NULL ||
1087 pipeline_name == NULL ||
1092 pipeline = softnic_pipeline_find(softnic, pipeline_name);
1093 if (pipeline == NULL)
1096 for (i = 0; i < pipeline->n_ports_out; i++)
1097 if (strcmp(pipeline->port_out[i].params.dev_name, name) == 0) {
1105 struct softnic_table_meter_profile *
1106 softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
1107 uint32_t meter_profile_id)
1109 struct softnic_table_meter_profile *mp;
1111 TAILQ_FOREACH(mp, &table->meter_profiles, node)
1112 if (mp->meter_profile_id == meter_profile_id)