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