VNFs: Fixing klocwork issue in VNFs code
[samplevnf.git] / VNFs / vACL / pipeline / pipeline_acl.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 /**
18  * @file
19  * Pipeline ACL FE Implementation.
20  *
21  * Implementation of the Pipeline ACL Front End (FE).
22  * Runs on the Master pipeline, responsible for CLI commands.
23  *
24  */
25
26 #include <stdio.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/queue.h>
31 #include <netinet/in.h>
32
33 #include <rte_common.h>
34 #include <rte_hexdump.h>
35 #include <rte_malloc.h>
36 #include <cmdline_rdline.h>
37 #include <cmdline_parse.h>
38 #include <cmdline_parse_num.h>
39 #include <cmdline_parse_string.h>
40 #include <cmdline_parse_ipaddr.h>
41 #include <cmdline_parse_etheraddr.h>
42 #include <cmdline_socket.h>
43 #include <cmdline.h>
44 #include <rte_table_acl.h>
45
46 #include "app.h"
47 #include "pipeline_common_fe.h"
48 #include "pipeline_acl.h"
49 #include "pipeline_acl_be.h"
50 #include "rte_cnxn_tracking.h"
51
52 int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
53 int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
54 int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata);
55 uint32_t rules_loaded = 0;
56 extern struct cmdline *pipe_cl;
57 struct app_params *myapp;
58
59 /**
60  * A structure defining the ACL rule for the TAILQ Tables.
61  */
62 struct app_pipeline_acl_rule {
63         struct pipeline_acl_key key;
64         int32_t priority;
65         uint32_t port_id;
66         uint32_t action_id;
67         uint32_t command;
68         void *entry_ptr;
69
70          TAILQ_ENTRY(app_pipeline_acl_rule) node;
71 };
72
73 /**
74  * A structure defining the ACL pipeline front end data.
75  */
76 struct app_pipeline_acl {
77         /* parameters */
78         uint32_t n_ports_in;
79         uint32_t n_ports_out;
80
81 };
82
83 /*
84  * Define a structure to calculate performance measurements for ACL.
85  * ACL continually updates counters for total number of packets
86  * processed, and total number of bytes processed. Each ACL backend thread
87  * i.e. the packet processing instances updates their own copy of these counters
88  * An optional, 1 second periodic timer fires on the master core, which combines
89  * those numbers to perform byte and packet per second calculations, without
90  * burdening the packet processors.
91  */
92 #define RTE_ACL_PERF_MSR_BUFF_SIZE 8    /* must be power of 2 */
93 #define RTE_ACL_PERF_MSR_BUFF_SIZE_MASK (RTE_ACL_PERF_MSR_BUFF_SIZE - 1)
94
95 /**
96  * A structure defining the ACL performance measurements.
97  */
98 struct rte_acl_performance_measures_t {
99         /* two circular buffers */
100         uint64_t total_packets[RTE_ACL_PERF_MSR_BUFF_SIZE];
101         uint64_t total_bytes[RTE_ACL_PERF_MSR_BUFF_SIZE];
102         uint32_t bytes_last_second;
103         uint32_t ave_bytes_per_second;
104         uint32_t pkts_last_second;
105         uint32_t ave_pkts_per_second;
106         uint64_t total_entries;
107         /* times data has been (over-)written into buffers */
108         uint8_t current_index;  /* for circular buffers */
109 };
110
111 struct rte_acl_performance_measures_t rte_acl_performance_measures;
112
113 /*
114  * Active and Standby Tables
115  * Active and standby tables exist to allow modifying ACL rules and
116  * actions and having no impact on the packet processing running on
117  * the multiple ACL threads/pipelines. The packet processing does a
118  * lookup on the active tables. Each ACL thread/pipeline runs on
119  * a separate core (i.e. 2,3,4, etc).
120  *
121  * All CLI actions run on the ACL Front End (FE) code on Core 0.
122  * All changes, adding/delete rules and action occurs on the standby tables.
123  * In activate the changes in the standby table, the CLI command is entered:
124  * p acl applyruleset
125  *
126  * The standby tables become active. The active table becomes the standby.
127  * The new standby table gets updated with the changes that were done.
128  *
129  * Table descriptions:
130  * ACL Rule Tables TAILQ - 2 global tables active/standby per ipv4,ipv6
131  * The TAILQ tables are required for the LS CLI command and in order
132  * to do a lookup using a rule when adding or deleting a rule.
133  * The ACL TRIE tables in DPDK do not allow this type of listing or lookup.
134  *
135  * ACL Rule Tables TRIE - 2 global tables active/standby per ipv4, ipv6
136  * The TRIE tables are the tables used during packet processing.
137  * A bulk lookup can be performed by passing in a burst of packets.
138  * Unfortunately, the current implementation of the TRIE tables does
139  * not allow lookup using a rule. Hence the need for the TAILQ tables.
140  *
141  * ACL Action Tables ARRAY - 2 global tables active/standby
142  * The action tables stores the ACL actions.
143  * Every rule has an action id which defines what action to take
144  * when a packet matching that rule is received.
145  * Actions: accept, drop, fwd, count, nat, dscp, conntrack
146  *
147  * Command Table TAILQ - 1 table
148  * After the active and standby tables are swithover, the new standby
149  * table needs to be updated with all the changes that were done.
150  * This table stores all the add and delete commands and updates
151  * the new standby table when the applyruleset command executes.
152  *
153  * The active and standby tables can be displayed individually:
154  * p acl ls 0    <== active ACL rules
155  * p acl ls 1    <== standby ACL rules
156  * p action ls 0 <== active ACL actions
157  * p action ls 1 <== standby ACL actions
158  */
159
160 /* Only create global ACL tables once */
161 int acl_rule_table_created;
162
163 /*
164  * ACL Rule Tables TAILQ - see description above
165  * Two tables/counters are required for active and standby.
166  * The A and B tables/counters are the actual instances.
167  * The pointers are set to point to these tables/counters.
168  * The pointers are updated during the switchover for the applyruleset.
169  */
170
171 /* Definition of the the TAILQ table */
172 TAILQ_HEAD(app_pipeline_acl_rule_type, app_pipeline_acl_rule);
173 /* Instances of tables and counters */
174 struct app_pipeline_acl_rule_type acl_tailq_rules_ipv4a;
175 struct app_pipeline_acl_rule_type acl_tailq_rules_ipv4b;
176 struct app_pipeline_acl_rule_type acl_tailq_rules_ipv6a;
177 struct app_pipeline_acl_rule_type acl_tailq_rules_ipv6b;
178 uint32_t acl_n_tailq_rules_ipv4a;
179 uint32_t acl_n_tailq_rules_ipv6a;
180 uint32_t acl_n_tailq_rules_ipv4b;
181 uint32_t acl_n_tailq_rules_ipv6b;
182 /* Pointers to tables and counters for switchover in applyruleset */
183 struct app_pipeline_acl_rule_type *acl_tailq_rules_ipv4_active;
184 struct app_pipeline_acl_rule_type *acl_tailq_rules_ipv4_standby;
185 struct app_pipeline_acl_rule_type *acl_tailq_rules_ipv6_active;
186 struct app_pipeline_acl_rule_type *acl_tailq_rules_ipv6_standby;
187 struct app_pipeline_acl_rule_type *acl_tailq_rules_temp_ptr;
188 uint32_t *acl_n_tailq_rules_ipv4_active;
189 uint32_t *acl_n_tailq_rules_ipv4_standby;
190 uint32_t *acl_n_tailq_rules_ipv6_active;
191 uint32_t *acl_n_tailq_rules_ipv6_standby;
192
193 /* ACL commands to update new standby tables after switchover */
194 TAILQ_HEAD(, app_pipeline_acl_rule) acl_commands;
195
196 /* ACL IPV4 and IPV6 enable flags for debugging (Default both on) */
197 int acl_ipv4_enabled = 1;
198 int acl_ipv6_enabled = 1;
199
200 /* Number of ACL Rules, default 4 * 1024 */
201 uint32_t acl_n_rules = 4 * 1024;
202 /* ACL Rule Table TRIE - 2 (Active, Standby) Global table per ipv4, ipv6 */
203 void *acl_rule_table_ipv4_active;
204 void *acl_rule_table_ipv4_standby;
205 void *acl_rule_table_ipv6_active;
206 void *acl_rule_table_ipv6_standby;
207
208 /**
209  * Reset running averages for performance measurements.
210  *
211  */
212 static void rte_acl_reset_running_averages(void)
213 {
214         memset(&rte_acl_performance_measures, 0,
215                sizeof(rte_acl_performance_measures));
216 };
217
218 /**
219  * Compute performance calculations on master to reduce computing on
220  * packet processor.
221  *
222  * @param total_bytes
223  *  Total bytes processed during this interval.
224  * @param total_packets
225  *  Total packets processed during this interval.
226  *
227  */
228 static void rte_acl_update_performance_measures(uint64_t total_bytes,
229                                                 uint64_t total_packets)
230 {
231         /* make readable */
232         struct rte_acl_performance_measures_t *pm =
233             &rte_acl_performance_measures;
234
235         if (unlikely(pm->total_entries == 0 && total_packets == 0))
236 /* the timer is running, but no traffic started yet, so do nothing */
237                 return;
238
239         if (likely(pm->total_entries > 0)) {
240                 uint8_t oldest_index;
241                 uint8_t divisor;
242
243                 pm->bytes_last_second =
244                     total_bytes - pm->total_bytes[pm->current_index];
245                 pm->pkts_last_second =
246                     total_packets - pm->total_packets[pm->current_index];
247
248                 /* if total_entries zero, current_index must remain as zero */
249                 pm->current_index =
250                     (pm->current_index + 1) & RTE_ACL_PERF_MSR_BUFF_SIZE_MASK;
251
252                 if (unlikely(pm->total_entries <= RTE_ACL_PERF_MSR_BUFF_SIZE)) {
253                         /* oldest value is at element 0 */
254                         oldest_index = 0;
255                         divisor = pm->total_entries;
256                         /* note, prior to incrementing total_entries */
257                 } else {
258                         /* oldest value is at element about to be overwritten */
259                         oldest_index = pm->current_index;
260                         divisor = RTE_ACL_PERF_MSR_BUFF_SIZE;
261                 }
262
263                 pm->ave_bytes_per_second =
264                     (total_bytes - pm->total_bytes[oldest_index]) / divisor;
265                 pm->ave_pkts_per_second =
266                     (total_packets - pm->total_packets[oldest_index]) / divisor;
267         }
268
269         pm->total_bytes[pm->current_index] = total_bytes;
270         pm->total_packets[pm->current_index] = total_packets;
271         pm->total_entries++;
272 }
273
274 /**
275  * Combine data from all acl+connection tracking instances.
276  * Calculate various statistics. Dump to console.
277  *
278  */
279 static void rte_acl_sum_and_print_counters(void)
280 {
281         int i;
282         struct rte_ACL_counter_block acl_counter_sums;
283         struct rte_CT_counter_block ct_counter_sums;
284         /* For ct instance with this fw instance */
285         struct rte_CT_counter_block *ct_counters;
286
287         memset(&acl_counter_sums, 0, sizeof(acl_counter_sums));
288         memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
289
290         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
291                 struct rte_ACL_counter_block *acl_ctrs =
292                     &rte_acl_counter_table[i];
293                 ct_counters = rte_acl_counter_table[i].ct_counters;
294
295                 printf
296             ("{\"ACL counters\" : {\"id\" : \"%s\", \"packets_processed\" : %"
297              PRIu64 ", \"bytes_processed\" : %" PRIu64
298              ", \"ct_packets_forwarded\" : %" PRIu64
299              ", \"ct_packets_dropped\" : %" PRIu64 "}}\n",
300              acl_ctrs->name, acl_ctrs->tpkts_processed,
301              acl_ctrs->bytes_processed, ct_counters->pkts_forwarded,
302              ct_counters->pkts_drop);
303
304                 /* sum ACL counters */
305                 acl_counter_sums.tpkts_processed += acl_ctrs->tpkts_processed;
306                 acl_counter_sums.bytes_processed += acl_ctrs->bytes_processed;
307                 acl_counter_sums.pkts_drop += acl_ctrs->pkts_drop;
308                 acl_counter_sums.pkts_received += acl_ctrs->pkts_received;
309                 acl_counter_sums.pkts_drop_ttl += acl_ctrs->pkts_drop_ttl;
310                 acl_counter_sums.pkts_drop_bad_size +=
311                     acl_ctrs->pkts_drop_bad_size;
312                 acl_counter_sums.pkts_drop_fragmented +=
313                     acl_ctrs->pkts_drop_fragmented;
314                 acl_counter_sums.pkts_drop_without_arp_entry +=
315                     acl_ctrs->pkts_drop_without_arp_entry;
316                 acl_counter_sums.sum_latencies += acl_ctrs->sum_latencies;
317                 acl_counter_sums.count_latencies += acl_ctrs->count_latencies;
318
319                 /* sum cnxn tracking counters */
320                 ct_counter_sums.current_active_sessions +=
321                     ct_counters->current_active_sessions;
322                 ct_counter_sums.sessions_activated +=
323                     ct_counters->sessions_activated;
324                 ct_counter_sums.sessions_closed += ct_counters->sessions_closed;
325                 ct_counter_sums.sessions_timedout +=
326                     ct_counters->sessions_timedout;
327                 ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
328                 ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
329                 ct_counter_sums.pkts_drop_invalid_conn +=
330                     ct_counters->pkts_drop_invalid_conn;
331                 ct_counter_sums.pkts_drop_invalid_state +=
332                     ct_counters->pkts_drop_invalid_state;
333                 ct_counter_sums.pkts_drop_invalid_rst +=
334                     ct_counters->pkts_drop_invalid_rst;
335                 ct_counter_sums.pkts_drop_outof_window +=
336                     ct_counters->pkts_drop_outof_window;
337         }
338
339         rte_acl_update_performance_measures(acl_counter_sums.bytes_processed,
340                                             acl_counter_sums.tpkts_processed);
341         uint64_t average_latency =
342             acl_counter_sums.count_latencies ==
343             0 ? 0 : acl_counter_sums.sum_latencies /
344             acl_counter_sums.count_latencies;
345
346         printf("{\"ACL sum counters\" : {"
347                "\"packets_last_sec\" : %" PRIu32
348                ", \"average_packets_per_sec\" : %" PRIu32
349                ", \"bytes_last_sec\" : %" PRIu32
350                ", \"average_bytes_per_sec\" : %" PRIu32
351                ", \"packets_processed\" : %" PRIu64 ", \"bytes_processed\" : %"
352                PRIu64 ", \"average_latency_in_clocks\" : %" PRIu64
353                ", \"ct_packets_forwarded\" : %" PRIu64
354                ", \"ct_packets_dropped\" : %" PRIu64 ", \"drops\" : {"
355                "\"TTL_zero\" : %" PRIu64 ", \"bad_size\" : %" PRIu64
356                ", \"fragmented_packet\" : %" PRIu64 ", \"no_arp_entry\" : %"
357                PRIu64 "}, \"ct_sessions\" : {" "\"active\" : %" PRIu64
358                ", \"open\" : %" PRIu64 ", \"closed\" : %" PRIu64
359                ", \"timeout\" : %" PRIu64 "}, \"ct_drops\" : {"
360                "\"out_of_window\" : %" PRIu64 ", \"invalid_conn\" : %" PRIu64
361                ", \"invalid_state_transition\" : %" PRIu64 " \"RST\" : %" PRIu64
362                "}}}\n", rte_acl_performance_measures.pkts_last_second,
363                rte_acl_performance_measures.ave_pkts_per_second,
364                rte_acl_performance_measures.bytes_last_second,
365                rte_acl_performance_measures.ave_bytes_per_second,
366                acl_counter_sums.tpkts_processed,
367                acl_counter_sums.bytes_processed, average_latency,
368                ct_counter_sums.pkts_forwarded, ct_counter_sums.pkts_drop,
369                acl_counter_sums.pkts_drop_ttl,
370                acl_counter_sums.pkts_drop_bad_size,
371                acl_counter_sums.pkts_drop_fragmented,
372                acl_counter_sums.pkts_drop_without_arp_entry,
373                ct_counter_sums.current_active_sessions,
374                ct_counter_sums.sessions_activated,
375                ct_counter_sums.sessions_closed,
376                ct_counter_sums.sessions_timedout,
377                ct_counter_sums.pkts_drop_outof_window,
378                ct_counter_sums.pkts_drop_invalid_conn,
379                ct_counter_sums.pkts_drop_invalid_state,
380                ct_counter_sums.pkts_drop_invalid_rst);
381
382 }
383
384 /**
385  * Callback routine for 1 second, periodic timer.
386  *
387  * @param rt
388  *  A pointer to the rte_timer.
389  * @param arg
390  *  A pointer to application specific arguments (not used).
391  *
392  * @return
393  *  0 on success and port_id is filled, negative on error.
394  */
395 void rte_dump_acl_counters_from_master(struct rte_timer *rt, void *arg)
396 {
397         rte_acl_sum_and_print_counters();
398 }
399
400 int rte_acl_hertz_computed;     /* only launch timer once */
401 uint64_t rte_acl_ticks_in_one_second;
402 /* TODO: is processor hertz computed/stored elsewhere? */
403 struct rte_timer rte_acl_one_second_timer = RTE_TIMER_INITIALIZER;
404
405 /**
406  * Print IPv4 Rule.
407  *
408  * @param rule
409  *  A pointer to the rule.
410  *
411  */
412 static void print_acl_ipv4_rule(struct app_pipeline_acl_rule *rule)
413 {
414         printf("Prio = %" PRId32 " (SA = %" PRIu32 ".%" PRIu32
415                ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 ", DA = %"
416                PRIu32 ".%" PRIu32
417                ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 ", SP = %"
418                PRIu32 "-%" PRIu32 ", DP = %"
419                PRIu32 "-%" PRIu32 ", Proto = %"
420                PRIu32 " / 0x%" PRIx32 ") => Action ID = %"
421                PRIu32 " (entry ptr = %p)\n",
422                rule->priority,
423                (rule->key.key.ipv4_5tuple.src_ip >> 24) & 0xFF,
424                (rule->key.key.ipv4_5tuple.src_ip >> 16) & 0xFF,
425                (rule->key.key.ipv4_5tuple.src_ip >> 8) & 0xFF,
426                rule->key.key.ipv4_5tuple.src_ip & 0xFF,
427                rule->key.key.ipv4_5tuple.src_ip_mask,
428                (rule->key.key.ipv4_5tuple.dst_ip >> 24) & 0xFF,
429                (rule->key.key.ipv4_5tuple.dst_ip >> 16) & 0xFF,
430                (rule->key.key.ipv4_5tuple.dst_ip >> 8) & 0xFF,
431                rule->key.key.ipv4_5tuple.dst_ip & 0xFF,
432                rule->key.key.ipv4_5tuple.dst_ip_mask,
433                rule->key.key.ipv4_5tuple.src_port_from,
434                rule->key.key.ipv4_5tuple.src_port_to,
435                rule->key.key.ipv4_5tuple.dst_port_from,
436                rule->key.key.ipv4_5tuple.dst_port_to,
437                rule->key.key.ipv4_5tuple.proto,
438                rule->key.key.ipv4_5tuple.proto_mask,
439                rule->action_id, rule->entry_ptr);
440 }
441
442 /**
443  * Print IPv6 Rule.
444  *
445  * @param rule
446  *  A pointer to the rule.
447  *
448  */
449 static void print_acl_ipv6_rule(struct app_pipeline_acl_rule *rule)
450 {
451         printf("Prio = %" PRId32 " (SA = %02" PRIx8 "%02" PRIx8
452                ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8
453                ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8
454                ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8
455                ":%02" PRIx8 "%02" PRIx8 "/" "%" PRIu32 ", DA = %02"
456                PRIx8 "%02" PRIx8 ":%02" PRIx8
457                "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8
458                "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8
459                "%02" PRIx8 ":%02" PRIx8 "%02" PRIx8 ":%02" PRIx8
460                "%02" PRIx8 "/" "%" PRIu32
461                ", " "SP = %" PRIu32 "-%" PRIu32 ", DP = %"
462                PRIu32 "-%" PRIu32 ", Proto = %"
463                PRIu32 " / 0x%" PRIx32 ") => Action ID = %"
464                PRIu32 " (entry ptr = %p)\n", rule->priority,
465                (rule->key.key.ipv6_5tuple.src_ip[0]),
466                (rule->key.key.ipv6_5tuple.src_ip[1]),
467                (rule->key.key.ipv6_5tuple.src_ip[2]),
468                (rule->key.key.ipv6_5tuple.src_ip[3]),
469                (rule->key.key.ipv6_5tuple.src_ip[4]),
470                (rule->key.key.ipv6_5tuple.src_ip[5]),
471                (rule->key.key.ipv6_5tuple.src_ip[6]),
472                (rule->key.key.ipv6_5tuple.src_ip[7]),
473                (rule->key.key.ipv6_5tuple.src_ip[8]),
474                (rule->key.key.ipv6_5tuple.src_ip[9]),
475                (rule->key.key.ipv6_5tuple.src_ip[10]),
476                (rule->key.key.ipv6_5tuple.src_ip[11]),
477                (rule->key.key.ipv6_5tuple.src_ip[12]),
478                (rule->key.key.ipv6_5tuple.src_ip[13]),
479                (rule->key.key.ipv6_5tuple.src_ip[14]),
480                (rule->key.key.ipv6_5tuple.src_ip[15]),
481                rule->key.key.ipv6_5tuple.src_ip_mask,
482                (rule->key.key.ipv6_5tuple.dst_ip[0]),
483                (rule->key.key.ipv6_5tuple.dst_ip[1]),
484                (rule->key.key.ipv6_5tuple.dst_ip[2]),
485                (rule->key.key.ipv6_5tuple.dst_ip[3]),
486                (rule->key.key.ipv6_5tuple.dst_ip[4]),
487                (rule->key.key.ipv6_5tuple.dst_ip[5]),
488                (rule->key.key.ipv6_5tuple.dst_ip[6]),
489                (rule->key.key.ipv6_5tuple.dst_ip[7]),
490                (rule->key.key.ipv6_5tuple.dst_ip[8]),
491                (rule->key.key.ipv6_5tuple.dst_ip[9]),
492                (rule->key.key.ipv6_5tuple.dst_ip[10]),
493                (rule->key.key.ipv6_5tuple.dst_ip[11]),
494                (rule->key.key.ipv6_5tuple.dst_ip[12]),
495                (rule->key.key.ipv6_5tuple.dst_ip[13]),
496                (rule->key.key.ipv6_5tuple.dst_ip[14]),
497                (rule->key.key.ipv6_5tuple.dst_ip[15]),
498                rule->key.key.ipv6_5tuple.dst_ip_mask,
499                rule->key.key.ipv6_5tuple.src_port_from,
500                rule->key.key.ipv6_5tuple.src_port_to,
501                rule->key.key.ipv6_5tuple.dst_port_from,
502                rule->key.key.ipv6_5tuple.dst_port_to,
503                rule->key.key.ipv6_5tuple.proto,
504                rule->key.key.ipv6_5tuple.proto_mask, rule->action_id,
505                rule->entry_ptr);
506 }
507
508 /**
509  * Find an ACL rule.
510  * This function is used by the add and delete rule functions.
511  * Since all updates are done on the standby tables,
512  * only search the standby tables.
513  * Both IPv4 and IPv6 rules can be searched
514  *
515  * @param key
516  *  A pointer to the rule to be found.
517  *
518  * @return
519  *  - Pointer to the rule found.
520  *  - NULL if no rule found.
521  */
522 static struct app_pipeline_acl_rule *app_pipeline_acl_rule_find(struct
523                                                                 pipeline_acl_key
524                                                                 *key)
525 {
526         /*
527          * This function is used by the add and delete rule functions.
528          * Since all updates are done on the standby tables,
529          * only search the standby tables.
530          */
531
532         struct app_pipeline_acl_rule *r;
533
534         if (key->type == PIPELINE_ACL_IPV4_5TUPLE) {
535                 TAILQ_FOREACH(r, acl_tailq_rules_ipv4_standby, node)
536                 if (memcmp(key,
537                                &r->key, sizeof(struct pipeline_acl_key)) == 0)
538                         return r;
539         } else {                /* IPV6 */
540                 TAILQ_FOREACH(r, acl_tailq_rules_ipv6_standby, node)
541                 if (memcmp(key,
542                                &r->key, sizeof(struct pipeline_acl_key)) == 0)
543                         return r;
544         }
545
546         return NULL;
547 }
548
549 /**
550  * Display ACL Rules to the console.
551  * Rules from Active and standby tables can be dispayed.
552  * Both IPv4 and IPv6 will be displayed.
553  *
554  * @param app
555  *  A pointer to application specific data.
556  * @param active_standby_table
557  *  Specifies which table to display:
558  *    - active_rule_table (0)
559  *    - standby_rule_table (1)
560  *
561  */
562 static void
563 app_pipeline_acl_ls(struct app_params *app, uint32_t active_standby_table)
564 {
565         struct app_pipeline_acl_rule *rule;
566         uint32_t n_rules;
567         int priority;
568
569         if (active_standby_table == active_rule_table) {
570                 n_rules = *acl_n_tailq_rules_ipv4_active;
571                 if (n_rules > 0)
572                         printf("ACL Active Table IPV4 Rules\n");
573                 for (priority = 0; n_rules; priority++)
574                         TAILQ_FOREACH(rule, acl_tailq_rules_ipv4_active, node)
575                         if (rule->priority == priority) {
576                                 print_acl_ipv4_rule(rule);
577                                 n_rules--;
578                         }
579
580                 n_rules = *acl_n_tailq_rules_ipv6_active;
581                 if (n_rules > 0)
582                         printf("ACL Active Table IPV6 Rules\n");
583                 for (priority = 0; n_rules; priority++)
584                         TAILQ_FOREACH(rule, acl_tailq_rules_ipv6_active, node)
585                         if (rule->priority == priority) {
586                                 print_acl_ipv6_rule(rule);
587                                 n_rules--;
588                         }
589         } else {
590                 n_rules = *acl_n_tailq_rules_ipv4_standby;
591                 if (n_rules > 0)
592                         printf("ACL Standby Table IPV4 Rules\n");
593                 for (priority = 0; n_rules; priority++)
594                         TAILQ_FOREACH(rule, acl_tailq_rules_ipv4_standby, node)
595                         if (rule->priority == priority) {
596                                 print_acl_ipv4_rule(rule);
597                                 n_rules--;
598                         }
599
600                 n_rules = *acl_n_tailq_rules_ipv6_standby;
601                 if (n_rules > 0)
602                         printf("ACL Standby Table IPV6a Rules\n");
603                 for (priority = 0; n_rules; priority++)
604                         TAILQ_FOREACH(rule, acl_tailq_rules_ipv6_standby, node)
605                         if (rule->priority == priority) {
606                                 print_acl_ipv6_rule(rule);
607                                 n_rules--;
608                         }
609         }
610         printf("\n");
611 }
612
613 /**
614  * Initialize ACL pipeline Front End (FE).
615  *
616  * @param params
617  *  A pointer to pipeline parameters
618  * @param arg
619  *  A pointer to pipeline specific data (not used).
620  *
621  * @return
622  *  - A pointer to the pipeline FE
623  *  - NULL if initialization failed.
624  */
625 static void *app_pipeline_acl_init(struct pipeline_params *params,
626                                    __rte_unused void *arg)
627 {
628         struct app_pipeline_acl *p;
629         uint32_t size;
630
631         /* Check input arguments */
632         if ((params == NULL) ||
633             (params->n_ports_in == 0) || (params->n_ports_out == 0))
634                 return NULL;
635
636         /* Memory allocation */
637         size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_acl));
638         p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
639         if (p == NULL)
640                 return NULL;
641
642         /* Initialization */
643         p->n_ports_in = params->n_ports_in;
644         p->n_ports_out = params->n_ports_out;
645
646         if (!acl_rule_table_created) {
647 /* Only create and init once when first ACL pipeline/thread comes up */
648
649                 /* Init tailq tables */
650                 TAILQ_INIT(&acl_tailq_rules_ipv4a);
651                 acl_n_tailq_rules_ipv4a = 0;
652                 TAILQ_INIT(&acl_tailq_rules_ipv4b);
653                 acl_n_tailq_rules_ipv4b = 0;
654                 TAILQ_INIT(&acl_tailq_rules_ipv6a);
655                 acl_n_tailq_rules_ipv6a = 0;
656                 TAILQ_INIT(&acl_tailq_rules_ipv6b);
657                 acl_n_tailq_rules_ipv6b = 0;
658                 TAILQ_INIT(&acl_commands);
659                 acl_tailq_rules_ipv4_active = &acl_tailq_rules_ipv4a;
660                 acl_tailq_rules_ipv4_standby = &acl_tailq_rules_ipv4b;
661                 acl_tailq_rules_ipv6_active = &acl_tailq_rules_ipv6a;
662                 acl_tailq_rules_ipv6_standby = &acl_tailq_rules_ipv6b;
663                 acl_n_tailq_rules_ipv4_active = &acl_n_tailq_rules_ipv4a;
664                 acl_n_tailq_rules_ipv4_standby = &acl_n_tailq_rules_ipv4b;
665                 acl_n_tailq_rules_ipv6_active = &acl_n_tailq_rules_ipv6a;
666                 acl_n_tailq_rules_ipv6_standby = &acl_n_tailq_rules_ipv6b;
667
668                 /* Both IPV4 and IPV6 enabled by default */
669                 acl_ipv4_enabled = 1;
670                 acl_ipv6_enabled = 1;
671
672                 printf("ACL FE Init Create ACL Tables acl_n_rules = %i\n",
673                        acl_n_rules);
674
675                 /* Init Action Array and Counter Table */
676                 action_array_size =
677                     RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_action_key) *
678                                            action_array_max);
679                 action_array_a =
680                     rte_zmalloc(NULL, action_array_size, RTE_CACHE_LINE_SIZE);
681                 if (action_array_a == NULL)
682                         return NULL;
683                 action_array_b =
684                     rte_zmalloc(NULL, action_array_size, RTE_CACHE_LINE_SIZE);
685                 if (action_array_b == NULL)
686                         return NULL;
687                 memset(action_array_a, 0, action_array_size);
688                 memset(action_array_b, 0, action_array_size);
689                 action_array_active = action_array_a;
690                 action_array_standby = action_array_b;
691                 memset(&action_counter_table, 0, sizeof(action_counter_table));
692
693                 acl_rule_table_created = 1;
694         }
695
696         if (!rte_acl_hertz_computed) {
697 /* all initialization serialized on core 0, so no need for lock */
698                 rte_acl_ticks_in_one_second = rte_get_tsc_hz();
699                 rte_acl_hertz_computed = 1;
700         }
701
702         return (void *)p;
703 }
704
705 /**
706  * Free ACL pipeline resources.
707  *
708  * @param pipeline
709  *  A pointer to the pipeline to delete.
710  *
711  * @return
712  *  0 on success, negative on error.
713  */
714 static int app_pipeline_acl_free(void *pipeline)
715 {
716         struct app_pipeline_acl *p = pipeline;
717
718         /* Check input arguments */
719         if (p == NULL)
720                 return -1;
721
722         /* Free resources */
723         /* Ignore Klockwork infinite loop issues for all while loops */
724         while (!TAILQ_EMPTY(&acl_tailq_rules_ipv4a)) {
725                 struct app_pipeline_acl_rule *rule;
726
727                 rule = TAILQ_FIRST(&acl_tailq_rules_ipv4a);
728                 TAILQ_REMOVE(&acl_tailq_rules_ipv4a, rule, node);
729                 rte_free(rule);
730         }
731         while (!TAILQ_EMPTY(&acl_tailq_rules_ipv4b)) {
732                 struct app_pipeline_acl_rule *rule;
733
734                 rule = TAILQ_FIRST(&acl_tailq_rules_ipv4b);
735                 TAILQ_REMOVE(&acl_tailq_rules_ipv4b, rule, node);
736                 rte_free(rule);
737         }
738         while (!TAILQ_EMPTY(&acl_tailq_rules_ipv6a)) {
739                 struct app_pipeline_acl_rule *rule;
740
741                 rule = TAILQ_FIRST(&acl_tailq_rules_ipv6a);
742                 TAILQ_REMOVE(&acl_tailq_rules_ipv6a, rule, node);
743                 rte_free(rule);
744         }
745         while (!TAILQ_EMPTY(&acl_tailq_rules_ipv6b)) {
746                 struct app_pipeline_acl_rule *rule;
747
748                 rule = TAILQ_FIRST(&acl_tailq_rules_ipv6b);
749                 TAILQ_REMOVE(&acl_tailq_rules_ipv6b, rule, node);
750                 rte_free(rule);
751         }
752         while (!TAILQ_EMPTY(&acl_commands)) {
753                 struct app_pipeline_acl_rule *command;
754
755                 command = TAILQ_FIRST(&acl_commands);
756                 TAILQ_REMOVE(&acl_commands, command, node);
757                 rte_free(command);
758         }
759         rte_free(action_array_a);
760         rte_free(action_array_b);
761         rte_free(p);
762         return 0;
763 }
764
765 /**
766  * Verify that the ACL rule is valid.
767  * Both IPv4 and IPv6 rules
768  *
769  * @param key
770  *  A pointer to the ACL rule to verify.
771  *
772  * @return
773  *  0 on success, negative on error.
774  */
775 static int
776 app_pipeline_acl_key_check_and_normalize(struct pipeline_acl_key *key)
777 {
778         switch (key->type) {
779         case PIPELINE_ACL_IPV4_5TUPLE:
780                 {
781                         uint32_t src_ip_depth =
782                             key->key.ipv4_5tuple.src_ip_mask;
783                         uint32_t dst_ip_depth =
784                             key->key.ipv4_5tuple.dst_ip_mask;
785                         uint16_t src_port_from =
786                             key->key.ipv4_5tuple.src_port_from;
787                         uint16_t src_port_to = key->key.ipv4_5tuple.src_port_to;
788                         uint16_t dst_port_from =
789                             key->key.ipv4_5tuple.dst_port_from;
790                         uint16_t dst_port_to = key->key.ipv4_5tuple.dst_port_to;
791
792                         uint32_t src_ip_netmask = 0;
793                         uint32_t dst_ip_netmask = 0;
794
795                         if ((src_ip_depth > 32) ||
796                             (dst_ip_depth > 32) ||
797                             (src_port_from > src_port_to) ||
798                             (dst_port_from > dst_port_to))
799                                 return -1;
800
801                         if (src_ip_depth)
802                                 src_ip_netmask = (~0) << (32 - src_ip_depth);
803
804                         if (dst_ip_depth)
805                                 dst_ip_netmask = ((~0) << (32 - dst_ip_depth));
806
807                         key->key.ipv4_5tuple.src_ip &= src_ip_netmask;
808                         key->key.ipv4_5tuple.dst_ip &= dst_ip_netmask;
809
810                         return 0;
811                 }
812         case PIPELINE_ACL_IPV6_5TUPLE:
813                 {
814                         uint32_t src_ip_depth =
815                             key->key.ipv6_5tuple.src_ip_mask;
816                         uint32_t dst_ip_depth =
817                             key->key.ipv6_5tuple.dst_ip_mask;
818                         uint16_t src_port_from =
819                             key->key.ipv6_5tuple.src_port_from;
820                         uint16_t src_port_to = key->key.ipv6_5tuple.src_port_to;
821                         uint16_t dst_port_from =
822                             key->key.ipv6_5tuple.dst_port_from;
823                         uint16_t dst_port_to = key->key.ipv6_5tuple.dst_port_to;
824                         uint8_t src_ip_netmask[16];
825                         uint8_t dst_ip_netmask[16];
826                         int i;
827
828                         convert_prefixlen_to_netmask_ipv6(src_ip_depth,
829                                                           src_ip_netmask);
830                         convert_prefixlen_to_netmask_ipv6(dst_ip_depth,
831                                                           dst_ip_netmask);
832                         for (i = 0; i < 16; i++) {
833                                 key->key.ipv6_5tuple.src_ip[i] &=
834                                     src_ip_netmask[i];
835                                 key->key.ipv6_5tuple.dst_ip[i] &=
836                                     dst_ip_netmask[i];
837                         }
838                         return 0;
839                 }
840
841         default:
842                 return -1;
843         }
844 }
845
846 /**
847  * Add ACL rule to the ACL rule table.
848  * Rules are added standby table.
849  * Applyruleset command will activate the change.
850  * Both IPv4 and IPv6 rules can be added.
851  *
852  * @param app
853  *  A pointer to the ACL pipeline parameters.
854  * @param key
855  *  A pointer to the ACL rule to add.
856  * @param priority
857  *  Priority of the ACL rule.
858  * @param port_id
859  *  Port ID of the ACL rule.
860  * @param action_id
861  *  Action ID of the ACL rule. Defined in Action Table.
862  *
863  * @return
864  *  0 on success, negative on error.
865  */
866 int
867 app_pipeline_acl_add_rule(struct app_params *app,
868                           struct pipeline_acl_key *key,
869                           uint32_t priority,
870                           uint32_t port_id, uint32_t action_id)
871 {
872         struct app_pipeline_acl_rule *rule;
873         struct pipeline_acl_add_msg_rsp *rsp;
874         int new_rule, src_field_start, dst_field_start, i;
875         uint32_t *ip1, *ip2, *ip3, *ip4, src_mask, dest_mask;
876         uint32_t src_ip[IPV6_32BIT_LENGTH], dst_ip[IPV6_32BIT_LENGTH];
877         const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT;
878
879         struct rte_table_acl_rule_add_params params;
880         struct acl_table_entry entry = {
881                 .head = {
882                          .action = RTE_PIPELINE_ACTION_PORT,
883                          {.port_id = port_id},
884                          },
885                 .action_id = action_id,
886         };
887
888         memset(&params, 0, sizeof(params));
889
890         /* Check input arguments */
891         if ((app == NULL) ||
892             (key == NULL) || !((key->type == PIPELINE_ACL_IPV4_5TUPLE) ||
893                                (key->type == PIPELINE_ACL_IPV6_5TUPLE)))
894                 return -1;
895
896         if (action_id > action_array_max) {
897                 printf("Action ID greater than max\n");
898                 return -1;
899         }
900
901         if (app_pipeline_acl_key_check_and_normalize(key) != 0)
902                 return -1;
903
904         /* Find existing rule or allocate new rule */
905         rule = app_pipeline_acl_rule_find(key);
906         new_rule = (rule == NULL);
907         if (rule == NULL) {
908                 rule = rte_malloc(NULL, sizeof(*rule), RTE_CACHE_LINE_SIZE);
909
910                 if (rule == NULL)
911                         return -1;
912         }
913
914         /* Allocate Response */
915         rsp = app_msg_alloc(app);
916         if (rsp == NULL) {
917                 if (new_rule)
918                         rte_free(rule);
919                 return -1;
920         }
921
922         switch (key->type) {
923         case PIPELINE_ACL_IPV4_5TUPLE:
924                 params.priority = priority;
925                 params.field_value[0].value.u8 = key->key.ipv4_5tuple.proto;
926                 params.field_value[0].mask_range.u8 =
927                     key->key.ipv4_5tuple.proto_mask;
928                 params.field_value[1].value.u32 = key->key.ipv4_5tuple.src_ip;
929                 params.field_value[1].mask_range.u32 =
930                     key->key.ipv4_5tuple.src_ip_mask;
931                 params.field_value[2].value.u32 = key->key.ipv4_5tuple.dst_ip;
932                 params.field_value[2].mask_range.u32 =
933                     key->key.ipv4_5tuple.dst_ip_mask;
934                 params.field_value[3].value.u16 =
935                     key->key.ipv4_5tuple.src_port_from;
936                 params.field_value[3].mask_range.u16 =
937                     key->key.ipv4_5tuple.src_port_to;
938                 params.field_value[4].value.u16 =
939                     key->key.ipv4_5tuple.dst_port_from;
940                 params.field_value[4].mask_range.u16 =
941                     key->key.ipv4_5tuple.dst_port_to;
942
943                 rsp->status =
944                     rte_table_acl_ops.f_add(acl_rule_table_ipv4_standby,
945                                             &params,
946                                             (struct rte_pipeline_table_entry *)
947                                             &entry, &rsp->key_found,
948                                             (void **)&rsp->entry_ptr);
949
950                 if (rsp->status != 0)
951                         printf
952                     ("ACL IPV4 Add Rule Command failed key_found: %i\n",
953                              rsp->key_found);
954                 else
955                         printf
956                     ("ACL IPV4 Add Rule Command success key_found: %i\n",
957                              rsp->key_found);
958
959                 break;
960
961         case PIPELINE_ACL_IPV6_5TUPLE:
962                 ip1 = (uint32_t *) (key->key.ipv6_5tuple.src_ip);
963                 ip2 = ip1 + 1;
964                 ip3 = ip1 + 2;
965                 ip4 = ip1 + 3;
966
967                 params.priority = priority;
968                 params.field_value[0].value.u8 = key->key.ipv6_5tuple.proto;
969                 params.field_value[0].mask_range.u8 =
970                     key->key.ipv6_5tuple.proto_mask;
971
972                 src_ip[0] = rte_bswap32(*ip1);
973                 src_ip[1] = rte_bswap32(*ip2);
974                 src_ip[2] = rte_bswap32(*ip3);
975                 src_ip[3] = rte_bswap32(*ip4);
976
977                 src_mask = key->key.ipv6_5tuple.src_ip_mask;
978
979                 src_field_start = 1;
980                 for (i = 0; i != RTE_DIM(src_ip); i++, src_field_start++) {
981                         if (src_mask >= (i + 1) * nbu32)
982                                 params.field_value[src_field_start].
983                                     mask_range.u32 = nbu32;
984                         else
985                                 params.field_value[src_field_start].
986                                     mask_range.u32 =
987                                     src_mask >
988                                     (i * nbu32) ? src_mask - (i * 32) : 0;
989                         params.field_value[src_field_start].value.u32 =
990                             src_ip[i];
991                 }
992
993                 ip1 = (uint32_t *) (key->key.ipv6_5tuple.dst_ip);
994                 ip2 = ip1 + 1;
995                 ip3 = ip1 + 2;
996                 ip4 = ip1 + 3;
997
998                 dst_ip[0] = rte_bswap32(*ip1);
999                 dst_ip[1] = rte_bswap32(*ip2);
1000                 dst_ip[2] = rte_bswap32(*ip3);
1001                 dst_ip[3] = rte_bswap32(*ip4);
1002
1003                 dest_mask = key->key.ipv6_5tuple.dst_ip_mask;
1004
1005                 dst_field_start = 5;
1006                 for (i = 0; i != RTE_DIM(dst_ip); i++, dst_field_start++) {
1007                         if (dest_mask >= (i + 1) * nbu32)
1008                                 params.field_value[dst_field_start].
1009                                     mask_range.u32 = nbu32;
1010                         else
1011                                 params.field_value[dst_field_start].
1012                                     mask_range.u32 =
1013                                     dest_mask >
1014                                     (i * nbu32) ? dest_mask - (i * 32) : 0;
1015                         params.field_value[dst_field_start].value.u32 =
1016                             dst_ip[i];
1017                 }
1018
1019                 params.field_value[9].value.u16 =
1020                     key->key.ipv6_5tuple.src_port_from;
1021                 params.field_value[9].mask_range.u16 =
1022                     key->key.ipv6_5tuple.src_port_to;
1023                 params.field_value[10].value.u16 =
1024                     key->key.ipv6_5tuple.dst_port_from;
1025                 params.field_value[10].mask_range.u16 =
1026                     key->key.ipv6_5tuple.dst_port_to;
1027
1028                 rsp->status =
1029                     rte_table_acl_ops.f_add(acl_rule_table_ipv6_standby,
1030                                             &params,
1031                                             (struct rte_pipeline_table_entry *)
1032                                             &entry, &rsp->key_found,
1033                                             (void **)&rsp->entry_ptr);
1034
1035                 if (rsp->status != 0)
1036                         printf
1037                     ("ACL IPV6 Add Rule Command failed key_found: %i\n",
1038                              rsp->key_found);
1039                 else
1040                         printf
1041                     ("ACL IPV6 Add Rule Command success key_found: %i\n",
1042                              rsp->key_found);
1043
1044                 break;
1045
1046         default:
1047                 /* Error */
1048                 app_msg_free(app, rsp);
1049                 if (new_rule)
1050                         rte_free(rule);
1051                 return -1;
1052         }
1053
1054         /* Read response and write rule */
1055         if (rsp->status ||
1056             (rsp->entry_ptr == NULL) ||
1057             ((new_rule == 0) && (rsp->key_found == 0)) ||
1058             ((new_rule == 1) && (rsp->key_found == 1))) {
1059                 app_msg_free(app, rsp);
1060                 if (new_rule)
1061                         rte_free(rule);
1062                 return -1;
1063         }
1064
1065         memcpy(&rule->key, key, sizeof(*key));
1066         rule->priority = priority;
1067         rule->port_id = port_id;
1068         rule->action_id = action_id;
1069         rule->entry_ptr = rsp->entry_ptr;
1070
1071         /* Commit rule */
1072         if (new_rule) {
1073                 if (key->type == PIPELINE_ACL_IPV4_5TUPLE) {
1074                         TAILQ_INSERT_TAIL(acl_tailq_rules_ipv4_standby, rule,
1075                                           node);
1076                         (*acl_n_tailq_rules_ipv4_standby)++;
1077                 } else {        /* IPV6 */
1078                         TAILQ_INSERT_TAIL(acl_tailq_rules_ipv6_standby, rule,
1079                                           node);
1080                         (*acl_n_tailq_rules_ipv6_standby)++;
1081                 }
1082         }
1083
1084         if (key->type == PIPELINE_ACL_IPV4_5TUPLE)
1085                 print_acl_ipv4_rule(rule);
1086         else
1087                 print_acl_ipv6_rule(rule);
1088
1089         /* Free response */
1090         app_msg_free(app, rsp);
1091
1092         return 0;
1093 }
1094
1095 /**
1096  * Delete ACL rule from the ACL rule table.
1097  * Rules deleted from standby tables.
1098  * Applyruleset command will activate the change.
1099  * Both IPv4 and IPv6 rules can be deleted.
1100  *
1101  * @param app
1102  *  A pointer to the ACL pipeline parameters.
1103  * @param key
1104  *  A pointer to the ACL rule to delete.
1105  *
1106  * @return
1107  *  0 on success, negative on error.
1108  */
1109 int
1110 app_pipeline_acl_delete_rule(struct app_params *app,
1111                              struct pipeline_acl_key *key)
1112 {
1113         struct app_pipeline_acl_rule *rule;
1114         int status, key_found;
1115         uint32_t src_ip[IPV6_32BIT_LENGTH], dst_ip[IPV6_32BIT_LENGTH];
1116         int new_rule, src_field_start, dst_field_start, i;
1117         uint32_t *ip1, *ip2, *ip3, *ip4, src_mask, dest_mask;
1118         const uint32_t nbu32 = sizeof(uint32_t) * CHAR_BIT;
1119
1120
1121         struct rte_table_acl_rule_delete_params params;
1122
1123         memset(&params, 0, sizeof(params));
1124
1125         /* Check input arguments */
1126         if ((app == NULL) ||
1127             (key == NULL) || !((key->type == PIPELINE_ACL_IPV4_5TUPLE) ||
1128                                (key->type == PIPELINE_ACL_IPV6_5TUPLE)))
1129                 return -1;
1130
1131         if (app_pipeline_acl_key_check_and_normalize(key) != 0)
1132                 return -1;
1133
1134         /* Find rule */
1135         rule = app_pipeline_acl_rule_find(key);
1136         if (rule == NULL) {
1137                 printf("ACL Delete Rule - Rule does not exist\n");
1138                 return 0;
1139         }
1140
1141         switch (key->type) {
1142         case PIPELINE_ACL_IPV4_5TUPLE:
1143                 params.field_value[0].value.u8 = key->key.ipv4_5tuple.proto;
1144                 params.field_value[0].mask_range.u8 =
1145                     key->key.ipv4_5tuple.proto_mask;
1146                 params.field_value[1].value.u32 = key->key.ipv4_5tuple.src_ip;
1147                 params.field_value[1].mask_range.u32 =
1148                     key->key.ipv4_5tuple.src_ip_mask;
1149                 params.field_value[2].value.u32 = key->key.ipv4_5tuple.dst_ip;
1150                 params.field_value[2].mask_range.u32 =
1151                     key->key.ipv4_5tuple.dst_ip_mask;
1152                 params.field_value[3].value.u16 =
1153                     key->key.ipv4_5tuple.src_port_from;
1154                 params.field_value[3].mask_range.u16 =
1155                     key->key.ipv4_5tuple.src_port_to;
1156                 params.field_value[4].value.u16 =
1157                     key->key.ipv4_5tuple.dst_port_from;
1158                 params.field_value[4].mask_range.u16 =
1159                     key->key.ipv4_5tuple.dst_port_to;
1160
1161                 status = rte_table_acl_ops.f_delete(acl_rule_table_ipv4_standby,
1162                                                     &params, &key_found, NULL);
1163
1164                 if (status != 0)
1165                         printf
1166                     ("ACL IPV4 Del Rule Command failed key_found: %i\n",
1167                              key_found);
1168                 else
1169                         printf
1170                     ("ACL IPV4 Del Rule Command success key_found: %i\n",
1171                              key_found);
1172
1173                 break;
1174
1175         case PIPELINE_ACL_IPV6_5TUPLE:
1176                 ip1 = (uint32_t *) (key->key.ipv6_5tuple.src_ip);
1177                 ip2 = ip1 + 1;
1178                 ip3 = ip1 + 2;
1179                 ip4 = ip1 + 3;
1180
1181                 params.field_value[0].value.u8 = key->key.ipv6_5tuple.proto;
1182                 params.field_value[0].mask_range.u8 =
1183                     key->key.ipv6_5tuple.proto_mask;
1184
1185                 src_ip[0] = rte_bswap32(*ip1);
1186                 src_ip[1] = rte_bswap32(*ip2);
1187                 src_ip[2] = rte_bswap32(*ip3);
1188                 src_ip[3] = rte_bswap32(*ip4);
1189
1190                 src_mask = key->key.ipv6_5tuple.src_ip_mask;
1191
1192                 src_field_start = 1;
1193                 for (i = 0; i != RTE_DIM(src_ip); i++, src_field_start++) {
1194                         if (src_mask >= (i + 1) * nbu32)
1195                                 params.field_value[src_field_start].
1196                                     mask_range.u32 = nbu32;
1197                         else
1198                                 params.field_value[src_field_start].
1199                                     mask_range.u32 =
1200                                     src_mask >
1201                                     (i * nbu32) ? src_mask - (i * 32) : 0;
1202                         params.field_value[src_field_start].value.u32 =
1203                             src_ip[i];
1204                 }
1205
1206                 ip1 = (uint32_t *) (key->key.ipv6_5tuple.dst_ip);
1207                 ip2 = ip1 + 1;
1208                 ip3 = ip1 + 2;
1209                 ip4 = ip1 + 3;
1210
1211                 dst_ip[0] = rte_bswap32(*ip1);
1212                 dst_ip[1] = rte_bswap32(*ip2);
1213                 dst_ip[2] = rte_bswap32(*ip3);
1214                 dst_ip[3] = rte_bswap32(*ip4);
1215
1216                 dest_mask = key->key.ipv6_5tuple.dst_ip_mask;
1217
1218                 dst_field_start = 5;
1219                 for (i = 0; i != RTE_DIM(dst_ip); i++, dst_field_start++) {
1220                         if (dest_mask >= (i + 1) * nbu32)
1221                                 params.field_value[dst_field_start].
1222                                     mask_range.u32 = nbu32;
1223                         else
1224                                 params.field_value[dst_field_start].
1225                                     mask_range.u32 =
1226                                     dest_mask >
1227                                     (i * nbu32) ? dest_mask - (i * 32) : 0;
1228                         params.field_value[dst_field_start].value.u32 =
1229                             dst_ip[i];
1230                 }
1231
1232                 params.field_value[9].value.u16 =
1233                     key->key.ipv6_5tuple.src_port_from;
1234                 params.field_value[9].mask_range.u16 =
1235                     key->key.ipv6_5tuple.src_port_to;
1236                 params.field_value[10].value.u16 =
1237                     key->key.ipv6_5tuple.dst_port_from;
1238                 params.field_value[10].mask_range.u16 =
1239                     key->key.ipv6_5tuple.dst_port_to;
1240
1241
1242                 status = rte_table_acl_ops.f_delete(acl_rule_table_ipv6_standby,
1243                                                     &params, &key_found, NULL);
1244
1245                 if (status != 0)
1246                         printf
1247                     ("ACL IPV6 Del Rule Command failed key_found: %i\n",
1248                              key_found);
1249                 else
1250                         printf
1251                    ("ACL IPV6 Del Rule Command success key_found: %i\n",
1252                              key_found);
1253
1254                 break;
1255
1256         default:
1257                 /* Error */
1258                 return -1;
1259         }
1260
1261         /* Read response */
1262         if (status || !key_found)
1263                 return -1;
1264
1265         /* Remove rule */
1266         if (key->type == PIPELINE_ACL_IPV4_5TUPLE) {
1267                 TAILQ_REMOVE(acl_tailq_rules_ipv4_standby, rule, node);
1268                 (*acl_n_tailq_rules_ipv4_standby)--;
1269         } else {                /* IPV6 */
1270                 TAILQ_REMOVE(acl_tailq_rules_ipv6_standby, rule, node);
1271                 (*acl_n_tailq_rules_ipv6_standby)--;
1272         }
1273
1274         rte_free(rule);
1275
1276         return 0;
1277 }
1278
1279 /**
1280  * Clear all ACL rules from the ACL rule table.
1281  * Rules cleared from standby tables.
1282  * Applyruleset command will activate the change.
1283  * Both IPv4 and IPv6 rules will be cleared.
1284  *
1285  * @param app
1286  *  A pointer to the ACL pipeline parameters.
1287  *
1288  * @return
1289  *  0 on success, negative on error.
1290  */
1291 int app_pipeline_acl_clearrules(struct app_params *app)
1292 {
1293         struct app_pipeline_acl_rule *rule;
1294         struct app_pipeline_acl_rule *command;
1295         uint32_t n_rules;
1296
1297         int priority;
1298
1299         /* Check input arguments */
1300         if (app == NULL)
1301                 return -1;
1302
1303         n_rules = *acl_n_tailq_rules_ipv4_standby;
1304         for (priority = 0; n_rules; priority++) {
1305                 TAILQ_FOREACH(rule, acl_tailq_rules_ipv4_standby, node) {
1306                         if (rule->priority == priority) {
1307                                 struct pipeline_acl_key key = rule->key;
1308
1309                 /* Store command to update standby tables after switchover */
1310                                 command =
1311                                     rte_malloc(NULL, sizeof(*command),
1312                                                RTE_CACHE_LINE_SIZE);
1313                                 if (command == NULL) {
1314                                         printf("Cannot allocation command\n");
1315                                         return -1;
1316                                 }
1317                                 memset(command, 0,
1318                                        sizeof(struct app_pipeline_acl_rule));
1319                                 memcpy(&command->key, &key, sizeof(key));
1320                                 command->command = acl_delete_command;
1321                                 TAILQ_INSERT_TAIL(&acl_commands, command, node);
1322
1323                                 /* Delete rule */
1324                                 app_pipeline_acl_delete_rule(app, &key);
1325                                 n_rules--;
1326                         }
1327                 }
1328         }
1329
1330         n_rules = *acl_n_tailq_rules_ipv6_standby;
1331         for (priority = 0; n_rules; priority++) {
1332                 TAILQ_FOREACH(rule, acl_tailq_rules_ipv6_standby, node) {
1333                         if (rule->priority == priority) {
1334                                 struct pipeline_acl_key key = rule->key;
1335
1336         /* Store command to update standby tables after switchover */
1337                                 command =
1338                                     rte_malloc(NULL, sizeof(*command),
1339                                                RTE_CACHE_LINE_SIZE);
1340                                 if (command == NULL) {
1341                                         printf("Cannot allocation command\n");
1342                                         return -1;
1343                                 }
1344                                 memset(command, 0,
1345                                        sizeof(struct app_pipeline_acl_rule));
1346                                 memcpy(&command->key, &key, sizeof(key));
1347                                 command->command = acl_delete_command;
1348                                 TAILQ_INSERT_TAIL(&acl_commands, command, node);
1349
1350                                 /* Delete rule */
1351                                 app_pipeline_acl_delete_rule(app, &key);
1352                                 n_rules--;
1353                         }
1354                 }
1355         }
1356
1357         /* Clear Action Array */
1358         memset(action_array_standby, 0, action_array_size);
1359
1360         return 0;
1361 }
1362
1363 /*
1364  * loadrules
1365  */
1366
1367 /**
1368  * Open file and process all commands in the file.
1369  *
1370  * @param ctx
1371  *  A pointer to the CLI context
1372  * @param file_name
1373  *  A pointer to the file to process.
1374  *
1375  */
1376 static void app_loadrules_file(cmdline_parse_ctx_t *ctx, const char *file_name)
1377 {
1378         struct cmdline *file_cl;
1379         int fd;
1380
1381         fd = open(file_name, O_RDONLY);
1382         if (fd < 0) {
1383                 printf("Cannot open file \"%s\"\n", file_name);
1384                 return;
1385         }
1386
1387         file_cl = cmdline_new(ctx, "", fd, 1);
1388         cmdline_interact(file_cl);
1389         close(fd);
1390 }
1391
1392 struct cmd_loadrules_file_result {
1393         cmdline_fixed_string_t p_string;
1394         cmdline_fixed_string_t acl_string;
1395         cmdline_fixed_string_t loadrules_string;
1396         char file_name[APP_FILE_NAME_SIZE];
1397 };
1398
1399 /**
1400  * Parse load rules command.
1401  * Verify that file exists.
1402  * Clear existing rules and action.
1403  * Process commands in command file.
1404  *
1405  * @param parsed_result
1406  *  A pointer to the CLI command parsed result
1407  * @param cl
1408  *  A pointer to command line context.
1409  * @param data
1410  *  A pointer to command specific data.
1411  *
1412  * @return
1413  *  0 on success, negative on error.
1414  *
1415  */
1416 static void
1417 cmd_loadrules_parsed(void *parsed_result, struct cmdline *cl, void *data)
1418 {
1419         struct cmd_loadrules_file_result *params = parsed_result;
1420         struct app_params *app = data;
1421         int status;
1422         int fd;
1423
1424         /* Make sure the file exists before clearing rules and actions */
1425         fd = open(params->file_name, O_RDONLY);
1426         if (fd < 0) {
1427                 printf("Cannot open file \"%s\"\n", params->file_name);
1428                 return;
1429         }
1430         close(fd);
1431
1432         /* Clear all rules and actions */
1433         status = app_pipeline_acl_clearrules(app);
1434
1435         if (status != 0) {
1436                 printf("Command clearrules failed\n");
1437                 return;
1438         }
1439
1440         /* Process commands in script file */
1441         app_loadrules_file(cl->ctx, params->file_name);
1442 }
1443
1444 cmdline_parse_token_string_t cmd_loadrules_p_string =
1445 TOKEN_STRING_INITIALIZER(struct cmd_loadrules_file_result,
1446                          p_string, "p");
1447
1448 cmdline_parse_token_string_t cmd_loadrules_acl_string =
1449 TOKEN_STRING_INITIALIZER(struct cmd_loadrules_file_result,
1450                          acl_string, "acl");
1451
1452 cmdline_parse_token_string_t cmd_loadrules_loadrules_string =
1453 TOKEN_STRING_INITIALIZER(struct cmd_loadrules_file_result, loadrules_string,
1454                          "loadrules");
1455
1456 cmdline_parse_token_string_t cmd_loadrules_file_name =
1457 TOKEN_STRING_INITIALIZER(struct cmd_loadrules_file_result, file_name, NULL);
1458
1459 cmdline_parse_inst_t cmd_loadrules = {
1460         .f = cmd_loadrules_parsed,
1461         .data = NULL,
1462         .help_str = "ACL Load Rules",
1463         .tokens = {
1464                    (void *)&cmd_loadrules_p_string,
1465                    (void *)&cmd_loadrules_acl_string,
1466                    (void *)&cmd_loadrules_loadrules_string,
1467                    (void *)&cmd_loadrules_file_name,
1468                    NULL,
1469                    },
1470 };
1471
1472 /**
1473  * Add Action to the Action table.
1474  * Actions are added standby table.
1475  * Applyruleset command will activate the change.
1476  *
1477  * @param app
1478  *  A pointer to the ACL pipeline parameters.
1479  * @param key
1480  *  A pointer to the Action to add.
1481  *
1482  * @return
1483  *  0 on success, negative on error.
1484  */
1485 int
1486 app_pipeline_action_add(struct app_params *app, struct pipeline_action_key *key)
1487 {
1488
1489         /*
1490          * This function will update the action IDs on the standby table.
1491          * Activating the changes is done with the applyruleset command.
1492          */
1493
1494         uint32_t action_bitmap = key->action_bitmap;
1495         uint32_t action_id = key->action_id;
1496
1497         if (action_id >= action_array_max) {
1498                 if (ACL_DEBUG)
1499                         printf("Action id: %u out of range\n", action_id);
1500                 return -1;
1501         }
1502
1503         action_array_standby[action_id].action_id = action_id;
1504
1505         if (ACL_DEBUG)
1506                 printf("Adding action id: %u Type: ", action_id);
1507         if (action_bitmap == acl_action_packet_accept) {
1508                 action_array_standby[action_id].action_bitmap |=
1509                     acl_action_packet_accept;
1510                 if (ACL_DEBUG)
1511                         printf("Accept\n");
1512         }
1513         if (action_bitmap == acl_action_packet_drop) {
1514                 action_array_standby[action_id].action_bitmap |=
1515                     acl_action_packet_drop;
1516                 if (ACL_DEBUG)
1517                         printf("Drop\n");
1518         }
1519         if (action_bitmap == acl_action_nat) {
1520                 action_array_standby[action_id].action_bitmap |= acl_action_nat;
1521                 action_array_standby[action_id].nat_port = key->nat_port;
1522                 if (ACL_DEBUG)
1523                         printf("NAT  Port ID: %u\n", key->nat_port);
1524         }
1525         if (action_bitmap == acl_action_fwd) {
1526                 action_array_standby[action_id].action_bitmap |= acl_action_fwd;
1527                 action_array_standby[action_id].fwd_port = key->fwd_port;
1528                 if (ACL_DEBUG)
1529                         printf("FWD  Port ID: %u\n", key->fwd_port);
1530         }
1531         if (action_bitmap == acl_action_count) {
1532                 action_array_standby[action_id].action_bitmap |=
1533                     acl_action_count;
1534                 if (ACL_DEBUG)
1535                         printf("Count\n");
1536         }
1537         if (action_bitmap == acl_action_conntrack) {
1538                 action_array_standby[action_id].action_bitmap |=
1539                     acl_action_conntrack;
1540                 if (ACL_DEBUG)
1541                         printf("Conntrack\n");
1542         }
1543         if (action_bitmap == acl_action_connexist) {
1544                 action_array_standby[action_id].action_bitmap |=
1545                     acl_action_connexist;
1546                 action_array_standby[action_id].private_public =
1547                     key->private_public;
1548                 if (ACL_DEBUG)
1549                         printf("Conntrack   prvpub: %i\n", key->private_public);
1550         }
1551         if (action_bitmap == acl_action_dscp) {
1552                 action_array_standby[action_id].action_bitmap |=
1553                     acl_action_dscp;
1554                 action_array_standby[action_id].dscp_priority =
1555                     key->dscp_priority;
1556                 if (ACL_DEBUG)
1557                         printf("DSCP  Priority: %u\n", key->dscp_priority);
1558         }
1559
1560         if (ACL_DEBUG)
1561                 printf("action_bitmap: %" PRIu32 "\n",
1562                        action_array_standby[action_id].action_bitmap);
1563
1564         return 0;
1565 }
1566
1567 /**
1568  * Delete Action from the Action table.
1569  * Actions are deleted from the standby table.
1570  * Applyruleset command will activate the change.
1571  *
1572  * @param app
1573  *  A pointer to the ACL pipeline parameters.
1574  * @param key
1575  *  A pointer to the Action to delete.
1576  *
1577  * @return
1578  *  0 on success, negative on error.
1579  */
1580 int
1581 app_pipeline_action_delete(struct app_params *app,
1582                            struct pipeline_action_key *key)
1583 {
1584         /*
1585          * This function will update the action IDs on the standby table.
1586          * Activating the changes is done with the applyruleset command.
1587          */
1588
1589         uint32_t action_bitmap = key->action_bitmap;
1590         uint32_t action_id = key->action_id;
1591
1592         if (action_id >= action_array_max) {
1593                 if (ACL_DEBUG)
1594                         printf("Action id: %u out of range\n", action_id);
1595                 return -1;
1596         }
1597
1598         if (action_array_standby[action_id].action_bitmap & action_bitmap)
1599                 action_array_standby[action_id].action_bitmap &= ~action_bitmap;
1600         else
1601                 printf("ACL Action Delete - Action not set\n");
1602
1603         if (ACL_DEBUG) {
1604                 printf("Deleting action id: %u Type: ", key->action_id);
1605                 if (action_bitmap == acl_action_packet_accept)
1606                         printf("Accept\n");
1607                 if (action_bitmap == acl_action_packet_drop)
1608                         printf("Drop\n");
1609                 if (action_bitmap == acl_action_nat)
1610                         printf("NAT\n");
1611                 if (action_bitmap == acl_action_fwd)
1612                         printf("FWD\n");
1613                 if (action_bitmap == acl_action_count)
1614                         printf("Count\n");
1615                 if (action_bitmap == acl_action_conntrack)
1616                         printf("Conntrack\n");
1617                 if (action_bitmap == acl_action_connexist)
1618                         printf("Connexist\n");
1619                 if (action_bitmap == acl_action_dscp)
1620                         printf("DSCP\n");
1621
1622                 printf("action_bitmap: %" PRIu32 "\n",
1623                        action_array_standby[action_id].action_bitmap);
1624         }
1625
1626         return 0;
1627 }
1628
1629 /*
1630  * p acl add
1631  */
1632
1633 /**
1634  * A structure defining the ACL add rule command.
1635  */
1636 struct cmd_acl_add_ip_result {
1637         cmdline_fixed_string_t p_string;
1638         cmdline_fixed_string_t acl_string;
1639         cmdline_fixed_string_t add_string;
1640         int32_t priority;
1641         cmdline_ipaddr_t src_ip;
1642         uint32_t src_ip_mask;
1643         cmdline_ipaddr_t dst_ip;
1644         uint32_t dst_ip_mask;
1645         uint16_t src_port_from;
1646         uint16_t src_port_to;
1647         uint16_t dst_port_from;
1648         uint16_t dst_port_to;
1649         uint8_t proto;
1650         uint8_t proto_mask;
1651         uint8_t port_id;
1652         uint32_t action_id;
1653 };
1654
1655 /**
1656  * Parse ACL add rule CLI command.
1657  * Add rule to standby table.
1658  * Store command to update standby table
1659  * after applyruleset command is invoked.
1660  *
1661  * @param parsed_result
1662  *  A pointer to CLI command parsed result.
1663  * @param cl
1664  *  A pointer to command line context.
1665  * @param data
1666  *  A pointer to command specific data
1667  *
1668  */
1669 static void cmd_acl_add_ip_parsed(void *parsed_result, __attribute__ ((unused))
1670                                   struct cmdline *cl, void *data)
1671 {
1672         struct cmd_acl_add_ip_result *params = parsed_result;
1673         struct app_params *app = data;
1674         struct pipeline_acl_key key;
1675         struct app_pipeline_acl_rule *command;
1676         int status;
1677
1678         memset(&key, 0, sizeof(struct pipeline_acl_key));
1679
1680         if (params->src_ip.family == AF_INET) {
1681                 key.type = PIPELINE_ACL_IPV4_5TUPLE;
1682                 key.key.ipv4_5tuple.src_ip = rte_bswap32((uint32_t)
1683                                                          params->src_ip.
1684                                                          addr.ipv4.s_addr);
1685                 key.key.ipv4_5tuple.src_ip_mask = params->src_ip_mask;
1686                 key.key.ipv4_5tuple.dst_ip = rte_bswap32((uint32_t)
1687                                                          params->dst_ip.
1688                                                          addr.ipv4.s_addr);
1689                 key.key.ipv4_5tuple.dst_ip_mask = params->dst_ip_mask;
1690                 key.key.ipv4_5tuple.src_port_from = params->src_port_from;
1691                 key.key.ipv4_5tuple.src_port_to = params->src_port_to;
1692                 key.key.ipv4_5tuple.dst_port_from = params->dst_port_from;
1693                 key.key.ipv4_5tuple.dst_port_to = params->dst_port_to;
1694                 key.key.ipv4_5tuple.proto = params->proto;
1695                 key.key.ipv4_5tuple.proto_mask = params->proto_mask;
1696         }
1697         if (params->src_ip.family == AF_INET6) {
1698                 if (ACL_DEBUG)
1699                         printf("entered IPV6");
1700                 key.type = PIPELINE_ACL_IPV6_5TUPLE;
1701                 memcpy(key.key.ipv6_5tuple.src_ip,
1702                        params->src_ip.addr.ipv6.s6_addr,
1703                        sizeof(params->src_ip.addr.ipv6.s6_addr));
1704                 key.key.ipv6_5tuple.src_ip_mask = params->src_ip_mask;
1705                 memcpy(key.key.ipv6_5tuple.dst_ip,
1706                        params->dst_ip.addr.ipv6.s6_addr,
1707                        sizeof(params->src_ip.addr.ipv6.s6_addr));
1708                 key.key.ipv6_5tuple.dst_ip_mask = params->dst_ip_mask;
1709                 key.key.ipv6_5tuple.src_port_from = params->src_port_from;
1710                 key.key.ipv6_5tuple.src_port_to = params->src_port_to;
1711                 key.key.ipv6_5tuple.dst_port_from = params->dst_port_from;
1712                 key.key.ipv6_5tuple.dst_port_to = params->dst_port_to;
1713                 key.key.ipv6_5tuple.proto = params->proto;
1714                 key.key.ipv6_5tuple.proto_mask = params->proto_mask;
1715         }
1716
1717         status = app_pipeline_acl_add_rule(app, &key, params->priority, 1,
1718 /* Set to 1 as default, overwritten by Action FWD/NAT Port */
1719                                            params->action_id);
1720
1721         if (status != 0) {
1722                 printf("Command failed\n");
1723                 return;
1724         }
1725
1726         /* Store command to update standby tables after switchover */
1727         command = rte_malloc(NULL, sizeof(*command), RTE_CACHE_LINE_SIZE);
1728         if (command == NULL) {
1729                 printf("Cannot allocation command\n");
1730                 return;
1731         }
1732         memset(command, 0, sizeof(struct app_pipeline_acl_rule));
1733         memcpy(&command->key, &key, sizeof(key));
1734         command->priority = params->priority;
1735         command->port_id = params->port_id;
1736         command->action_id = params->action_id;
1737         command->command = acl_add_command;
1738         TAILQ_INSERT_TAIL(&acl_commands, command, node);
1739 }
1740
1741 cmdline_parse_token_string_t cmd_acl_add_ip_p_string =
1742 TOKEN_STRING_INITIALIZER(struct cmd_acl_add_ip_result, p_string,
1743                          "p");
1744
1745 cmdline_parse_token_string_t cmd_acl_add_ip_acl_string =
1746 TOKEN_STRING_INITIALIZER(struct cmd_acl_add_ip_result,
1747                          acl_string, "acl");
1748
1749 cmdline_parse_token_string_t cmd_acl_add_ip_add_string =
1750 TOKEN_STRING_INITIALIZER(struct cmd_acl_add_ip_result,
1751                          add_string, "add");
1752
1753 cmdline_parse_token_num_t cmd_acl_add_ip_priority =
1754 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result, priority,
1755                       INT32);
1756
1757 cmdline_parse_token_ipaddr_t cmd_acl_add_ip_src_ip =
1758 TOKEN_IPADDR_INITIALIZER(struct cmd_acl_add_ip_result, src_ip);
1759
1760 cmdline_parse_token_num_t cmd_acl_add_ip_src_ip_mask =
1761 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result, src_ip_mask,
1762                       UINT32);
1763
1764 cmdline_parse_token_ipaddr_t cmd_acl_add_ip_dst_ip =
1765 TOKEN_IPADDR_INITIALIZER(struct cmd_acl_add_ip_result, dst_ip);
1766
1767 cmdline_parse_token_num_t cmd_acl_add_ip_dst_ip_mask =
1768 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result, dst_ip_mask,
1769                       UINT32);
1770
1771 cmdline_parse_token_num_t cmd_acl_add_ip_src_port_from =
1772 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1773                       src_port_from, UINT16);
1774
1775 cmdline_parse_token_num_t cmd_acl_add_ip_src_port_to =
1776 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1777                       src_port_to, UINT16);
1778
1779 cmdline_parse_token_num_t cmd_acl_add_ip_dst_port_from =
1780 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1781                       dst_port_from, UINT16);
1782
1783 cmdline_parse_token_num_t cmd_acl_add_ip_dst_port_to =
1784 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1785                       dst_port_to, UINT16);
1786
1787 cmdline_parse_token_num_t cmd_acl_add_ip_proto =
1788 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1789                       proto, UINT8);
1790
1791 cmdline_parse_token_num_t cmd_acl_add_ip_proto_mask =
1792 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1793                       proto_mask, UINT8);
1794
1795 cmdline_parse_token_num_t cmd_acl_add_ip_port_id =
1796 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1797                       port_id, UINT8);
1798
1799 cmdline_parse_token_num_t cmd_acl_add_ip_action_id =
1800 TOKEN_NUM_INITIALIZER(struct cmd_acl_add_ip_result,
1801                       action_id, UINT32);
1802
1803 cmdline_parse_inst_t cmd_acl_add_ip = {
1804         .f = cmd_acl_add_ip_parsed,
1805         .data = NULL,
1806         .help_str = "ACL rule add",
1807         .tokens = {
1808                    (void *)&cmd_acl_add_ip_p_string,
1809                    (void *)&cmd_acl_add_ip_acl_string,
1810                    (void *)&cmd_acl_add_ip_add_string,
1811                    (void *)&cmd_acl_add_ip_priority,
1812                    (void *)&cmd_acl_add_ip_src_ip,
1813                    (void *)&cmd_acl_add_ip_src_ip_mask,
1814                    (void *)&cmd_acl_add_ip_dst_ip,
1815                    (void *)&cmd_acl_add_ip_dst_ip_mask,
1816                    (void *)&cmd_acl_add_ip_src_port_from,
1817                    (void *)&cmd_acl_add_ip_src_port_to,
1818                    (void *)&cmd_acl_add_ip_dst_port_from,
1819                    (void *)&cmd_acl_add_ip_dst_port_to,
1820                    (void *)&cmd_acl_add_ip_proto,
1821                    (void *)&cmd_acl_add_ip_proto_mask,
1822                    (void *)&cmd_acl_add_ip_action_id,
1823                    NULL,
1824                    },
1825 };
1826
1827 /*
1828  * p acl del
1829  */
1830
1831 /**
1832  * A structure defining the ACL delete rule command.
1833  */
1834 struct cmd_acl_del_ip_result {
1835         cmdline_fixed_string_t p_string;
1836         cmdline_fixed_string_t acl_string;
1837         cmdline_fixed_string_t del_string;
1838         cmdline_ipaddr_t src_ip;
1839         uint32_t src_ip_mask;
1840         cmdline_ipaddr_t dst_ip;
1841         uint32_t dst_ip_mask;
1842         uint16_t src_port_from;
1843         uint16_t src_port_to;
1844         uint16_t dst_port_from;
1845         uint16_t dst_port_to;
1846         uint8_t proto;
1847         uint8_t proto_mask;
1848 };
1849
1850 /**
1851  * Parse ACL delete rule CLI command.
1852  * Delete rule from standby table.
1853  * Store command to update standby table
1854  * after applyruleset command is invoked.
1855  *
1856  * @param parsed_result
1857  *  A pointer to CLI command parsed result.
1858  * @param cl
1859  *  A pointer to command line context.
1860  * @param data
1861  *  A pointer to command specific data
1862  *
1863  */
1864 static void cmd_acl_del_ip_parsed(void *parsed_result, __attribute__ ((unused))
1865                                   struct cmdline *cl, void *data)
1866 {
1867         struct cmd_acl_del_ip_result *params = parsed_result;
1868         struct app_params *app = data;
1869         struct pipeline_acl_key key;
1870         struct app_pipeline_acl_rule *command;
1871         int status;
1872
1873         memset(&key, 0, sizeof(struct pipeline_acl_key));
1874
1875         if (params->src_ip.family == AF_INET) {
1876                 key.type = PIPELINE_ACL_IPV4_5TUPLE;
1877                 key.key.ipv4_5tuple.src_ip = rte_bswap32((uint32_t)
1878                                                          params->src_ip.
1879                                                          addr.ipv4.s_addr);
1880                 key.key.ipv4_5tuple.src_ip_mask = params->src_ip_mask;
1881                 key.key.ipv4_5tuple.dst_ip = rte_bswap32((uint32_t)
1882                                                          params->dst_ip.
1883                                                          addr.ipv4.s_addr);
1884                 key.key.ipv4_5tuple.dst_ip_mask = params->dst_ip_mask;
1885                 key.key.ipv4_5tuple.src_port_from = params->src_port_from;
1886                 key.key.ipv4_5tuple.src_port_to = params->src_port_to;
1887                 key.key.ipv4_5tuple.dst_port_from = params->dst_port_from;
1888                 key.key.ipv4_5tuple.dst_port_to = params->dst_port_to;
1889                 key.key.ipv4_5tuple.proto = params->proto;
1890                 key.key.ipv4_5tuple.proto_mask = params->proto_mask;
1891         }
1892         if (params->src_ip.family == AF_INET6) {
1893                 key.type = PIPELINE_ACL_IPV6_5TUPLE;
1894                 memcpy(key.key.ipv6_5tuple.src_ip,
1895                        params->src_ip.addr.ipv6.s6_addr,
1896                        sizeof(params->src_ip.addr.ipv6.s6_addr));
1897                 key.key.ipv6_5tuple.src_ip_mask = params->src_ip_mask;
1898                 memcpy(key.key.ipv6_5tuple.dst_ip,
1899                        params->dst_ip.addr.ipv6.s6_addr,
1900                        sizeof(params->dst_ip.addr.ipv6.s6_addr));
1901                 key.key.ipv6_5tuple.dst_ip_mask = params->dst_ip_mask;
1902                 key.key.ipv6_5tuple.src_port_from = params->src_port_from;
1903                 key.key.ipv6_5tuple.src_port_to = params->src_port_to;
1904                 key.key.ipv6_5tuple.dst_port_from = params->dst_port_from;
1905                 key.key.ipv6_5tuple.dst_port_to = params->dst_port_to;
1906                 key.key.ipv6_5tuple.proto = params->proto;
1907                 key.key.ipv6_5tuple.proto_mask = params->proto_mask;
1908         }
1909
1910         status = app_pipeline_acl_delete_rule(app, &key);
1911
1912         if (status != 0) {
1913                 printf("Command failed\n");
1914                 return;
1915         }
1916
1917         /* Store command to update standby tables after switchover */
1918         command = rte_malloc(NULL, sizeof(*command), RTE_CACHE_LINE_SIZE);
1919         if (command == NULL) {
1920                 printf("Cannot allocation command\n");
1921                 return;
1922         }
1923         memset(command, 0, sizeof(struct app_pipeline_acl_rule));
1924         memcpy(&command->key, &key, sizeof(key));
1925         command->command = acl_delete_command;
1926         TAILQ_INSERT_TAIL(&acl_commands, command, node);
1927 }
1928
1929 cmdline_parse_token_string_t cmd_acl_del_ip_p_string =
1930 TOKEN_STRING_INITIALIZER(struct cmd_acl_del_ip_result, p_string,
1931                          "p");
1932
1933 cmdline_parse_token_string_t cmd_acl_del_ip_acl_string =
1934 TOKEN_STRING_INITIALIZER(struct cmd_acl_del_ip_result,
1935                          acl_string, "acl");
1936
1937 cmdline_parse_token_string_t cmd_acl_del_ip_del_string =
1938 TOKEN_STRING_INITIALIZER(struct cmd_acl_del_ip_result,
1939                          del_string, "del");
1940
1941 cmdline_parse_token_ipaddr_t cmd_acl_del_ip_src_ip =
1942 TOKEN_IPADDR_INITIALIZER(struct cmd_acl_del_ip_result, src_ip);
1943
1944 cmdline_parse_token_num_t cmd_acl_del_ip_src_ip_mask =
1945 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result, src_ip_mask,
1946                       UINT32);
1947
1948 cmdline_parse_token_ipaddr_t cmd_acl_del_ip_dst_ip =
1949 TOKEN_IPADDR_INITIALIZER(struct cmd_acl_del_ip_result, dst_ip);
1950
1951 cmdline_parse_token_num_t cmd_acl_del_ip_dst_ip_mask =
1952 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result, dst_ip_mask,
1953                       UINT32);
1954
1955 cmdline_parse_token_num_t cmd_acl_del_ip_src_port_from =
1956 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result,
1957                       src_port_from, UINT16);
1958
1959 cmdline_parse_token_num_t cmd_acl_del_ip_src_port_to =
1960 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result, src_port_to,
1961                       UINT16);
1962
1963 cmdline_parse_token_num_t cmd_acl_del_ip_dst_port_from =
1964 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result,
1965                       dst_port_from, UINT16);
1966
1967 cmdline_parse_token_num_t cmd_acl_del_ip_dst_port_to =
1968 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result,
1969                       dst_port_to, UINT16);
1970
1971 cmdline_parse_token_num_t cmd_acl_del_ip_proto =
1972 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result,
1973                       proto, UINT8);
1974
1975 cmdline_parse_token_num_t cmd_acl_del_ip_proto_mask =
1976 TOKEN_NUM_INITIALIZER(struct cmd_acl_del_ip_result, proto_mask,
1977                       UINT8);
1978
1979 cmdline_parse_inst_t cmd_acl_del_ip = {
1980         .f = cmd_acl_del_ip_parsed,
1981         .data = NULL,
1982         .help_str = "ACL rule delete",
1983         .tokens = {
1984                    (void *)&cmd_acl_del_ip_p_string,
1985                    (void *)&cmd_acl_del_ip_acl_string,
1986                    (void *)&cmd_acl_del_ip_del_string,
1987                    (void *)&cmd_acl_del_ip_src_ip,
1988                    (void *)&cmd_acl_del_ip_src_ip_mask,
1989                    (void *)&cmd_acl_del_ip_dst_ip,
1990                    (void *)&cmd_acl_del_ip_dst_ip_mask,
1991                    (void *)&cmd_acl_del_ip_src_port_from,
1992                    (void *)&cmd_acl_del_ip_src_port_to,
1993                    (void *)&cmd_acl_del_ip_dst_port_from,
1994                    (void *)&cmd_acl_del_ip_dst_port_to,
1995                    (void *)&cmd_acl_del_ip_proto,
1996                    (void *)&cmd_acl_del_ip_proto_mask,
1997                    NULL,
1998                    },
1999 };
2000
2001 /*
2002  * p acl stats
2003  */
2004
2005 /**
2006  * A structure defining the ACL stats command.
2007  */
2008 struct cmd_acl_stats_result {
2009         cmdline_fixed_string_t p_string;
2010         cmdline_fixed_string_t acl_string;
2011         cmdline_fixed_string_t stats_string;
2012 };
2013
2014 /**
2015  * Display ACL and Connection Tracker stats to the console.
2016  *
2017  * @param parsed_result
2018  *  A pointer to CLI command parsed result.
2019  * @param cl
2020  *  A pointer to command line context.
2021  * @param data
2022  *  A pointer to command specific data
2023  *
2024  */
2025 static void cmd_acl_stats_parsed(void *parsed_result, __attribute__ ((unused))
2026                                  struct cmdline *cl, void *data)
2027 {
2028         struct cmd_acl_stats_result *params = parsed_result;
2029         struct app_params *app = data;
2030         int i, j;
2031         struct rte_ACL_counter_block acl_counter_sums;
2032         struct rte_CT_counter_block ct_counter_sums;
2033         struct rte_CT_counter_block *ct_counters;
2034         struct action_counter_block action_counter_sum[action_array_max];
2035
2036         memset(&acl_counter_sums, 0, sizeof(acl_counter_sums));
2037         memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
2038         memset(&action_counter_sum, 0, sizeof(action_counter_sum));
2039
2040         printf("ACL Stats\n");
2041         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
2042                 struct rte_ACL_counter_block *acl_ctrs =
2043                     &rte_acl_counter_table[i];
2044                 ct_counters = rte_acl_counter_table[i].ct_counters;
2045                 printf("acl entry[%i] tpkts_processed: %" PRIu64
2046                        ", pkts_drop: %" PRIu64 ", pkts_received: %" PRIu64
2047                        ", bytes_processed: %" PRIu64 "\n", i,
2048                        acl_ctrs->tpkts_processed, acl_ctrs->pkts_drop,
2049                        acl_ctrs->pkts_received, acl_ctrs->bytes_processed);
2050
2051                 acl_counter_sums.tpkts_processed += acl_ctrs->tpkts_processed;
2052                 acl_counter_sums.bytes_processed += acl_ctrs->bytes_processed;
2053                 acl_counter_sums.pkts_drop += acl_ctrs->pkts_drop;
2054                 acl_counter_sums.pkts_received += acl_ctrs->pkts_received;
2055                 ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
2056                 ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
2057         }
2058
2059         printf("ACL TOTAL: tpkts_processed: %" PRIu64 ", pkts_drop: %" PRIu64
2060                ", pkts_received: %" PRIu64 ", bytes_processed: %" PRIu64 "\n\n",
2061                acl_counter_sums.tpkts_processed,
2062                acl_counter_sums.pkts_drop,
2063                acl_counter_sums.pkts_received,
2064                acl_counter_sums.bytes_processed);
2065
2066         printf("CT TOTAL: ct_packets_forwarded: %" PRIu64
2067                ", ct_packets_dropped: %" PRIu64 "\n\n",
2068                ct_counter_sums.pkts_forwarded, ct_counter_sums.pkts_drop);
2069
2070         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
2071                 for (j = 0; j < action_array_max; j++) {
2072                         if (action_array_active[j].action_bitmap &
2073                             acl_action_count) {
2074                                 action_counter_sum[j].packetCount +=
2075                                     action_counter_table[i][j].packetCount;
2076                                 action_counter_sum[j].byteCount +=
2077                                     action_counter_table[i][j].byteCount;
2078                         }
2079                 }
2080         }
2081
2082         for (j = 0; j < action_array_max; j++) {
2083                 if (action_array_active[j].action_bitmap & acl_action_count)
2084                         printf("Action ID: %02u, packetCount: %" PRIu64
2085                                ", byteCount: %" PRIu64 "\n", j,
2086                                action_counter_sum[j].packetCount,
2087                                action_counter_sum[j].byteCount);
2088         }
2089 }
2090
2091 cmdline_parse_token_string_t cmd_acl_stats_p_string =
2092 TOKEN_STRING_INITIALIZER(struct cmd_acl_stats_result,
2093                          p_string, "p");
2094
2095 cmdline_parse_token_string_t cmd_acl_stats_acl_string =
2096 TOKEN_STRING_INITIALIZER(struct cmd_acl_stats_result,
2097                          acl_string, "acl");
2098
2099 cmdline_parse_token_string_t cmd_acl_stats_stats_string =
2100 TOKEN_STRING_INITIALIZER(struct cmd_acl_stats_result,
2101                          stats_string, "stats");
2102
2103 cmdline_parse_inst_t cmd_acl_stats = {
2104         .f = cmd_acl_stats_parsed,
2105         .data = NULL,
2106         .help_str = "ACL stats",
2107         .tokens = {
2108                    (void *)&cmd_acl_stats_p_string,
2109                    (void *)&cmd_acl_stats_acl_string,
2110                    (void *)&cmd_acl_stats_stats_string,
2111                    NULL,
2112                    },
2113 };
2114
2115 /*
2116  * p acl clearstats
2117  */
2118
2119 /**
2120  * A structure defining the ACL clear stats command.
2121  */
2122 struct cmd_acl_clearstats_result {
2123         cmdline_fixed_string_t p_string;
2124         cmdline_fixed_string_t acl_string;
2125         cmdline_fixed_string_t clearstats_string;
2126 };
2127
2128 /**
2129  * Clear ACL and Connection Tracker stats.
2130  *
2131  * @param parsed_result
2132  *  A pointer to CLI command parsed result.
2133  * @param cl
2134  *  A pointer to command line context.
2135  * @param data
2136  *  A pointer to command specific data
2137  *
2138  */
2139 static void cmd_acl_clearstats_parsed(__attribute__ ((unused))
2140                                       void *parsed_result,
2141                                       __attribute__ ((unused))
2142                                       struct cmdline *cl,
2143                                       __attribute__ ((unused))
2144                                       void *data)
2145 {
2146         int i;
2147
2148         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
2149                 rte_acl_counter_table[i].tpkts_processed = 0;
2150                 rte_acl_counter_table[i].bytes_processed = 0;
2151                 rte_acl_counter_table[i].pkts_drop = 0;
2152                 rte_acl_counter_table[i].pkts_received = 0;
2153                 rte_acl_counter_table[i].pkts_drop_ttl = 0;
2154                 rte_acl_counter_table[i].pkts_drop_bad_size = 0;
2155                 rte_acl_counter_table[i].pkts_drop_fragmented = 0;
2156                 rte_acl_counter_table[i].pkts_drop_without_arp_entry = 0;
2157                 rte_acl_counter_table[i].ct_counters->pkts_forwarded = 0;
2158                 rte_acl_counter_table[i].ct_counters->pkts_drop = 0;
2159         }
2160
2161         memset(&action_counter_table, 0, sizeof(action_counter_table));
2162
2163 }
2164
2165 cmdline_parse_token_string_t cmd_acl_clearstats_p_string =
2166 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearstats_result,
2167                          p_string, "p");
2168
2169 cmdline_parse_token_string_t cmd_acl_clearstats_acl_string =
2170 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearstats_result,
2171                          acl_string, "acl");
2172
2173 cmdline_parse_token_string_t cmd_acl_clearstats_clearstats_string =
2174 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearstats_result,
2175                          clearstats_string, "clearstats");
2176
2177 cmdline_parse_inst_t cmd_acl_clearstats = {
2178         .f = cmd_acl_clearstats_parsed,
2179         .data = NULL,
2180         .help_str = "ACL clearstats",
2181         .tokens = {
2182                    (void *)&cmd_acl_clearstats_p_string,
2183                    (void *)&cmd_acl_clearstats_acl_string,
2184                    (void *)&cmd_acl_clearstats_clearstats_string,
2185                    NULL,
2186                    },
2187 };
2188
2189 /*
2190  * p acl dbg
2191  */
2192
2193 /**
2194  * A structure defining the ACL debug command.
2195  */
2196 struct cmd_acl_dbg_result {
2197         cmdline_fixed_string_t p_string;
2198         cmdline_fixed_string_t acl_string;
2199         cmdline_fixed_string_t dbg_string;
2200         uint8_t dbg;
2201 };
2202
2203 /**
2204  * Parse and handle ACL debug command.
2205  *
2206  * @param parsed_result
2207  *  A pointer to CLI command parsed result.
2208  * @param cl
2209  *  A pointer to command line context.
2210  * @param data
2211  *  A pointer to command specific data
2212  *
2213  */
2214 static void cmd_acl_dbg_parsed(void *parsed_result, __attribute__ ((unused))
2215                                struct cmdline *cl, void *data)
2216 {
2217         struct cmd_acl_dbg_result *params = parsed_result;
2218         struct app_params *app = data;
2219
2220         if (params->dbg == 0) {
2221                 printf("DBG turned OFF\n");
2222                 ACL_DEBUG = 0;
2223         } else if (params->dbg == 1) {
2224                 printf("DBG turned ON\n");
2225                 ACL_DEBUG = 1;
2226         } else if (params->dbg == 2) {
2227                 printf("ACL IPV4 enabled\n");
2228                 printf("ACL IPV6 enabled\n");
2229                 acl_ipv4_enabled = 1;
2230                 acl_ipv6_enabled = 1;
2231         } else if (params->dbg == 3) {
2232                 printf("ACL IPV4 enabled\n");
2233                 printf("ACL IPV6 disabled\n");
2234                 acl_ipv4_enabled = 1;
2235                 acl_ipv6_enabled = 0;
2236         } else if (params->dbg == 4) {
2237                 printf("ACL IPV4 disabled\n");
2238                 printf("ACL IPV6 enabled\n");
2239                 acl_ipv4_enabled = 0;
2240                 acl_ipv6_enabled = 1;
2241         } else if (params->dbg == 5) {
2242                 printf("ACL Version: 3.03\n");
2243         } else
2244                 printf("Invalid DBG setting\n");
2245 }
2246
2247 cmdline_parse_token_string_t cmd_acl_dbg_p_string =
2248 TOKEN_STRING_INITIALIZER(struct cmd_acl_dbg_result,
2249                          p_string, "p");
2250
2251 cmdline_parse_token_string_t cmd_acl_dbg_acl_string =
2252 TOKEN_STRING_INITIALIZER(struct cmd_acl_dbg_result,
2253                          acl_string, "acl");
2254
2255 cmdline_parse_token_string_t cmd_acl_dbg_dbg_string =
2256 TOKEN_STRING_INITIALIZER(struct cmd_acl_dbg_result,
2257                          dbg_string, "dbg");
2258
2259 cmdline_parse_token_num_t cmd_acl_dbg_dbg =
2260 TOKEN_NUM_INITIALIZER(struct cmd_acl_dbg_result, dbg,
2261                       UINT8);
2262
2263 cmdline_parse_inst_t cmd_acl_dbg = {
2264         .f = cmd_acl_dbg_parsed,
2265         .data = NULL,
2266         .help_str = "ACL dbg",
2267         .tokens = {
2268                    (void *)&cmd_acl_dbg_p_string,
2269                    (void *)&cmd_acl_dbg_acl_string,
2270                    (void *)&cmd_acl_dbg_dbg_string,
2271                    (void *)&cmd_acl_dbg_dbg,
2272                    NULL,
2273                    },
2274 };
2275
2276 /*
2277  * p acl clearrules
2278  */
2279
2280 /**
2281  * A structure defining the ACL clear rules command.
2282  */
2283 struct cmd_acl_clearrules_result {
2284         cmdline_fixed_string_t p_string;
2285         cmdline_fixed_string_t acl_string;
2286         cmdline_fixed_string_t clearrules_string;
2287 };
2288
2289 /**
2290  * Parse clear rule command.
2291  *
2292  * @param parsed_result
2293  *  A pointer to CLI command parsed result.
2294  * @param cl
2295  *  A pointer to command line context.
2296  * @param data
2297  *  A pointer to command specific data
2298  *
2299  */
2300 static void cmd_acl_clearrules_parsed(__attribute__ ((unused))
2301                                       void *parsed_result,
2302                                       __attribute__ ((unused))
2303                                       struct cmdline *cl, void *data)
2304 {
2305         struct app_params *app = data;
2306         int status;
2307
2308         status = app_pipeline_acl_clearrules(app);
2309
2310         if (status != 0) {
2311                 printf("Command failed\n");
2312                 return;
2313         }
2314 }
2315
2316 cmdline_parse_token_string_t cmd_acl_clearrules_p_string =
2317 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearrules_result,
2318                          p_string, "p");
2319
2320 cmdline_parse_token_string_t cmd_acl_clearrules_acl_string =
2321 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearrules_result,
2322                          acl_string, "acl");
2323
2324 cmdline_parse_token_string_t cmd_acl_clearrules_clearrules_string =
2325 TOKEN_STRING_INITIALIZER(struct cmd_acl_clearrules_result,
2326                          clearrules_string, "clearrules");
2327
2328 cmdline_parse_inst_t cmd_acl_clearrules = {
2329         .f = cmd_acl_clearrules_parsed,
2330         .data = NULL,
2331         .help_str = "ACL clearrules",
2332         .tokens = {
2333                    (void *)&cmd_acl_clearrules_p_string,
2334                    (void *)&cmd_acl_clearrules_acl_string,
2335                    (void *)&cmd_acl_clearrules_clearrules_string,
2336                    NULL,
2337                    },
2338 };
2339
2340 /*
2341  * p acl ls
2342  */
2343
2344 /**
2345  * A structure defining the ACL ls CLI command result.
2346  */
2347 struct cmd_acl_ls_result {
2348         cmdline_fixed_string_t p_string;
2349         cmdline_fixed_string_t acl_string;
2350         cmdline_fixed_string_t ls_string;
2351         uint32_t table_instance;
2352 };
2353
2354 /**
2355  * Parse ACL ls command to display rules to the console.
2356  *
2357  * @param parsed_result
2358  *  A pointer to CLI command parsed result.
2359  * @param cl
2360  *  A pointer to command line context.
2361  * @param data
2362  *  A pointer to command specific data
2363  *
2364  */
2365 static void cmd_acl_ls_parsed(__attribute__ ((unused))
2366                               void *parsed_result, __attribute__ ((unused))
2367                               struct cmdline *cl, void *data)
2368 {
2369         struct app_params *app = data;
2370         struct cmd_acl_ls_result *params = parsed_result;
2371
2372         app_pipeline_acl_ls(app, params->table_instance);
2373 }
2374
2375 cmdline_parse_token_string_t cmd_acl_ls_p_string =
2376 TOKEN_STRING_INITIALIZER(struct cmd_acl_ls_result, p_string,
2377                          "p");
2378
2379 cmdline_parse_token_string_t cmd_acl_ls_acl_string =
2380 TOKEN_STRING_INITIALIZER(struct cmd_acl_ls_result,
2381                          acl_string, "acl");
2382
2383 cmdline_parse_token_string_t cmd_acl_ls_ls_string =
2384 TOKEN_STRING_INITIALIZER(struct cmd_acl_ls_result, ls_string,
2385                          "ls");
2386
2387 cmdline_parse_token_num_t cmd_acl_ls_table_instance =
2388 TOKEN_NUM_INITIALIZER(struct cmd_acl_ls_result, table_instance,
2389                       UINT32);
2390
2391 cmdline_parse_inst_t cmd_acl_ls = {
2392         .f = cmd_acl_ls_parsed,
2393         .data = NULL,
2394         .help_str = "ACL rule list",
2395         .tokens = {
2396                    (void *)&cmd_acl_ls_p_string,
2397                    (void *)&cmd_acl_ls_acl_string,
2398                    (void *)&cmd_acl_ls_ls_string,
2399                    (void *)&cmd_acl_ls_table_instance,
2400                    NULL,
2401                    },
2402 };
2403
2404 /*
2405  * p acl applyruleset
2406  */
2407
2408 /**
2409  * A structure defining the ACL apply ruleset command.
2410  */
2411 struct cmd_acl_applyruleset_result {
2412         cmdline_fixed_string_t p_string;
2413         cmdline_fixed_string_t acl_string;
2414         cmdline_fixed_string_t applyruleset_string;
2415 };
2416
2417 /**
2418  * Parse ACL Apply Ruleset Command.
2419  * Switchover active and standby tables.
2420  * Sync newly standby tables to match updated data.
2421  * Both ACL rule and ACL action tables updated.
2422  *
2423  * @param parsed_result
2424  *  A pointer to CLI command parsed result.
2425  * @param cl
2426  *  A pointer to command line context.
2427  * @param data
2428  *  A pointer to command specific data
2429  *
2430  */
2431 static void cmd_acl_applyruleset_parsed(__attribute__ ((unused))
2432                                         void *parsed_result,
2433                                         __attribute__ ((unused))
2434                                         struct cmdline *cl, void *data)
2435 {
2436         struct app_params *app = data;
2437         void *temp_ptr;
2438         uint32_t *temp_count_ptr;
2439         struct pipeline_action_key *action_array_temp_ptr;
2440         int status;
2441
2442         printf("ACL Apply Ruleset\n");
2443
2444         /* Switchover Active and Standby TRIE rule tables */
2445         temp_ptr = acl_rule_table_ipv4_active;
2446         acl_rule_table_ipv4_active = acl_rule_table_ipv4_standby;
2447         acl_rule_table_ipv4_standby = temp_ptr;
2448         temp_ptr = acl_rule_table_ipv6_active;
2449         acl_rule_table_ipv6_active = acl_rule_table_ipv6_standby;
2450         acl_rule_table_ipv6_standby = temp_ptr;
2451
2452         /* Switchover tailq tables */
2453         acl_tailq_rules_temp_ptr = acl_tailq_rules_ipv4_active;
2454         acl_tailq_rules_ipv4_active = acl_tailq_rules_ipv4_standby;
2455         acl_tailq_rules_ipv4_standby = acl_tailq_rules_temp_ptr;
2456         acl_tailq_rules_temp_ptr = acl_tailq_rules_ipv6_active;
2457         acl_tailq_rules_ipv6_active = acl_tailq_rules_ipv6_standby;
2458         acl_tailq_rules_ipv6_standby = acl_tailq_rules_temp_ptr;
2459         temp_count_ptr = acl_n_tailq_rules_ipv4_active;
2460         acl_n_tailq_rules_ipv4_active = acl_n_tailq_rules_ipv4_standby;
2461         acl_n_tailq_rules_ipv4_standby = temp_count_ptr;
2462         temp_count_ptr = acl_n_tailq_rules_ipv6_active;
2463         acl_n_tailq_rules_ipv6_active = acl_n_tailq_rules_ipv6_standby;
2464         acl_n_tailq_rules_ipv6_standby = temp_count_ptr;
2465
2466         /* Switchover Active and Standby action table */
2467         action_array_temp_ptr = action_array_active;
2468         action_array_active = action_array_standby;
2469         action_array_standby = action_array_temp_ptr;
2470         /* Update Standby action table with all changes */
2471         memcpy(action_array_standby, action_array_active, action_array_size);
2472
2473         /* Update Standby Rule Tables with all changes */
2474         while (!TAILQ_EMPTY(&acl_commands)) {
2475                 struct app_pipeline_acl_rule *command;
2476
2477                 command = TAILQ_FIRST(&acl_commands);
2478                 TAILQ_REMOVE(&acl_commands, command, node);
2479
2480                 if (command->command == acl_add_command) {
2481                         status = app_pipeline_acl_add_rule(app,
2482                                                            &command->key,
2483                                                            command->priority,
2484                                                            command->port_id,
2485                                                            command->action_id);
2486                 } else
2487                         status =
2488                             app_pipeline_acl_delete_rule(app, &command->key);
2489
2490                 if (status != 0) {
2491                         printf("Command applyruleset add rule failed\n");
2492                         rte_free(command);
2493                         return;
2494                 }
2495
2496                 rte_free(command);
2497         }
2498 }
2499
2500 cmdline_parse_token_string_t cmd_acl_applyruleset_p_string =
2501 TOKEN_STRING_INITIALIZER(struct cmd_acl_applyruleset_result, p_string,
2502                          "p");
2503
2504 cmdline_parse_token_string_t cmd_acl_applyruleset_acl_string =
2505 TOKEN_STRING_INITIALIZER(struct cmd_acl_applyruleset_result,
2506                          acl_string, "acl");
2507
2508 cmdline_parse_token_string_t cmd_acl_applyruleset_applyruleset_string =
2509 TOKEN_STRING_INITIALIZER(struct cmd_acl_applyruleset_result,
2510                          applyruleset_string,
2511                          "applyruleset");
2512
2513 cmdline_parse_inst_t cmd_acl_applyruleset = {
2514         .f = cmd_acl_applyruleset_parsed,
2515         .data = NULL,
2516         .help_str = "ACL applyruleset",
2517         .tokens = {
2518                    (void *)&cmd_acl_applyruleset_p_string,
2519                    (void *)&cmd_acl_applyruleset_acl_string,
2520                    (void *)&cmd_acl_applyruleset_applyruleset_string,
2521                    NULL,
2522                    },
2523 };
2524
2525 /*
2526  * p action add accept
2527  */
2528
2529 /**
2530  * A structure defining the add accept action command.
2531  */
2532 struct cmd_action_add_accept_result {
2533         cmdline_fixed_string_t p_string;
2534         cmdline_fixed_string_t action_string;
2535         cmdline_fixed_string_t add_string;
2536         int32_t action_id;
2537         cmdline_fixed_string_t accept_string;
2538 };
2539
2540 /**
2541  * Parse Accept Action Add Command.
2542  *
2543  * @param parsed_result
2544  *  A pointer to CLI command parsed result.
2545  * @param cl
2546  *  A pointer to command line context.
2547  * @param data
2548  *  A pointer to command specific data
2549  *
2550  */
2551 static void
2552 cmd_action_add_accept_parsed(void *parsed_result, __attribute__ ((unused))
2553                              struct cmdline *cl, void *data)
2554 {
2555         struct cmd_action_add_accept_result *params = parsed_result;
2556         struct app_params *app = data;
2557         struct pipeline_action_key key;
2558         int status;
2559
2560         key.action_id = params->action_id;
2561         key.action_bitmap = acl_action_packet_accept;
2562
2563         status = app_pipeline_action_add(app, &key);
2564
2565         if (status != 0) {
2566                 printf("Command failed\n");
2567                 return;
2568         }
2569 }
2570
2571 cmdline_parse_token_string_t cmd_action_add_accept_p_string =
2572 TOKEN_STRING_INITIALIZER(struct cmd_action_add_accept_result, p_string,
2573                          "p");
2574
2575 cmdline_parse_token_string_t cmd_action_add_accept_action_string =
2576 TOKEN_STRING_INITIALIZER(struct cmd_action_add_accept_result,
2577                          action_string, "action");
2578
2579 cmdline_parse_token_string_t cmd_action_add_accept_add_string =
2580 TOKEN_STRING_INITIALIZER(struct cmd_action_add_accept_result,
2581                          add_string, "add");
2582
2583 cmdline_parse_token_num_t cmd_action_add_accept_action_id =
2584 TOKEN_NUM_INITIALIZER(struct cmd_action_add_accept_result, action_id,
2585                       UINT32);
2586
2587 cmdline_parse_token_string_t cmd_action_add_accept_accept_string =
2588 TOKEN_STRING_INITIALIZER(struct cmd_action_add_accept_result,
2589                          accept_string, "accept");
2590
2591 cmdline_parse_inst_t cmd_action_add_accept = {
2592         .f = cmd_action_add_accept_parsed,
2593         .data = NULL,
2594         .help_str = "ACL action add accept",
2595         .tokens = {
2596                    (void *)&cmd_action_add_accept_p_string,
2597                    (void *)&cmd_action_add_accept_action_string,
2598                    (void *)&cmd_action_add_accept_add_string,
2599                    (void *)&cmd_action_add_accept_action_id,
2600                    (void *)&cmd_action_add_accept_accept_string,
2601                    NULL,
2602                    },
2603 };
2604
2605 /*
2606  * p action del accept
2607  */
2608
2609 /**
2610  * A structure defining the delete accept action command.
2611  */
2612 struct cmd_action_del_accept_result {
2613         cmdline_fixed_string_t p_string;
2614         cmdline_fixed_string_t action_string;
2615         cmdline_fixed_string_t del_string;
2616         int32_t action_id;
2617         cmdline_fixed_string_t accept_string;
2618 };
2619
2620 /**
2621  * Parse Accept Action Delete Command.
2622  *
2623  * @param parsed_result
2624  *  A pointer to CLI command parsed result.
2625  * @param cl
2626  *  A pointer to command line context.
2627  * @param data
2628  *  A pointer to command specific data
2629  *
2630  */
2631 static void
2632 cmd_action_del_accept_parsed(void *parsed_result, __attribute__ ((unused))
2633                              struct cmdline *cl, void *data)
2634 {
2635         struct cmd_action_del_accept_result *params = parsed_result;
2636         struct app_params *app = data;
2637         struct pipeline_action_key key;
2638         int status;
2639
2640         key.action_id = params->action_id;
2641         key.action_bitmap = acl_action_packet_accept;
2642
2643         status = app_pipeline_action_delete(app, &key);
2644
2645         if (status != 0) {
2646                 printf("Command failed\n");
2647                 return;
2648         }
2649 }
2650
2651 cmdline_parse_token_string_t cmd_action_del_accept_p_string =
2652 TOKEN_STRING_INITIALIZER(struct cmd_action_del_accept_result, p_string,
2653                          "p");
2654
2655 cmdline_parse_token_string_t cmd_action_del_accept_action_string =
2656 TOKEN_STRING_INITIALIZER(struct cmd_action_del_accept_result,
2657                          action_string, "action");
2658
2659 cmdline_parse_token_string_t cmd_action_del_accept_del_string =
2660 TOKEN_STRING_INITIALIZER(struct cmd_action_del_accept_result,
2661                          del_string, "del");
2662
2663 cmdline_parse_token_num_t cmd_action_del_accept_action_id =
2664 TOKEN_NUM_INITIALIZER(struct cmd_action_del_accept_result, action_id,
2665                       UINT32);
2666
2667 cmdline_parse_token_string_t cmd_action_del_accept_accept_string =
2668 TOKEN_STRING_INITIALIZER(struct cmd_action_del_accept_result,
2669                          accept_string, "accept");
2670
2671 cmdline_parse_inst_t cmd_action_del_accept = {
2672         .f = cmd_action_del_accept_parsed,
2673         .data = NULL,
2674         .help_str = "ACL action delete accept",
2675         .tokens = {
2676                    (void *)&cmd_action_del_accept_p_string,
2677                    (void *)&cmd_action_del_accept_action_string,
2678                    (void *)&cmd_action_del_accept_del_string,
2679                    (void *)&cmd_action_del_accept_action_id,
2680                    (void *)&cmd_action_del_accept_accept_string,
2681                    NULL,
2682                    },
2683 };
2684
2685 /*
2686  * p action add drop
2687  */
2688
2689 /**
2690  * A structure defining the add drop action command.
2691  */
2692 struct cmd_action_add_drop_result {
2693         cmdline_fixed_string_t p_string;
2694         cmdline_fixed_string_t action_string;
2695         cmdline_fixed_string_t add_string;
2696         int32_t action_id;
2697         cmdline_fixed_string_t drop_string;
2698 };
2699
2700 /**
2701  * Parse Drop Action Add Command.
2702  *
2703  * @param parsed_result
2704  *  A pointer to CLI command parsed result.
2705  * @param cl
2706  *  A pointer to command line context.
2707  * @param data
2708  *  A pointer to command specific data
2709  *
2710  */
2711 static void
2712 cmd_action_add_drop_parsed(void *parsed_result, __attribute__ ((unused))
2713                            struct cmdline *cl, void *data)
2714 {
2715         struct cmd_action_add_drop_result *params = parsed_result;
2716         struct app_params *app = data;
2717         struct pipeline_action_key key;
2718         int status;
2719
2720         key.action_id = params->action_id;
2721         key.action_bitmap = acl_action_packet_drop;
2722
2723         status = app_pipeline_action_add(app, &key);
2724
2725         if (status != 0) {
2726                 printf("Command failed\n");
2727                 return;
2728         }
2729 }
2730
2731 cmdline_parse_token_string_t cmd_action_add_drop_p_string =
2732 TOKEN_STRING_INITIALIZER(struct cmd_action_add_drop_result, p_string,
2733                          "p");
2734
2735 cmdline_parse_token_string_t cmd_action_add_drop_action_string =
2736 TOKEN_STRING_INITIALIZER(struct cmd_action_add_drop_result,
2737                          action_string, "action");
2738
2739 cmdline_parse_token_string_t cmd_action_add_drop_add_string =
2740 TOKEN_STRING_INITIALIZER(struct cmd_action_add_drop_result,
2741                          add_string, "add");
2742
2743 cmdline_parse_token_num_t cmd_action_add_drop_action_id =
2744 TOKEN_NUM_INITIALIZER(struct cmd_action_add_drop_result, action_id,
2745                       UINT32);
2746
2747 cmdline_parse_token_string_t cmd_action_add_drop_drop_string =
2748 TOKEN_STRING_INITIALIZER(struct cmd_action_add_drop_result,
2749                          drop_string, "drop");
2750
2751 cmdline_parse_inst_t cmd_action_add_drop = {
2752         .f = cmd_action_add_drop_parsed,
2753         .data = NULL,
2754         .help_str = "ACL action add drop",
2755         .tokens = {
2756                    (void *)&cmd_action_add_drop_p_string,
2757                    (void *)&cmd_action_add_drop_action_string,
2758                    (void *)&cmd_action_add_drop_add_string,
2759                    (void *)&cmd_action_add_drop_action_id,
2760                    (void *)&cmd_action_add_drop_drop_string,
2761                    NULL,
2762                    },
2763 };
2764
2765 /*
2766  * p action del drop
2767  */
2768
2769 /**
2770  * A structure defining the delete drop action command.
2771  */
2772 struct cmd_action_del_drop_result {
2773         cmdline_fixed_string_t p_string;
2774         cmdline_fixed_string_t action_string;
2775         cmdline_fixed_string_t del_string;
2776         int32_t action_id;
2777         cmdline_fixed_string_t drop_string;
2778 };
2779
2780 /**
2781  * Parse Drop Action Delete Command.
2782  *
2783  * @param parsed_result
2784  *  A pointer to CLI command parsed result.
2785  * @param cl
2786  *  A pointer to command line context.
2787  * @param data
2788  *  A pointer to command specific data
2789  *
2790  */
2791 static void
2792 cmd_action_del_drop_parsed(void *parsed_result, __attribute__ ((unused))
2793                            struct cmdline *cl, void *data)
2794 {
2795         struct cmd_action_del_drop_result *params = parsed_result;
2796         struct app_params *app = data;
2797         struct pipeline_action_key key;
2798         int status;
2799
2800         key.action_id = params->action_id;
2801         key.action_bitmap = acl_action_packet_drop;
2802
2803         status = app_pipeline_action_delete(app, &key);
2804
2805         if (status != 0) {
2806                 printf("Command failed\n");
2807                 return;
2808         }
2809 }
2810
2811 cmdline_parse_token_string_t cmd_action_del_drop_p_string =
2812 TOKEN_STRING_INITIALIZER(struct cmd_action_del_drop_result, p_string,
2813                          "p");
2814
2815 cmdline_parse_token_string_t cmd_action_del_drop_action_string =
2816 TOKEN_STRING_INITIALIZER(struct cmd_action_del_drop_result,
2817                          action_string, "action");
2818
2819 cmdline_parse_token_string_t cmd_action_del_drop_del_string =
2820 TOKEN_STRING_INITIALIZER(struct cmd_action_del_drop_result,
2821                          del_string, "del");
2822
2823 cmdline_parse_token_num_t cmd_action_del_drop_action_id =
2824 TOKEN_NUM_INITIALIZER(struct cmd_action_del_drop_result, action_id,
2825                       UINT32);
2826
2827 cmdline_parse_token_string_t cmd_action_del_drop_drop_string =
2828 TOKEN_STRING_INITIALIZER(struct cmd_action_del_drop_result,
2829                          drop_string, "drop");
2830
2831 cmdline_parse_inst_t cmd_action_del_drop = {
2832         .f = cmd_action_del_drop_parsed,
2833         .data = NULL,
2834         .help_str = "ACL action delete drop",
2835         .tokens = {
2836                    (void *)&cmd_action_del_drop_p_string,
2837                    (void *)&cmd_action_del_drop_action_string,
2838                    (void *)&cmd_action_del_drop_del_string,
2839                    (void *)&cmd_action_del_drop_action_id,
2840                    (void *)&cmd_action_del_drop_drop_string,
2841                    NULL,
2842                    },
2843 };
2844
2845 /*
2846  * p action add fwd
2847  */
2848
2849 /**
2850  * A structure defining the add forward action command.
2851  */
2852 struct cmd_action_add_fwd_result {
2853         cmdline_fixed_string_t p_string;
2854         cmdline_fixed_string_t action_string;
2855         cmdline_fixed_string_t add_string;
2856         int32_t action_id;
2857         cmdline_fixed_string_t fwd_string;
2858         int32_t port_id;
2859 };
2860
2861 /**
2862  * Parse Forward Action Add Command.
2863  *
2864  * @param parsed_result
2865  *  A pointer to CLI command parsed result.
2866  * @param cl
2867  *  A pointer to command line context.
2868  * @param data
2869  *  A pointer to command specific data
2870  *
2871  */
2872 static void
2873 cmd_action_add_fwd_parsed(void *parsed_result, __attribute__ ((unused))
2874                           struct cmdline *cl, void *data)
2875 {
2876         struct cmd_action_add_fwd_result *params = parsed_result;
2877         struct app_params *app = data;
2878         struct pipeline_action_key key;
2879         int status;
2880
2881         key.action_id = params->action_id;
2882         key.action_bitmap = acl_action_fwd;
2883         key.fwd_port = params->port_id;
2884
2885         status = app_pipeline_action_add(app, &key);
2886
2887         if (status != 0) {
2888                 printf("Command failed\n");
2889                 return;
2890         }
2891 }
2892
2893 cmdline_parse_token_string_t cmd_action_add_fwd_p_string =
2894 TOKEN_STRING_INITIALIZER(struct cmd_action_add_fwd_result, p_string,
2895                          "p");
2896
2897 cmdline_parse_token_string_t cmd_action_add_fwd_action_string =
2898 TOKEN_STRING_INITIALIZER(struct cmd_action_add_fwd_result,
2899                          action_string, "action");
2900
2901 cmdline_parse_token_string_t cmd_action_add_fwd_add_string =
2902 TOKEN_STRING_INITIALIZER(struct cmd_action_add_fwd_result,
2903                          add_string, "add");
2904
2905 cmdline_parse_token_num_t cmd_action_add_fwd_action_id =
2906 TOKEN_NUM_INITIALIZER(struct cmd_action_add_fwd_result, action_id,
2907                       UINT32);
2908
2909 cmdline_parse_token_string_t cmd_action_add_fwd_fwd_string =
2910 TOKEN_STRING_INITIALIZER(struct cmd_action_add_fwd_result,
2911                          fwd_string, "fwd");
2912
2913 cmdline_parse_token_num_t cmd_action_add_fwd_port_id =
2914 TOKEN_NUM_INITIALIZER(struct cmd_action_add_fwd_result, port_id,
2915                       UINT32);
2916
2917 cmdline_parse_inst_t cmd_action_add_fwd = {
2918         .f = cmd_action_add_fwd_parsed,
2919         .data = NULL,
2920         .help_str = "ACL action add fwd",
2921         .tokens = {
2922                    (void *)&cmd_action_add_fwd_p_string,
2923                    (void *)&cmd_action_add_fwd_action_string,
2924                    (void *)&cmd_action_add_fwd_add_string,
2925                    (void *)&cmd_action_add_fwd_action_id,
2926                    (void *)&cmd_action_add_fwd_fwd_string,
2927                    (void *)&cmd_action_add_fwd_port_id,
2928                    NULL,
2929                    },
2930 };
2931
2932 /*
2933  * p action del fwd
2934  */
2935
2936 /**
2937  * A structure defining the delete forward action command.
2938  */
2939 struct cmd_action_del_fwd_result {
2940         cmdline_fixed_string_t p_string;
2941         cmdline_fixed_string_t action_string;
2942         cmdline_fixed_string_t del_string;
2943         int32_t action_id;
2944         cmdline_fixed_string_t fwd_string;
2945 };
2946
2947 /**
2948  * Parse Forward Action Delete Command.
2949  *
2950  * @param parsed_result
2951  *  A pointer to CLI command parsed result.
2952  * @param cl
2953  *  A pointer to command line context.
2954  * @param data
2955  *  A pointer to command specific data
2956  *
2957  */
2958 static void
2959 cmd_action_del_fwd_parsed(void *parsed_result, __attribute__ ((unused))
2960                           struct cmdline *cl, void *data)
2961 {
2962         struct cmd_action_del_fwd_result *params = parsed_result;
2963         struct app_params *app = data;
2964         struct pipeline_action_key key;
2965         int status;
2966
2967         key.action_id = params->action_id;
2968         key.action_bitmap = acl_action_fwd;
2969
2970         status = app_pipeline_action_delete(app, &key);
2971
2972         if (status != 0) {
2973                 printf("Command failed\n");
2974                 return;
2975         }
2976 }
2977
2978 cmdline_parse_token_string_t cmd_action_del_fwd_p_string =
2979 TOKEN_STRING_INITIALIZER(struct cmd_action_del_fwd_result, p_string,
2980                          "p");
2981
2982 cmdline_parse_token_string_t cmd_action_del_fwd_action_string =
2983 TOKEN_STRING_INITIALIZER(struct cmd_action_del_fwd_result,
2984                          action_string, "action");
2985
2986 cmdline_parse_token_string_t cmd_action_del_fwd_del_string =
2987 TOKEN_STRING_INITIALIZER(struct cmd_action_del_fwd_result,
2988                          del_string, "del");
2989
2990 cmdline_parse_token_num_t cmd_action_del_fwd_action_id =
2991 TOKEN_NUM_INITIALIZER(struct cmd_action_del_fwd_result, action_id,
2992                       UINT32);
2993
2994 cmdline_parse_token_string_t cmd_action_del_fwd_fwd_string =
2995 TOKEN_STRING_INITIALIZER(struct cmd_action_del_fwd_result,
2996                          fwd_string, "fwd");
2997
2998 cmdline_parse_inst_t cmd_action_del_fwd = {
2999         .f = cmd_action_del_fwd_parsed,
3000         .data = NULL,
3001         .help_str = "ACL action delete fwd",
3002         .tokens = {
3003                    (void *)&cmd_action_del_fwd_p_string,
3004                    (void *)&cmd_action_del_fwd_action_string,
3005                    (void *)&cmd_action_del_fwd_del_string,
3006                    (void *)&cmd_action_del_fwd_action_id,
3007                    (void *)&cmd_action_del_fwd_fwd_string,
3008                    NULL,
3009                    },
3010 };
3011
3012 /*
3013  * p action add nat
3014  */
3015
3016 /**
3017  * A structure defining the add NAT action command.
3018  */
3019 struct cmd_action_add_nat_result {
3020         cmdline_fixed_string_t p_string;
3021         cmdline_fixed_string_t action_string;
3022         cmdline_fixed_string_t add_string;
3023         int32_t action_id;
3024         cmdline_fixed_string_t nat_string;
3025         int32_t port_id;
3026 };
3027
3028 /**
3029  * Parse NAT Action Add Command.
3030  *
3031  * @param parsed_result
3032  *  A pointer to CLI command parsed result.
3033  * @param cl
3034  *  A pointer to command line context.
3035  * @param data
3036  *  A pointer to command specific data
3037  *
3038  */
3039 static void
3040 cmd_action_add_nat_parsed(void *parsed_result, __attribute__ ((unused))
3041                           struct cmdline *cl, void *data)
3042 {
3043         struct cmd_action_add_nat_result *params = parsed_result;
3044         struct app_params *app = data;
3045         struct pipeline_action_key key;
3046         int status;
3047
3048         key.action_id = params->action_id;
3049         key.action_bitmap = acl_action_nat;
3050         key.nat_port = params->port_id;
3051
3052         status = app_pipeline_action_add(app, &key);
3053
3054         if (status != 0) {
3055                 printf("Command failed\n");
3056                 return;
3057         }
3058 }
3059
3060 cmdline_parse_token_string_t cmd_action_add_nat_p_string =
3061 TOKEN_STRING_INITIALIZER(struct cmd_action_add_nat_result, p_string,
3062                          "p");
3063
3064 cmdline_parse_token_string_t cmd_action_add_nat_action_string =
3065 TOKEN_STRING_INITIALIZER(struct cmd_action_add_nat_result,
3066                          action_string, "action");
3067
3068 cmdline_parse_token_string_t cmd_action_add_nat_add_string =
3069 TOKEN_STRING_INITIALIZER(struct cmd_action_add_nat_result,
3070                          add_string, "add");
3071
3072 cmdline_parse_token_num_t cmd_action_add_nat_action_id =
3073 TOKEN_NUM_INITIALIZER(struct cmd_action_add_nat_result, action_id,
3074                       UINT32);
3075
3076 cmdline_parse_token_string_t cmd_action_add_nat_nat_string =
3077 TOKEN_STRING_INITIALIZER(struct cmd_action_add_nat_result,
3078                          nat_string, "nat");
3079
3080 cmdline_parse_token_num_t cmd_action_add_nat_port_id =
3081 TOKEN_NUM_INITIALIZER(struct cmd_action_add_nat_result, port_id,
3082                       UINT32);
3083
3084 cmdline_parse_inst_t cmd_action_add_nat = {
3085         .f = cmd_action_add_nat_parsed,
3086         .data = NULL,
3087         .help_str = "ACL action add nat",
3088         .tokens = {
3089                    (void *)&cmd_action_add_nat_p_string,
3090                    (void *)&cmd_action_add_nat_action_string,
3091                    (void *)&cmd_action_add_nat_add_string,
3092                    (void *)&cmd_action_add_nat_action_id,
3093                    (void *)&cmd_action_add_nat_nat_string,
3094                    (void *)&cmd_action_add_nat_port_id,
3095                    NULL,
3096                    },
3097 };
3098
3099 /*
3100  * p action del nat
3101  */
3102
3103 /**
3104  * A structure defining the delete NAT action command.
3105  */
3106 struct cmd_action_del_nat_result {
3107         cmdline_fixed_string_t p_string;
3108         cmdline_fixed_string_t action_string;
3109         cmdline_fixed_string_t del_string;
3110         int32_t action_id;
3111         cmdline_fixed_string_t nat_string;
3112 };
3113
3114 /**
3115  * Parse NAT Action Delete Command.
3116  *
3117  * @param parsed_result
3118  *  A pointer to CLI command parsed result.
3119  * @param cl
3120  *  A pointer to command line context.
3121  * @param data
3122  *  A pointer to command specific data
3123  *
3124  */
3125 static void
3126 cmd_action_del_nat_parsed(void *parsed_result, __attribute__ ((unused))
3127                           struct cmdline *cl, void *data)
3128 {
3129         struct cmd_action_del_nat_result *params = parsed_result;
3130         struct app_params *app = data;
3131         struct pipeline_action_key key;
3132         int status;
3133
3134         key.action_id = params->action_id;
3135         key.action_bitmap = acl_action_nat;
3136
3137         status = app_pipeline_action_delete(app, &key);
3138
3139         if (status != 0) {
3140                 printf("Command failed\n");
3141                 return;
3142         }
3143 }
3144
3145 cmdline_parse_token_string_t cmd_action_del_nat_p_string =
3146 TOKEN_STRING_INITIALIZER(struct cmd_action_del_nat_result, p_string,
3147                          "p");
3148
3149 cmdline_parse_token_string_t cmd_action_del_nat_action_string =
3150 TOKEN_STRING_INITIALIZER(struct cmd_action_del_nat_result,
3151                          action_string, "action");
3152
3153 cmdline_parse_token_string_t cmd_action_del_nat_del_string =
3154 TOKEN_STRING_INITIALIZER(struct cmd_action_del_nat_result,
3155                          del_string, "del");
3156
3157 cmdline_parse_token_num_t cmd_action_del_nat_action_id =
3158 TOKEN_NUM_INITIALIZER(struct cmd_action_del_nat_result, action_id,
3159                       UINT32);
3160
3161 cmdline_parse_token_string_t cmd_action_del_nat_nat_string =
3162 TOKEN_STRING_INITIALIZER(struct cmd_action_del_nat_result,
3163                          nat_string, "nat");
3164
3165 cmdline_parse_inst_t cmd_action_del_nat = {
3166         .f = cmd_action_del_nat_parsed,
3167         .data = NULL,
3168         .help_str = "ACL action delete nat",
3169         .tokens = {
3170                    (void *)&cmd_action_del_nat_p_string,
3171                    (void *)&cmd_action_del_nat_action_string,
3172                    (void *)&cmd_action_del_nat_del_string,
3173                    (void *)&cmd_action_del_nat_action_id,
3174                    (void *)&cmd_action_del_nat_nat_string,
3175                    NULL,
3176                    },
3177 };
3178
3179 /*
3180  * p action add count
3181  */
3182
3183 /**
3184  * A structure defining the add count action command.
3185  */
3186 struct cmd_action_add_count_result {
3187         cmdline_fixed_string_t p_string;
3188         cmdline_fixed_string_t action_string;
3189         cmdline_fixed_string_t add_string;
3190         int32_t action_id;
3191         cmdline_fixed_string_t count_string;
3192 };
3193
3194 /**
3195  * Parse Count Action Add Command.
3196  *
3197  * @param parsed_result
3198  *  A pointer to CLI command parsed result.
3199  * @param cl
3200  *  A pointer to command line context.
3201  * @param data
3202  *  A pointer to command specific data
3203  *
3204  */
3205 static void
3206 cmd_action_add_count_parsed(void *parsed_result, __attribute__ ((unused))
3207                             struct cmdline *cl, void *data)
3208 {
3209         struct cmd_action_add_count_result *params = parsed_result;
3210         struct app_params *app = data;
3211         struct pipeline_action_key key;
3212         int status;
3213
3214         key.action_id = params->action_id;
3215         key.action_bitmap = acl_action_count;
3216
3217         status = app_pipeline_action_add(app, &key);
3218
3219         if (status != 0) {
3220                 printf("Command failed\n");
3221                 return;
3222         }
3223 }
3224
3225 cmdline_parse_token_string_t cmd_action_add_count_p_string =
3226 TOKEN_STRING_INITIALIZER(struct cmd_action_add_count_result, p_string,
3227                          "p");
3228
3229 cmdline_parse_token_string_t cmd_action_add_count_action_string =
3230 TOKEN_STRING_INITIALIZER(struct cmd_action_add_count_result,
3231                          action_string, "action");
3232
3233 cmdline_parse_token_string_t cmd_action_add_count_add_string =
3234 TOKEN_STRING_INITIALIZER(struct cmd_action_add_count_result,
3235                          add_string, "add");
3236
3237 cmdline_parse_token_num_t cmd_action_add_count_action_id =
3238 TOKEN_NUM_INITIALIZER(struct cmd_action_add_count_result, action_id,
3239                       UINT32);
3240
3241 cmdline_parse_token_string_t cmd_action_add_count_count_string =
3242 TOKEN_STRING_INITIALIZER(struct cmd_action_add_count_result,
3243                          count_string, "count");
3244
3245 cmdline_parse_inst_t cmd_action_add_count = {
3246         .f = cmd_action_add_count_parsed,
3247         .data = NULL,
3248         .help_str = "ACL action add count",
3249         .tokens = {
3250                    (void *)&cmd_action_add_count_p_string,
3251                    (void *)&cmd_action_add_count_action_string,
3252                    (void *)&cmd_action_add_count_add_string,
3253                    (void *)&cmd_action_add_count_action_id,
3254                    (void *)&cmd_action_add_count_count_string,
3255                    NULL,
3256                    },
3257 };
3258
3259 /*
3260  * p action del count
3261  */
3262
3263 /**
3264  * A structure defining the delete count action command.
3265  */
3266 struct cmd_action_del_count_result {
3267         cmdline_fixed_string_t p_string;
3268         cmdline_fixed_string_t action_string;
3269         cmdline_fixed_string_t del_string;
3270         int32_t action_id;
3271         cmdline_fixed_string_t count_string;
3272 };
3273
3274 /**
3275  * Parse Count Action Delete Command.
3276  *
3277  * @param parsed_result
3278  *  A pointer to CLI command parsed result.
3279  * @param cl
3280  *  A pointer to command line context.
3281  * @param data
3282  *  A pointer to command specific data
3283  *
3284  */
3285 static void
3286 cmd_action_del_count_parsed(void *parsed_result, __attribute__ ((unused))
3287                             struct cmdline *cl, void *data)
3288 {
3289         struct cmd_action_del_count_result *params = parsed_result;
3290         struct app_params *app = data;
3291         struct pipeline_action_key key;
3292         int status;
3293
3294         key.action_id = params->action_id;
3295         key.action_bitmap = acl_action_count;
3296
3297         status = app_pipeline_action_delete(app, &key);
3298
3299         if (status != 0) {
3300                 printf("Command failed\n");
3301                 return;
3302         }
3303 }
3304
3305 cmdline_parse_token_string_t cmd_action_del_count_p_string =
3306 TOKEN_STRING_INITIALIZER(struct cmd_action_del_count_result, p_string,
3307                          "p");
3308
3309 cmdline_parse_token_string_t cmd_action_del_count_action_string =
3310 TOKEN_STRING_INITIALIZER(struct cmd_action_del_count_result,
3311                          action_string, "action");
3312
3313 cmdline_parse_token_string_t cmd_action_del_count_del_string =
3314 TOKEN_STRING_INITIALIZER(struct cmd_action_del_count_result,
3315                          del_string, "del");
3316
3317 cmdline_parse_token_num_t cmd_action_del_count_action_id =
3318 TOKEN_NUM_INITIALIZER(struct cmd_action_del_count_result, action_id,
3319                       UINT32);
3320
3321 cmdline_parse_token_string_t cmd_action_del_count_count_string =
3322 TOKEN_STRING_INITIALIZER(struct cmd_action_del_count_result,
3323                          count_string, "count");
3324
3325 cmdline_parse_inst_t cmd_action_del_count = {
3326         .f = cmd_action_del_count_parsed,
3327         .data = NULL,
3328         .help_str = "ACL action delete count",
3329         .tokens = {
3330                    (void *)&cmd_action_del_count_p_string,
3331                    (void *)&cmd_action_del_count_action_string,
3332                    (void *)&cmd_action_del_count_del_string,
3333                    (void *)&cmd_action_del_count_action_id,
3334                    (void *)&cmd_action_del_count_count_string,
3335                    NULL,
3336                    },
3337 };
3338
3339 /*
3340  * p action add dscp
3341  */
3342
3343 /**
3344  * A structure defining the add DSCP action command.
3345  */
3346 struct cmd_action_add_dscp_result {
3347         cmdline_fixed_string_t p_string;
3348         cmdline_fixed_string_t action_string;
3349         cmdline_fixed_string_t add_string;
3350         int32_t action_id;
3351         cmdline_fixed_string_t dscp_string;
3352         uint8_t dscp_priority;
3353 };
3354
3355 /**
3356  * Parse DSCP Action Add Command.
3357  *
3358  * @param parsed_result
3359  *  A pointer to CLI command parsed result.
3360  * @param cl
3361  *  A pointer to command line context.
3362  * @param data
3363  *  A pointer to command specific data
3364  *
3365  */
3366 static void
3367 cmd_action_add_dscp_parsed(void *parsed_result, __attribute__ ((unused))
3368                            struct cmdline *cl, void *data)
3369 {
3370         struct cmd_action_add_dscp_result *params = parsed_result;
3371         struct app_params *app = data;
3372         struct pipeline_action_key key;
3373         int status;
3374
3375         key.action_id = params->action_id;
3376         key.action_bitmap = acl_action_dscp;
3377         key.dscp_priority = params->dscp_priority;
3378
3379         status = app_pipeline_action_add(app, &key);
3380
3381         if (status != 0) {
3382                 printf("Command failed\n");
3383                 return;
3384         }
3385 }
3386
3387 cmdline_parse_token_string_t cmd_action_add_dscp_p_string =
3388 TOKEN_STRING_INITIALIZER(struct cmd_action_add_dscp_result, p_string,
3389                          "p");
3390
3391 cmdline_parse_token_string_t cmd_action_add_dscp_action_string =
3392 TOKEN_STRING_INITIALIZER(struct cmd_action_add_dscp_result,
3393                          action_string, "action");
3394
3395 cmdline_parse_token_string_t cmd_action_add_dscp_add_string =
3396 TOKEN_STRING_INITIALIZER(struct cmd_action_add_dscp_result,
3397                          add_string, "add");
3398
3399 cmdline_parse_token_num_t cmd_action_add_dscp_action_id =
3400 TOKEN_NUM_INITIALIZER(struct cmd_action_add_dscp_result, action_id,
3401                       UINT32);
3402
3403 cmdline_parse_token_string_t cmd_action_add_dscp_dscp_string =
3404 TOKEN_STRING_INITIALIZER(struct cmd_action_add_dscp_result,
3405                          dscp_string, "dscp");
3406
3407 cmdline_parse_token_num_t cmd_action_add_dscp_dscp_priority =
3408 TOKEN_NUM_INITIALIZER(struct cmd_action_add_dscp_result, dscp_priority,
3409                       UINT8);
3410
3411 cmdline_parse_inst_t cmd_action_add_dscp = {
3412         .f = cmd_action_add_dscp_parsed,
3413         .data = NULL,
3414         .help_str = "ACL action add dscp",
3415         .tokens = {
3416                    (void *)&cmd_action_add_dscp_p_string,
3417                    (void *)&cmd_action_add_dscp_action_string,
3418                    (void *)&cmd_action_add_dscp_add_string,
3419                    (void *)&cmd_action_add_dscp_action_id,
3420                    (void *)&cmd_action_add_dscp_dscp_string,
3421                    (void *)&cmd_action_add_dscp_dscp_priority,
3422                    NULL,
3423                    },
3424 };
3425
3426 /*
3427  * p action del dscp
3428  */
3429
3430 /**
3431  * A structure defining the delete DSCP action command.
3432  */
3433 struct cmd_action_del_dscp_result {
3434         cmdline_fixed_string_t p_string;
3435         cmdline_fixed_string_t action_string;
3436         cmdline_fixed_string_t del_string;
3437         int32_t action_id;
3438         cmdline_fixed_string_t dscp_string;
3439 };
3440
3441 /**
3442  * Parse DSCP Action Delete Command.
3443  *
3444  * @param parsed_result
3445  *  A pointer to CLI command parsed result.
3446  * @param cl
3447  *  A pointer to command line context.
3448  * @param data
3449  *  A pointer to command specific data
3450  *
3451  */
3452 static void
3453 cmd_action_del_dscp_parsed(void *parsed_result, __attribute__ ((unused))
3454                            struct cmdline *cl, void *data)
3455 {
3456         struct cmd_action_del_dscp_result *params = parsed_result;
3457         struct app_params *app = data;
3458         struct pipeline_action_key key;
3459         int status;
3460
3461         key.action_id = params->action_id;
3462         key.action_bitmap = acl_action_dscp;
3463
3464         status = app_pipeline_action_delete(app, &key);
3465
3466         if (status != 0) {
3467                 printf("Command failed\n");
3468                 return;
3469         }
3470 }
3471
3472 cmdline_parse_token_string_t cmd_action_del_dscp_p_string =
3473 TOKEN_STRING_INITIALIZER(struct cmd_action_del_dscp_result, p_string,
3474                          "p");
3475
3476 cmdline_parse_token_string_t cmd_action_del_dscp_action_string =
3477 TOKEN_STRING_INITIALIZER(struct cmd_action_del_dscp_result,
3478                          action_string, "action");
3479
3480 cmdline_parse_token_string_t cmd_action_del_dscp_del_string =
3481 TOKEN_STRING_INITIALIZER(struct cmd_action_del_dscp_result,
3482                          del_string, "del");
3483
3484 cmdline_parse_token_num_t cmd_action_del_dscp_action_id =
3485 TOKEN_NUM_INITIALIZER(struct cmd_action_del_dscp_result, action_id,
3486                       UINT32);
3487
3488 cmdline_parse_token_string_t cmd_action_del_dscp_dscp_string =
3489 TOKEN_STRING_INITIALIZER(struct cmd_action_del_dscp_result,
3490                          dscp_string, "dscp");
3491
3492 cmdline_parse_inst_t cmd_action_del_dscp = {
3493         .f = cmd_action_del_dscp_parsed,
3494         .data = NULL,
3495         .help_str = "ACL action delete dscp",
3496         .tokens = {
3497                    (void *)&cmd_action_del_dscp_p_string,
3498                    (void *)&cmd_action_del_dscp_action_string,
3499                    (void *)&cmd_action_del_dscp_del_string,
3500                    (void *)&cmd_action_del_dscp_action_id,
3501                    (void *)&cmd_action_del_dscp_dscp_string,
3502                    NULL,
3503                    },
3504 };
3505
3506 /*
3507  * p action add conntrack
3508  */
3509
3510 /**
3511  * A structure defining the add Connection Tracking action command.
3512  */
3513 struct cmd_action_add_conntrack_result {
3514         cmdline_fixed_string_t p_string;
3515         cmdline_fixed_string_t action_string;
3516         cmdline_fixed_string_t add_string;
3517         int32_t action_id;
3518         cmdline_fixed_string_t conntrack_string;
3519 };
3520
3521 /**
3522  * Parse Connection Tracking Action Add Command.
3523  *
3524  * @param parsed_result
3525  *  A pointer to CLI command parsed result.
3526  * @param cl
3527  *  A pointer to command line context.
3528  * @param data
3529  *  A pointer to command specific data
3530  *
3531  */
3532 static void
3533 cmd_action_add_conntrack_parsed(void *parsed_result, __attribute__ ((unused))
3534                                 struct cmdline *cl, void *data)
3535 {
3536         struct cmd_action_add_conntrack_result *params = parsed_result;
3537         struct app_params *app = data;
3538         struct pipeline_action_key key;
3539         int status;
3540
3541         key.action_id = params->action_id;
3542         key.action_bitmap = acl_action_conntrack;
3543
3544         status = app_pipeline_action_add(app, &key);
3545
3546         if (status != 0) {
3547                 printf("Command failed\n");
3548                 return;
3549         }
3550 }
3551
3552 cmdline_parse_token_string_t cmd_action_add_conntrack_p_string =
3553 TOKEN_STRING_INITIALIZER(struct cmd_action_add_conntrack_result, p_string,
3554                          "p");
3555
3556 cmdline_parse_token_string_t cmd_action_add_conntrack_action_string =
3557 TOKEN_STRING_INITIALIZER(struct cmd_action_add_conntrack_result,
3558                          action_string, "action");
3559
3560 cmdline_parse_token_string_t cmd_action_add_conntrack_add_string =
3561 TOKEN_STRING_INITIALIZER(struct cmd_action_add_conntrack_result,
3562                          add_string, "add");
3563
3564 cmdline_parse_token_num_t cmd_action_add_conntrack_action_id =
3565 TOKEN_NUM_INITIALIZER(struct cmd_action_add_conntrack_result, action_id,
3566                       UINT32);
3567
3568 cmdline_parse_token_string_t cmd_action_add_conntrack_conntrack_string =
3569 TOKEN_STRING_INITIALIZER(struct cmd_action_add_conntrack_result,
3570                          conntrack_string, "conntrack");
3571
3572 cmdline_parse_inst_t cmd_action_add_conntrack = {
3573         .f = cmd_action_add_conntrack_parsed,
3574         .data = NULL,
3575         .help_str = "ACL action add conntrack",
3576         .tokens = {
3577                    (void *)&cmd_action_add_conntrack_p_string,
3578                    (void *)&cmd_action_add_conntrack_action_string,
3579                    (void *)&cmd_action_add_conntrack_add_string,
3580                    (void *)&cmd_action_add_conntrack_action_id,
3581                    (void *)&cmd_action_add_conntrack_conntrack_string,
3582                    NULL,
3583                    },
3584 };
3585
3586 /*
3587  * p action del conntrack
3588  */
3589
3590 /**
3591  * A structure defining the delete Connection Tracking action command.
3592  */
3593 struct cmd_action_del_conntrack_result {
3594         cmdline_fixed_string_t p_string;
3595         cmdline_fixed_string_t action_string;
3596         cmdline_fixed_string_t del_string;
3597         int32_t action_id;
3598         cmdline_fixed_string_t conntrack_string;
3599 };
3600
3601 /**
3602  * Parse Connection Tracking Action Delete Command.
3603  *
3604  * @param parsed_result
3605  *  A pointer to CLI command parsed result.
3606  * @param cl
3607  *  A pointer to command line context.
3608  * @param data
3609  *  A pointer to command specific data
3610  *
3611  */
3612 static void
3613 cmd_action_del_conntrack_parsed(void *parsed_result, __attribute__ ((unused))
3614                                 struct cmdline *cl, void *data)
3615 {
3616         struct cmd_action_del_conntrack_result *params = parsed_result;
3617         struct app_params *app = data;
3618         struct pipeline_action_key key;
3619         int status;
3620
3621         key.action_id = params->action_id;
3622         key.action_bitmap = acl_action_conntrack;
3623
3624         status = app_pipeline_action_delete(app, &key);
3625
3626         if (status != 0) {
3627                 printf("Command failed\n");
3628                 return;
3629         }
3630 }
3631
3632 cmdline_parse_token_string_t cmd_action_del_conntrack_p_string =
3633 TOKEN_STRING_INITIALIZER(struct cmd_action_del_conntrack_result, p_string,
3634                          "p");
3635
3636 cmdline_parse_token_string_t cmd_action_del_conntrack_action_string =
3637 TOKEN_STRING_INITIALIZER(struct cmd_action_del_conntrack_result,
3638                          action_string, "action");
3639
3640 cmdline_parse_token_string_t cmd_action_del_conntrack_del_string =
3641 TOKEN_STRING_INITIALIZER(struct cmd_action_del_conntrack_result,
3642                          del_string, "del");
3643
3644 cmdline_parse_token_num_t cmd_action_del_conntrack_action_id =
3645 TOKEN_NUM_INITIALIZER(struct cmd_action_del_conntrack_result, action_id,
3646                       UINT32);
3647
3648 cmdline_parse_token_string_t cmd_action_del_conntrack_conntrack_string =
3649 TOKEN_STRING_INITIALIZER(struct cmd_action_del_conntrack_result,
3650                          conntrack_string, "conntrack");
3651
3652 cmdline_parse_inst_t cmd_action_del_conntrack = {
3653         .f = cmd_action_del_conntrack_parsed,
3654         .data = NULL,
3655         .help_str = "ACL action delete conntrack",
3656         .tokens = {
3657                    (void *)&cmd_action_del_conntrack_p_string,
3658                    (void *)&cmd_action_del_conntrack_action_string,
3659                    (void *)&cmd_action_del_conntrack_del_string,
3660                    (void *)&cmd_action_del_conntrack_action_id,
3661                    (void *)&cmd_action_del_conntrack_conntrack_string,
3662                    NULL,
3663                    },
3664 };
3665
3666 /*
3667  * p action add connexist
3668  */
3669
3670 /**
3671  * A structure defining the add Connection Exist action command.
3672  */
3673 struct cmd_action_add_connexist_result {
3674         cmdline_fixed_string_t p_string;
3675         cmdline_fixed_string_t action_string;
3676         cmdline_fixed_string_t add_string;
3677         int32_t action_id;
3678         cmdline_fixed_string_t connexist_string;
3679         cmdline_fixed_string_t private_public_string;
3680 };
3681
3682 /**
3683  * Parse Connection Exist Action Add Command.
3684  *
3685  * @param parsed_result
3686  *  A pointer to CLI command parsed result.
3687  * @param cl
3688  *  A pointer to command line context.
3689  * @param data
3690  *  A pointer to command specific data
3691  *
3692  */
3693 static void
3694 cmd_action_add_connexist_parsed(void *parsed_result, __attribute__ ((unused))
3695                                 struct cmdline *cl, void *data)
3696 {
3697         struct cmd_action_add_connexist_result *params = parsed_result;
3698         struct app_params *app = data;
3699         struct pipeline_action_key key;
3700         int status;
3701
3702         if (ACL_DEBUG)
3703                 printf("public_private: %s\n", params->private_public_string);
3704         key.action_id = params->action_id;
3705         key.action_bitmap = acl_action_connexist;
3706         if (strcmp(params->private_public_string, "prvpub") == 0)
3707                 key.private_public = acl_private_public;
3708         else if (strcmp(params->private_public_string, "pubprv") == 0)
3709                 key.private_public = acl_public_private;
3710         else {
3711                 printf("Command failed - Invalid string: %s\n",
3712                        params->private_public_string);
3713                 return;
3714         }
3715
3716         status = app_pipeline_action_add(app, &key);
3717
3718         if (status != 0) {
3719                 printf("Command failed\n");
3720                 return;
3721         }
3722 }
3723
3724 cmdline_parse_token_string_t cmd_action_add_connexist_p_string =
3725 TOKEN_STRING_INITIALIZER(struct cmd_action_add_connexist_result, p_string,
3726                          "p");
3727
3728 cmdline_parse_token_string_t cmd_action_add_connexist_action_string =
3729 TOKEN_STRING_INITIALIZER(struct cmd_action_add_connexist_result,
3730                          action_string, "action");
3731
3732 cmdline_parse_token_string_t cmd_action_add_connexist_add_string =
3733 TOKEN_STRING_INITIALIZER(struct cmd_action_add_connexist_result,
3734                          add_string, "add");
3735
3736 cmdline_parse_token_num_t cmd_action_add_connexist_action_id =
3737 TOKEN_NUM_INITIALIZER(struct cmd_action_add_connexist_result, action_id,
3738                       UINT32);
3739
3740 cmdline_parse_token_string_t cmd_action_add_connexist_connexist_string =
3741 TOKEN_STRING_INITIALIZER(struct cmd_action_add_connexist_result,
3742                          connexist_string, "connexist");
3743
3744 cmdline_parse_token_string_t cmd_action_add_connexist_private_public =
3745 TOKEN_STRING_INITIALIZER(struct cmd_action_add_connexist_result,
3746                          private_public_string,
3747                          NULL);
3748
3749 cmdline_parse_inst_t cmd_action_add_connexist = {
3750         .f = cmd_action_add_connexist_parsed,
3751         .data = NULL,
3752         .help_str = "ACL action add connexist",
3753         .tokens = {
3754                    (void *)&cmd_action_add_connexist_p_string,
3755                    (void *)&cmd_action_add_connexist_action_string,
3756                    (void *)&cmd_action_add_connexist_add_string,
3757                    (void *)&cmd_action_add_connexist_action_id,
3758                    (void *)&cmd_action_add_connexist_connexist_string,
3759                    (void *)&cmd_action_add_connexist_private_public,
3760                    NULL,
3761                    },
3762 };
3763
3764 /*
3765  * p action del connexist
3766  */
3767
3768 /**
3769  * A structure defining the delete Connection Exist action command.
3770  */
3771 struct cmd_action_del_connexist_result {
3772         cmdline_fixed_string_t p_string;
3773         cmdline_fixed_string_t action_string;
3774         cmdline_fixed_string_t del_string;
3775         int32_t action_id;
3776         cmdline_fixed_string_t connexist_string;
3777 };
3778
3779 /**
3780  * Parse Connection Exist Action Delete Command.
3781  *
3782  * @param parsed_result
3783  *  A pointer to CLI command parsed result.
3784  * @param cl
3785  *  A pointer to command line context.
3786  * @param data
3787  *  A pointer to command specific data
3788  *
3789  */
3790 static void
3791 cmd_action_del_connexist_parsed(void *parsed_result, __attribute__ ((unused))
3792                                 struct cmdline *cl, void *data)
3793 {
3794         struct cmd_action_del_connexist_result *params = parsed_result;
3795         struct app_params *app = data;
3796         struct pipeline_action_key key;
3797         int status;
3798
3799         key.action_id = params->action_id;
3800         key.action_bitmap = acl_action_connexist;
3801
3802         status = app_pipeline_action_delete(app, &key);
3803
3804         if (status != 0) {
3805                 printf("Command failed\n");
3806                 return;
3807         }
3808 }
3809
3810 cmdline_parse_token_string_t cmd_action_del_connexist_p_string =
3811 TOKEN_STRING_INITIALIZER(struct cmd_action_del_connexist_result, p_string,
3812                          "p");
3813
3814 cmdline_parse_token_string_t cmd_action_del_connexist_action_string =
3815 TOKEN_STRING_INITIALIZER(struct cmd_action_del_connexist_result,
3816                          action_string, "action");
3817
3818 cmdline_parse_token_string_t cmd_action_del_connexist_add_string =
3819 TOKEN_STRING_INITIALIZER(struct cmd_action_del_connexist_result,
3820                          del_string, "del");
3821
3822 cmdline_parse_token_num_t cmd_action_del_connexist_action_id =
3823 TOKEN_NUM_INITIALIZER(struct cmd_action_del_connexist_result, action_id,
3824                       UINT32);
3825
3826 cmdline_parse_token_string_t cmd_action_del_connexist_connexist_string =
3827 TOKEN_STRING_INITIALIZER(struct cmd_action_del_connexist_result,
3828                          connexist_string, "connexist");
3829
3830 cmdline_parse_inst_t cmd_action_del_connexist = {
3831         .f = cmd_action_del_connexist_parsed,
3832         .data = NULL,
3833         .help_str = "ACL action del connexist",
3834         .tokens = {
3835                    (void *)&cmd_action_del_connexist_p_string,
3836                    (void *)&cmd_action_del_connexist_action_string,
3837                    (void *)&cmd_action_del_connexist_add_string,
3838                    (void *)&cmd_action_del_connexist_action_id,
3839                    (void *)&cmd_action_del_connexist_connexist_string,
3840                    NULL,
3841                    },
3842 };
3843
3844 /*
3845  * p action ls
3846  */
3847
3848 /**
3849  * A structure defining the action ls command.
3850  */
3851 struct cmd_action_ls_result {
3852         cmdline_fixed_string_t p_string;
3853         cmdline_fixed_string_t action_string;
3854         cmdline_fixed_string_t ls_string;
3855         uint32_t table_instance;
3856 };
3857
3858 /**
3859  * Parse Action LS Command.
3860  *
3861  * @param parsed_result
3862  *  A pointer to CLI command parsed result.
3863  * @param cl
3864  *  A pointer to command line context.
3865  * @param data
3866  *  A pointer to command specific data
3867  *
3868  */
3869 static void cmd_action_ls_parsed(void *parsed_result, __attribute__ ((unused))
3870                                  struct cmdline *cl, void *data)
3871 {
3872         struct cmd_action_ls_result *params = parsed_result;
3873         struct app_params *app = data;
3874         uint32_t action_bitmap, i, j;
3875         uint8_t action_found = 0;
3876         struct action_counter_block action_counter_sum;
3877
3878         if (params->table_instance == active_rule_table) {
3879                 printf("Active Action Table:\n");
3880                 printf("Action ID     Action\n");
3881                 printf("=========     ======\n");
3882
3883                 for (i = 0; i < action_array_max; i++) {
3884                         action_bitmap = action_array_active[i].action_bitmap;
3885                         if (action_bitmap != 0) {
3886                                 action_found = 1;
3887                                 if (action_bitmap & acl_action_packet_accept)
3888                                         printf("  %04u        Accept\n", i);
3889                                 if (action_bitmap & acl_action_packet_drop)
3890                                         printf("  %04u        Drop\n", i);
3891                                 if (action_bitmap & acl_action_nat)
3892                                         printf
3893                                             ("  %04u        NAT        "
3894                                              "NAT Port: %u\n",
3895                                              i,
3896                                              action_array_active[i].nat_port);
3897                                 if (action_bitmap & acl_action_fwd)
3898                                         printf
3899                                             ("  %04u        FWD        "
3900                                              "FWD Port: %u\n",
3901                                              i,
3902                                              action_array_active[i].fwd_port);
3903                                 if (action_bitmap & acl_action_count) {
3904                                         action_counter_sum.packetCount = 0;
3905                                         action_counter_sum.byteCount = 0;
3906                                         for (j = 0;
3907                                              j <=
3908                                              rte_ACL_hi_counter_block_in_use;
3909                                              j++) {
3910                                                 action_counter_sum.packetCount
3911                                                     += action_counter_table[j]
3912                                                     [i].packetCount;
3913                                                 action_counter_sum.byteCount +=
3914                                                     action_counter_table[j]
3915                                                     [i].byteCount;
3916                                         }
3917                                         printf
3918                                             ("  %04u         "
3919                                              "Count     Packet Count: %"
3920                                              PRIu64 "   Byte Count: %" PRIu64
3921                                              "\n", i,
3922                                              action_counter_sum.packetCount,
3923                                              action_counter_sum.byteCount);
3924                                 }
3925                                 if (action_bitmap & acl_action_conntrack)
3926                                         printf("  %04u        Conntrack\n", i);
3927                                 if (action_bitmap & acl_action_connexist) {
3928                                         printf("  %04u        Connexist", i);
3929                                         if (action_array_active
3930                                             [i].private_public ==
3931                                             acl_private_public)
3932                                                 printf(" prvpub\n");
3933                                         else
3934                                                 printf(" pubprv\n");
3935                                 }
3936                                 if (action_bitmap & acl_action_dscp)
3937                                         printf
3938                                             ("  %04u        DSCP       "
3939                                              "DSCP Priority: %u\n",
3940                                              i,
3941                                              action_array_active
3942                                              [i].dscp_priority);
3943                         }
3944                 }
3945
3946                 if (!action_found)
3947                         printf("None\n");
3948
3949         } else {
3950                 action_found = 0;
3951                 printf("Standby Action Table:\n");
3952                 printf("Action ID     Action\n");
3953                 printf("=========     ======\n");
3954
3955                 for (i = 0; i < action_array_max; i++) {
3956                         action_bitmap = action_array_standby[i].action_bitmap;
3957                         if (action_bitmap != 0) {
3958                                 action_found = 1;
3959                                 if (action_bitmap & acl_action_packet_accept)
3960                                         printf("  %04u        Accept\n", i);
3961                                 if (action_bitmap & acl_action_packet_drop)
3962                                         printf("  %04u        Drop\n", i);
3963                                 if (action_bitmap & acl_action_nat)
3964                                         printf
3965                                             ("  %04u        NAT        "
3966                                              "NAT Port: %u\n",
3967                                              i,
3968                                              action_array_standby[i].nat_port);
3969                                 if (action_bitmap & acl_action_fwd)
3970                                         printf
3971                                             ("  %04u        FWD        "
3972                                              "FWD Port: %u\n",
3973                                              i,
3974                                              action_array_standby[i].fwd_port);
3975                                 if (action_bitmap & acl_action_count)
3976                                         printf("  %04u        Count\n", i);
3977                                 if (action_bitmap & acl_action_conntrack)
3978                                         printf("  %04u        Conntrack\n", i);
3979                                 if (action_bitmap & acl_action_connexist) {
3980                                         printf("  %04u        Connexist", i);
3981                                         if (action_array_standby
3982                                             [i].private_public ==
3983                                             acl_private_public)
3984                                                 printf(" prvpub\n");
3985                                         else
3986                                                 printf(" pubprv\n");
3987                                 }
3988                                 if (action_bitmap & acl_action_dscp)
3989                                         printf
3990                                             ("  %04u        DSCP       "
3991                                              "DSCP Priority: %u\n",
3992                                              i,
3993                                              action_array_standby
3994                                              [i].dscp_priority);
3995                         }
3996                 }
3997
3998                 if (!action_found)
3999                         printf("None\n");
4000         }
4001 }
4002
4003 cmdline_parse_token_string_t cmd_action_ls_p_string =
4004 TOKEN_STRING_INITIALIZER(struct cmd_action_ls_result, p_string,
4005                          "p");
4006
4007 cmdline_parse_token_string_t cmd_action_ls_action_string =
4008 TOKEN_STRING_INITIALIZER(struct cmd_action_ls_result,
4009                          action_string, "action");
4010
4011 cmdline_parse_token_string_t cmd_action_ls_ls_string =
4012 TOKEN_STRING_INITIALIZER(struct cmd_action_ls_result, ls_string,
4013                          "ls");
4014
4015 cmdline_parse_token_num_t cmd_action_ls_table_instance =
4016 TOKEN_NUM_INITIALIZER(struct cmd_action_ls_result, table_instance,
4017                       UINT32);
4018
4019 cmdline_parse_inst_t cmd_action_ls = {
4020         .f = cmd_action_ls_parsed,
4021         .data = NULL,
4022         .help_str = "ACL action list",
4023         .tokens = {
4024                    (void *)&cmd_action_ls_p_string,
4025                    (void *)&cmd_action_ls_action_string,
4026                    (void *)&cmd_action_ls_ls_string,
4027                    (void *)&cmd_action_ls_table_instance,
4028                    NULL,
4029                    },
4030 };
4031
4032 /*
4033  * p acl onesectimer start/stop
4034  */
4035
4036 /**
4037  * A structure defining the ACL Dump Counter start/stop command.
4038  */
4039 struct cmd_acl_per_sec_ctr_dump_result {
4040         cmdline_fixed_string_t p_string;
4041         cmdline_fixed_string_t acl_string;
4042         cmdline_fixed_string_t per_sec_ctr_dump_string;
4043         cmdline_fixed_string_t stop_string;
4044 };
4045
4046 /**
4047  * Parse Dump Counter Start Command.
4048  * Start timer to display stats to console at regular intervals.
4049  *
4050  * @param parsed_result
4051  *  A pointer to CLI command parsed result.
4052  * @param cl
4053  *  A pointer to command line context.
4054  * @param data
4055  *  A pointer to command specific data
4056  *
4057  */
4058 static void
4059 cmd_acl_per_sec_ctr_dump_start_parsed(void *parsed_result,
4060                                       __attribute__ ((unused))
4061                                       struct cmdline *cl, void *data)
4062 {
4063         struct cmd_acl_per_sec_ctr_dump_result *params = parsed_result;
4064         struct app_params *app = data;
4065
4066         rte_acl_reset_running_averages();
4067         uint32_t core_id = rte_lcore_id();/* execute timeout on current core */
4068         int success = rte_timer_reset(&rte_acl_one_second_timer,
4069                                       rte_acl_ticks_in_one_second, PERIODICAL,
4070                                       core_id,
4071                                       rte_dump_acl_counters_from_master, NULL);
4072 }
4073
4074 /**
4075  * Parse Dump Counter Stop Command.
4076  * Stop timer that was started to display stats.
4077  *
4078  * @param parsed_result
4079  *  A pointer to CLI command parsed result.
4080  * @param cl
4081  *  A pointer to command line context.
4082  * @param data
4083  *  A pointer to command specific data
4084  *
4085  */
4086 static void
4087 cmd_acl_per_sec_ctr_dump_stop_parsed(void *parsed_result,
4088                                      __attribute__ ((unused))
4089                                      struct cmdline *cl, void *data)
4090 {
4091         struct cmd_acl_per_sec_ctr_dump_result *params = parsed_result;
4092         struct app_params *app = data;
4093
4094         rte_timer_stop(&rte_acl_one_second_timer);
4095 }
4096
4097 cmdline_parse_token_string_t cmd_acl_per_sec_ctr_dump_p_string =
4098 TOKEN_STRING_INITIALIZER(struct cmd_acl_per_sec_ctr_dump_result,
4099                          p_string, "p");
4100
4101 cmdline_parse_token_string_t cmd_acl_per_sec_ctr_dump_acl_string =
4102 TOKEN_STRING_INITIALIZER(struct cmd_acl_per_sec_ctr_dump_result,
4103                          acl_string, "acl");
4104
4105 cmdline_parse_token_string_t cmd_acl_per_sec_ctr_dump_string =
4106 TOKEN_STRING_INITIALIZER(struct cmd_acl_per_sec_ctr_dump_result,
4107                          per_sec_ctr_dump_string, "counterdump");
4108
4109 cmdline_parse_token_string_t cmd_acl_stop_string =
4110 TOKEN_STRING_INITIALIZER(struct cmd_acl_per_sec_ctr_dump_result,
4111                          stop_string, "stop");
4112
4113 cmdline_parse_token_string_t cmd_acl_start_string =
4114 TOKEN_STRING_INITIALIZER(struct cmd_acl_per_sec_ctr_dump_result,
4115                          stop_string, "start");
4116
4117 cmdline_parse_inst_t cmd_acl_per_sec_ctr_dump_stop = {
4118         .f = cmd_acl_per_sec_ctr_dump_stop_parsed,
4119         .data = NULL,
4120         .help_str = "ACL counterdump stop",
4121         .tokens = {
4122                    (void *)&cmd_acl_per_sec_ctr_dump_p_string,
4123                    (void *)&cmd_acl_per_sec_ctr_dump_acl_string,
4124                    (void *)&cmd_acl_per_sec_ctr_dump_string,
4125                    (void *)&cmd_acl_stop_string,
4126                    NULL,
4127                    },
4128 };
4129
4130 cmdline_parse_inst_t cmd_acl_per_sec_ctr_dump_start = {
4131         .f = cmd_acl_per_sec_ctr_dump_start_parsed,
4132         .data = NULL,
4133         .help_str = "ACL counterdump start",
4134         .tokens = {
4135                    (void *)&cmd_acl_per_sec_ctr_dump_p_string,
4136                    (void *)&cmd_acl_per_sec_ctr_dump_acl_string,
4137                    (void *)&cmd_acl_per_sec_ctr_dump_string,
4138                    (void *)&cmd_acl_start_string,
4139                    NULL,
4140                    },
4141 };
4142
4143 static cmdline_parse_ctx_t pipeline_cmds[] = {
4144         (cmdline_parse_inst_t *) &cmd_acl_add_ip,
4145         (cmdline_parse_inst_t *) &cmd_acl_del_ip,
4146         (cmdline_parse_inst_t *) &cmd_acl_stats,
4147         (cmdline_parse_inst_t *) &cmd_acl_clearstats,
4148         (cmdline_parse_inst_t *) &cmd_acl_dbg,
4149         (cmdline_parse_inst_t *) &cmd_acl_clearrules,
4150         (cmdline_parse_inst_t *) &cmd_loadrules,
4151         (cmdline_parse_inst_t *) &cmd_acl_ls,
4152         (cmdline_parse_inst_t *) &cmd_action_add_accept,
4153         (cmdline_parse_inst_t *) &cmd_action_del_accept,
4154         (cmdline_parse_inst_t *) &cmd_action_add_drop,
4155         (cmdline_parse_inst_t *) &cmd_action_del_drop,
4156         (cmdline_parse_inst_t *) &cmd_action_add_fwd,
4157         (cmdline_parse_inst_t *) &cmd_action_del_fwd,
4158         (cmdline_parse_inst_t *) &cmd_action_add_nat,
4159         (cmdline_parse_inst_t *) &cmd_action_del_nat,
4160         (cmdline_parse_inst_t *) &cmd_action_add_count,
4161         (cmdline_parse_inst_t *) &cmd_action_del_count,
4162         (cmdline_parse_inst_t *) &cmd_action_add_dscp,
4163         (cmdline_parse_inst_t *) &cmd_action_del_dscp,
4164         (cmdline_parse_inst_t *) &cmd_action_add_conntrack,
4165         (cmdline_parse_inst_t *) &cmd_action_del_conntrack,
4166         (cmdline_parse_inst_t *) &cmd_action_add_connexist,
4167         (cmdline_parse_inst_t *) &cmd_action_del_connexist,
4168         (cmdline_parse_inst_t *) &cmd_action_ls,
4169         (cmdline_parse_inst_t *) &cmd_acl_applyruleset,
4170         (cmdline_parse_inst_t *) &cmd_acl_per_sec_ctr_dump_stop,
4171         (cmdline_parse_inst_t *) &cmd_acl_per_sec_ctr_dump_start,
4172         NULL,
4173 };
4174
4175 static struct pipeline_fe_ops pipeline_acl_fe_ops = {
4176         .f_init = app_pipeline_acl_init,
4177         .f_free = app_pipeline_acl_free,
4178         .cmds = pipeline_cmds,
4179 };
4180
4181 struct pipeline_type pipeline_acl = {
4182         .name = "ACL",
4183         .be_ops = &pipeline_acl_be_ops,
4184         .fe_ops = &pipeline_acl_fe_ops,
4185 };
4186
4187 void all_acl_stats(struct mg_connection *conn)
4188 {
4189
4190         struct app_params *app = myapp;
4191         int i, j;
4192         struct rte_ACL_counter_block acl_counter_sums;
4193         struct rte_CT_counter_block ct_counter_sums;
4194         struct rte_CT_counter_block *ct_counters;
4195         struct action_counter_block action_counter_sum[action_array_max];
4196
4197         memset(&acl_counter_sums, 0, sizeof(acl_counter_sums));
4198         memset(&ct_counter_sums, 0, sizeof(ct_counter_sums));
4199
4200         mg_printf(conn,
4201                   "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
4202                   "close\r\n\r\n");
4203         mg_printf(conn, "<html><body>");
4204         mg_printf(conn, "ACL Stats\n");
4205         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
4206                 struct rte_ACL_counter_block *acl_ctrs =
4207                     &rte_acl_counter_table[i];
4208                 ct_counters = rte_acl_counter_table[i].ct_counters;
4209                 mg_printf(conn, "acl entry[%i] tpkts_processed: %" PRIu64
4210                        ", pkts_drop: %" PRIu64 ", pkts_received: %" PRIu64
4211                        ", bytes_processed: %" PRIu64 "\n", i,
4212                        acl_ctrs->tpkts_processed, acl_ctrs->pkts_drop,
4213                        acl_ctrs->pkts_received, acl_ctrs->bytes_processed);
4214
4215                 acl_counter_sums.tpkts_processed += acl_ctrs->tpkts_processed;
4216                 acl_counter_sums.bytes_processed += acl_ctrs->bytes_processed;
4217                 acl_counter_sums.pkts_drop += acl_ctrs->pkts_drop;
4218                 acl_counter_sums.pkts_received += acl_ctrs->pkts_received;
4219                 ct_counter_sums.pkts_forwarded += ct_counters->pkts_forwarded;
4220                 ct_counter_sums.pkts_drop += ct_counters->pkts_drop;
4221         }
4222
4223         mg_printf(conn, "ACL TOTAL: tpkts_processed: %" PRIu64 ", pkts_drop: %" PRIu64
4224                ", pkts_received: %" PRIu64 ", bytes_processed: %" PRIu64 "\n\n",
4225                acl_counter_sums.tpkts_processed,
4226                acl_counter_sums.pkts_drop,
4227                acl_counter_sums.pkts_received,
4228                acl_counter_sums.bytes_processed);
4229
4230         mg_printf(conn, "CT TOTAL: ct_packets_forwarded: %" PRIu64
4231                ", ct_packets_dropped: %" PRIu64 "\n\n",
4232                ct_counter_sums.pkts_forwarded, ct_counter_sums.pkts_drop);
4233
4234         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
4235                 for (j = 0; j < action_array_max; j++) {
4236                         if (action_array_active[j].action_bitmap &
4237                             acl_action_count) {
4238                                 action_counter_sum[j].packetCount +=
4239                                     action_counter_table[i][j].packetCount;
4240                                 action_counter_sum[j].byteCount +=
4241                                     action_counter_table[i][j].byteCount;
4242                         }
4243                 }
4244         }
4245
4246         for (j = 0; j < action_array_max; j++) {
4247                 if (action_array_active[j].action_bitmap & acl_action_count)
4248                         mg_printf(conn, "Action ID: %02u, packetCount: %" PRIu64
4249                                ", byteCount: %" PRIu64 "\n", j,
4250                                action_counter_sum[j].packetCount,
4251                                action_counter_sum[j].byteCount);
4252         }
4253         mg_printf(conn, "<p>Command Passed</p>");
4254         mg_printf(conn, "</body></html>\n");
4255 }
4256
4257 int acl_stats_handler(struct mg_connection *conn, void *cbdata)
4258 {
4259         uint32_t num_links = 0, len = 0;
4260         char buf[1024];
4261         const struct mg_request_info *ri = mg_get_request_info(conn);
4262         struct app_params *app = myapp;
4263         int i;
4264
4265         if (!strcmp(ri->request_method, "GET")) {
4266                 all_acl_stats(conn);
4267                 mg_printf(conn, "%s\n", &buf[0]);
4268                 return 1;
4269         }
4270
4271         if (strcmp(ri->request_method, "POST")) {
4272                 mg_printf(conn,
4273                     "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n");
4274                 mg_printf(conn, "Content-Type: text/plain\r\n\r\n");
4275                 mg_printf(conn,
4276                           "%s method not allowed in the GET handler\n",
4277                           ri->request_method);
4278         }
4279
4280         for (i = 0; i <= rte_ACL_hi_counter_block_in_use; i++) {
4281                 rte_acl_counter_table[i].tpkts_processed = 0;
4282                 rte_acl_counter_table[i].bytes_processed = 0;
4283                 rte_acl_counter_table[i].pkts_drop = 0;
4284                 rte_acl_counter_table[i].pkts_received = 0;
4285                 rte_acl_counter_table[i].pkts_drop_ttl = 0;
4286                 rte_acl_counter_table[i].pkts_drop_bad_size = 0;
4287                 rte_acl_counter_table[i].pkts_drop_fragmented = 0;
4288                 rte_acl_counter_table[i].pkts_drop_without_arp_entry = 0;
4289                 rte_acl_counter_table[i].ct_counters->pkts_forwarded = 0;
4290                 rte_acl_counter_table[i].ct_counters->pkts_drop = 0;
4291         }
4292
4293         memset(&action_counter_table, 0, sizeof(action_counter_table));
4294
4295         mg_printf(conn, "%s\n", &buf[0]);
4296         return 1;
4297
4298 }
4299
4300 int acl_version_handler(struct mg_connection *conn, void *cbdata)
4301 {
4302         const struct mg_request_info *req_info = mg_get_request_info(conn);
4303
4304         mg_printf(conn,
4305                   "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
4306                   "close\r\n\r\n");
4307         mg_printf(conn, "<html><body>");
4308         mg_printf(conn, "<p>Command Passed</p>");
4309         mg_printf(conn, "</body></html>\n");
4310
4311         return 1;
4312 }
4313
4314 int acl_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
4315 {
4316
4317         const struct mg_request_info *req_info = mg_get_request_info(conn);
4318         if (strcmp(req_info->request_method, "GET")) {
4319                         mg_printf(conn, "Only GET method allowed");
4320                         return 1;
4321         }
4322
4323         mg_printf(conn,
4324                  "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
4325                  "close\r\n\r\n");
4326         mg_printf(conn, "<html><body>");
4327         mg_printf(conn, "<h2> These are the methods that are supported </h2>");
4328         mg_printf(conn, "<h3>     /load  </h3>");
4329         mg_printf(conn, "<h3>     /clear </h3>");
4330         mg_printf(conn, "<html><body>");
4331
4332         mg_printf(conn, "</body></html>\n");
4333
4334         return 1;
4335 }
4336
4337 static int acl_field_found(const char *key,
4338                         const char *filename,
4339                         char *path,
4340                         size_t pathlen,
4341                         void *user_data)
4342 {
4343         struct mg_connection *conn = (struct mg_connection *)user_data;
4344
4345         mg_printf(conn, "\r\n\r\n%s:\r\n", key);
4346         mg_printf(conn, "Inside vfw_field_found %s \n", filename);
4347
4348         if (filename && *filename) {
4349                 snprintf(path, pathlen, "/tmp/%s", filename);
4350                 struct app_params *app = myapp;
4351                 int status;
4352                 int fd;
4353
4354                 mg_printf(conn, "path: %s\n", path);
4355
4356                 /* Make sure the file exists before clearing rules and actions */
4357                 fd = open(path, O_RDONLY);
4358                 if (fd < 0) {
4359                         mg_printf(conn, "Cannot open file \"%s\"\n", filename);
4360                         return FORM_FIELD_STORAGE_GET;
4361                 }
4362                 close(fd);
4363
4364                 return FORM_FIELD_STORAGE_STORE;
4365         }
4366
4367         return FORM_FIELD_STORAGE_GET;
4368 }
4369
4370 static int acl_field_get(const char *key, const char *value, size_t valuelen,
4371                  void *user_data)
4372 {
4373         struct mg_connection *conn = (struct mg_connection *)user_data;
4374
4375         if (key[0]) {
4376                 mg_printf(conn, "%s = ", key);
4377         }
4378         mg_write(conn, value, valuelen);
4379
4380         return 0;
4381 }
4382
4383 static int acl_field_stored(const char *path, long long file_size,
4384                  void *user_data)
4385 {
4386         struct mg_connection *conn = (struct mg_connection *)user_data;
4387         int status;
4388
4389         mg_printf(conn,
4390                   "stored as %s (%lu bytes)\r\n\r\n",
4391                   path,
4392                   (unsigned long)file_size);
4393
4394         /* Clear all rules and actions */
4395         status = app_pipeline_acl_clearrules(myapp);
4396
4397         if (status != 0) {
4398                 mg_printf(conn, "Command failed\n");
4399                 return 1;
4400         }
4401
4402         /* Process commands in script file */
4403         app_loadrules_file(pipe_cl->ctx, path);
4404         rules_loaded = 1;
4405
4406         return 0;
4407 }
4408
4409 int acl_load_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
4410 {
4411                 /* Handler may access the request info using mg_get_request_info */
4412                 int ret;
4413                 const struct mg_request_info *req_info = mg_get_request_info(conn);
4414                 struct mg_form_data_handler fdh = {acl_field_found, acl_field_get,
4415                                                                                                  acl_field_stored, 0};
4416
4417                 /* It would be possible to check the request info here before calling
4418                  * mg_handle_form_request. */
4419                 (void)req_info;
4420
4421                 mg_printf(conn,
4422                                   "HTTP/1.1 200 OK\r\nContent-Type: "
4423                                   "text/plain\r\nConnection: close\r\n\r\n");
4424
4425                 if (!strcmp(req_info->request_method, "GET")) {
4426                                 mg_printf(conn, "Rule file is %s\n", rules_loaded? "LOADED":"NOT LOADED");
4427                 }
4428
4429                 if (strcmp(req_info->request_method, "PUT")) {
4430                                 mg_printf(conn, "Only PUT method allowed");
4431                                 return 1;
4432                 }
4433
4434                 fdh.user_data = (void *)conn;
4435
4436                 /* Call the form handler */
4437                 mg_printf(conn, "Form data:");
4438                 ret = mg_handle_form_request(conn, &fdh);
4439                 mg_printf(conn, "\r\n%i fields found", ret);
4440
4441                 return 1;
4442 }
4443
4444 int acl_clear_rules_handler(struct mg_connection *conn, __rte_unused void *cbdata)
4445 {
4446         struct app_params *app = myapp;
4447         int status;
4448         mg_printf(conn,
4449                 "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
4450                 "close\r\n\r\n");
4451         mg_printf(conn, "<html><body>");
4452         status = app_pipeline_acl_clearrules(app);
4453
4454         if (status != 0) {
4455                 mg_printf(conn, "Command failed\n");
4456                 return 1;
4457         }
4458
4459         mg_printf(conn, "Command Success\n");
4460         mg_printf(conn, "</body></html>\n");
4461         return 1;
4462 }
4463
4464 void rest_api_acl_init(struct mg_context *ctx, struct app_params *app)
4465 {
4466         myapp = app;
4467
4468         /* vCGNAPT commands */
4469         mg_set_request_handler(ctx, "/vnf/config/rules", acl_rules_handler, 0);
4470         mg_set_request_handler(ctx, "/vnf/config/rules/load", acl_load_rules_handler, 0);
4471         mg_set_request_handler(ctx, "/vnf/config/rules/clear", acl_clear_rules_handler, 0);
4472         mg_set_request_handler(ctx, "/vnf/status", acl_version_handler, 0);
4473         mg_set_request_handler(ctx, "/vnf/stats", acl_stats_handler, 0);
4474
4475 }