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>
15 #include <rte_port_kni.h>
17 #include <rte_port_ring.h>
18 #include <rte_port_source_sink.h>
19 #include <rte_port_fd.h>
20 #include <rte_port_sched.h>
21 #include <rte_port_sym_crypto.h>
23 #include <rte_table_acl.h>
24 #include <rte_table_array.h>
25 #include <rte_table_hash.h>
26 #include <rte_table_hash_func.h>
27 #include <rte_table_lpm.h>
28 #include <rte_table_lpm_ipv6.h>
29 #include <rte_table_stub.h>
40 #include "cryptodev.h"
42 #ifndef PIPELINE_MSGQ_SIZE
43 #define PIPELINE_MSGQ_SIZE 64
46 #ifndef TABLE_LPM_NUMBER_TBL8
47 #define TABLE_LPM_NUMBER_TBL8 256
50 static struct pipeline_list pipeline_list
;
55 TAILQ_INIT(&pipeline_list
);
61 pipeline_find(const char *name
)
63 struct pipeline
*pipeline
;
68 TAILQ_FOREACH(pipeline
, &pipeline_list
, node
)
69 if (strcmp(name
, pipeline
->name
) == 0)
76 pipeline_create(const char *name
, struct pipeline_params
*params
)
78 char msgq_name
[NAME_MAX
];
79 struct rte_pipeline_params pp
;
80 struct pipeline
*pipeline
;
81 struct rte_pipeline
*p
;
82 struct rte_ring
*msgq_req
;
83 struct rte_ring
*msgq_rsp
;
85 /* Check input params */
87 pipeline_find(name
) ||
89 (params
->timer_period_ms
== 0))
93 snprintf(msgq_name
, sizeof(msgq_name
), "%s-MSGQ-REQ", name
);
95 msgq_req
= rte_ring_create(msgq_name
,
98 RING_F_SP_ENQ
| RING_F_SC_DEQ
);
102 snprintf(msgq_name
, sizeof(msgq_name
), "%s-MSGQ-RSP", name
);
104 msgq_rsp
= rte_ring_create(msgq_name
,
107 RING_F_SP_ENQ
| RING_F_SC_DEQ
);
108 if (msgq_rsp
== NULL
) {
109 rte_ring_free(msgq_req
);
114 pp
.socket_id
= (int) params
->cpu_id
;
115 pp
.offset_port_id
= params
->offset_port_id
;
117 p
= rte_pipeline_create(&pp
);
119 rte_ring_free(msgq_rsp
);
120 rte_ring_free(msgq_req
);
124 /* Node allocation */
125 pipeline
= calloc(1, sizeof(struct pipeline
));
126 if (pipeline
== NULL
) {
127 rte_pipeline_free(p
);
128 rte_ring_free(msgq_rsp
);
129 rte_ring_free(msgq_req
);
134 strlcpy(pipeline
->name
, name
, sizeof(pipeline
->name
));
136 pipeline
->n_ports_in
= 0;
137 pipeline
->n_ports_out
= 0;
138 pipeline
->n_tables
= 0;
139 pipeline
->msgq_req
= msgq_req
;
140 pipeline
->msgq_rsp
= msgq_rsp
;
141 pipeline
->timer_period_ms
= params
->timer_period_ms
;
142 pipeline
->enabled
= 0;
143 pipeline
->cpu_id
= params
->cpu_id
;
145 /* Node add to list */
146 TAILQ_INSERT_TAIL(&pipeline_list
, pipeline
, node
);
152 pipeline_port_in_create(const char *pipeline_name
,
153 struct port_in_params
*params
,
156 struct rte_pipeline_port_in_params p
;
159 struct rte_port_ethdev_reader_params ethdev
;
160 struct rte_port_ring_reader_params ring
;
161 struct rte_port_sched_reader_params sched
;
162 struct rte_port_fd_reader_params fd
;
163 #ifdef RTE_LIBRTE_KNI
164 struct rte_port_kni_reader_params kni
;
166 struct rte_port_source_params source
;
167 struct rte_port_sym_crypto_reader_params sym_crypto
;
170 struct pipeline
*pipeline
;
171 struct port_in
*port_in
;
172 struct port_in_action_profile
*ap
;
173 struct rte_port_in_action
*action
;
177 memset(&p
, 0, sizeof(p
));
178 memset(&pp
, 0, sizeof(pp
));
180 /* Check input params */
181 if ((pipeline_name
== NULL
) ||
183 (params
->burst_size
== 0) ||
184 (params
->burst_size
> RTE_PORT_IN_BURST_SIZE_MAX
))
187 pipeline
= pipeline_find(pipeline_name
);
188 if (pipeline
== NULL
)
192 if (params
->action_profile_name
) {
193 ap
= port_in_action_profile_find(params
->action_profile_name
);
198 switch (params
->type
) {
203 link
= link_find(params
->dev_name
);
207 if (params
->rxq
.queue_id
>= link
->n_rxq
)
210 pp
.ethdev
.port_id
= link
->port_id
;
211 pp
.ethdev
.queue_id
= params
->rxq
.queue_id
;
213 p
.ops
= &rte_port_ethdev_reader_ops
;
214 p
.arg_create
= &pp
.ethdev
;
222 swq
= swq_find(params
->dev_name
);
226 pp
.ring
.ring
= swq
->r
;
228 p
.ops
= &rte_port_ring_reader_ops
;
229 p
.arg_create
= &pp
.ring
;
235 struct tmgr_port
*tmgr_port
;
237 tmgr_port
= tmgr_port_find(params
->dev_name
);
238 if (tmgr_port
== NULL
)
241 pp
.sched
.sched
= tmgr_port
->s
;
243 p
.ops
= &rte_port_sched_reader_ops
;
244 p
.arg_create
= &pp
.sched
;
251 struct mempool
*mempool
;
253 tap
= tap_find(params
->dev_name
);
254 mempool
= mempool_find(params
->tap
.mempool_name
);
255 if ((tap
== NULL
) || (mempool
== NULL
))
259 pp
.fd
.mempool
= mempool
->m
;
260 pp
.fd
.mtu
= params
->tap
.mtu
;
262 p
.ops
= &rte_port_fd_reader_ops
;
263 p
.arg_create
= &pp
.fd
;
267 #ifdef RTE_LIBRTE_KNI
272 kni
= kni_find(params
->dev_name
);
278 p
.ops
= &rte_port_kni_reader_ops
;
279 p
.arg_create
= &pp
.kni
;
286 struct mempool
*mempool
;
288 mempool
= mempool_find(params
->source
.mempool_name
);
292 pp
.source
.mempool
= mempool
->m
;
293 pp
.source
.file_name
= params
->source
.file_name
;
294 pp
.source
.n_bytes_per_pkt
= params
->source
.n_bytes_per_pkt
;
296 p
.ops
= &rte_port_source_ops
;
297 p
.arg_create
= &pp
.source
;
301 case PORT_IN_CRYPTODEV
:
303 struct cryptodev
*cryptodev
;
305 cryptodev
= cryptodev_find(params
->dev_name
);
306 if (cryptodev
== NULL
)
309 if (params
->rxq
.queue_id
> cryptodev
->n_queues
- 1)
312 pp
.sym_crypto
.cryptodev_id
= cryptodev
->dev_id
;
313 pp
.sym_crypto
.queue_id
= params
->cryptodev
.queue_id
;
314 pp
.sym_crypto
.f_callback
= params
->cryptodev
.f_callback
;
315 pp
.sym_crypto
.arg_callback
= params
->cryptodev
.arg_callback
;
316 p
.ops
= &rte_port_sym_crypto_reader_ops
;
317 p
.arg_create
= &pp
.sym_crypto
;
326 p
.burst_size
= params
->burst_size
;
328 /* Resource create */
334 action
= rte_port_in_action_create(ap
->ap
,
339 status
= rte_port_in_action_params_get(
343 rte_port_in_action_free(action
);
348 status
= rte_pipeline_port_in_create(pipeline
->p
,
352 rte_port_in_action_free(action
);
357 rte_pipeline_port_in_enable(pipeline
->p
, port_id
);
360 port_in
= &pipeline
->port_in
[pipeline
->n_ports_in
];
361 memcpy(&port_in
->params
, params
, sizeof(*params
));
364 pipeline
->n_ports_in
++;
370 pipeline_port_in_connect_to_table(const char *pipeline_name
,
374 struct pipeline
*pipeline
;
377 /* Check input params */
378 if (pipeline_name
== NULL
)
381 pipeline
= pipeline_find(pipeline_name
);
382 if ((pipeline
== NULL
) ||
383 (port_id
>= pipeline
->n_ports_in
) ||
384 (table_id
>= pipeline
->n_tables
))
388 status
= rte_pipeline_port_in_connect_to_table(pipeline
->p
,
397 pipeline_port_out_create(const char *pipeline_name
,
398 struct port_out_params
*params
)
400 struct rte_pipeline_port_out_params p
;
403 struct rte_port_ethdev_writer_params ethdev
;
404 struct rte_port_ring_writer_params ring
;
405 struct rte_port_sched_writer_params sched
;
406 struct rte_port_fd_writer_params fd
;
407 #ifdef RTE_LIBRTE_KNI
408 struct rte_port_kni_writer_params kni
;
410 struct rte_port_sink_params sink
;
411 struct rte_port_sym_crypto_writer_params sym_crypto
;
415 struct rte_port_ethdev_writer_nodrop_params ethdev
;
416 struct rte_port_ring_writer_nodrop_params ring
;
417 struct rte_port_fd_writer_nodrop_params fd
;
418 #ifdef RTE_LIBRTE_KNI
419 struct rte_port_kni_writer_nodrop_params kni
;
421 struct rte_port_sym_crypto_writer_nodrop_params sym_crypto
;
424 struct pipeline
*pipeline
;
428 memset(&p
, 0, sizeof(p
));
429 memset(&pp
, 0, sizeof(pp
));
430 memset(&pp_nodrop
, 0, sizeof(pp_nodrop
));
432 /* Check input params */
433 if ((pipeline_name
== NULL
) ||
435 (params
->burst_size
== 0) ||
436 (params
->burst_size
> RTE_PORT_IN_BURST_SIZE_MAX
))
439 pipeline
= pipeline_find(pipeline_name
);
440 if (pipeline
== NULL
)
443 switch (params
->type
) {
448 link
= link_find(params
->dev_name
);
452 if (params
->txq
.queue_id
>= link
->n_txq
)
455 pp
.ethdev
.port_id
= link
->port_id
;
456 pp
.ethdev
.queue_id
= params
->txq
.queue_id
;
457 pp
.ethdev
.tx_burst_sz
= params
->burst_size
;
459 pp_nodrop
.ethdev
.port_id
= link
->port_id
;
460 pp_nodrop
.ethdev
.queue_id
= params
->txq
.queue_id
;
461 pp_nodrop
.ethdev
.tx_burst_sz
= params
->burst_size
;
462 pp_nodrop
.ethdev
.n_retries
= params
->n_retries
;
464 if (params
->retry
== 0) {
465 p
.ops
= &rte_port_ethdev_writer_ops
;
466 p
.arg_create
= &pp
.ethdev
;
468 p
.ops
= &rte_port_ethdev_writer_nodrop_ops
;
469 p
.arg_create
= &pp_nodrop
.ethdev
;
478 swq
= swq_find(params
->dev_name
);
482 pp
.ring
.ring
= swq
->r
;
483 pp
.ring
.tx_burst_sz
= params
->burst_size
;
485 pp_nodrop
.ring
.ring
= swq
->r
;
486 pp_nodrop
.ring
.tx_burst_sz
= params
->burst_size
;
487 pp_nodrop
.ring
.n_retries
= params
->n_retries
;
489 if (params
->retry
== 0) {
490 p
.ops
= &rte_port_ring_writer_ops
;
491 p
.arg_create
= &pp
.ring
;
493 p
.ops
= &rte_port_ring_writer_nodrop_ops
;
494 p
.arg_create
= &pp_nodrop
.ring
;
501 struct tmgr_port
*tmgr_port
;
503 tmgr_port
= tmgr_port_find(params
->dev_name
);
504 if (tmgr_port
== NULL
)
507 pp
.sched
.sched
= tmgr_port
->s
;
508 pp
.sched
.tx_burst_sz
= params
->burst_size
;
510 p
.ops
= &rte_port_sched_writer_ops
;
511 p
.arg_create
= &pp
.sched
;
519 tap
= tap_find(params
->dev_name
);
524 pp
.fd
.tx_burst_sz
= params
->burst_size
;
526 pp_nodrop
.fd
.fd
= tap
->fd
;
527 pp_nodrop
.fd
.tx_burst_sz
= params
->burst_size
;
528 pp_nodrop
.fd
.n_retries
= params
->n_retries
;
530 if (params
->retry
== 0) {
531 p
.ops
= &rte_port_fd_writer_ops
;
532 p
.arg_create
= &pp
.fd
;
534 p
.ops
= &rte_port_fd_writer_nodrop_ops
;
535 p
.arg_create
= &pp_nodrop
.fd
;
540 #ifdef RTE_LIBRTE_KNI
545 kni
= kni_find(params
->dev_name
);
550 pp
.kni
.tx_burst_sz
= params
->burst_size
;
552 pp_nodrop
.kni
.kni
= kni
->k
;
553 pp_nodrop
.kni
.tx_burst_sz
= params
->burst_size
;
554 pp_nodrop
.kni
.n_retries
= params
->n_retries
;
556 if (params
->retry
== 0) {
557 p
.ops
= &rte_port_kni_writer_ops
;
558 p
.arg_create
= &pp
.kni
;
560 p
.ops
= &rte_port_kni_writer_nodrop_ops
;
561 p
.arg_create
= &pp_nodrop
.kni
;
569 pp
.sink
.file_name
= params
->sink
.file_name
;
570 pp
.sink
.max_n_pkts
= params
->sink
.max_n_pkts
;
572 p
.ops
= &rte_port_sink_ops
;
573 p
.arg_create
= &pp
.sink
;
577 case PORT_OUT_CRYPTODEV
:
579 struct cryptodev
*cryptodev
;
581 cryptodev
= cryptodev_find(params
->dev_name
);
582 if (cryptodev
== NULL
)
585 if (params
->cryptodev
.queue_id
>= cryptodev
->n_queues
)
588 pp
.sym_crypto
.cryptodev_id
= cryptodev
->dev_id
;
589 pp
.sym_crypto
.queue_id
= params
->cryptodev
.queue_id
;
590 pp
.sym_crypto
.tx_burst_sz
= params
->burst_size
;
591 pp
.sym_crypto
.crypto_op_offset
= params
->cryptodev
.op_offset
;
593 pp_nodrop
.sym_crypto
.cryptodev_id
= cryptodev
->dev_id
;
594 pp_nodrop
.sym_crypto
.queue_id
= params
->cryptodev
.queue_id
;
595 pp_nodrop
.sym_crypto
.tx_burst_sz
= params
->burst_size
;
596 pp_nodrop
.sym_crypto
.n_retries
= params
->retry
;
597 pp_nodrop
.sym_crypto
.crypto_op_offset
=
598 params
->cryptodev
.op_offset
;
600 if (params
->retry
== 0) {
601 p
.ops
= &rte_port_sym_crypto_writer_ops
;
602 p
.arg_create
= &pp
.sym_crypto
;
604 p
.ops
= &rte_port_sym_crypto_writer_nodrop_ops
;
605 p
.arg_create
= &pp_nodrop
.sym_crypto
;
618 /* Resource create */
619 status
= rte_pipeline_port_out_create(pipeline
->p
,
627 pipeline
->n_ports_out
++;
632 static const struct rte_acl_field_def table_acl_field_format_ipv4
[] = {
635 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
636 .size
= sizeof(uint8_t),
639 .offset
= offsetof(struct ipv4_hdr
, next_proto_id
),
642 /* Source IP address (IPv4) */
644 .type
= RTE_ACL_FIELD_TYPE_MASK
,
645 .size
= sizeof(uint32_t),
648 .offset
= offsetof(struct ipv4_hdr
, src_addr
),
651 /* Destination IP address (IPv4) */
653 .type
= RTE_ACL_FIELD_TYPE_MASK
,
654 .size
= sizeof(uint32_t),
657 .offset
= offsetof(struct ipv4_hdr
, dst_addr
),
662 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
663 .size
= sizeof(uint16_t),
666 .offset
= sizeof(struct ipv4_hdr
) +
667 offsetof(struct tcp_hdr
, src_port
),
670 /* Destination Port */
672 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
673 .size
= sizeof(uint16_t),
676 .offset
= sizeof(struct ipv4_hdr
) +
677 offsetof(struct tcp_hdr
, dst_port
),
681 static const struct rte_acl_field_def table_acl_field_format_ipv6
[] = {
684 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
685 .size
= sizeof(uint8_t),
688 .offset
= offsetof(struct ipv6_hdr
, proto
),
691 /* Source IP address (IPv6) */
693 .type
= RTE_ACL_FIELD_TYPE_MASK
,
694 .size
= sizeof(uint32_t),
697 .offset
= offsetof(struct ipv6_hdr
, src_addr
[0]),
701 .type
= RTE_ACL_FIELD_TYPE_MASK
,
702 .size
= sizeof(uint32_t),
705 .offset
= offsetof(struct ipv6_hdr
, src_addr
[4]),
709 .type
= RTE_ACL_FIELD_TYPE_MASK
,
710 .size
= sizeof(uint32_t),
713 .offset
= offsetof(struct ipv6_hdr
, src_addr
[8]),
717 .type
= RTE_ACL_FIELD_TYPE_MASK
,
718 .size
= sizeof(uint32_t),
721 .offset
= offsetof(struct ipv6_hdr
, src_addr
[12]),
724 /* Destination IP address (IPv6) */
726 .type
= RTE_ACL_FIELD_TYPE_MASK
,
727 .size
= sizeof(uint32_t),
730 .offset
= offsetof(struct ipv6_hdr
, dst_addr
[0]),
734 .type
= RTE_ACL_FIELD_TYPE_MASK
,
735 .size
= sizeof(uint32_t),
738 .offset
= offsetof(struct ipv6_hdr
, dst_addr
[4]),
742 .type
= RTE_ACL_FIELD_TYPE_MASK
,
743 .size
= sizeof(uint32_t),
746 .offset
= offsetof(struct ipv6_hdr
, dst_addr
[8]),
750 .type
= RTE_ACL_FIELD_TYPE_MASK
,
751 .size
= sizeof(uint32_t),
754 .offset
= offsetof(struct ipv6_hdr
, dst_addr
[12]),
759 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
760 .size
= sizeof(uint16_t),
763 .offset
= sizeof(struct ipv6_hdr
) +
764 offsetof(struct tcp_hdr
, src_port
),
767 /* Destination Port */
769 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
770 .size
= sizeof(uint16_t),
773 .offset
= sizeof(struct ipv6_hdr
) +
774 offsetof(struct tcp_hdr
, dst_port
),
779 pipeline_table_create(const char *pipeline_name
,
780 struct table_params
*params
)
783 struct rte_pipeline_table_params p
;
786 struct rte_table_acl_params acl
;
787 struct rte_table_array_params array
;
788 struct rte_table_hash_params hash
;
789 struct rte_table_lpm_params lpm
;
790 struct rte_table_lpm_ipv6_params lpm_ipv6
;
793 struct pipeline
*pipeline
;
795 struct table_action_profile
*ap
;
796 struct rte_table_action
*action
;
800 memset(&p
, 0, sizeof(p
));
801 memset(&pp
, 0, sizeof(pp
));
803 /* Check input params */
804 if ((pipeline_name
== NULL
) ||
808 pipeline
= pipeline_find(pipeline_name
);
809 if ((pipeline
== NULL
) ||
810 (pipeline
->n_tables
>= RTE_PIPELINE_TABLE_MAX
))
814 if (params
->action_profile_name
) {
815 ap
= table_action_profile_find(params
->action_profile_name
);
820 snprintf(name
, NAME_MAX
, "%s_table%u",
821 pipeline_name
, pipeline
->n_tables
);
823 switch (params
->match_type
) {
826 uint32_t ip_header_offset
= params
->match
.acl
.ip_header_offset
-
827 (sizeof(struct rte_mbuf
) + RTE_PKTMBUF_HEADROOM
);
830 if (params
->match
.acl
.n_rules
== 0)
834 pp
.acl
.n_rules
= params
->match
.acl
.n_rules
;
835 if (params
->match
.acl
.ip_version
) {
836 memcpy(&pp
.acl
.field_format
,
837 &table_acl_field_format_ipv4
,
838 sizeof(table_acl_field_format_ipv4
));
839 pp
.acl
.n_rule_fields
=
840 RTE_DIM(table_acl_field_format_ipv4
);
842 memcpy(&pp
.acl
.field_format
,
843 &table_acl_field_format_ipv6
,
844 sizeof(table_acl_field_format_ipv6
));
845 pp
.acl
.n_rule_fields
=
846 RTE_DIM(table_acl_field_format_ipv6
);
849 for (i
= 0; i
< pp
.acl
.n_rule_fields
; i
++)
850 pp
.acl
.field_format
[i
].offset
+= ip_header_offset
;
852 p
.ops
= &rte_table_acl_ops
;
853 p
.arg_create
= &pp
.acl
;
859 if (params
->match
.array
.n_keys
== 0)
862 pp
.array
.n_entries
= params
->match
.array
.n_keys
;
863 pp
.array
.offset
= params
->match
.array
.key_offset
;
865 p
.ops
= &rte_table_array_ops
;
866 p
.arg_create
= &pp
.array
;
872 struct rte_table_ops
*ops
;
873 rte_table_hash_op_hash f_hash
;
875 if (params
->match
.hash
.n_keys
== 0)
878 switch (params
->match
.hash
.key_size
) {
880 f_hash
= rte_table_hash_crc_key8
;
883 f_hash
= rte_table_hash_crc_key16
;
886 f_hash
= rte_table_hash_crc_key24
;
889 f_hash
= rte_table_hash_crc_key32
;
892 f_hash
= rte_table_hash_crc_key40
;
895 f_hash
= rte_table_hash_crc_key48
;
898 f_hash
= rte_table_hash_crc_key56
;
901 f_hash
= rte_table_hash_crc_key64
;
908 pp
.hash
.key_size
= params
->match
.hash
.key_size
;
909 pp
.hash
.key_offset
= params
->match
.hash
.key_offset
;
910 pp
.hash
.key_mask
= params
->match
.hash
.key_mask
;
911 pp
.hash
.n_keys
= params
->match
.hash
.n_keys
;
912 pp
.hash
.n_buckets
= params
->match
.hash
.n_buckets
;
913 pp
.hash
.f_hash
= f_hash
;
916 if (params
->match
.hash
.extendable_bucket
)
917 switch (params
->match
.hash
.key_size
) {
919 ops
= &rte_table_hash_key8_ext_ops
;
922 ops
= &rte_table_hash_key16_ext_ops
;
925 ops
= &rte_table_hash_ext_ops
;
928 switch (params
->match
.hash
.key_size
) {
930 ops
= &rte_table_hash_key8_lru_ops
;
933 ops
= &rte_table_hash_key16_lru_ops
;
936 ops
= &rte_table_hash_lru_ops
;
940 p
.arg_create
= &pp
.hash
;
946 if (params
->match
.lpm
.n_rules
== 0)
949 switch (params
->match
.lpm
.key_size
) {
953 pp
.lpm
.n_rules
= params
->match
.lpm
.n_rules
;
954 pp
.lpm
.number_tbl8s
= TABLE_LPM_NUMBER_TBL8
;
956 pp
.lpm
.entry_unique_size
= p
.action_data_size
+
957 sizeof(struct rte_pipeline_table_entry
);
958 pp
.lpm
.offset
= params
->match
.lpm
.key_offset
;
960 p
.ops
= &rte_table_lpm_ops
;
961 p
.arg_create
= &pp
.lpm
;
967 pp
.lpm_ipv6
.name
= name
;
968 pp
.lpm_ipv6
.n_rules
= params
->match
.lpm
.n_rules
;
969 pp
.lpm_ipv6
.number_tbl8s
= TABLE_LPM_NUMBER_TBL8
;
970 pp
.lpm_ipv6
.entry_unique_size
= p
.action_data_size
+
971 sizeof(struct rte_pipeline_table_entry
);
972 pp
.lpm_ipv6
.offset
= params
->match
.lpm
.key_offset
;
974 p
.ops
= &rte_table_lpm_ipv6_ops
;
975 p
.arg_create
= &pp
.lpm_ipv6
;
988 p
.ops
= &rte_table_stub_ops
;
997 /* Resource create */
999 p
.f_action_hit
= NULL
;
1000 p
.f_action_miss
= NULL
;
1004 action
= rte_table_action_create(ap
->ap
,
1009 status
= rte_table_action_table_params_get(
1013 ((p
.action_data_size
+
1014 sizeof(struct rte_pipeline_table_entry
)) >
1015 TABLE_RULE_ACTION_SIZE_MAX
)) {
1016 rte_table_action_free(action
);
1021 if (params
->match_type
== TABLE_LPM
) {
1022 if (params
->match
.lpm
.key_size
== 4)
1023 pp
.lpm
.entry_unique_size
= p
.action_data_size
+
1024 sizeof(struct rte_pipeline_table_entry
);
1026 if (params
->match
.lpm
.key_size
== 16)
1027 pp
.lpm_ipv6
.entry_unique_size
= p
.action_data_size
+
1028 sizeof(struct rte_pipeline_table_entry
);
1031 status
= rte_pipeline_table_create(pipeline
->p
,
1035 rte_table_action_free(action
);
1040 table
= &pipeline
->table
[pipeline
->n_tables
];
1041 memcpy(&table
->params
, params
, sizeof(*params
));
1044 TAILQ_INIT(&table
->rules
);
1045 table
->rule_default
= NULL
;
1047 pipeline
->n_tables
++;
1053 table_rule_find(struct table
*table
,
1054 struct table_rule_match
*match
)
1056 struct table_rule
*rule
;
1058 TAILQ_FOREACH(rule
, &table
->rules
, node
)
1059 if (memcmp(&rule
->match
, match
, sizeof(*match
)) == 0)
1066 table_rule_add(struct table
*table
,
1067 struct table_rule
*new_rule
)
1069 struct table_rule
*existing_rule
;
1071 existing_rule
= table_rule_find(table
, &new_rule
->match
);
1072 if (existing_rule
== NULL
)
1073 TAILQ_INSERT_TAIL(&table
->rules
, new_rule
, node
);
1075 TAILQ_INSERT_AFTER(&table
->rules
, existing_rule
, new_rule
, node
);
1076 TAILQ_REMOVE(&table
->rules
, existing_rule
, node
);
1077 free(existing_rule
);
1082 table_rule_add_bulk(struct table
*table
,
1083 struct table_rule_list
*list
,
1088 for (i
= 0; i
< n_rules
; i
++) {
1089 struct table_rule
*existing_rule
, *new_rule
;
1091 new_rule
= TAILQ_FIRST(list
);
1092 if (new_rule
== NULL
)
1095 TAILQ_REMOVE(list
, new_rule
, node
);
1097 existing_rule
= table_rule_find(table
, &new_rule
->match
);
1098 if (existing_rule
== NULL
)
1099 TAILQ_INSERT_TAIL(&table
->rules
, new_rule
, node
);
1101 TAILQ_INSERT_AFTER(&table
->rules
, existing_rule
, new_rule
, node
);
1102 TAILQ_REMOVE(&table
->rules
, existing_rule
, node
);
1103 free(existing_rule
);
1109 table_rule_delete(struct table
*table
,
1110 struct table_rule_match
*match
)
1112 struct table_rule
*rule
;
1114 rule
= table_rule_find(table
, match
);
1118 TAILQ_REMOVE(&table
->rules
, rule
, node
);
1123 table_rule_default_add(struct table
*table
,
1124 struct table_rule
*rule
)
1126 free(table
->rule_default
);
1127 table
->rule_default
= rule
;
1131 table_rule_default_delete(struct table
*table
)
1133 free(table
->rule_default
);
1134 table
->rule_default
= NULL
;