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;