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