4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
38 #include <netinet/in.h>
42 #include <rte_ether.h>
43 #include <rte_byteorder.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>
59 #define IS_RULE_PRESENT(res, rule_key, table, type) \
61 struct app_rule *it; \
64 TAILQ_FOREACH(it, &table, entries) { \
65 if (memcmp(&rule_key, &it->type.key, sizeof(rule_key)) == 0) {\
74 app_init_rule_tables(void);
76 TAILQ_HEAD(linked_list, app_rule) arp_table, routing_table, firewall_table,
80 uint32_t n_routing_rules;
81 uint32_t n_firewall_rules;
82 uint32_t n_flow_rules;
90 struct ether_addr nh_arp;
93 struct app_routing_rule {
103 struct app_firewall_rule {
106 uint32_t src_ip_mask;
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;
121 struct app_flow_rule {
135 struct app_arp_rule arp;
136 struct app_routing_rule routing;
137 struct app_firewall_rule firewall;
138 struct app_flow_rule flow;
141 TAILQ_ENTRY(app_rule) entries;
146 app_init_rule_tables(void)
148 TAILQ_INIT(&arp_table);
149 TAILQ_INIT(&routing_table);
150 TAILQ_INIT(&firewall_table);
151 TAILQ_INIT(&flow_table);
155 n_firewall_rules = 0;
161 print_arp_rule(struct app_arp_rule rule)
163 printf("(Iface = %u, Address = %u.%u.%u.%u) => "
164 "HWaddress = %02x:%02x:%02x:%02x:%02x:%02x\n",
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,
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]);
180 print_routing_rule(struct app_routing_rule rule)
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,
192 (rule.nh_ip >> 24) & 0xFF,
193 (rule.nh_ip >> 16) & 0xFF,
194 (rule.nh_ip >> 8) & 0xFF,
198 #ifdef RTE_LIBRTE_ACL
201 print_firewall_rule(struct app_firewall_rule rule)
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)) => "
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,
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,
221 rule.key.src_port_from,
222 rule.key.src_port_to,
223 rule.key.dst_port_from,
224 rule.key.dst_port_to,
233 print_flow_rule(struct app_flow_rule rule)
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,
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,
249 (uint32_t) rule.key.proto,
255 /* *** Run file (script) *** */
256 struct cmd_run_file_result {
257 cmdline_fixed_string_t run_string;
265 __attribute__((unused)) void *data)
267 struct cmd_run_file_result *params = parsed_result;
268 struct cmdline *file_cl;
272 if (!params->file_path) {
273 printf("Illegal value for file path (%s)\n", params->file_path);
277 fd = open(params->file_path, O_RDONLY, 0);
279 printf("Illegal value for file path (%s)\n", params->file_path);
283 file_cl = cmdline_new(cl->ctx, "", fd, 1);
284 cmdline_interact(file_cl);
288 cmdline_parse_token_string_t cmd_run_file_run_string =
289 TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, run_string, "run");
291 cmdline_parse_token_string_t cmd_run_file_file_path =
292 TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, file_path, NULL);
294 cmdline_parse_inst_t cmd_run_file = {
295 .f = cmd_run_file_parsed,
297 .help_str = "Run commands from file",
299 (void *)&cmd_run_file_run_string,
300 (void *)&cmd_run_file_file_path,
305 /* *** Link - Enable *** */
306 struct cmd_link_enable_result {
307 cmdline_fixed_string_t link_string;
309 cmdline_fixed_string_t up_string;
313 cmd_link_enable_parsed(
315 __attribute__((unused)) struct cmdline *cl,
316 __attribute__((unused)) void *data)
318 struct cmd_link_enable_result *params = parsed_result;
320 struct app_msg_req *req;
321 struct app_msg_resp *resp;
324 uint32_t core_id = app_get_first_core_id(APP_CORE_RX);
326 if (core_id == RTE_MAX_LCORE) {
327 printf("RX core not preformed by any CPU core\n");
331 struct rte_ring *ring_req = app_get_ring_req(core_id);
332 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
335 if (params->port >= app.n_ports) {
336 printf("Illegal value for port parameter (%u)\n", params->port);
340 printf("Enabling port %d\n", params->port);
342 /* Allocate message buffer */
343 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
345 rte_panic("Unable to allocate new message\n");
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;
354 status = rte_ring_sp_enqueue(ring_req, msg);
355 } while (status == -ENOBUFS);
357 /* Wait for response */
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);
363 if (resp->result != 0)
364 printf("Request LINK_UP failed (%u)\n", resp->result);
366 /* Free message buffer */
367 rte_ctrlmbuf_free(msg);
370 cmdline_parse_token_string_t cmd_link_enable_link_string =
371 TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, link_string,
374 cmdline_parse_token_num_t cmd_link_enable_port =
375 TOKEN_NUM_INITIALIZER(struct cmd_link_enable_result, port, UINT8);
377 cmdline_parse_token_string_t cmd_link_enable_up_string =
378 TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, up_string,
381 cmdline_parse_inst_t cmd_link_enable = {
382 .f = cmd_link_enable_parsed,
384 .help_str = "Link down",
386 (void *)&cmd_link_enable_link_string,
387 (void *)&cmd_link_enable_port,
388 (void *)&cmd_link_enable_up_string,
393 /* *** Link - Disable *** */
394 struct cmd_link_disable_result {
395 cmdline_fixed_string_t link_string;
397 cmdline_fixed_string_t down_string;
401 cmd_link_disable_parsed(
403 __attribute__((unused)) struct cmdline *cl,
404 __attribute__((unused)) void *data)
406 struct cmd_link_disable_result *params = parsed_result;
407 struct app_msg_req *req;
408 struct app_msg_resp *resp;
412 uint32_t core_id = app_get_first_core_id(APP_CORE_RX);
414 if (core_id == RTE_MAX_LCORE) {
415 printf("RX not performed by any CPU core\n");
419 struct rte_ring *ring_req = app_get_ring_req(core_id);
420 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
423 if (params->port >= app.n_ports) {
424 printf("Illegal value for port parameter (%u)\n", params->port);
428 printf("Disabling port %d\n", params->port);
430 /* Allocate message buffer */
431 msg = rte_ctrlmbuf_alloc(app.msg_pool);
433 rte_panic("Unable to allocate new message\n");
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;
442 status = rte_ring_sp_enqueue(ring_req, msg);
443 } while (status == -ENOBUFS);
445 /* Wait for response */
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);
452 if (resp->result != 0)
453 printf("Request LINK_DOWN failed (%u)\n", resp->result);
455 /* Free message buffer */
456 rte_ctrlmbuf_free((struct rte_mbuf *)msg);
459 cmdline_parse_token_string_t cmd_link_disable_link_string =
460 TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, link_string,
463 cmdline_parse_token_num_t cmd_link_disable_port =
464 TOKEN_NUM_INITIALIZER(struct cmd_link_disable_result, port, UINT8);
466 cmdline_parse_token_string_t cmd_link_disable_down_string =
467 TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, down_string,
470 cmdline_parse_inst_t cmd_link_disable = {
471 .f = cmd_link_disable_parsed,
473 .help_str = "Link up",
475 (void *)&cmd_link_disable_link_string,
476 (void *)&cmd_link_disable_port,
477 (void *)&cmd_link_disable_down_string,
483 /* *** ARP - Add *** */
484 struct cmd_arp_add_result {
485 cmdline_fixed_string_t arp_string;
486 cmdline_fixed_string_t add_string;
488 cmdline_ipaddr_t nh_ip;
489 struct ether_addr nh_arp;
496 __attribute__((unused)) struct cmdline *cl,
497 __attribute__((unused)) void *data)
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;
506 uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
508 if (core_id == RTE_MAX_LCORE) {
509 printf("ARP not performed by any CPU core\n");
513 struct rte_ring *ring_req = app_get_ring_req(core_id);
514 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
517 if (params->out_iface >= app.n_ports) {
518 printf("Illegal value for output interface parameter (%u)\n",
524 memset(&rule, 0, sizeof(rule));
525 rule.arp.key.out_iface = params->out_iface;
527 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
528 rule.arp.nh_arp = params->nh_arp;
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");
537 printf("Adding ARP entry: ");
538 print_arp_rule(rule.arp);
540 /* Allocate message buffer */
541 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
543 rte_panic("Unable to allocate new message\n");
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;
554 status = rte_ring_sp_enqueue(ring_req, msg);
555 } while (status == -ENOBUFS);
557 /* Wait for response */
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);
564 if (resp->result != 0)
565 printf("Request ARP_ADD failed (%u)\n", resp->result);
567 if (old_rule == NULL) {
568 struct app_rule *new_rule = (struct app_rule *)
569 rte_zmalloc_socket("CLI",
570 sizeof(struct app_rule),
574 if (new_rule == NULL)
575 rte_panic("Unable to allocate new rule\n");
577 memcpy(new_rule, &rule, sizeof(rule));
578 TAILQ_INSERT_TAIL(&arp_table, new_rule, entries);
581 old_rule->arp.nh_arp = rule.arp.nh_arp;
584 /* Free message buffer */
585 rte_ctrlmbuf_free((struct rte_mbuf *) msg);
588 cmdline_parse_token_string_t cmd_arp_add_arp_string =
589 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arp_string, "arp");
591 cmdline_parse_token_string_t cmd_arp_add_add_string =
592 TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, add_string, "add");
594 cmdline_parse_token_num_t cmd_arp_add_out_iface =
595 TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, out_iface, UINT8);
597 cmdline_parse_token_ipaddr_t cmd_arp_add_nh_ip =
598 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, nh_ip);
600 cmdline_parse_token_etheraddr_t cmd_arp_add_nh_arp =
601 TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, nh_arp);
603 cmdline_parse_inst_t cmd_arp_add = {
604 .f = cmd_arp_add_parsed,
606 .help_str = "ARP add",
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,
617 /* *** ARP - Del *** */
618 struct cmd_arp_del_result {
619 cmdline_fixed_string_t arp_string;
620 cmdline_fixed_string_t del_string;
622 cmdline_ipaddr_t nh_ip;
628 __attribute__((unused)) struct cmdline *cl,
629 __attribute__((unused)) void *data)
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;
638 uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
640 if (core_id == RTE_MAX_LCORE) {
641 printf("ARP not performed by any CPU core\n");
645 struct rte_ring *ring_req = app_get_ring_req(core_id);
646 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
649 if (params->out_iface > app.n_ports) {
650 printf("Illegal value for output interface parameter (%u)\n",
656 memset(&rule, 0, sizeof(rule));
657 rule.arp.key.out_iface = params->out_iface;
659 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
661 /* Check rule existence */
662 IS_RULE_PRESENT(old_rule, rule.arp.key, arp_table, arp);
663 if (old_rule == NULL)
666 printf("Deleting ARP entry: ");
667 print_arp_rule(old_rule->arp);
669 /* Allocate message buffer */
670 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
672 rte_panic("Unable to allocate new message\n");
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;
682 status = rte_ring_sp_enqueue(ring_req, msg);
683 } while (status == -ENOBUFS);
685 /* Wait for response */
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);
692 if (resp->result != 0)
693 printf("Request ARP_DEL failed (%u)\n", resp->result);
695 TAILQ_REMOVE(&arp_table, old_rule, entries);
700 /* Free message buffer */
701 rte_ctrlmbuf_free((struct rte_mbuf *) msg);
704 cmdline_parse_token_string_t cmd_arp_del_arp_string =
705 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arp");
707 cmdline_parse_token_string_t cmd_arp_del_del_string =
708 TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, del_string, "del");
710 cmdline_parse_token_num_t cmd_arp_del_out_iface =
711 TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, out_iface, UINT8);
713 cmdline_parse_token_ipaddr_t cmd_arp_del_nh_ip =
714 TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, nh_ip);
716 cmdline_parse_inst_t cmd_arp_del = {
717 .f = cmd_arp_del_parsed,
719 .help_str = "ARP delete",
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,
729 /* *** ARP - Print *** */
730 struct cmd_arp_print_result {
731 cmdline_fixed_string_t arp_string;
732 cmdline_fixed_string_t print_string;
736 cmd_arp_print_parsed(
737 __attribute__((unused)) void *parsed_result,
738 __attribute__((unused)) struct cmdline *cl,
739 __attribute__((unused)) void *data)
743 TAILQ_FOREACH(it, &arp_table, entries) {
744 print_arp_rule(it->arp);
748 cmdline_parse_token_string_t cmd_arp_print_arp_string =
749 TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, arp_string,
752 cmdline_parse_token_string_t cmd_arp_print_print_string =
753 TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, print_string,
756 cmdline_parse_inst_t cmd_arp_print = {
757 .f = cmd_arp_print_parsed,
759 .help_str = "ARP list",
761 (void *)&cmd_arp_print_arp_string,
762 (void *)&cmd_arp_print_print_string,
767 /* *** Routing - Add *** */
768 struct cmd_route_add_result {
769 cmdline_fixed_string_t route_string;
770 cmdline_fixed_string_t add_string;
774 cmdline_ipaddr_t nh_ip;
778 cmd_route_add_parsed(
780 __attribute__((unused)) struct cmdline *cl,
781 __attribute__((unused)) void *data)
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;
790 uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
792 if (core_id == RTE_MAX_LCORE) {
793 printf("Routing not performed by any CPU core\n");
797 struct rte_ring *ring_req = app_get_ring_req(core_id);
798 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
801 if ((params->depth == 0) || (params->depth > 32)) {
802 printf("Illegal value for depth parameter (%u)\n",
807 if (params->port >= app.n_ports) {
808 printf("Illegal value for port parameter (%u)\n", params->port);
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;
819 rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
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");
828 printf("Adding route: ");
829 print_routing_rule(rule.routing);
831 /* Allocate message buffer */
832 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
834 rte_panic("Unable to allocate new message\n");
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;
846 status = rte_ring_sp_enqueue(ring_req, msg);
847 } while (status == -ENOBUFS);
849 /* Wait for response */
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);
856 if (resp->result != 0)
857 printf("Request ROUTE_ADD failed (%u)\n", resp->result);
859 if (old_rule == NULL) {
860 struct app_rule *new_rule = (struct app_rule *)
861 rte_zmalloc_socket("CLI",
862 sizeof(struct app_rule),
866 if (new_rule == NULL)
867 rte_panic("Unable to allocate new rule\n");
869 memcpy(new_rule, &rule, sizeof(rule));
870 TAILQ_INSERT_TAIL(&routing_table, new_rule, entries);
873 old_rule->routing.port = rule.routing.port;
874 old_rule->routing.nh_ip = rule.routing.nh_ip;
878 /* Free message buffer */
879 rte_ctrlmbuf_free((struct rte_mbuf *) msg);
882 cmdline_parse_token_string_t cmd_route_add_route_string =
883 TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, route_string,
886 cmdline_parse_token_string_t cmd_route_add_add_string =
887 TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, add_string,
890 cmdline_parse_token_ipaddr_t cmd_route_add_ip =
891 TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, ip);
893 cmdline_parse_token_num_t cmd_route_add_depth =
894 TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, depth, UINT8);
896 cmdline_parse_token_num_t cmd_route_add_port =
897 TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, port, UINT8);
899 cmdline_parse_token_ipaddr_t cmd_route_add_nh_ip =
900 TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, nh_ip);
902 cmdline_parse_inst_t cmd_route_add = {
903 .f = cmd_route_add_parsed,
905 .help_str = "Route add",
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,
917 /* *** Routing - Del *** */
918 struct cmd_route_del_result {
919 cmdline_fixed_string_t route_string;
920 cmdline_fixed_string_t del_string;
926 cmd_route_del_parsed(
928 __attribute__((unused)) struct cmdline *cl,
929 __attribute__((unused)) void *data)
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;
938 uint32_t core_id = app_get_first_core_id(APP_CORE_RT);
940 if (core_id == RTE_MAX_LCORE) {
941 printf("Routing not performed by any CPU core\n");
945 struct rte_ring *ring_req = app_get_ring_req(core_id);
946 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
949 if ((params->depth == 0) || (params->depth > 32)) {
950 printf("Illegal value for depth parameter (%u)\n",
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;
961 /* Check rule existence */
962 IS_RULE_PRESENT(old_rule, rule.routing.key, routing_table, routing);
963 if (old_rule == NULL)
966 printf("Deleting route: ");
967 print_routing_rule(old_rule->routing);
969 /* Allocate message buffer */
970 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
972 rte_panic("Unable to allocate new message\n");
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;
982 status = rte_ring_sp_enqueue(ring_req, msg);
983 } while (status == -ENOBUFS);
985 /* Wait for response */
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);
992 if (resp->result != 0)
993 printf("Request ROUTE_DEL failed %u)\n", resp->result);
995 TAILQ_REMOVE(&routing_table, old_rule, entries);
1000 /* Free message buffer */
1001 rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1004 cmdline_parse_token_string_t cmd_route_del_route_string =
1005 TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, route_string,
1008 cmdline_parse_token_string_t cmd_route_del_del_string =
1009 TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, del_string,
1012 cmdline_parse_token_ipaddr_t cmd_route_del_ip =
1013 TOKEN_IPADDR_INITIALIZER(struct cmd_route_del_result, ip);
1015 cmdline_parse_token_num_t cmd_route_del_depth =
1016 TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, depth, UINT8);
1018 cmdline_parse_inst_t cmd_route_del = {
1019 .f = cmd_route_del_parsed,
1021 .help_str = "Route delete",
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,
1031 /* *** Routing - Print *** */
1032 struct cmd_routing_print_result {
1033 cmdline_fixed_string_t routing_string;
1034 cmdline_fixed_string_t print_string;
1038 cmd_routing_print_parsed(
1039 __attribute__((unused)) void *parsed_result,
1040 __attribute__((unused)) struct cmdline *cl,
1041 __attribute__((unused)) void *data)
1043 struct app_rule *it;
1045 TAILQ_FOREACH(it, &routing_table, entries) {
1046 print_routing_rule(it->routing);
1050 cmdline_parse_token_string_t cmd_routing_print_routing_string =
1051 TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result,
1052 routing_string, "route");
1054 cmdline_parse_token_string_t cmd_routing_print_print_string =
1055 TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result, print_string,
1058 cmdline_parse_inst_t cmd_routing_print = {
1059 .f = cmd_routing_print_parsed,
1061 .help_str = "Route list",
1063 (void *)&cmd_routing_print_routing_string,
1064 (void *)&cmd_routing_print_print_string,
1069 #ifdef RTE_LIBRTE_ACL
1071 /* *** Firewall - Add *** */
1072 struct cmd_firewall_add_result {
1073 cmdline_fixed_string_t firewall_string;
1074 cmdline_fixed_string_t add_string;
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;
1090 cmd_firewall_add_parsed(
1091 void *parsed_result,
1092 __attribute__((unused)) struct cmdline *cl,
1093 __attribute__((unused)) void *data)
1095 struct cmd_firewall_add_result *params = parsed_result;
1096 struct app_rule rule, *old_rule, *new_rule = NULL;
1097 struct rte_mbuf *msg;
1098 struct app_msg_req *req;
1099 struct app_msg_resp *resp;
1102 uint32_t core_id = app_get_first_core_id(APP_CORE_FW);
1104 if (core_id == RTE_MAX_LCORE) {
1105 printf("Firewall not performed by any CPU core\n");
1109 struct rte_ring *ring_req = app_get_ring_req(core_id);
1110 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1113 if (params->port >= app.n_ports) {
1114 printf("Illegal value for port parameter (%u)\n", params->port);
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;
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");
1143 printf("Adding firewall rule: ");
1144 print_firewall_rule(rule.firewall);
1146 /* Allocate message buffer */
1147 msg = rte_ctrlmbuf_alloc(app.msg_pool);
1149 rte_panic("Unable to allocate new message\n");
1151 /* if we need a new rule structure, allocate it before we go further */
1152 if (old_rule == NULL) {
1153 new_rule = rte_zmalloc_socket("CLI", sizeof(struct app_rule),
1154 RTE_CACHE_LINE_SIZE, rte_socket_id());
1155 if (new_rule == NULL) {
1156 printf("Cannot allocate memory for new rule\n");
1157 rte_ctrlmbuf_free(msg);
1163 /* Fill request message */
1164 req = (struct app_msg_req *)rte_ctrlmbuf_data(msg);
1165 req->type = APP_MSG_REQ_FW_ADD;
1166 req->firewall_add.add_params.priority = rule.firewall.priority;
1167 req->firewall_add.add_params.field_value[1].value.u32 =
1168 rule.firewall.key.src_ip;
1169 req->firewall_add.add_params.field_value[1].mask_range.u32 =
1170 rule.firewall.key.src_ip_mask;
1171 req->firewall_add.add_params.field_value[2].value.u32 =
1172 rule.firewall.key.dst_ip;
1173 req->firewall_add.add_params.field_value[2].mask_range.u32 =
1174 rule.firewall.key.dst_ip_mask;
1175 req->firewall_add.add_params.field_value[3].value.u16 =
1176 rule.firewall.key.src_port_from;
1177 req->firewall_add.add_params.field_value[3].mask_range.u16 =
1178 rule.firewall.key.src_port_to;
1179 req->firewall_add.add_params.field_value[4].value.u16 =
1180 rule.firewall.key.dst_port_from;
1181 req->firewall_add.add_params.field_value[4].mask_range.u16 =
1182 rule.firewall.key.dst_port_to;
1183 req->firewall_add.add_params.field_value[0].value.u8 =
1184 rule.firewall.key.proto;
1185 req->firewall_add.add_params.field_value[0].mask_range.u8 =
1186 rule.firewall.key.proto_mask;
1187 req->firewall_add.port = rule.firewall.port;
1191 status = rte_ring_sp_enqueue(ring_req, (void *) msg);
1192 } while (status == -ENOBUFS);
1194 /* Wait for response */
1196 status = rte_ring_sc_dequeue(ring_resp, (void **) &msg);
1197 } while (status != 0);
1198 resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg);
1200 /* Check response */
1201 if (resp->result != 0)
1202 printf("Request FIREWALL_ADD failed (%u)\n", resp->result);
1204 if (old_rule == NULL) {
1205 memcpy(new_rule, &rule, sizeof(rule));
1206 TAILQ_INSERT_TAIL(&firewall_table, new_rule, entries);
1209 old_rule->firewall.priority = rule.firewall.priority;
1210 old_rule->firewall.port = rule.firewall.port;
1214 /* Free message buffer */
1215 rte_ctrlmbuf_free(msg);
1218 cmdline_parse_token_string_t cmd_firewall_add_firewall_string =
1219 TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result,
1220 firewall_string, "firewall");
1222 cmdline_parse_token_string_t cmd_firewall_add_add_string =
1223 TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result, add_string,
1226 cmdline_parse_token_num_t cmd_firewall_add_priority =
1227 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, priority, INT32);
1229 cmdline_parse_token_ipaddr_t cmd_firewall_add_src_ip =
1230 TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, src_ip);
1231 cmdline_parse_token_num_t cmd_firewall_add_src_ip_mask =
1232 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_ip_mask,
1235 cmdline_parse_token_ipaddr_t cmd_firewall_add_dst_ip =
1236 TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, dst_ip);
1237 cmdline_parse_token_num_t cmd_firewall_add_dst_ip_mask =
1238 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_ip_mask,
1241 cmdline_parse_token_num_t cmd_firewall_add_src_port_from =
1242 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_from,
1244 cmdline_parse_token_num_t cmd_firewall_add_src_port_to =
1245 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_to,
1248 cmdline_parse_token_num_t cmd_firewall_add_dst_port_from =
1249 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_from,
1251 cmdline_parse_token_num_t cmd_firewall_add_dst_port_to =
1252 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_to,
1255 cmdline_parse_token_num_t cmd_firewall_add_proto =
1256 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto, UINT8);
1257 cmdline_parse_token_num_t cmd_firewall_add_proto_mask =
1258 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto_mask,
1260 cmdline_parse_token_num_t cmd_firewall_add_port =
1261 TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, port, UINT8);
1263 cmdline_parse_inst_t cmd_firewall_add = {
1264 .f = cmd_firewall_add_parsed,
1266 .help_str = "Firewall rule add",
1268 (void *)&cmd_firewall_add_firewall_string,
1269 (void *)&cmd_firewall_add_add_string,
1270 (void *)&cmd_firewall_add_priority,
1271 (void *)&cmd_firewall_add_src_ip,
1272 (void *)&cmd_firewall_add_src_ip_mask,
1273 (void *)&cmd_firewall_add_dst_ip,
1274 (void *)&cmd_firewall_add_dst_ip_mask,
1275 (void *)&cmd_firewall_add_src_port_from,
1276 (void *)&cmd_firewall_add_src_port_to,
1277 (void *)&cmd_firewall_add_dst_port_from,
1278 (void *)&cmd_firewall_add_dst_port_to,
1279 (void *)&cmd_firewall_add_proto,
1280 (void *)&cmd_firewall_add_proto_mask,
1281 (void *)&cmd_firewall_add_port,
1286 /* *** firewall - Del *** */
1287 struct cmd_firewall_del_result {
1288 cmdline_fixed_string_t firewall_string;
1289 cmdline_fixed_string_t del_string;
1290 cmdline_ipaddr_t src_ip;
1291 uint32_t src_ip_mask;
1292 cmdline_ipaddr_t dst_ip;
1293 uint32_t dst_ip_mask;
1294 uint16_t src_port_from;
1295 uint16_t src_port_to;
1296 uint16_t dst_port_from;
1297 uint16_t dst_port_to;
1303 cmd_firewall_del_parsed(
1304 void *parsed_result,
1305 __attribute__((unused)) struct cmdline *cl,
1306 __attribute__((unused)) void *data)
1308 struct cmd_firewall_del_result *params = parsed_result;
1309 struct app_rule rule, *old_rule;
1310 struct rte_mbuf *msg;
1311 struct app_msg_req *req;
1312 struct app_msg_resp *resp;
1315 uint32_t core_id = app_get_first_core_id(APP_CORE_FW);
1317 if (core_id == RTE_MAX_LCORE) {
1318 printf("Firewall not performed by any CPU core\n");
1322 struct rte_ring *ring_req = app_get_ring_req(core_id);
1323 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1328 memset(&rule, 0, sizeof(rule));
1329 rule.firewall.key.src_ip =
1330 rte_bswap32((uint32_t) params->src_ip.addr.ipv4.s_addr);
1331 rule.firewall.key.src_ip_mask = params->src_ip_mask;
1332 rule.firewall.key.dst_ip =
1333 rte_bswap32((uint32_t) params->dst_ip.addr.ipv4.s_addr);
1334 rule.firewall.key.dst_ip_mask = params->dst_ip_mask;
1335 rule.firewall.key.src_port_from = params->src_port_from;
1336 rule.firewall.key.src_port_to = params->src_port_to;
1337 rule.firewall.key.dst_port_from = params->dst_port_from;
1338 rule.firewall.key.dst_port_to = params->dst_port_to;
1339 rule.firewall.key.proto = params->proto;
1340 rule.firewall.key.proto_mask = params->proto_mask;
1342 /* Check rule existence */
1343 IS_RULE_PRESENT(old_rule, rule.firewall.key, firewall_table, firewall);
1344 if (old_rule == NULL)
1347 printf("Deleting firewall rule: ");
1348 print_firewall_rule(old_rule->firewall);
1350 /* Allocate message buffer */
1351 msg = rte_ctrlmbuf_alloc(app.msg_pool);
1353 rte_panic("Unable to allocate new message\n");
1355 /* Fill request message */
1356 req = (struct app_msg_req *)rte_ctrlmbuf_data(msg);
1357 memset(&req->firewall_del, 0, sizeof(req->firewall_del));
1358 req->type = APP_MSG_REQ_FW_DEL;
1359 req->firewall_del.delete_params.field_value[1].value.u32 =
1360 rule.firewall.key.src_ip;
1361 req->firewall_del.delete_params.field_value[1].mask_range.u32 =
1362 rule.firewall.key.src_ip_mask;
1363 req->firewall_del.delete_params.field_value[2].value.u32 =
1364 rule.firewall.key.dst_ip;
1365 req->firewall_del.delete_params.field_value[2].mask_range.u32 =
1366 rule.firewall.key.dst_ip_mask;
1367 req->firewall_del.delete_params.field_value[3].value.u16 =
1368 rule.firewall.key.src_port_from;
1369 req->firewall_del.delete_params.field_value[3].mask_range.u16 =
1370 rule.firewall.key.src_port_to;
1371 req->firewall_del.delete_params.field_value[4].value.u16 =
1372 rule.firewall.key.dst_port_from;
1373 req->firewall_del.delete_params.field_value[4].mask_range.u16 =
1374 rule.firewall.key.dst_port_to;
1375 req->firewall_del.delete_params.field_value[0].value.u8 =
1376 rule.firewall.key.proto;
1377 req->firewall_del.delete_params.field_value[0].mask_range.u8 =
1378 rule.firewall.key.proto_mask;
1382 status = rte_ring_sp_enqueue(ring_req, (void *) msg);
1383 } while (status == -ENOBUFS);
1385 /* Wait for response */
1387 status = rte_ring_sc_dequeue(ring_resp, (void **) &msg);
1388 } while (status != 0);
1389 resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg);
1391 /* Check response */
1392 if (resp->result != 0)
1393 printf("Request FIREWALL_DEL failed %u)\n", resp->result);
1395 TAILQ_REMOVE(&firewall_table, old_rule, entries);
1400 /* Free message buffer */
1401 rte_ctrlmbuf_free(msg);
1404 cmdline_parse_token_string_t cmd_firewall_del_firewall_string =
1405 TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result,
1406 firewall_string, "firewall");
1408 cmdline_parse_token_string_t cmd_firewall_del_del_string =
1409 TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result, del_string,
1412 cmdline_parse_token_ipaddr_t cmd_firewall_del_src_ip =
1413 TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, src_ip);
1414 cmdline_parse_token_num_t cmd_firewall_del_src_ip_mask =
1415 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_ip_mask,
1418 cmdline_parse_token_ipaddr_t cmd_firewall_del_dst_ip =
1419 TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, dst_ip);
1420 cmdline_parse_token_num_t cmd_firewall_del_dst_ip_mask =
1421 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_ip_mask,
1424 cmdline_parse_token_num_t cmd_firewall_del_src_port_from =
1425 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_from,
1427 cmdline_parse_token_num_t cmd_firewall_del_src_port_to =
1428 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_to,
1431 cmdline_parse_token_num_t cmd_firewall_del_dst_port_from =
1432 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_from,
1434 cmdline_parse_token_num_t cmd_firewall_del_dst_port_to =
1435 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_to,
1438 cmdline_parse_token_num_t cmd_firewall_del_proto =
1439 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto, UINT8);
1440 cmdline_parse_token_num_t cmd_firewall_del_proto_mask =
1441 TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto_mask,
1444 cmdline_parse_inst_t cmd_firewall_del = {
1445 .f = cmd_firewall_del_parsed,
1447 .help_str = "Firewall rule delete",
1449 (void *)&cmd_firewall_del_firewall_string,
1450 (void *)&cmd_firewall_del_del_string,
1451 (void *)&cmd_firewall_del_src_ip,
1452 (void *)&cmd_firewall_del_src_ip_mask,
1453 (void *)&cmd_firewall_del_dst_ip,
1454 (void *)&cmd_firewall_del_dst_ip_mask,
1455 (void *)&cmd_firewall_del_src_port_from,
1456 (void *)&cmd_firewall_del_src_port_to,
1457 (void *)&cmd_firewall_del_dst_port_from,
1458 (void *)&cmd_firewall_del_dst_port_to,
1459 (void *)&cmd_firewall_del_proto,
1460 (void *)&cmd_firewall_del_proto_mask,
1465 /* *** Firewall - Print *** */
1466 struct cmd_firewall_print_result {
1467 cmdline_fixed_string_t firewall_string;
1468 cmdline_fixed_string_t print_string;
1472 cmd_firewall_print_parsed(
1473 __attribute__((unused)) void *parsed_result,
1474 __attribute__((unused)) struct cmdline *cl,
1475 __attribute__((unused)) void *data)
1477 struct app_rule *it;
1479 TAILQ_FOREACH(it, &firewall_table, entries) {
1480 print_firewall_rule(it->firewall);
1484 cmdline_parse_token_string_t cmd_firewall_print_firewall_string =
1485 TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result,
1486 firewall_string, "firewall");
1488 cmdline_parse_token_string_t cmd_firewall_print_print_string =
1489 TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result, print_string,
1492 cmdline_parse_inst_t cmd_firewall_print = {
1493 .f = cmd_firewall_print_parsed,
1495 .help_str = "Firewall rules list",
1497 (void *)&cmd_firewall_print_firewall_string,
1498 (void *)&cmd_firewall_print_print_string,
1505 /* *** Flow Classification - Add All *** */
1506 struct cmd_flow_add_all_result {
1507 cmdline_fixed_string_t flow_string;
1508 cmdline_fixed_string_t add_string;
1509 cmdline_fixed_string_t all_string;
1513 cmd_flow_add_all_parsed(
1514 __attribute__((unused)) void *parsed_result,
1515 __attribute__((unused)) struct cmdline *cl,
1516 __attribute__((unused)) void *data)
1518 struct app_msg_req *req;
1519 struct app_msg_resp *resp;
1523 struct rte_ring *ring_req =
1524 app_get_ring_req(app_get_first_core_id(APP_CORE_FC));
1525 struct rte_ring *ring_resp =
1526 app_get_ring_resp(app_get_first_core_id(APP_CORE_FC));
1528 /* Allocate message buffer */
1529 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1531 rte_panic("Unable to allocate new message\n");
1533 /* Fill request message */
1534 req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1535 memset(req, 0, sizeof(struct app_msg_req));
1537 req->type = APP_MSG_REQ_FC_ADD_ALL;
1541 status = rte_ring_sp_enqueue(ring_req, msg);
1542 } while (status == -ENOBUFS);
1544 /* Wait for response */
1546 status = rte_ring_sc_dequeue(ring_resp, &msg);
1547 } while (status != 0);
1548 resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1550 /* Check response */
1551 if (resp->result != 0)
1552 printf("Request FLOW_ADD_ALL failed (%u)\n", resp->result);
1554 /* Free message buffer */
1555 rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1558 cmdline_parse_token_string_t cmd_flow_add_all_flow_string =
1559 TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, flow_string,
1562 cmdline_parse_token_string_t cmd_flow_add_all_add_string =
1563 TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, add_string,
1566 cmdline_parse_token_string_t cmd_flow_add_all_all_string =
1567 TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, all_string,
1570 cmdline_parse_inst_t cmd_flow_add_all = {
1571 .f = cmd_flow_add_all_parsed,
1573 .help_str = "Flow table initialization based on hard-coded rule",
1575 (void *)&cmd_flow_add_all_flow_string,
1576 (void *)&cmd_flow_add_all_add_string,
1577 (void *)&cmd_flow_add_all_all_string,
1582 /* *** Flow Classification - Add *** */
1583 struct cmd_flow_add_result {
1584 cmdline_fixed_string_t flow_string;
1585 cmdline_fixed_string_t add_string;
1586 cmdline_ipaddr_t src_ip;
1587 cmdline_ipaddr_t dst_ip;
1595 cmd_flow_add_parsed(
1596 void *parsed_result,
1597 __attribute__((unused)) struct cmdline *cl,
1598 __attribute__((unused)) void *data)
1600 struct cmd_flow_add_result *params = parsed_result;
1601 struct app_rule rule, *old_rule;
1602 struct app_msg_req *req;
1603 struct app_msg_resp *resp;
1607 uint32_t core_id = app_get_first_core_id(APP_CORE_FC);
1609 if (core_id == RTE_MAX_LCORE) {
1610 printf("Flow classification not performed by any CPU core\n");
1614 struct rte_ring *ring_req = app_get_ring_req(core_id);
1615 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1618 if (params->port >= app.n_ports) {
1619 printf("Illegal value for port parameter (%u)\n", params->port);
1624 memset(&rule, 0, sizeof(rule));
1625 rule.flow.key.src_ip =
1626 rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr);
1627 rule.flow.key.dst_ip =
1628 rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr);
1629 rule.flow.key.src_port = params->src_port;
1630 rule.flow.key.dst_port = params->dst_port;
1631 rule.flow.key.proto = params->proto;
1632 rule.flow.port = params->port;
1634 /* Check rule existence */
1635 IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow);
1636 if ((old_rule == NULL) && (n_flow_rules == app.max_flow_rules)) {
1637 printf("Flow table is full.\n");
1641 printf("Adding flow: ");
1642 print_flow_rule(rule.flow);
1644 /* Allocate message buffer */
1645 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1647 rte_panic("Unable to allocate new message\n");
1649 /* Fill request message */
1650 req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1651 memset(req, 0, sizeof(struct app_msg_req));
1653 req->type = APP_MSG_REQ_FC_ADD;
1654 req->flow_classif_add.key.ip_src = rte_bswap32(rule.flow.key.src_ip);
1655 req->flow_classif_add.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip);
1656 req->flow_classif_add.key.port_src =
1657 rte_bswap16(rule.flow.key.src_port);
1658 req->flow_classif_add.key.port_dst =
1659 rte_bswap16(rule.flow.key.dst_port);
1660 req->flow_classif_add.key.proto = rule.flow.key.proto;
1661 req->flow_classif_add.port = rule.flow.port;
1665 status = rte_ring_sp_enqueue(ring_req, msg);
1666 } while (status == -ENOBUFS);
1668 /* Wait for response */
1670 status = rte_ring_sc_dequeue(ring_resp, &msg);
1671 } while (status != 0);
1672 resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1674 /* Check response */
1675 if (resp->result != 0)
1676 printf("Request FLOW_ADD failed (%u)\n", resp->result);
1678 if (old_rule == NULL) {
1679 struct app_rule *new_rule = (struct app_rule *)
1680 rte_zmalloc_socket("CLI",
1681 sizeof(struct app_rule),
1682 RTE_CACHE_LINE_SIZE,
1685 if (new_rule == NULL)
1686 rte_panic("Unable to allocate new rule\n");
1688 memcpy(new_rule, &rule, sizeof(rule));
1689 TAILQ_INSERT_TAIL(&flow_table, new_rule, entries);
1692 old_rule->flow.port = rule.flow.port;
1695 /* Free message buffer */
1696 rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1699 cmdline_parse_token_string_t cmd_flow_add_flow_string =
1700 TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, flow_string,
1703 cmdline_parse_token_string_t cmd_flow_add_add_string =
1704 TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, add_string, "add");
1706 cmdline_parse_token_ipaddr_t cmd_flow_add_src_ip =
1707 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, src_ip);
1709 cmdline_parse_token_ipaddr_t cmd_flow_add_dst_ip =
1710 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, dst_ip);
1712 cmdline_parse_token_num_t cmd_flow_add_src_port =
1713 TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, src_port, UINT16);
1715 cmdline_parse_token_num_t cmd_flow_add_dst_port =
1716 TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, dst_port, UINT16);
1718 cmdline_parse_token_num_t cmd_flow_add_proto =
1719 TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, proto, UINT8);
1721 cmdline_parse_token_num_t cmd_flow_add_port =
1722 TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, port, UINT8);
1724 cmdline_parse_inst_t cmd_flow_add = {
1725 .f = cmd_flow_add_parsed,
1727 .help_str = "Flow add",
1729 (void *)&cmd_flow_add_flow_string,
1730 (void *)&cmd_flow_add_add_string,
1731 (void *)&cmd_flow_add_src_ip,
1732 (void *)&cmd_flow_add_dst_ip,
1733 (void *)&cmd_flow_add_src_port,
1734 (void *)&cmd_flow_add_dst_port,
1735 (void *)&cmd_flow_add_proto,
1736 (void *)&cmd_flow_add_port,
1741 /* *** Flow Classification - Del *** */
1742 struct cmd_flow_del_result {
1743 cmdline_fixed_string_t flow_string;
1744 cmdline_fixed_string_t del_string;
1745 cmdline_ipaddr_t src_ip;
1746 cmdline_ipaddr_t dst_ip;
1753 cmd_flow_del_parsed(
1754 void *parsed_result,
1755 __attribute__((unused)) struct cmdline *cl,
1756 __attribute__((unused)) void *data)
1758 struct cmd_flow_del_result *params = parsed_result;
1759 struct app_rule rule, *old_rule;
1760 struct app_msg_req *req;
1761 struct app_msg_resp *resp;
1765 uint32_t core_id = app_get_first_core_id(APP_CORE_FC);
1767 if (core_id == RTE_MAX_LCORE) {
1768 printf("Flow classification not performed by any CPU core.\n");
1772 struct rte_ring *ring_req = app_get_ring_req(core_id);
1773 struct rte_ring *ring_resp = app_get_ring_resp(core_id);
1776 memset(&rule, 0, sizeof(rule));
1777 rule.flow.key.src_ip =
1778 rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr);
1779 rule.flow.key.dst_ip =
1780 rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr);
1781 rule.flow.key.src_port = params->src_port;
1782 rule.flow.key.dst_port = params->dst_port;
1783 rule.flow.key.proto = params->proto;
1785 /* Check rule existence */
1786 IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow);
1787 if (old_rule == NULL)
1790 printf("Deleting flow: ");
1791 print_flow_rule(old_rule->flow);
1793 /* Allocate message buffer */
1794 msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool);
1796 rte_panic("Unable to allocate new message\n");
1798 /* Fill request message */
1799 req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1800 memset(req, 0, sizeof(struct app_msg_req));
1802 req->type = APP_MSG_REQ_FC_DEL;
1803 req->flow_classif_del.key.ip_src = rte_bswap32(rule.flow.key.src_ip);
1804 req->flow_classif_del.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip);
1805 req->flow_classif_del.key.port_src =
1806 rte_bswap32(rule.flow.key.src_port);
1807 req->flow_classif_del.key.port_dst =
1808 rte_bswap32(rule.flow.key.dst_port);
1809 req->flow_classif_del.key.proto = rule.flow.key.proto;
1813 status = rte_ring_sp_enqueue(ring_req, msg);
1814 } while (status == -ENOBUFS);
1816 /* Wait for response */
1818 status = rte_ring_sc_dequeue(ring_resp, &msg);
1819 } while (status != 0);
1820 resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);
1822 /* Check response */
1823 if (resp->result != 0)
1824 printf("Request FLOW_DEL failed (%u)\n", resp->result);
1826 TAILQ_REMOVE(&flow_table, old_rule, entries);
1831 /* Free message buffer */
1832 rte_ctrlmbuf_free((struct rte_mbuf *)msg);
1835 cmdline_parse_token_string_t cmd_flow_del_flow_string =
1836 TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, flow_string,
1839 cmdline_parse_token_string_t cmd_flow_del_del_string =
1840 TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, del_string, "del");
1842 cmdline_parse_token_ipaddr_t cmd_flow_del_src_ip =
1843 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, src_ip);
1845 cmdline_parse_token_ipaddr_t cmd_flow_del_dst_ip =
1846 TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, dst_ip);
1848 cmdline_parse_token_num_t cmd_flow_del_src_port =
1849 TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, src_port, UINT16);
1851 cmdline_parse_token_num_t cmd_flow_del_dst_port =
1852 TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, dst_port, UINT16);
1854 cmdline_parse_token_num_t cmd_flow_del_proto =
1855 TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, proto, UINT8);
1857 cmdline_parse_inst_t cmd_flow_del = {
1858 .f = cmd_flow_del_parsed,
1860 .help_str = "Flow delete",
1862 (void *)&cmd_flow_del_flow_string,
1863 (void *)&cmd_flow_del_del_string,
1864 (void *)&cmd_flow_del_src_ip,
1865 (void *)&cmd_flow_del_dst_ip,
1866 (void *)&cmd_flow_del_src_port,
1867 (void *)&cmd_flow_del_dst_port,
1868 (void *)&cmd_flow_del_proto,
1873 /* *** Flow Classification - Print *** */
1874 struct cmd_flow_print_result {
1875 cmdline_fixed_string_t flow_string;
1876 cmdline_fixed_string_t print_string;
1880 cmd_flow_print_parsed(
1881 __attribute__((unused)) void *parsed_result,
1882 __attribute__((unused)) struct cmdline *cl,
1883 __attribute__((unused)) void *data)
1885 struct app_rule *it;
1887 TAILQ_FOREACH(it, &flow_table, entries) {
1888 print_flow_rule(it->flow);
1892 cmdline_parse_token_string_t cmd_flow_print_flow_string =
1893 TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, flow_string,
1896 cmdline_parse_token_string_t cmd_flow_print_print_string =
1897 TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, print_string,
1900 cmdline_parse_inst_t cmd_flow_print = {
1901 .f = cmd_flow_print_parsed,
1903 .help_str = "Flow list",
1905 (void *)&cmd_flow_print_flow_string,
1906 (void *)&cmd_flow_print_print_string,
1912 struct cmd_quit_result {
1913 cmdline_fixed_string_t quit;
1916 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
1918 __attribute__((unused)) void *data)
1923 cmdline_parse_token_string_t cmd_quit_quit =
1924 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
1926 cmdline_parse_inst_t cmd_quit = {
1927 .f = cmd_quit_parsed,
1929 .help_str = "Exit application",
1931 (void *)&cmd_quit_quit,
1936 /* List of commands */
1937 cmdline_parse_ctx_t main_ctx[] = {
1938 (cmdline_parse_inst_t *)&cmd_flow_add,
1939 (cmdline_parse_inst_t *)&cmd_flow_del,
1940 (cmdline_parse_inst_t *)&cmd_flow_add_all,
1941 (cmdline_parse_inst_t *)&cmd_flow_print,
1942 #ifdef RTE_LIBRTE_ACL
1943 (cmdline_parse_inst_t *)&cmd_firewall_add,
1944 (cmdline_parse_inst_t *)&cmd_firewall_del,
1945 (cmdline_parse_inst_t *)&cmd_firewall_print,
1947 (cmdline_parse_inst_t *)&cmd_route_add,
1948 (cmdline_parse_inst_t *)&cmd_route_del,
1949 (cmdline_parse_inst_t *)&cmd_routing_print,
1950 (cmdline_parse_inst_t *)&cmd_arp_add,
1951 (cmdline_parse_inst_t *)&cmd_arp_del,
1952 (cmdline_parse_inst_t *)&cmd_arp_print,
1953 (cmdline_parse_inst_t *)&cmd_run_file,
1954 (cmdline_parse_inst_t *)&cmd_link_enable,
1955 (cmdline_parse_inst_t *)&cmd_link_disable,
1956 (cmdline_parse_inst_t *)&cmd_quit,
1962 app_main_loop_cmdline(void)
1965 uint32_t core_id = rte_lcore_id();
1967 RTE_LOG(INFO, USER1, "Core %u is running the command line interface\n",
1971 n_routing_rules = 0;
1972 n_firewall_rules = 0;
1975 app_init_rule_tables();
1977 cl = cmdline_stdin_new(main_ctx, "pipeline> ");
1980 cmdline_interact(cl);
1981 cmdline_stdin_exit(cl);