add prefix to cache line macros
[dpdk.git] / examples / ip_pipeline / cmdline.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <termios.h>
36 #include <inttypes.h>
37 #include <string.h>
38 #include <netinet/in.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41
42 #include <rte_ether.h>
43 #include <rte_byteorder.h>
44 #include <rte_ring.h>
45 #include <rte_mbuf.h>
46 #include <rte_malloc.h>
47 #include <rte_string_fns.h>
48 #include <cmdline_rdline.h>
49 #include <cmdline_parse.h>
50 #include <cmdline_parse_num.h>
51 #include <cmdline_parse_string.h>
52 #include <cmdline_parse_ipaddr.h>
53 #include <cmdline_parse_etheraddr.h>
54 #include <cmdline_socket.h>
55 #include <cmdline.h>
56
57 #include "main.h"
58
59 #define IS_RULE_PRESENT(res, rule_key, table, type)                     \
60 do {                                                                    \
61         struct app_rule *it;                                            \
62                                                                         \
63         (res) = NULL;                                                   \
64         TAILQ_FOREACH(it, &table, entries) {                            \
65                 if (memcmp(&rule_key, &it->type.key, sizeof(rule_key)) == 0) {\
66                         (res) = it;                                     \
67                         break;                                          \
68                 }                                                       \
69         }                                                               \
70 } while (0)
71
72 /* Rules */
73 static void
74 app_init_rule_tables(void);
75
76 TAILQ_HEAD(linked_list, app_rule) arp_table, routing_table, firewall_table,
77         flow_table;
78
79 uint32_t n_arp_rules;
80 uint32_t n_routing_rules;
81 uint32_t n_firewall_rules;
82 uint32_t n_flow_rules;
83
84 struct app_arp_rule {
85         struct {
86                 uint8_t out_iface;
87                 uint32_t nh_ip;
88         } key;
89
90         struct ether_addr nh_arp;
91 };
92
93 struct app_routing_rule {
94         struct {
95                 uint32_t ip;
96                 uint8_t depth;
97         } key;
98
99         uint8_t port;
100         uint32_t nh_ip;
101 };
102
103 struct app_firewall_rule {
104         struct {
105                 uint32_t src_ip;
106                 uint32_t src_ip_mask;
107                 uint32_t dst_ip;
108                 uint32_t dst_ip_mask;
109                 uint16_t src_port_from;
110                 uint16_t src_port_to;
111                 uint16_t dst_port_from;
112                 uint16_t dst_port_to;
113                 uint8_t proto;
114                 uint8_t proto_mask;
115         } key;
116
117         int32_t priority;
118         uint8_t port;
119 };
120
121 struct app_flow_rule {
122         struct {
123                 uint32_t src_ip;
124                 uint32_t dst_ip;
125                 uint16_t src_port;
126                 uint16_t dst_port;
127                 uint8_t proto;
128         } key;
129
130         uint8_t port;
131 };
132
133 struct app_rule {
134         union {
135                 struct app_arp_rule arp;
136                 struct app_routing_rule routing;
137                 struct app_firewall_rule firewall;
138                 struct app_flow_rule flow;
139         };
140
141         TAILQ_ENTRY(app_rule) entries;
142 };
143
144 /* Initialization */
145 static void
146 app_init_rule_tables(void)
147 {
148         TAILQ_INIT(&arp_table);
149         TAILQ_INIT(&routing_table);
150         TAILQ_INIT(&firewall_table);
151         TAILQ_INIT(&flow_table);
152
153         n_arp_rules = 0;
154         n_routing_rules = 0;
155         n_firewall_rules = 0;
156         n_flow_rules = 0;
157 }
158
159 /* Printing */
160 static void
161 print_arp_rule(struct app_arp_rule rule)
162 {
163         printf("(Iface = %u, Address = %u.%u.%u.%u) => "
164                 "HWaddress = %02x:%02x:%02x:%02x:%02x:%02x\n",
165                 rule.key.out_iface,
166                 (rule.key.nh_ip >> 24) & 0xFF,
167                 (rule.key.nh_ip >> 16) & 0xFF,
168                 (rule.key.nh_ip >> 8) & 0xFF,
169                 rule.key.nh_ip & 0xFF,
170
171                 rule.nh_arp.addr_bytes[0],
172                 rule.nh_arp.addr_bytes[1],
173                 rule.nh_arp.addr_bytes[2],
174                 rule.nh_arp.addr_bytes[3],
175                 rule.nh_arp.addr_bytes[4],
176                 rule.nh_arp.addr_bytes[5]);
177 }
178
179 static void
180 print_routing_rule(struct app_routing_rule rule)
181 {
182         printf("IP Prefix = %u.%u.%u.%u/%u => "
183                 "(Iface = %u, Gateway = %u.%u.%u.%u)\n",
184                 (rule.key.ip >> 24) & 0xFF,
185                 (rule.key.ip >> 16) & 0xFF,
186                 (rule.key.ip >> 8) & 0xFF,
187                 rule.key.ip & 0xFF,
188
189                 rule.key.depth,
190                 rule.port,
191
192                 (rule.nh_ip >> 24) & 0xFF,
193                 (rule.nh_ip >> 16) & 0xFF,
194                 (rule.nh_ip >> 8) & 0xFF,
195                 rule.nh_ip & 0xFF);
196 }
197
198 #ifdef RTE_LIBRTE_ACL
199
200 static void
201 print_firewall_rule(struct app_firewall_rule rule)
202 {
203         printf("Priority %d: (IP Src = %u.%u.%u.%u/%u, "
204                 "IP Dst = %u.%u.%u.%u/%u, "
205                 "Port Src = %u-%u, Port Dst = %u-%u, Proto = %u (%u)) => "
206                 "Port = %u\n",
207                 rule.priority,
208
209                 (rule.key.src_ip >> 24) & 0xFF,
210                 (rule.key.src_ip >> 16) & 0xFF,
211                 (rule.key.src_ip >> 8) & 0xFF,
212                 rule.key.src_ip & 0xFF,
213                 rule.key.src_ip_mask,
214
215                 (rule.key.dst_ip >> 24) & 0xFF,
216                 (rule.key.dst_ip >> 16) & 0xFF,
217                 (rule.key.dst_ip >> 8) & 0xFF,
218                 rule.key.dst_ip & 0xFF,
219                 rule.key.dst_ip_mask,
220
221                 rule.key.src_port_from,
222                 rule.key.src_port_to,
223                 rule.key.dst_port_from,
224                 rule.key.dst_port_to,
225                 rule.key.proto,
226                 rule.key.proto_mask,
227                 rule.port);
228 }
229
230 #endif
231
232 static void
233 print_flow_rule(struct app_flow_rule rule)
234 {
235         printf("(IP Src = %u.%u.%u.%u, IP Dst = %u.%u.%u.%u, Port Src = %u, "
236                 "Port Dst = %u, Proto = %u) => Port = %u\n",
237                 (rule.key.src_ip >> 24) & 0xFF,
238                 (rule.key.src_ip >> 16) & 0xFF,
239                 (rule.key.src_ip >> 8) & 0xFF,
240                 rule.key.src_ip & 0xFF,
241
242                 (rule.key.dst_ip >> 24) & 0xFF,
243                 (rule.key.dst_ip >> 16) & 0xFF,
244                 (rule.key.dst_ip >> 8) & 0xFF,
245                 rule.key.dst_ip  & 0xFF,
246
247                 rule.key.src_port,
248                 rule.key.dst_port,
249                 (uint32_t) rule.key.proto,
250                 rule.port);
251 }
252
253 /* Commands */
254
255 /* *** Run file (script) *** */
256 struct cmd_run_file_result {
257         cmdline_fixed_string_t run_string;
258         char file_path[100];
259 };
260
261 static void
262 cmd_run_file_parsed(
263         void *parsed_result,
264         struct cmdline *cl,
265         __attribute__((unused)) void *data)
266 {
267         struct cmd_run_file_result *params = parsed_result;
268         struct cmdline *file_cl;
269         int fd;
270
271         /* Check params */
272         if (!params->file_path) {
273                 printf("Illegal value for file path (%s)\n", params->file_path);
274                 return;
275         }
276
277         fd = open(params->file_path, O_RDONLY, 0);
278         if (fd < 0) {
279                 printf("Illegal value for file path (%s)\n", params->file_path);
280                 return;
281         }
282
283         file_cl = cmdline_new(cl->ctx, "", fd, 1);
284         cmdline_interact(file_cl);
285         close(fd);
286 }
287
288 cmdline_parse_token_string_t cmd_run_file_run_string =
289         TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, run_string, "run");
290
291 cmdline_parse_token_string_t cmd_run_file_file_path =
292         TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, file_path, NULL);
293
294 cmdline_parse_inst_t cmd_run_file = {
295         .f = cmd_run_file_parsed,
296         .data = NULL,
297         .help_str = "Run commands from file",
298         .tokens = {
299                 (void *)&cmd_run_file_run_string,
300                 (void *)&cmd_run_file_file_path,
301                 NULL,
302         },
303 };
304
305 /* *** Link - Enable *** */
306 struct cmd_link_enable_result {
307         cmdline_fixed_string_t link_string;
308         uint8_t port;
309         cmdline_fixed_string_t up_string;
310 };
311
312 static void
313 cmd_link_enable_parsed(
314         void *parsed_result,
315         __attribute__((unused)) struct cmdline *cl,
316         __attribute__((unused)) void *data)
317 {
318         struct cmd_link_enable_result *params = parsed_result;
319         void *msg;
320         struct app_msg_req *req;
321         struct app_msg_resp *resp;
322         int status;
323
324         uint32_t core_id = app_get_first_core_id(APP_CORE_RX);
325
326         if (core_id == RTE_MAX_LCORE) {
327                 printf("RX core not preformed by any CPU core\n");
328                 return;
329         }
330
331         struct rte_ring *ring_req = app_get_ring_req(core_id);
332         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
333
334         /* Check params */
335         if (params->port >= app.n_ports) {
336                 printf("Illegal value for port parameter (%u)\n", params->port);
337                 return;
338         }
339
340         printf("Enabling port %d\n", params->port);
341
342         /* Allocate message buffer */
343         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
344         if (msg == NULL)
345                 rte_panic("Unable to allocate new message\n");
346
347         /* Fill request message */
348         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
349         req->type = APP_MSG_REQ_RX_PORT_ENABLE;
350         req->rx_up.port = params->port;
351
352         /* Send request */
353         do {
354                 status = rte_ring_sp_enqueue(ring_req, msg);
355         } while (status == -ENOBUFS);
356
357         /* Wait for response */
358         do {
359                 status = rte_ring_sc_dequeue(ring_resp, &msg);
360         } while (status != 0);
361         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
362         /* Check response */
363         if (resp->result != 0)
364                 printf("Request LINK_UP failed (%u)\n", resp->result);
365
366         /* Free message buffer */
367         rte_ctrlmbuf_free(msg);
368 }
369
370 cmdline_parse_token_string_t cmd_link_enable_link_string =
371         TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, link_string,
372         "link");
373
374 cmdline_parse_token_num_t cmd_link_enable_port =
375         TOKEN_NUM_INITIALIZER(struct cmd_link_enable_result, port, UINT8);
376
377 cmdline_parse_token_string_t cmd_link_enable_up_string =
378         TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, up_string,
379         "up");
380
381 cmdline_parse_inst_t cmd_link_enable = {
382         .f = cmd_link_enable_parsed,
383         .data = NULL,
384         .help_str = "Link down",
385         .tokens = {
386                 (void *)&cmd_link_enable_link_string,
387                 (void *)&cmd_link_enable_port,
388                 (void *)&cmd_link_enable_up_string,
389                 NULL,
390         },
391 };
392
393 /* *** Link - Disable *** */
394 struct cmd_link_disable_result {
395         cmdline_fixed_string_t link_string;
396         uint8_t port;
397         cmdline_fixed_string_t down_string;
398 };
399
400 static void
401 cmd_link_disable_parsed(
402         void *parsed_result,
403         __attribute__((unused)) struct cmdline *cl,
404         __attribute__((unused)) void *data)
405 {
406         struct cmd_link_disable_result *params = parsed_result;
407         struct app_msg_req *req;
408         struct app_msg_resp *resp;
409         void *msg;
410         int status;
411
412         uint32_t core_id = app_get_first_core_id(APP_CORE_RX);
413
414         if (core_id == RTE_MAX_LCORE) {
415                 printf("RX not performed by any CPU core\n");
416                 return;
417         }
418
419         struct rte_ring *ring_req = app_get_ring_req(core_id);
420         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
421
422         /* Check params */
423         if (params->port >= app.n_ports) {
424                 printf("Illegal value for port parameter (%u)\n", params->port);
425                 return;
426         }
427
428         printf("Disabling port %d\n", params->port);
429
430         /* Allocate message buffer */
431         msg = rte_ctrlmbuf_alloc(app.msg_pool);
432         if (msg == NULL)
433                 rte_panic("Unable to allocate new message\n");
434
435         /* Fill request message */
436         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
437         req->type = APP_MSG_REQ_RX_PORT_DISABLE;
438         req->rx_down.port = params->port;
439
440         /* Send request */
441         do {
442                 status = rte_ring_sp_enqueue(ring_req, msg);
443         } while (status == -ENOBUFS);
444
445         /* Wait for response */
446         do {
447                 status = rte_ring_sc_dequeue(ring_resp, &msg);
448         } while (status != 0);
449         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
450
451         /* Check response */
452         if (resp->result != 0)
453                 printf("Request LINK_DOWN failed (%u)\n", resp->result);
454
455         /* Free message buffer */
456         rte_ctrlmbuf_free((struct rte_mbuf *)msg);
457 }
458
459 cmdline_parse_token_string_t cmd_link_disable_link_string =
460         TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, link_string,
461         "link");
462
463 cmdline_parse_token_num_t cmd_link_disable_port =
464         TOKEN_NUM_INITIALIZER(struct cmd_link_disable_result, port, UINT8);
465
466 cmdline_parse_token_string_t cmd_link_disable_down_string =
467         TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, down_string,
468         "down");
469
470 cmdline_parse_inst_t cmd_link_disable = {
471         .f = cmd_link_disable_parsed,
472         .data = NULL,
473         .help_str = "Link up",
474         .tokens = {
475                 (void *)&cmd_link_disable_link_string,
476                 (void *)&cmd_link_disable_port,
477                 (void *)&cmd_link_disable_down_string,
478                 NULL,
479         },
480 };
481
482
483 /* *** ARP - Add *** */
484 struct cmd_arp_add_result {
485         cmdline_fixed_string_t arp_string;
486         cmdline_fixed_string_t add_string;
487         uint8_t out_iface;
488         cmdline_ipaddr_t nh_ip;
489         struct ether_addr nh_arp;
490
491 };
492
493 static void
494 cmd_arp_add_parsed(
495         void *parsed_result,
496         __attribute__((unused)) struct cmdline *cl,
497         __attribute__((unused)) void *data)
498 {
499         struct cmd_arp_add_result *params = parsed_result;
500         struct app_rule rule, *old_rule;
501         struct app_msg_req *req;
502         struct app_msg_resp *resp;
503         void *msg;
504         int status;
505
506         uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
507
508         if (core_id == RTE_MAX_LCORE) {
509                 printf("ARP not performed by any CPU core\n");
510                 return;
511         }
512
513         struct rte_ring *ring_req = app_get_ring_req(core_id);
514         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
515
516         /* Check params */
517         if (params->out_iface >= app.n_ports) {
518                 printf("Illegal value for output interface parameter (%u)\n",
519                         params->out_iface);
520                 return;
521         }
522
523         /* Create rule */
524         memset(&rule, 0, sizeof(rule));
525         rule.arp.key.out_iface = params->out_iface;
526         rule.arp.key.nh_ip =
527                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
528         rule.arp.nh_arp = params->nh_arp;
529
530         /* Check rule existence */
531         IS_RULE_PRESENT(old_rule, rule.arp.key, arp_table, arp);
532         if ((old_rule == NULL) && (n_arp_rules == app.max_arp_rules)) {
533                 printf("ARP table is full.\n");
534                 return;
535         }
536
537         printf("Adding ARP entry: ");
538         print_arp_rule(rule.arp);
539
540         /* Allocate message buffer */
541         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
542         if (msg == NULL)
543                 rte_panic("Unable to allocate new message\n");
544
545         /* Fill request message */
546         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
547         req->type = APP_MSG_REQ_ARP_ADD;
548         req->arp_add.out_iface = rule.arp.key.out_iface;
549         req->arp_add.nh_ip = rule.arp.key.nh_ip;
550         req->arp_add.nh_arp = rule.arp.nh_arp;
551
552         /* Send request */
553         do {
554                 status = rte_ring_sp_enqueue(ring_req, msg);
555         } while (status == -ENOBUFS);
556
557         /* Wait for response */
558         do {
559                 status = rte_ring_sc_dequeue(ring_resp, &msg);
560         } while (status != 0);
561         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
562
563         /* Check response */
564         if (resp->result != 0)
565                 printf("Request ARP_ADD failed (%u)\n", resp->result);
566         else {
567                 if (old_rule == NULL) {
568                         struct app_rule *new_rule = (struct app_rule *)
569                                 rte_zmalloc_socket("CLI",
570                                 sizeof(struct app_rule),
571                                 RTE_CACHE_LINE_SIZE,
572                                 rte_socket_id());
573
574                         if (new_rule == NULL)
575                                 rte_panic("Unable to allocate new rule\n");
576
577                         memcpy(new_rule, &rule, sizeof(rule));
578                         TAILQ_INSERT_TAIL(&arp_table, new_rule, entries);
579                         n_arp_rules++;
580                 } else
581                         old_rule->arp.nh_arp = rule.arp.nh_arp;
582         }
583
584         /* Free message buffer */
585         rte_ctrlmbuf_free((struct rte_mbuf *) msg);
586 }
587
588 cmdline_parse_token_string_t cmd_arp_add_arp_string =
589         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arp_string, "arp");
590
591 cmdline_parse_token_string_t cmd_arp_add_add_string =
592         TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, add_string, "add");
593
594 cmdline_parse_token_num_t cmd_arp_add_out_iface =
595         TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, out_iface, UINT8);
596
597 cmdline_parse_token_ipaddr_t cmd_arp_add_nh_ip =
598         TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, nh_ip);
599
600 cmdline_parse_token_etheraddr_t cmd_arp_add_nh_arp =
601         TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, nh_arp);
602
603 cmdline_parse_inst_t cmd_arp_add = {
604         .f = cmd_arp_add_parsed,
605         .data = NULL,
606         .help_str = "ARP add",
607         .tokens = {
608                 (void *)&cmd_arp_add_arp_string,
609                 (void *)&cmd_arp_add_add_string,
610                 (void *)&cmd_arp_add_out_iface,
611                 (void *)&cmd_arp_add_nh_ip,
612                 (void *)&cmd_arp_add_nh_arp,
613                 NULL,
614         },
615         };
616
617 /* *** ARP - Del *** */
618 struct cmd_arp_del_result {
619         cmdline_fixed_string_t arp_string;
620         cmdline_fixed_string_t del_string;
621         uint8_t out_iface;
622         cmdline_ipaddr_t nh_ip;
623 };
624
625 static void
626 cmd_arp_del_parsed(
627         void *parsed_result,
628         __attribute__((unused)) struct cmdline *cl,
629         __attribute__((unused)) void *data)
630 {
631         struct cmd_arp_del_result *params = parsed_result;
632         struct app_rule rule, *old_rule;
633         struct app_msg_req *req;
634         struct app_msg_resp *resp;
635         void *msg;
636         int status;
637
638         uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
639
640         if (core_id == RTE_MAX_LCORE) {
641                 printf("ARP not performed by any CPU core\n");
642                 return;
643         }
644
645         struct rte_ring *ring_req = app_get_ring_req(core_id);
646         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
647
648         /* Check params */
649         if (params->out_iface > app.n_ports) {
650                 printf("Illegal value for output interface parameter (%u)\n",
651                         params->out_iface);
652                 return;
653         }
654
655         /* Create rule */
656         memset(&rule, 0, sizeof(rule));
657         rule.arp.key.out_iface = params->out_iface;
658         rule.arp.key.nh_ip =
659                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
660
661         /* Check rule existence */
662         IS_RULE_PRESENT(old_rule, rule.arp.key, arp_table, arp);
663         if (old_rule == NULL)
664                 return;
665
666         printf("Deleting ARP entry: ");
667         print_arp_rule(old_rule->arp);
668
669         /* Allocate message buffer */
670         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
671         if (msg == NULL)
672                 rte_panic("Unable to allocate new message\n");
673
674         /* Fill request message */
675         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
676         req->type = APP_MSG_REQ_ARP_DEL;
677         req->arp_del.out_iface = rule.arp.key.out_iface;
678         req->arp_del.nh_ip = rule.arp.key.nh_ip;
679
680         /* Send request */
681         do {
682                 status = rte_ring_sp_enqueue(ring_req, msg);
683         } while (status == -ENOBUFS);
684
685         /* Wait for response */
686         do {
687                 status = rte_ring_sc_dequeue(ring_resp, &msg);
688         } while (status != 0);
689         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
690
691         /* Check response */
692         if (resp->result != 0)
693                 printf("Request ARP_DEL failed (%u)\n", resp->result);
694         else {
695                 TAILQ_REMOVE(&arp_table, old_rule, entries);
696                 n_arp_rules--;
697                 rte_free(old_rule);
698         }
699
700         /* Free message buffer */
701         rte_ctrlmbuf_free((struct rte_mbuf *) msg);
702 }
703
704 cmdline_parse_token_string_t cmd_arp_del_arp_string =
705         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arp");
706
707 cmdline_parse_token_string_t cmd_arp_del_del_string =
708         TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, del_string, "del");
709
710 cmdline_parse_token_num_t cmd_arp_del_out_iface =
711         TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, out_iface, UINT8);
712
713 cmdline_parse_token_ipaddr_t cmd_arp_del_nh_ip =
714         TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, nh_ip);
715
716 cmdline_parse_inst_t cmd_arp_del = {
717         .f = cmd_arp_del_parsed,
718         .data = NULL,
719         .help_str = "ARP delete",
720         .tokens = {
721                 (void *)&cmd_arp_del_arp_string,
722                 (void *)&cmd_arp_del_del_string,
723                 (void *)&cmd_arp_del_out_iface,
724                 (void *)&cmd_arp_del_nh_ip,
725                 NULL,
726         },
727 };
728
729 /* *** ARP - Print *** */
730 struct cmd_arp_print_result {
731         cmdline_fixed_string_t arp_string;
732         cmdline_fixed_string_t print_string;
733 };
734
735 static void
736 cmd_arp_print_parsed(
737         __attribute__((unused)) void *parsed_result,
738         __attribute__((unused)) struct cmdline *cl,
739         __attribute__((unused)) void *data)
740 {
741         struct app_rule *it;
742
743         TAILQ_FOREACH(it, &arp_table, entries) {
744                 print_arp_rule(it->arp);
745         }
746 }
747
748 cmdline_parse_token_string_t cmd_arp_print_arp_string =
749         TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, arp_string,
750         "arp");
751
752 cmdline_parse_token_string_t cmd_arp_print_print_string =
753         TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, print_string,
754         "ls");
755
756 cmdline_parse_inst_t cmd_arp_print = {
757         .f = cmd_arp_print_parsed,
758         .data = NULL,
759         .help_str = "ARP list",
760         .tokens = {
761                 (void *)&cmd_arp_print_arp_string,
762                 (void *)&cmd_arp_print_print_string,
763                 NULL,
764         },
765 };
766
767 /* *** Routing - Add *** */
768 struct cmd_route_add_result {
769         cmdline_fixed_string_t route_string;
770         cmdline_fixed_string_t add_string;
771         cmdline_ipaddr_t ip;
772         uint8_t depth;
773         uint8_t port;
774         cmdline_ipaddr_t nh_ip;
775 };
776
777 static void
778 cmd_route_add_parsed(
779         void *parsed_result,
780         __attribute__((unused)) struct cmdline *cl,
781         __attribute__((unused)) void *data)
782 {
783         struct cmd_route_add_result *params = parsed_result;
784         struct app_rule rule, *old_rule;
785         struct app_msg_req *req;
786         struct app_msg_resp *resp;
787         void *msg;
788         int status;
789
790         uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
791
792         if (core_id == RTE_MAX_LCORE) {
793                 printf("Routing not performed by any CPU core\n");
794                 return;
795         }
796
797         struct rte_ring *ring_req = app_get_ring_req(core_id);
798         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
799
800         /* Check params */
801         if ((params->depth == 0) || (params->depth > 32)) {
802                 printf("Illegal value for depth parameter (%u)\n",
803                         params->depth);
804                 return;
805         }
806
807         if (params->port >= app.n_ports) {
808                 printf("Illegal value for port parameter (%u)\n", params->port);
809                 return;
810         }
811
812         /* Create rule */
813         memset(&rule, 0, sizeof(rule));
814         rule.routing.key.ip = rte_bswap32((uint32_t)
815                 params->ip.addr.ipv4.s_addr);
816         rule.routing.key.depth = params->depth;
817         rule.routing.port = params->port;
818         rule.routing.nh_ip =
819                 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
820
821         /* Check rule existence */
822         IS_RULE_PRESENT(old_rule, rule.routing.key, routing_table, routing);
823         if ((old_rule == NULL) && (n_routing_rules == app.max_routing_rules)) {
824                 printf("Routing table is full.\n");
825                 return;
826         }
827
828         printf("Adding route: ");
829         print_routing_rule(rule.routing);
830
831         /* Allocate message buffer */
832         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
833         if (msg == NULL)
834                 rte_panic("Unable to allocate new message\n");
835
836         /* Fill request message */
837         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
838         req->type = APP_MSG_REQ_RT_ADD;
839         req->routing_add.ip = rule.routing.key.ip;
840         req->routing_add.depth = rule.routing.key.depth;
841         req->routing_add.port = rule.routing.port;
842         req->routing_add.nh_ip = rule.routing.nh_ip;
843
844         /* Send request */
845         do {
846                 status = rte_ring_sp_enqueue(ring_req, msg);
847         } while (status == -ENOBUFS);
848
849         /* Wait for response */
850         do {
851                 status = rte_ring_sc_dequeue(ring_resp, &msg);
852         } while (status != 0);
853         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
854
855         /* Check response */
856         if (resp->result != 0)
857                 printf("Request ROUTE_ADD failed (%u)\n", resp->result);
858         else {
859                 if (old_rule == NULL) {
860                         struct app_rule *new_rule = (struct app_rule *)
861                                 rte_zmalloc_socket("CLI",
862                                 sizeof(struct app_rule),
863                                 RTE_CACHE_LINE_SIZE,
864                                 rte_socket_id());
865
866                         if (new_rule == NULL)
867                                 rte_panic("Unable to allocate new rule\n");
868
869                         memcpy(new_rule, &rule, sizeof(rule));
870                         TAILQ_INSERT_TAIL(&routing_table, new_rule, entries);
871                         n_routing_rules++;
872                 } else {
873                         old_rule->routing.port = rule.routing.port;
874                         old_rule->routing.nh_ip = rule.routing.nh_ip;
875                 }
876         }
877
878         /* Free message buffer */
879         rte_ctrlmbuf_free((struct rte_mbuf *) msg);
880 }
881
882 cmdline_parse_token_string_t cmd_route_add_route_string =
883         TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, route_string,
884         "route");
885
886 cmdline_parse_token_string_t cmd_route_add_add_string =
887         TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, add_string,
888         "add");
889
890 cmdline_parse_token_ipaddr_t cmd_route_add_ip =
891         TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, ip);
892
893 cmdline_parse_token_num_t cmd_route_add_depth =
894         TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, depth, UINT8);
895
896 cmdline_parse_token_num_t cmd_route_add_port =
897         TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, port, UINT8);
898
899 cmdline_parse_token_ipaddr_t cmd_route_add_nh_ip =
900         TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, nh_ip);
901
902 cmdline_parse_inst_t cmd_route_add = {
903         .f = cmd_route_add_parsed,
904         .data = NULL,
905         .help_str = "Route add",
906         .tokens = {
907                 (void *)&cmd_route_add_route_string,
908                 (void *)&cmd_route_add_add_string,
909                 (void *)&cmd_route_add_ip,
910                 (void *)&cmd_route_add_depth,
911                 (void *)&cmd_route_add_port,
912                 (void *)&cmd_route_add_nh_ip,
913                 NULL,
914         },
915 };
916
917 /* *** Routing - Del *** */
918 struct cmd_route_del_result {
919         cmdline_fixed_string_t route_string;
920         cmdline_fixed_string_t del_string;
921         cmdline_ipaddr_t ip;
922         uint8_t depth;
923 };
924
925 static void
926 cmd_route_del_parsed(
927         void *parsed_result,
928         __attribute__((unused)) struct cmdline *cl,
929         __attribute__((unused)) void *data)
930 {
931         struct cmd_route_del_result *params = parsed_result;
932         struct app_rule rule, *old_rule;
933         struct app_msg_req *req;
934         struct app_msg_resp *resp;
935         void *msg;
936         int status;
937
938         uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
939
940         if (core_id == RTE_MAX_LCORE) {
941                 printf("Routing not performed by any CPU core\n");
942                 return;
943         }
944
945         struct rte_ring *ring_req = app_get_ring_req(core_id);
946         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
947
948         /* Check params */
949         if ((params->depth == 0) || (params->depth > 32)) {
950                 printf("Illegal value for depth parameter (%u)\n",
951                         params->depth);
952                 return;
953         }
954
955         /* Create rule */
956         memset(&rule, 0, sizeof(rule));
957         rule.routing.key.ip = rte_bswap32((uint32_t)
958                 params->ip.addr.ipv4.s_addr);
959         rule.routing.key.depth = params->depth;
960
961         /* Check rule existence */
962         IS_RULE_PRESENT(old_rule, rule.routing.key, routing_table, routing);
963         if (old_rule == NULL)
964                 return;
965
966         printf("Deleting route: ");
967         print_routing_rule(old_rule->routing);
968
969         /* Allocate message buffer */
970         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
971         if (msg == NULL)
972                 rte_panic("Unable to allocate new message\n");
973
974         /* Fill request message */
975         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
976         req->type = APP_MSG_REQ_RT_DEL;
977         req->routing_del.ip = rule.routing.key.ip;
978         req->routing_del.depth = rule.routing.key.depth;
979
980         /* Send request */
981         do {
982                 status = rte_ring_sp_enqueue(ring_req, msg);
983         } while (status == -ENOBUFS);
984
985         /* Wait for response */
986         do {
987                 status = rte_ring_sc_dequeue(ring_resp, &msg);
988         } while (status != 0);
989         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
990
991         /* Check response */
992         if (resp->result != 0)
993                 printf("Request ROUTE_DEL failed %u)\n", resp->result);
994         else {
995                 TAILQ_REMOVE(&routing_table, old_rule, entries);
996                 rte_free(old_rule);
997                 n_routing_rules--;
998         }
999
1000         /* Free message buffer */
1001         rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1002 }
1003
1004 cmdline_parse_token_string_t cmd_route_del_route_string =
1005         TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, route_string,
1006         "route");
1007
1008 cmdline_parse_token_string_t cmd_route_del_del_string =
1009         TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, del_string,
1010         "del");
1011
1012 cmdline_parse_token_ipaddr_t cmd_route_del_ip =
1013         TOKEN_IPADDR_INITIALIZER(struct cmd_route_del_result, ip);
1014
1015 cmdline_parse_token_num_t cmd_route_del_depth =
1016         TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, depth, UINT8);
1017
1018 cmdline_parse_inst_t cmd_route_del = {
1019         .f = cmd_route_del_parsed,
1020         .data = NULL,
1021         .help_str = "Route delete",
1022         .tokens = {
1023                 (void *)&cmd_route_del_route_string,
1024                 (void *)&cmd_route_del_del_string,
1025                 (void *)&cmd_route_del_ip,
1026                 (void *)&cmd_route_del_depth,
1027                 NULL,
1028         },
1029 };
1030
1031 /* *** Routing - Print *** */
1032 struct cmd_routing_print_result {
1033         cmdline_fixed_string_t routing_string;
1034         cmdline_fixed_string_t print_string;
1035 };
1036
1037 static void
1038 cmd_routing_print_parsed(
1039         __attribute__((unused)) void *parsed_result,
1040         __attribute__((unused)) struct cmdline *cl,
1041         __attribute__((unused)) void *data)
1042 {
1043         struct app_rule *it;
1044
1045         TAILQ_FOREACH(it, &routing_table, entries) {
1046                 print_routing_rule(it->routing);
1047         }
1048 }
1049
1050 cmdline_parse_token_string_t cmd_routing_print_routing_string =
1051         TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result,
1052         routing_string, "route");
1053
1054 cmdline_parse_token_string_t cmd_routing_print_print_string =
1055         TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result, print_string,
1056         "ls");
1057
1058 cmdline_parse_inst_t cmd_routing_print = {
1059         .f = cmd_routing_print_parsed,
1060         .data = NULL,
1061         .help_str = "Route list",
1062         .tokens = {
1063                 (void *)&cmd_routing_print_routing_string,
1064                 (void *)&cmd_routing_print_print_string,
1065                 NULL,
1066         },
1067 };
1068
1069 #ifdef RTE_LIBRTE_ACL
1070
1071 /* *** Firewall - Add *** */
1072 struct cmd_firewall_add_result {
1073         cmdline_fixed_string_t firewall_string;
1074         cmdline_fixed_string_t add_string;
1075         int32_t priority;
1076         cmdline_ipaddr_t src_ip;
1077         uint32_t src_ip_mask;
1078         cmdline_ipaddr_t dst_ip;
1079         uint32_t dst_ip_mask;
1080         uint16_t src_port_from;
1081         uint16_t src_port_to;
1082         uint16_t dst_port_from;
1083         uint16_t dst_port_to;
1084         uint8_t proto;
1085         uint8_t proto_mask;
1086         uint8_t port;
1087 };
1088
1089 static void
1090 cmd_firewall_add_parsed(
1091         void *parsed_result,
1092         __attribute__((unused)) struct cmdline *cl,
1093         __attribute__((unused)) void *data)
1094 {
1095         struct cmd_firewall_add_result *params = parsed_result;
1096         struct app_rule rule, *old_rule;
1097         struct rte_mbuf *msg;
1098         struct app_msg_req *req;
1099         struct app_msg_resp *resp;
1100         int status;
1101
1102         uint32_t core_id = app_get_first_core_id(APP_CORE_FW);
1103
1104         if (core_id == RTE_MAX_LCORE) {
1105                 printf("Firewall not performed by any CPU core\n");
1106                 return;
1107         }
1108
1109         struct rte_ring *ring_req = app_get_ring_req(core_id);
1110         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1111
1112         /* Check params */
1113         if (params->port >= app.n_ports) {
1114                 printf("Illegal value for port parameter (%u)\n", params->port);
1115                 return;
1116         }
1117
1118         /* Create rule */
1119         memset(&rule, 0, sizeof(rule));
1120         rule.firewall.priority = params->priority;
1121         rule.firewall.key.src_ip =
1122                 rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr);
1123         rule.firewall.key.src_ip_mask = params->src_ip_mask;
1124         rule.firewall.key.dst_ip =
1125                 rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr);
1126         rule.firewall.key.dst_ip_mask = params->dst_ip_mask;
1127         rule.firewall.key.src_port_from = params->src_port_from;
1128         rule.firewall.key.src_port_to = params->src_port_to;
1129         rule.firewall.key.dst_port_from = params->dst_port_from;
1130         rule.firewall.key.dst_port_to = params->dst_port_to;
1131         rule.firewall.key.proto = params->proto;
1132         rule.firewall.key.proto_mask = params->proto_mask;
1133         rule.firewall.port = params->port;
1134
1135         /* Check rule existence */
1136         IS_RULE_PRESENT(old_rule, rule.firewall.key, firewall_table, firewall);
1137         if ((old_rule == NULL) &&
1138                 (n_firewall_rules == app.max_firewall_rules)) {
1139                 printf("Firewall table is full.\n");
1140                 return;
1141         }
1142
1143         printf("Adding firewall rule: ");
1144         print_firewall_rule(rule.firewall);
1145
1146         /* Allocate message buffer */
1147         msg = rte_ctrlmbuf_alloc(app.msg_pool);
1148         if (msg == NULL)
1149                 rte_panic("Unable to allocate new message\n");
1150
1151         /* Fill request message */
1152         req = (struct app_msg_req *)rte_ctrlmbuf_data(msg);
1153         req->type = APP_MSG_REQ_FW_ADD;
1154         req->firewall_add.add_params.priority = rule.firewall.priority;
1155         req->firewall_add.add_params.field_value[1].value.u32 =
1156                 rule.firewall.key.src_ip;
1157         req->firewall_add.add_params.field_value[1].mask_range.u32 =
1158                 rule.firewall.key.src_ip_mask;
1159         req->firewall_add.add_params.field_value[2].value.u32 =
1160                 rule.firewall.key.dst_ip;
1161         req->firewall_add.add_params.field_value[2].mask_range.u32 =
1162                 rule.firewall.key.dst_ip_mask;
1163         req->firewall_add.add_params.field_value[3].value.u16 =
1164                 rule.firewall.key.src_port_from;
1165         req->firewall_add.add_params.field_value[3].mask_range.u16 =
1166                 rule.firewall.key.src_port_to;
1167         req->firewall_add.add_params.field_value[4].value.u16 =
1168                 rule.firewall.key.dst_port_from;
1169         req->firewall_add.add_params.field_value[4].mask_range.u16 =
1170                 rule.firewall.key.dst_port_to;
1171         req->firewall_add.add_params.field_value[0].value.u8 =
1172                 rule.firewall.key.proto;
1173         req->firewall_add.add_params.field_value[0].mask_range.u8 =
1174                 rule.firewall.key.proto_mask;
1175         req->firewall_add.port = rule.firewall.port;
1176
1177         /* Send request */
1178         do {
1179                 status = rte_ring_sp_enqueue(ring_req, (void *) msg);
1180         } while (status == -ENOBUFS);
1181
1182         /* Wait for response */
1183         do {
1184                 status = rte_ring_sc_dequeue(ring_resp, (void **) &msg);
1185         } while (status != 0);
1186         resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg);
1187
1188         /* Check response */
1189         if (resp->result != 0)
1190                 printf("Request FIREWALL_ADD failed (%u)\n", resp->result);
1191         else {
1192                 if (old_rule == NULL) {
1193                         struct app_rule *new_rule = (struct app_rule *)
1194                                 rte_zmalloc_socket("CLI",
1195                                 sizeof(struct app_rule),
1196                                 RTE_CACHE_LINE_SIZE,
1197                                 rte_socket_id());
1198
1199                         memcpy(new_rule, &rule, sizeof(rule));
1200                         TAILQ_INSERT_TAIL(&firewall_table, new_rule, entries);
1201                         n_firewall_rules++;
1202                 } else {
1203                         old_rule->firewall.priority = rule.firewall.priority;
1204                         old_rule->firewall.port = rule.firewall.port;
1205                 }
1206         }
1207
1208         /* Free message buffer */
1209         rte_ctrlmbuf_free(msg);
1210 }
1211
1212 cmdline_parse_token_string_t cmd_firewall_add_firewall_string =
1213         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result,
1214         firewall_string, "firewall");
1215
1216 cmdline_parse_token_string_t cmd_firewall_add_add_string =
1217         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result, add_string,
1218         "add");
1219
1220 cmdline_parse_token_num_t cmd_firewall_add_priority =
1221         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, priority, INT32);
1222
1223 cmdline_parse_token_ipaddr_t cmd_firewall_add_src_ip =
1224         TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, src_ip);
1225 cmdline_parse_token_num_t cmd_firewall_add_src_ip_mask =
1226         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_ip_mask,
1227         UINT32);
1228
1229 cmdline_parse_token_ipaddr_t cmd_firewall_add_dst_ip =
1230         TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, dst_ip);
1231 cmdline_parse_token_num_t cmd_firewall_add_dst_ip_mask =
1232         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_ip_mask,
1233         UINT32);
1234
1235 cmdline_parse_token_num_t cmd_firewall_add_src_port_from =
1236         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_from,
1237         UINT16);
1238 cmdline_parse_token_num_t cmd_firewall_add_src_port_to =
1239         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_to,
1240         UINT16);
1241
1242 cmdline_parse_token_num_t cmd_firewall_add_dst_port_from =
1243         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_from,
1244         UINT16);
1245 cmdline_parse_token_num_t cmd_firewall_add_dst_port_to =
1246         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_to,
1247         UINT16);
1248
1249 cmdline_parse_token_num_t cmd_firewall_add_proto =
1250         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto, UINT8);
1251 cmdline_parse_token_num_t cmd_firewall_add_proto_mask =
1252         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto_mask,
1253         UINT8);
1254 cmdline_parse_token_num_t cmd_firewall_add_port =
1255         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, port, UINT8);
1256
1257 cmdline_parse_inst_t cmd_firewall_add = {
1258         .f = cmd_firewall_add_parsed,
1259         .data = NULL,
1260         .help_str = "Firewall rule add",
1261         .tokens = {
1262                 (void *)&cmd_firewall_add_firewall_string,
1263                 (void *)&cmd_firewall_add_add_string,
1264                 (void *)&cmd_firewall_add_priority,
1265                 (void *)&cmd_firewall_add_src_ip,
1266                 (void *)&cmd_firewall_add_src_ip_mask,
1267                 (void *)&cmd_firewall_add_dst_ip,
1268                 (void *)&cmd_firewall_add_dst_ip_mask,
1269                 (void *)&cmd_firewall_add_src_port_from,
1270                 (void *)&cmd_firewall_add_src_port_to,
1271                 (void *)&cmd_firewall_add_dst_port_from,
1272                 (void *)&cmd_firewall_add_dst_port_to,
1273                 (void *)&cmd_firewall_add_proto,
1274                 (void *)&cmd_firewall_add_proto_mask,
1275                 (void *)&cmd_firewall_add_port,
1276                 NULL,
1277         },
1278 };
1279
1280 /* *** firewall - Del *** */
1281 struct cmd_firewall_del_result {
1282         cmdline_fixed_string_t firewall_string;
1283         cmdline_fixed_string_t del_string;
1284         cmdline_ipaddr_t src_ip;
1285         uint32_t src_ip_mask;
1286         cmdline_ipaddr_t dst_ip;
1287         uint32_t dst_ip_mask;
1288         uint16_t src_port_from;
1289         uint16_t src_port_to;
1290         uint16_t dst_port_from;
1291         uint16_t dst_port_to;
1292         uint8_t proto;
1293         uint8_t proto_mask;
1294 };
1295
1296 static void
1297 cmd_firewall_del_parsed(
1298         void *parsed_result,
1299         __attribute__((unused)) struct cmdline *cl,
1300         __attribute__((unused)) void *data)
1301 {
1302         struct cmd_firewall_del_result *params = parsed_result;
1303         struct app_rule rule, *old_rule;
1304         struct rte_mbuf *msg;
1305         struct app_msg_req *req;
1306         struct app_msg_resp *resp;
1307         int status;
1308
1309         uint32_t core_id = app_get_first_core_id(APP_CORE_FW);
1310
1311         if (core_id == RTE_MAX_LCORE) {
1312                 printf("Firewall not performed by any CPU core\n");
1313                 return;
1314         }
1315
1316         struct rte_ring *ring_req = app_get_ring_req(core_id);
1317         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1318
1319         /* Check params */
1320
1321         /* Create rule */
1322         memset(&rule, 0, sizeof(rule));
1323         rule.firewall.key.src_ip =
1324                 rte_bswap32((uint32_t) params->src_ip.addr.ipv4.s_addr);
1325         rule.firewall.key.src_ip_mask = params->src_ip_mask;
1326         rule.firewall.key.dst_ip =
1327                 rte_bswap32((uint32_t) params->dst_ip.addr.ipv4.s_addr);
1328         rule.firewall.key.dst_ip_mask = params->dst_ip_mask;
1329         rule.firewall.key.src_port_from = params->src_port_from;
1330         rule.firewall.key.src_port_to = params->src_port_to;
1331         rule.firewall.key.dst_port_from = params->dst_port_from;
1332         rule.firewall.key.dst_port_to = params->dst_port_to;
1333         rule.firewall.key.proto = params->proto;
1334         rule.firewall.key.proto_mask = params->proto_mask;
1335
1336         /* Check rule existence */
1337         IS_RULE_PRESENT(old_rule, rule.firewall.key, firewall_table, firewall);
1338         if (old_rule == NULL)
1339                 return;
1340
1341         printf("Deleting firewall rule: ");
1342         print_firewall_rule(old_rule->firewall);
1343
1344         /* Allocate message buffer */
1345         msg = rte_ctrlmbuf_alloc(app.msg_pool);
1346         if (msg == NULL)
1347                 rte_panic("Unable to allocate new message\n");
1348
1349         /* Fill request message */
1350         req = (struct app_msg_req *)rte_ctrlmbuf_data(msg);
1351         memset(&req->firewall_del, 0, sizeof(req->firewall_del));
1352         req->type = APP_MSG_REQ_FW_DEL;
1353         req->firewall_del.delete_params.field_value[1].value.u32 =
1354                 rule.firewall.key.src_ip;
1355         req->firewall_del.delete_params.field_value[1].mask_range.u32 =
1356                 rule.firewall.key.src_ip_mask;
1357         req->firewall_del.delete_params.field_value[2].value.u32 =
1358                 rule.firewall.key.dst_ip;
1359         req->firewall_del.delete_params.field_value[2].mask_range.u32 =
1360                 rule.firewall.key.dst_ip_mask;
1361         req->firewall_del.delete_params.field_value[3].value.u16 =
1362                 rule.firewall.key.src_port_from;
1363         req->firewall_del.delete_params.field_value[3].mask_range.u16 =
1364                 rule.firewall.key.src_port_to;
1365         req->firewall_del.delete_params.field_value[4].value.u16 =
1366                 rule.firewall.key.dst_port_from;
1367         req->firewall_del.delete_params.field_value[4].mask_range.u16 =
1368                 rule.firewall.key.dst_port_to;
1369         req->firewall_del.delete_params.field_value[0].value.u8 =
1370                 rule.firewall.key.proto;
1371         req->firewall_del.delete_params.field_value[0].mask_range.u8 =
1372                 rule.firewall.key.proto_mask;
1373
1374         /* Send request */
1375         do {
1376                 status = rte_ring_sp_enqueue(ring_req, (void *) msg);
1377         } while (status == -ENOBUFS);
1378
1379         /* Wait for response */
1380         do {
1381                 status = rte_ring_sc_dequeue(ring_resp, (void **) &msg);
1382         } while (status != 0);
1383         resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg);
1384
1385         /* Check response */
1386         if (resp->result != 0)
1387                 printf("Request FIREWALL_DEL failed %u)\n", resp->result);
1388         else {
1389                 TAILQ_REMOVE(&firewall_table, old_rule, entries);
1390                 rte_free(old_rule);
1391                 n_firewall_rules--;
1392         }
1393
1394         /* Free message buffer */
1395         rte_ctrlmbuf_free(msg);
1396 }
1397
1398 cmdline_parse_token_string_t cmd_firewall_del_firewall_string =
1399         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result,
1400         firewall_string, "firewall");
1401
1402 cmdline_parse_token_string_t cmd_firewall_del_del_string =
1403         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result, del_string,
1404         "del");
1405
1406 cmdline_parse_token_ipaddr_t cmd_firewall_del_src_ip =
1407         TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, src_ip);
1408 cmdline_parse_token_num_t cmd_firewall_del_src_ip_mask =
1409         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_ip_mask,
1410         UINT32);
1411
1412 cmdline_parse_token_ipaddr_t cmd_firewall_del_dst_ip =
1413         TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, dst_ip);
1414 cmdline_parse_token_num_t cmd_firewall_del_dst_ip_mask =
1415         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_ip_mask,
1416         UINT32);
1417
1418 cmdline_parse_token_num_t cmd_firewall_del_src_port_from =
1419         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_from,
1420         UINT16);
1421 cmdline_parse_token_num_t cmd_firewall_del_src_port_to =
1422         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_to,
1423         UINT16);
1424
1425 cmdline_parse_token_num_t cmd_firewall_del_dst_port_from =
1426         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_from,
1427         UINT16);
1428 cmdline_parse_token_num_t cmd_firewall_del_dst_port_to =
1429         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_to,
1430         UINT16);
1431
1432 cmdline_parse_token_num_t cmd_firewall_del_proto =
1433         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto, UINT8);
1434 cmdline_parse_token_num_t cmd_firewall_del_proto_mask =
1435         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto_mask,
1436         UINT8);
1437
1438 cmdline_parse_inst_t cmd_firewall_del = {
1439         .f = cmd_firewall_del_parsed,
1440         .data = NULL,
1441         .help_str = "Firewall rule delete",
1442         .tokens = {
1443                 (void *)&cmd_firewall_del_firewall_string,
1444                 (void *)&cmd_firewall_del_del_string,
1445                 (void *)&cmd_firewall_del_src_ip,
1446                 (void *)&cmd_firewall_del_src_ip_mask,
1447                 (void *)&cmd_firewall_del_dst_ip,
1448                 (void *)&cmd_firewall_del_dst_ip_mask,
1449                 (void *)&cmd_firewall_del_src_port_from,
1450                 (void *)&cmd_firewall_del_src_port_to,
1451                 (void *)&cmd_firewall_del_dst_port_from,
1452                 (void *)&cmd_firewall_del_dst_port_to,
1453                 (void *)&cmd_firewall_del_proto,
1454                 (void *)&cmd_firewall_del_proto_mask,
1455                 NULL,
1456         },
1457 };
1458
1459 /* *** Firewall - Print *** */
1460 struct cmd_firewall_print_result {
1461         cmdline_fixed_string_t firewall_string;
1462         cmdline_fixed_string_t print_string;
1463 };
1464
1465 static void
1466 cmd_firewall_print_parsed(
1467         __attribute__((unused)) void *parsed_result,
1468         __attribute__((unused)) struct cmdline *cl,
1469         __attribute__((unused)) void *data)
1470 {
1471         struct app_rule *it;
1472
1473         TAILQ_FOREACH(it, &firewall_table, entries) {
1474                 print_firewall_rule(it->firewall);
1475         }
1476 }
1477
1478 cmdline_parse_token_string_t cmd_firewall_print_firewall_string =
1479         TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result,
1480         firewall_string, "firewall");
1481
1482 cmdline_parse_token_string_t cmd_firewall_print_print_string =
1483         TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result, print_string,
1484         "ls");
1485
1486 cmdline_parse_inst_t cmd_firewall_print = {
1487         .f = cmd_firewall_print_parsed,
1488         .data = NULL,
1489         .help_str = "Firewall rules list",
1490         .tokens = {
1491                 (void *)&cmd_firewall_print_firewall_string,
1492                 (void *)&cmd_firewall_print_print_string,
1493                 NULL,
1494         },
1495 };
1496
1497 #endif
1498
1499 /* *** Flow Classification - Add All *** */
1500 struct cmd_flow_add_all_result {
1501         cmdline_fixed_string_t flow_string;
1502         cmdline_fixed_string_t add_string;
1503         cmdline_fixed_string_t all_string;
1504 };
1505
1506 static void
1507 cmd_flow_add_all_parsed(
1508         __attribute__((unused)) void *parsed_result,
1509         __attribute__((unused)) struct cmdline *cl,
1510         __attribute__((unused)) void *data)
1511 {
1512         struct app_msg_req *req;
1513         struct app_msg_resp *resp;
1514         void *msg;
1515         int status;
1516
1517         struct rte_ring *ring_req =
1518                 app_get_ring_req(app_get_first_core_id(APP_CORE_FC));
1519         struct rte_ring *ring_resp =
1520                 app_get_ring_resp(app_get_first_core_id(APP_CORE_FC));
1521
1522         /* Allocate message buffer */
1523         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1524         if (msg == NULL)
1525                 rte_panic("Unable to allocate new message\n");
1526
1527         /* Fill request message */
1528         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1529         memset(req, 0, sizeof(struct app_msg_req));
1530
1531         req->type = APP_MSG_REQ_FC_ADD_ALL;
1532
1533         /* Send request */
1534         do {
1535                 status = rte_ring_sp_enqueue(ring_req, msg);
1536         } while (status == -ENOBUFS);
1537
1538         /* Wait for response */
1539         do {
1540                 status = rte_ring_sc_dequeue(ring_resp, &msg);
1541         } while (status != 0);
1542         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1543
1544         /* Check response */
1545         if (resp->result != 0)
1546                 printf("Request FLOW_ADD_ALL failed (%u)\n", resp->result);
1547
1548         /* Free message buffer */
1549         rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1550 }
1551
1552 cmdline_parse_token_string_t cmd_flow_add_all_flow_string =
1553         TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, flow_string,
1554         "flow");
1555
1556 cmdline_parse_token_string_t cmd_flow_add_all_add_string =
1557         TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, add_string,
1558         "add");
1559
1560 cmdline_parse_token_string_t cmd_flow_add_all_all_string =
1561         TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, all_string,
1562         "all");
1563
1564 cmdline_parse_inst_t cmd_flow_add_all = {
1565         .f = cmd_flow_add_all_parsed,
1566         .data = NULL,
1567         .help_str = "Flow table initialization based on hard-coded rule",
1568         .tokens = {
1569                 (void *)&cmd_flow_add_all_flow_string,
1570                 (void *)&cmd_flow_add_all_add_string,
1571                 (void *)&cmd_flow_add_all_all_string,
1572                 NULL,
1573         },
1574 };
1575
1576 /* *** Flow Classification - Add *** */
1577 struct cmd_flow_add_result {
1578         cmdline_fixed_string_t flow_string;
1579         cmdline_fixed_string_t add_string;
1580         cmdline_ipaddr_t src_ip;
1581         cmdline_ipaddr_t dst_ip;
1582         uint16_t src_port;
1583         uint16_t dst_port;
1584         uint8_t proto;
1585         uint8_t port;
1586 };
1587
1588 static void
1589 cmd_flow_add_parsed(
1590         void *parsed_result,
1591         __attribute__((unused)) struct cmdline *cl,
1592         __attribute__((unused)) void *data)
1593 {
1594         struct cmd_flow_add_result *params = parsed_result;
1595         struct app_rule rule, *old_rule;
1596         struct app_msg_req *req;
1597         struct app_msg_resp *resp;
1598         void *msg;
1599         int status;
1600
1601         uint32_t core_id = app_get_first_core_id(APP_CORE_FC);
1602
1603         if (core_id == RTE_MAX_LCORE) {
1604                 printf("Flow classification not performed by any CPU core\n");
1605                 return;
1606         }
1607
1608         struct rte_ring *ring_req = app_get_ring_req(core_id);
1609         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1610
1611         /* Check params */
1612         if (params->port >= app.n_ports) {
1613                 printf("Illegal value for port parameter (%u)\n", params->port);
1614                 return;
1615         }
1616
1617         /* Create rule */
1618         memset(&rule, 0, sizeof(rule));
1619         rule.flow.key.src_ip =
1620                 rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr);
1621         rule.flow.key.dst_ip =
1622                 rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr);
1623         rule.flow.key.src_port = params->src_port;
1624         rule.flow.key.dst_port = params->dst_port;
1625         rule.flow.key.proto = params->proto;
1626         rule.flow.port = params->port;
1627
1628         /* Check rule existence */
1629         IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow);
1630         if ((old_rule == NULL) && (n_flow_rules == app.max_flow_rules)) {
1631                 printf("Flow table is full.\n");
1632                 return;
1633         }
1634
1635         printf("Adding flow: ");
1636         print_flow_rule(rule.flow);
1637
1638         /* Allocate message buffer */
1639         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1640         if (msg == NULL)
1641                 rte_panic("Unable to allocate new message\n");
1642
1643         /* Fill request message */
1644         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1645         memset(req, 0, sizeof(struct app_msg_req));
1646
1647         req->type = APP_MSG_REQ_FC_ADD;
1648         req->flow_classif_add.key.ip_src = rte_bswap32(rule.flow.key.src_ip);
1649         req->flow_classif_add.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip);
1650         req->flow_classif_add.key.port_src =
1651                 rte_bswap16(rule.flow.key.src_port);
1652         req->flow_classif_add.key.port_dst =
1653                 rte_bswap16(rule.flow.key.dst_port);
1654         req->flow_classif_add.key.proto = rule.flow.key.proto;
1655         req->flow_classif_add.port = rule.flow.port;
1656
1657         /* Send request */
1658         do {
1659                 status = rte_ring_sp_enqueue(ring_req, msg);
1660         } while (status == -ENOBUFS);
1661
1662         /* Wait for response */
1663         do {
1664                 status = rte_ring_sc_dequeue(ring_resp, &msg);
1665         } while (status != 0);
1666         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1667
1668         /* Check response */
1669         if (resp->result != 0)
1670                 printf("Request FLOW_ADD failed (%u)\n", resp->result);
1671         else {
1672                 if (old_rule == NULL) {
1673                         struct app_rule *new_rule = (struct app_rule *)
1674                                 rte_zmalloc_socket("CLI",
1675                                 sizeof(struct app_rule),
1676                                 RTE_CACHE_LINE_SIZE,
1677                                 rte_socket_id());
1678
1679                         if (new_rule == NULL)
1680                                 rte_panic("Unable to allocate new rule\n");
1681
1682                         memcpy(new_rule, &rule, sizeof(rule));
1683                         TAILQ_INSERT_TAIL(&flow_table, new_rule, entries);
1684                         n_flow_rules++;
1685                 } else
1686                         old_rule->flow.port = rule.flow.port;
1687         }
1688
1689         /* Free message buffer */
1690         rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1691 }
1692
1693 cmdline_parse_token_string_t cmd_flow_add_flow_string =
1694         TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, flow_string,
1695         "flow");
1696
1697 cmdline_parse_token_string_t cmd_flow_add_add_string =
1698         TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, add_string, "add");
1699
1700 cmdline_parse_token_ipaddr_t cmd_flow_add_src_ip =
1701         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, src_ip);
1702
1703 cmdline_parse_token_ipaddr_t cmd_flow_add_dst_ip =
1704         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, dst_ip);
1705
1706 cmdline_parse_token_num_t cmd_flow_add_src_port =
1707         TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, src_port, UINT16);
1708
1709 cmdline_parse_token_num_t cmd_flow_add_dst_port =
1710         TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, dst_port, UINT16);
1711
1712 cmdline_parse_token_num_t cmd_flow_add_proto =
1713         TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, proto, UINT8);
1714
1715 cmdline_parse_token_num_t cmd_flow_add_port =
1716         TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, port, UINT8);
1717
1718 cmdline_parse_inst_t cmd_flow_add = {
1719         .f = cmd_flow_add_parsed,
1720         .data = NULL,
1721         .help_str = "Flow add",
1722         .tokens = {
1723                 (void *)&cmd_flow_add_flow_string,
1724                 (void *)&cmd_flow_add_add_string,
1725                 (void *)&cmd_flow_add_src_ip,
1726                 (void *)&cmd_flow_add_dst_ip,
1727                 (void *)&cmd_flow_add_src_port,
1728                 (void *)&cmd_flow_add_dst_port,
1729                 (void *)&cmd_flow_add_proto,
1730                 (void *)&cmd_flow_add_port,
1731                 NULL,
1732         },
1733 };
1734
1735 /* *** Flow Classification - Del *** */
1736 struct cmd_flow_del_result {
1737         cmdline_fixed_string_t flow_string;
1738         cmdline_fixed_string_t del_string;
1739         cmdline_ipaddr_t src_ip;
1740         cmdline_ipaddr_t dst_ip;
1741         uint16_t src_port;
1742         uint16_t dst_port;
1743         uint8_t proto;
1744 };
1745
1746 static void
1747 cmd_flow_del_parsed(
1748         void *parsed_result,
1749         __attribute__((unused)) struct cmdline *cl,
1750         __attribute__((unused)) void *data)
1751 {
1752         struct cmd_flow_del_result *params = parsed_result;
1753         struct app_rule rule, *old_rule;
1754         struct app_msg_req *req;
1755         struct app_msg_resp *resp;
1756         void *msg;
1757         int status;
1758
1759         uint32_t core_id = app_get_first_core_id(APP_CORE_FC);
1760
1761         if (core_id == RTE_MAX_LCORE) {
1762                 printf("Flow classification not performed by any CPU core.\n");
1763                 return;
1764         }
1765
1766         struct rte_ring *ring_req = app_get_ring_req(core_id);
1767         struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1768
1769         /* Create rule */
1770         memset(&rule, 0, sizeof(rule));
1771         rule.flow.key.src_ip =
1772                 rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr);
1773         rule.flow.key.dst_ip =
1774                 rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr);
1775         rule.flow.key.src_port = params->src_port;
1776         rule.flow.key.dst_port = params->dst_port;
1777         rule.flow.key.proto = params->proto;
1778
1779         /* Check rule existence */
1780         IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow);
1781         if (old_rule == NULL)
1782                 return;
1783
1784         printf("Deleting flow: ");
1785         print_flow_rule(old_rule->flow);
1786
1787         /* Allocate message buffer */
1788         msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1789         if (msg == NULL)
1790                 rte_panic("Unable to allocate new message\n");
1791
1792         /* Fill request message */
1793         req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1794         memset(req, 0, sizeof(struct app_msg_req));
1795
1796         req->type = APP_MSG_REQ_FC_DEL;
1797         req->flow_classif_del.key.ip_src = rte_bswap32(rule.flow.key.src_ip);
1798         req->flow_classif_del.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip);
1799         req->flow_classif_del.key.port_src =
1800                 rte_bswap32(rule.flow.key.src_port);
1801         req->flow_classif_del.key.port_dst =
1802                 rte_bswap32(rule.flow.key.dst_port);
1803         req->flow_classif_del.key.proto = rule.flow.key.proto;
1804
1805         /* Send request */
1806         do {
1807                 status = rte_ring_sp_enqueue(ring_req, msg);
1808         } while (status == -ENOBUFS);
1809
1810         /* Wait for response */
1811         do {
1812                 status = rte_ring_sc_dequeue(ring_resp, &msg);
1813         } while (status != 0);
1814         resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1815
1816         /* Check response */
1817         if (resp->result != 0)
1818                 printf("Request FLOW_DEL failed (%u)\n", resp->result);
1819         else {
1820                 TAILQ_REMOVE(&flow_table, old_rule, entries);
1821                 rte_free(old_rule);
1822                 n_flow_rules--;
1823         }
1824
1825         /* Free message buffer */
1826         rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1827 }
1828
1829 cmdline_parse_token_string_t cmd_flow_del_flow_string =
1830         TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, flow_string,
1831         "flow");
1832
1833 cmdline_parse_token_string_t cmd_flow_del_del_string =
1834         TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, del_string, "del");
1835
1836 cmdline_parse_token_ipaddr_t cmd_flow_del_src_ip =
1837         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, src_ip);
1838
1839 cmdline_parse_token_ipaddr_t cmd_flow_del_dst_ip =
1840         TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, dst_ip);
1841
1842 cmdline_parse_token_num_t cmd_flow_del_src_port =
1843         TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, src_port, UINT16);
1844
1845 cmdline_parse_token_num_t cmd_flow_del_dst_port =
1846         TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, dst_port, UINT16);
1847
1848 cmdline_parse_token_num_t cmd_flow_del_proto =
1849         TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, proto, UINT8);
1850
1851 cmdline_parse_inst_t cmd_flow_del = {
1852         .f = cmd_flow_del_parsed,
1853         .data = NULL,
1854         .help_str = "Flow delete",
1855         .tokens = {
1856                 (void *)&cmd_flow_del_flow_string,
1857                 (void *)&cmd_flow_del_del_string,
1858                 (void *)&cmd_flow_del_src_ip,
1859                 (void *)&cmd_flow_del_dst_ip,
1860                 (void *)&cmd_flow_del_src_port,
1861                 (void *)&cmd_flow_del_dst_port,
1862                 (void *)&cmd_flow_del_proto,
1863                 NULL,
1864         },
1865 };
1866
1867 /* *** Flow Classification - Print *** */
1868 struct cmd_flow_print_result {
1869         cmdline_fixed_string_t flow_string;
1870         cmdline_fixed_string_t print_string;
1871 };
1872
1873 static void
1874 cmd_flow_print_parsed(
1875         __attribute__((unused)) void *parsed_result,
1876         __attribute__((unused)) struct cmdline *cl,
1877         __attribute__((unused)) void *data)
1878 {
1879         struct app_rule *it;
1880
1881         TAILQ_FOREACH(it, &flow_table, entries) {
1882                 print_flow_rule(it->flow);
1883         }
1884 }
1885
1886 cmdline_parse_token_string_t cmd_flow_print_flow_string =
1887         TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, flow_string,
1888         "flow");
1889
1890 cmdline_parse_token_string_t cmd_flow_print_print_string =
1891         TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, print_string,
1892         "ls");
1893
1894 cmdline_parse_inst_t cmd_flow_print = {
1895         .f = cmd_flow_print_parsed,
1896         .data = NULL,
1897         .help_str = "Flow list",
1898         .tokens = {
1899                 (void *)&cmd_flow_print_flow_string,
1900                 (void *)&cmd_flow_print_print_string,
1901                 NULL,
1902         },
1903 };
1904
1905 /* *** QUIT *** */
1906 struct cmd_quit_result {
1907         cmdline_fixed_string_t quit;
1908 };
1909
1910 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
1911                 struct cmdline *cl,
1912                 __attribute__((unused)) void *data)
1913 {
1914         cmdline_quit(cl);
1915 }
1916
1917 cmdline_parse_token_string_t cmd_quit_quit =
1918                 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
1919
1920 cmdline_parse_inst_t cmd_quit = {
1921         .f = cmd_quit_parsed,
1922         .data = NULL,
1923         .help_str = "Exit application",
1924         .tokens = {
1925                 (void *)&cmd_quit_quit,
1926                 NULL,
1927         },
1928 };
1929
1930 /* List of commands */
1931 cmdline_parse_ctx_t main_ctx[] = {
1932         (cmdline_parse_inst_t *)&cmd_flow_add,
1933         (cmdline_parse_inst_t *)&cmd_flow_del,
1934         (cmdline_parse_inst_t *)&cmd_flow_add_all,
1935         (cmdline_parse_inst_t *)&cmd_flow_print,
1936 #ifdef RTE_LIBRTE_ACL
1937         (cmdline_parse_inst_t *)&cmd_firewall_add,
1938         (cmdline_parse_inst_t *)&cmd_firewall_del,
1939         (cmdline_parse_inst_t *)&cmd_firewall_print,
1940 #endif
1941         (cmdline_parse_inst_t *)&cmd_route_add,
1942         (cmdline_parse_inst_t *)&cmd_route_del,
1943         (cmdline_parse_inst_t *)&cmd_routing_print,
1944         (cmdline_parse_inst_t *)&cmd_arp_add,
1945         (cmdline_parse_inst_t *)&cmd_arp_del,
1946         (cmdline_parse_inst_t *)&cmd_arp_print,
1947         (cmdline_parse_inst_t *)&cmd_run_file,
1948         (cmdline_parse_inst_t *)&cmd_link_enable,
1949         (cmdline_parse_inst_t *)&cmd_link_disable,
1950         (cmdline_parse_inst_t *)&cmd_quit,
1951         NULL,
1952 };
1953
1954 /* Main loop */
1955 void
1956 app_main_loop_cmdline(void)
1957 {
1958         struct cmdline *cl;
1959         uint32_t core_id = rte_lcore_id();
1960
1961         RTE_LOG(INFO, USER1, "Core %u is running the command line interface\n",
1962                 core_id);
1963
1964         n_arp_rules = 0;
1965         n_routing_rules = 0;
1966         n_firewall_rules = 0;
1967         n_flow_rules = 0;
1968
1969         app_init_rule_tables();
1970
1971         cl = cmdline_stdin_new(main_ctx, "pipeline> ");
1972         if (cl == NULL)
1973                 return;
1974         cmdline_interact(cl);
1975         cmdline_stdin_exit(cl);
1976 }