diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile index 213e879996..9ce80a832e 100644 --- a/examples/ip_pipeline/Makefile +++ b/examples/ip_pipeline/Makefile @@ -55,6 +55,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += cpu_core_map.c +SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_common_be.c +SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_common_fe.c +SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_master_be.c +SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_master.c + CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/pipeline CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) -Wno-error=unused-function -Wno-error=unused-variable diff --git a/examples/ip_pipeline/cmdline.c b/examples/ip_pipeline/cmdline.c deleted file mode 100644 index 3173fd0f47..0000000000 --- a/examples/ip_pipeline/cmdline.c +++ /dev/null @@ -1,1976 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "main.h" - -#define IS_RULE_PRESENT(res, rule_key, table, type) \ -do { \ - struct app_rule *it; \ - \ - (res) = NULL; \ - TAILQ_FOREACH(it, &table, entries) { \ - if (memcmp(&rule_key, &it->type.key, sizeof(rule_key)) == 0) {\ - (res) = it; \ - break; \ - } \ - } \ -} while (0) - -/* Rules */ -static void -app_init_rule_tables(void); - -TAILQ_HEAD(linked_list, app_rule) arp_table, routing_table, firewall_table, - flow_table; - -uint32_t n_arp_rules; -uint32_t n_routing_rules; -uint32_t n_firewall_rules; -uint32_t n_flow_rules; - -struct app_arp_rule { - struct { - uint8_t out_iface; - uint32_t nh_ip; - } key; - - struct ether_addr nh_arp; -}; - -struct app_routing_rule { - struct { - uint32_t ip; - uint8_t depth; - } key; - - uint8_t port; - uint32_t nh_ip; -}; - -struct app_firewall_rule { - struct { - uint32_t src_ip; - uint32_t src_ip_mask; - uint32_t dst_ip; - uint32_t dst_ip_mask; - uint16_t src_port_from; - uint16_t src_port_to; - uint16_t dst_port_from; - uint16_t dst_port_to; - uint8_t proto; - uint8_t proto_mask; - } key; - - int32_t priority; - uint8_t port; -}; - -struct app_flow_rule { - struct { - uint32_t src_ip; - uint32_t dst_ip; - uint16_t src_port; - uint16_t dst_port; - uint8_t proto; - } key; - - uint8_t port; -}; - -struct app_rule { - union { - struct app_arp_rule arp; - struct app_routing_rule routing; - struct app_firewall_rule firewall; - struct app_flow_rule flow; - }; - - TAILQ_ENTRY(app_rule) entries; -}; - -/* Initialization */ -static void -app_init_rule_tables(void) -{ - TAILQ_INIT(&arp_table); - TAILQ_INIT(&routing_table); - TAILQ_INIT(&firewall_table); - TAILQ_INIT(&flow_table); - - n_arp_rules = 0; - n_routing_rules = 0; - n_firewall_rules = 0; - n_flow_rules = 0; -} - -/* Printing */ -static void -print_arp_rule(struct app_arp_rule rule) -{ - printf("(Iface = %u, Address = %u.%u.%u.%u) => " - "HWaddress = %02x:%02x:%02x:%02x:%02x:%02x\n", - rule.key.out_iface, - (rule.key.nh_ip >> 24) & 0xFF, - (rule.key.nh_ip >> 16) & 0xFF, - (rule.key.nh_ip >> 8) & 0xFF, - rule.key.nh_ip & 0xFF, - - rule.nh_arp.addr_bytes[0], - rule.nh_arp.addr_bytes[1], - rule.nh_arp.addr_bytes[2], - rule.nh_arp.addr_bytes[3], - rule.nh_arp.addr_bytes[4], - rule.nh_arp.addr_bytes[5]); -} - -static void -print_routing_rule(struct app_routing_rule rule) -{ - printf("IP Prefix = %u.%u.%u.%u/%u => " - "(Iface = %u, Gateway = %u.%u.%u.%u)\n", - (rule.key.ip >> 24) & 0xFF, - (rule.key.ip >> 16) & 0xFF, - (rule.key.ip >> 8) & 0xFF, - rule.key.ip & 0xFF, - - rule.key.depth, - rule.port, - - (rule.nh_ip >> 24) & 0xFF, - (rule.nh_ip >> 16) & 0xFF, - (rule.nh_ip >> 8) & 0xFF, - rule.nh_ip & 0xFF); -} - -#ifdef RTE_LIBRTE_ACL - -static void -print_firewall_rule(struct app_firewall_rule rule) -{ - printf("Priority %d: (IP Src = %u.%u.%u.%u/%u, " - "IP Dst = %u.%u.%u.%u/%u, " - "Port Src = %u-%u, Port Dst = %u-%u, Proto = %u (%u)) => " - "Port = %u\n", - rule.priority, - - (rule.key.src_ip >> 24) & 0xFF, - (rule.key.src_ip >> 16) & 0xFF, - (rule.key.src_ip >> 8) & 0xFF, - rule.key.src_ip & 0xFF, - rule.key.src_ip_mask, - - (rule.key.dst_ip >> 24) & 0xFF, - (rule.key.dst_ip >> 16) & 0xFF, - (rule.key.dst_ip >> 8) & 0xFF, - rule.key.dst_ip & 0xFF, - rule.key.dst_ip_mask, - - rule.key.src_port_from, - rule.key.src_port_to, - rule.key.dst_port_from, - rule.key.dst_port_to, - rule.key.proto, - rule.key.proto_mask, - rule.port); -} - -#endif - -static void -print_flow_rule(struct app_flow_rule rule) -{ - printf("(IP Src = %u.%u.%u.%u, IP Dst = %u.%u.%u.%u, Port Src = %u, " - "Port Dst = %u, Proto = %u) => Port = %u\n", - (rule.key.src_ip >> 24) & 0xFF, - (rule.key.src_ip >> 16) & 0xFF, - (rule.key.src_ip >> 8) & 0xFF, - rule.key.src_ip & 0xFF, - - (rule.key.dst_ip >> 24) & 0xFF, - (rule.key.dst_ip >> 16) & 0xFF, - (rule.key.dst_ip >> 8) & 0xFF, - rule.key.dst_ip & 0xFF, - - rule.key.src_port, - rule.key.dst_port, - (uint32_t) rule.key.proto, - rule.port); -} - -/* Commands */ - -/* *** Run file (script) *** */ -struct cmd_run_file_result { - cmdline_fixed_string_t run_string; - char file_path[100]; -}; - -static void -cmd_run_file_parsed( - void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_run_file_result *params = parsed_result; - struct cmdline *file_cl; - int fd; - - fd = open(params->file_path, O_RDONLY, 0); - if (fd < 0) { - printf("Illegal value for file path (%s)\n", params->file_path); - return; - } - - file_cl = cmdline_new(cl->ctx, "", fd, 1); - cmdline_interact(file_cl); - close(fd); -} - -cmdline_parse_token_string_t cmd_run_file_run_string = - TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, run_string, "run"); - -cmdline_parse_token_string_t cmd_run_file_file_path = - TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, file_path, NULL); - -cmdline_parse_inst_t cmd_run_file = { - .f = cmd_run_file_parsed, - .data = NULL, - .help_str = "Run commands from file", - .tokens = { - (void *)&cmd_run_file_run_string, - (void *)&cmd_run_file_file_path, - NULL, - }, -}; - -/* *** Link - Enable *** */ -struct cmd_link_enable_result { - cmdline_fixed_string_t link_string; - uint8_t port; - cmdline_fixed_string_t up_string; -}; - -static void -cmd_link_enable_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_link_enable_result *params = parsed_result; - void *msg; - struct app_msg_req *req; - struct app_msg_resp *resp; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RX); - - if (core_id == RTE_MAX_LCORE) { - printf("RX core not preformed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->port >= app.n_ports) { - printf("Illegal value for port parameter (%u)\n", params->port); - return; - } - - printf("Enabling port %d\n", params->port); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_RX_PORT_ENABLE; - req->rx_up.port = params->port; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - /* Check response */ - if (resp->result != 0) - printf("Request LINK_UP failed (%u)\n", resp->result); - - /* Free message buffer */ - rte_ctrlmbuf_free(msg); -} - -cmdline_parse_token_string_t cmd_link_enable_link_string = - TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, link_string, - "link"); - -cmdline_parse_token_num_t cmd_link_enable_port = - TOKEN_NUM_INITIALIZER(struct cmd_link_enable_result, port, UINT8); - -cmdline_parse_token_string_t cmd_link_enable_up_string = - TOKEN_STRING_INITIALIZER(struct cmd_link_enable_result, up_string, - "up"); - -cmdline_parse_inst_t cmd_link_enable = { - .f = cmd_link_enable_parsed, - .data = NULL, - .help_str = "Link down", - .tokens = { - (void *)&cmd_link_enable_link_string, - (void *)&cmd_link_enable_port, - (void *)&cmd_link_enable_up_string, - NULL, - }, -}; - -/* *** Link - Disable *** */ -struct cmd_link_disable_result { - cmdline_fixed_string_t link_string; - uint8_t port; - cmdline_fixed_string_t down_string; -}; - -static void -cmd_link_disable_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_link_disable_result *params = parsed_result; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RX); - - if (core_id == RTE_MAX_LCORE) { - printf("RX not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->port >= app.n_ports) { - printf("Illegal value for port parameter (%u)\n", params->port); - return; - } - - printf("Disabling port %d\n", params->port); - - /* Allocate message buffer */ - msg = rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_RX_PORT_DISABLE; - req->rx_down.port = params->port; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request LINK_DOWN failed (%u)\n", resp->result); - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *)msg); -} - -cmdline_parse_token_string_t cmd_link_disable_link_string = - TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, link_string, - "link"); - -cmdline_parse_token_num_t cmd_link_disable_port = - TOKEN_NUM_INITIALIZER(struct cmd_link_disable_result, port, UINT8); - -cmdline_parse_token_string_t cmd_link_disable_down_string = - TOKEN_STRING_INITIALIZER(struct cmd_link_disable_result, down_string, - "down"); - -cmdline_parse_inst_t cmd_link_disable = { - .f = cmd_link_disable_parsed, - .data = NULL, - .help_str = "Link up", - .tokens = { - (void *)&cmd_link_disable_link_string, - (void *)&cmd_link_disable_port, - (void *)&cmd_link_disable_down_string, - NULL, - }, -}; - - -/* *** ARP - Add *** */ -struct cmd_arp_add_result { - cmdline_fixed_string_t arp_string; - cmdline_fixed_string_t add_string; - uint8_t out_iface; - cmdline_ipaddr_t nh_ip; - struct ether_addr nh_arp; - -}; - -static void -cmd_arp_add_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_arp_add_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RT); - - if (core_id == RTE_MAX_LCORE) { - printf("ARP not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->out_iface >= app.n_ports) { - printf("Illegal value for output interface parameter (%u)\n", - params->out_iface); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.arp.key.out_iface = params->out_iface; - rule.arp.key.nh_ip = - rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr); - rule.arp.nh_arp = params->nh_arp; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.arp.key, arp_table, arp); - if ((old_rule == NULL) && (n_arp_rules == app.max_arp_rules)) { - printf("ARP table is full.\n"); - return; - } - - printf("Adding ARP entry: "); - print_arp_rule(rule.arp); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_ARP_ADD; - req->arp_add.out_iface = rule.arp.key.out_iface; - req->arp_add.nh_ip = rule.arp.key.nh_ip; - req->arp_add.nh_arp = rule.arp.nh_arp; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request ARP_ADD failed (%u)\n", resp->result); - else { - if (old_rule == NULL) { - struct app_rule *new_rule = (struct app_rule *) - rte_zmalloc_socket("CLI", - sizeof(struct app_rule), - RTE_CACHE_LINE_SIZE, - rte_socket_id()); - - if (new_rule == NULL) - rte_panic("Unable to allocate new rule\n"); - - memcpy(new_rule, &rule, sizeof(rule)); - TAILQ_INSERT_TAIL(&arp_table, new_rule, entries); - n_arp_rules++; - } else - old_rule->arp.nh_arp = rule.arp.nh_arp; - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *) msg); -} - -cmdline_parse_token_string_t cmd_arp_add_arp_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arp_string, "arp"); - -cmdline_parse_token_string_t cmd_arp_add_add_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, add_string, "add"); - -cmdline_parse_token_num_t cmd_arp_add_out_iface = - TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, out_iface, UINT8); - -cmdline_parse_token_ipaddr_t cmd_arp_add_nh_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_arp_add_result, nh_ip); - -cmdline_parse_token_etheraddr_t cmd_arp_add_nh_arp = - TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, nh_arp); - -cmdline_parse_inst_t cmd_arp_add = { - .f = cmd_arp_add_parsed, - .data = NULL, - .help_str = "ARP add", - .tokens = { - (void *)&cmd_arp_add_arp_string, - (void *)&cmd_arp_add_add_string, - (void *)&cmd_arp_add_out_iface, - (void *)&cmd_arp_add_nh_ip, - (void *)&cmd_arp_add_nh_arp, - NULL, - }, - }; - -/* *** ARP - Del *** */ -struct cmd_arp_del_result { - cmdline_fixed_string_t arp_string; - cmdline_fixed_string_t del_string; - uint8_t out_iface; - cmdline_ipaddr_t nh_ip; -}; - -static void -cmd_arp_del_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_arp_del_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RT); - - if (core_id == RTE_MAX_LCORE) { - printf("ARP not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->out_iface > app.n_ports) { - printf("Illegal value for output interface parameter (%u)\n", - params->out_iface); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.arp.key.out_iface = params->out_iface; - rule.arp.key.nh_ip = - rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr); - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.arp.key, arp_table, arp); - if (old_rule == NULL) - return; - - printf("Deleting ARP entry: "); - print_arp_rule(old_rule->arp); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_ARP_DEL; - req->arp_del.out_iface = rule.arp.key.out_iface; - req->arp_del.nh_ip = rule.arp.key.nh_ip; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request ARP_DEL failed (%u)\n", resp->result); - else { - TAILQ_REMOVE(&arp_table, old_rule, entries); - n_arp_rules--; - rte_free(old_rule); - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *) msg); -} - -cmdline_parse_token_string_t cmd_arp_del_arp_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arp"); - -cmdline_parse_token_string_t cmd_arp_del_del_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, del_string, "del"); - -cmdline_parse_token_num_t cmd_arp_del_out_iface = - TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, out_iface, UINT8); - -cmdline_parse_token_ipaddr_t cmd_arp_del_nh_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_arp_del_result, nh_ip); - -cmdline_parse_inst_t cmd_arp_del = { - .f = cmd_arp_del_parsed, - .data = NULL, - .help_str = "ARP delete", - .tokens = { - (void *)&cmd_arp_del_arp_string, - (void *)&cmd_arp_del_del_string, - (void *)&cmd_arp_del_out_iface, - (void *)&cmd_arp_del_nh_ip, - NULL, - }, -}; - -/* *** ARP - Print *** */ -struct cmd_arp_print_result { - cmdline_fixed_string_t arp_string; - cmdline_fixed_string_t print_string; -}; - -static void -cmd_arp_print_parsed( - __attribute__((unused)) void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct app_rule *it; - - TAILQ_FOREACH(it, &arp_table, entries) { - print_arp_rule(it->arp); - } -} - -cmdline_parse_token_string_t cmd_arp_print_arp_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, arp_string, - "arp"); - -cmdline_parse_token_string_t cmd_arp_print_print_string = - TOKEN_STRING_INITIALIZER(struct cmd_arp_print_result, print_string, - "ls"); - -cmdline_parse_inst_t cmd_arp_print = { - .f = cmd_arp_print_parsed, - .data = NULL, - .help_str = "ARP list", - .tokens = { - (void *)&cmd_arp_print_arp_string, - (void *)&cmd_arp_print_print_string, - NULL, - }, -}; - -/* *** Routing - Add *** */ -struct cmd_route_add_result { - cmdline_fixed_string_t route_string; - cmdline_fixed_string_t add_string; - cmdline_ipaddr_t ip; - uint8_t depth; - uint8_t port; - cmdline_ipaddr_t nh_ip; -}; - -static void -cmd_route_add_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_route_add_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RT); - - if (core_id == RTE_MAX_LCORE) { - printf("Routing not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if ((params->depth == 0) || (params->depth > 32)) { - printf("Illegal value for depth parameter (%u)\n", - params->depth); - return; - } - - if (params->port >= app.n_ports) { - printf("Illegal value for port parameter (%u)\n", params->port); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.routing.key.ip = rte_bswap32((uint32_t) - params->ip.addr.ipv4.s_addr); - rule.routing.key.depth = params->depth; - rule.routing.port = params->port; - rule.routing.nh_ip = - rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr); - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.routing.key, routing_table, routing); - if ((old_rule == NULL) && (n_routing_rules == app.max_routing_rules)) { - printf("Routing table is full.\n"); - return; - } - - printf("Adding route: "); - print_routing_rule(rule.routing); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_RT_ADD; - req->routing_add.ip = rule.routing.key.ip; - req->routing_add.depth = rule.routing.key.depth; - req->routing_add.port = rule.routing.port; - req->routing_add.nh_ip = rule.routing.nh_ip; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request ROUTE_ADD failed (%u)\n", resp->result); - else { - if (old_rule == NULL) { - struct app_rule *new_rule = (struct app_rule *) - rte_zmalloc_socket("CLI", - sizeof(struct app_rule), - RTE_CACHE_LINE_SIZE, - rte_socket_id()); - - if (new_rule == NULL) - rte_panic("Unable to allocate new rule\n"); - - memcpy(new_rule, &rule, sizeof(rule)); - TAILQ_INSERT_TAIL(&routing_table, new_rule, entries); - n_routing_rules++; - } else { - old_rule->routing.port = rule.routing.port; - old_rule->routing.nh_ip = rule.routing.nh_ip; - } - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *) msg); -} - -cmdline_parse_token_string_t cmd_route_add_route_string = - TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, route_string, - "route"); - -cmdline_parse_token_string_t cmd_route_add_add_string = - TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, add_string, - "add"); - -cmdline_parse_token_ipaddr_t cmd_route_add_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, ip); - -cmdline_parse_token_num_t cmd_route_add_depth = - TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, depth, UINT8); - -cmdline_parse_token_num_t cmd_route_add_port = - TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, port, UINT8); - -cmdline_parse_token_ipaddr_t cmd_route_add_nh_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_route_add_result, nh_ip); - -cmdline_parse_inst_t cmd_route_add = { - .f = cmd_route_add_parsed, - .data = NULL, - .help_str = "Route add", - .tokens = { - (void *)&cmd_route_add_route_string, - (void *)&cmd_route_add_add_string, - (void *)&cmd_route_add_ip, - (void *)&cmd_route_add_depth, - (void *)&cmd_route_add_port, - (void *)&cmd_route_add_nh_ip, - NULL, - }, -}; - -/* *** Routing - Del *** */ -struct cmd_route_del_result { - cmdline_fixed_string_t route_string; - cmdline_fixed_string_t del_string; - cmdline_ipaddr_t ip; - uint8_t depth; -}; - -static void -cmd_route_del_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_route_del_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_RT); - - if (core_id == RTE_MAX_LCORE) { - printf("Routing not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if ((params->depth == 0) || (params->depth > 32)) { - printf("Illegal value for depth parameter (%u)\n", - params->depth); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.routing.key.ip = rte_bswap32((uint32_t) - params->ip.addr.ipv4.s_addr); - rule.routing.key.depth = params->depth; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.routing.key, routing_table, routing); - if (old_rule == NULL) - return; - - printf("Deleting route: "); - print_routing_rule(old_rule->routing); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - req->type = APP_MSG_REQ_RT_DEL; - req->routing_del.ip = rule.routing.key.ip; - req->routing_del.depth = rule.routing.key.depth; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request ROUTE_DEL failed %u)\n", resp->result); - else { - TAILQ_REMOVE(&routing_table, old_rule, entries); - rte_free(old_rule); - n_routing_rules--; - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *)msg); -} - -cmdline_parse_token_string_t cmd_route_del_route_string = - TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, route_string, - "route"); - -cmdline_parse_token_string_t cmd_route_del_del_string = - TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, del_string, - "del"); - -cmdline_parse_token_ipaddr_t cmd_route_del_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_route_del_result, ip); - -cmdline_parse_token_num_t cmd_route_del_depth = - TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, depth, UINT8); - -cmdline_parse_inst_t cmd_route_del = { - .f = cmd_route_del_parsed, - .data = NULL, - .help_str = "Route delete", - .tokens = { - (void *)&cmd_route_del_route_string, - (void *)&cmd_route_del_del_string, - (void *)&cmd_route_del_ip, - (void *)&cmd_route_del_depth, - NULL, - }, -}; - -/* *** Routing - Print *** */ -struct cmd_routing_print_result { - cmdline_fixed_string_t routing_string; - cmdline_fixed_string_t print_string; -}; - -static void -cmd_routing_print_parsed( - __attribute__((unused)) void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct app_rule *it; - - TAILQ_FOREACH(it, &routing_table, entries) { - print_routing_rule(it->routing); - } -} - -cmdline_parse_token_string_t cmd_routing_print_routing_string = - TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result, - routing_string, "route"); - -cmdline_parse_token_string_t cmd_routing_print_print_string = - TOKEN_STRING_INITIALIZER(struct cmd_routing_print_result, print_string, - "ls"); - -cmdline_parse_inst_t cmd_routing_print = { - .f = cmd_routing_print_parsed, - .data = NULL, - .help_str = "Route list", - .tokens = { - (void *)&cmd_routing_print_routing_string, - (void *)&cmd_routing_print_print_string, - NULL, - }, -}; - -#ifdef RTE_LIBRTE_ACL - -/* *** Firewall - Add *** */ -struct cmd_firewall_add_result { - cmdline_fixed_string_t firewall_string; - cmdline_fixed_string_t add_string; - int32_t priority; - cmdline_ipaddr_t src_ip; - uint32_t src_ip_mask; - cmdline_ipaddr_t dst_ip; - uint32_t dst_ip_mask; - uint16_t src_port_from; - uint16_t src_port_to; - uint16_t dst_port_from; - uint16_t dst_port_to; - uint8_t proto; - uint8_t proto_mask; - uint8_t port; -}; - -static void -cmd_firewall_add_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_firewall_add_result *params = parsed_result; - struct app_rule rule, *old_rule, *new_rule = NULL; - struct rte_mbuf *msg; - struct app_msg_req *req; - struct app_msg_resp *resp; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_FW); - - if (core_id == RTE_MAX_LCORE) { - printf("Firewall not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->port >= app.n_ports) { - printf("Illegal value for port parameter (%u)\n", params->port); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.firewall.priority = params->priority; - rule.firewall.key.src_ip = - rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr); - rule.firewall.key.src_ip_mask = params->src_ip_mask; - rule.firewall.key.dst_ip = - rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr); - rule.firewall.key.dst_ip_mask = params->dst_ip_mask; - rule.firewall.key.src_port_from = params->src_port_from; - rule.firewall.key.src_port_to = params->src_port_to; - rule.firewall.key.dst_port_from = params->dst_port_from; - rule.firewall.key.dst_port_to = params->dst_port_to; - rule.firewall.key.proto = params->proto; - rule.firewall.key.proto_mask = params->proto_mask; - rule.firewall.port = params->port; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.firewall.key, firewall_table, firewall); - if ((old_rule == NULL) && - (n_firewall_rules == app.max_firewall_rules)) { - printf("Firewall table is full.\n"); - return; - } - - printf("Adding firewall rule: "); - print_firewall_rule(rule.firewall); - - /* Allocate message buffer */ - msg = rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* if we need a new rule structure, allocate it before we go further */ - if (old_rule == NULL) { - new_rule = rte_zmalloc_socket("CLI", sizeof(struct app_rule), - RTE_CACHE_LINE_SIZE, rte_socket_id()); - if (new_rule == NULL) { - printf("Cannot allocate memory for new rule\n"); - rte_ctrlmbuf_free(msg); - return; - } - } - - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data(msg); - req->type = APP_MSG_REQ_FW_ADD; - req->firewall_add.add_params.priority = rule.firewall.priority; - req->firewall_add.add_params.field_value[1].value.u32 = - rule.firewall.key.src_ip; - req->firewall_add.add_params.field_value[1].mask_range.u32 = - rule.firewall.key.src_ip_mask; - req->firewall_add.add_params.field_value[2].value.u32 = - rule.firewall.key.dst_ip; - req->firewall_add.add_params.field_value[2].mask_range.u32 = - rule.firewall.key.dst_ip_mask; - req->firewall_add.add_params.field_value[3].value.u16 = - rule.firewall.key.src_port_from; - req->firewall_add.add_params.field_value[3].mask_range.u16 = - rule.firewall.key.src_port_to; - req->firewall_add.add_params.field_value[4].value.u16 = - rule.firewall.key.dst_port_from; - req->firewall_add.add_params.field_value[4].mask_range.u16 = - rule.firewall.key.dst_port_to; - req->firewall_add.add_params.field_value[0].value.u8 = - rule.firewall.key.proto; - req->firewall_add.add_params.field_value[0].mask_range.u8 = - rule.firewall.key.proto_mask; - req->firewall_add.port = rule.firewall.port; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, (void *) msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, (void **) &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg); - - /* Check response */ - if (resp->result != 0) - printf("Request FIREWALL_ADD failed (%u)\n", resp->result); - else { - if (old_rule == NULL) { - memcpy(new_rule, &rule, sizeof(rule)); - TAILQ_INSERT_TAIL(&firewall_table, new_rule, entries); - n_firewall_rules++; - } else { - old_rule->firewall.priority = rule.firewall.priority; - old_rule->firewall.port = rule.firewall.port; - } - } - - /* Free message buffer */ - rte_ctrlmbuf_free(msg); -} - -cmdline_parse_token_string_t cmd_firewall_add_firewall_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result, - firewall_string, "firewall"); - -cmdline_parse_token_string_t cmd_firewall_add_add_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_result, add_string, - "add"); - -cmdline_parse_token_num_t cmd_firewall_add_priority = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, priority, INT32); - -cmdline_parse_token_ipaddr_t cmd_firewall_add_src_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, src_ip); -cmdline_parse_token_num_t cmd_firewall_add_src_ip_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_ip_mask, - UINT32); - -cmdline_parse_token_ipaddr_t cmd_firewall_add_dst_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_add_result, dst_ip); -cmdline_parse_token_num_t cmd_firewall_add_dst_ip_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_ip_mask, - UINT32); - -cmdline_parse_token_num_t cmd_firewall_add_src_port_from = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_from, - UINT16); -cmdline_parse_token_num_t cmd_firewall_add_src_port_to = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, src_port_to, - UINT16); - -cmdline_parse_token_num_t cmd_firewall_add_dst_port_from = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_from, - UINT16); -cmdline_parse_token_num_t cmd_firewall_add_dst_port_to = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, dst_port_to, - UINT16); - -cmdline_parse_token_num_t cmd_firewall_add_proto = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto, UINT8); -cmdline_parse_token_num_t cmd_firewall_add_proto_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, proto_mask, - UINT8); -cmdline_parse_token_num_t cmd_firewall_add_port = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_result, port, UINT8); - -cmdline_parse_inst_t cmd_firewall_add = { - .f = cmd_firewall_add_parsed, - .data = NULL, - .help_str = "Firewall rule add", - .tokens = { - (void *)&cmd_firewall_add_firewall_string, - (void *)&cmd_firewall_add_add_string, - (void *)&cmd_firewall_add_priority, - (void *)&cmd_firewall_add_src_ip, - (void *)&cmd_firewall_add_src_ip_mask, - (void *)&cmd_firewall_add_dst_ip, - (void *)&cmd_firewall_add_dst_ip_mask, - (void *)&cmd_firewall_add_src_port_from, - (void *)&cmd_firewall_add_src_port_to, - (void *)&cmd_firewall_add_dst_port_from, - (void *)&cmd_firewall_add_dst_port_to, - (void *)&cmd_firewall_add_proto, - (void *)&cmd_firewall_add_proto_mask, - (void *)&cmd_firewall_add_port, - NULL, - }, -}; - -/* *** firewall - Del *** */ -struct cmd_firewall_del_result { - cmdline_fixed_string_t firewall_string; - cmdline_fixed_string_t del_string; - cmdline_ipaddr_t src_ip; - uint32_t src_ip_mask; - cmdline_ipaddr_t dst_ip; - uint32_t dst_ip_mask; - uint16_t src_port_from; - uint16_t src_port_to; - uint16_t dst_port_from; - uint16_t dst_port_to; - uint8_t proto; - uint8_t proto_mask; -}; - -static void -cmd_firewall_del_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_firewall_del_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct rte_mbuf *msg; - struct app_msg_req *req; - struct app_msg_resp *resp; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_FW); - - if (core_id == RTE_MAX_LCORE) { - printf("Firewall not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.firewall.key.src_ip = - rte_bswap32((uint32_t) params->src_ip.addr.ipv4.s_addr); - rule.firewall.key.src_ip_mask = params->src_ip_mask; - rule.firewall.key.dst_ip = - rte_bswap32((uint32_t) params->dst_ip.addr.ipv4.s_addr); - rule.firewall.key.dst_ip_mask = params->dst_ip_mask; - rule.firewall.key.src_port_from = params->src_port_from; - rule.firewall.key.src_port_to = params->src_port_to; - rule.firewall.key.dst_port_from = params->dst_port_from; - rule.firewall.key.dst_port_to = params->dst_port_to; - rule.firewall.key.proto = params->proto; - rule.firewall.key.proto_mask = params->proto_mask; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.firewall.key, firewall_table, firewall); - if (old_rule == NULL) - return; - - printf("Deleting firewall rule: "); - print_firewall_rule(old_rule->firewall); - - /* Allocate message buffer */ - msg = rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data(msg); - memset(&req->firewall_del, 0, sizeof(req->firewall_del)); - req->type = APP_MSG_REQ_FW_DEL; - req->firewall_del.delete_params.field_value[1].value.u32 = - rule.firewall.key.src_ip; - req->firewall_del.delete_params.field_value[1].mask_range.u32 = - rule.firewall.key.src_ip_mask; - req->firewall_del.delete_params.field_value[2].value.u32 = - rule.firewall.key.dst_ip; - req->firewall_del.delete_params.field_value[2].mask_range.u32 = - rule.firewall.key.dst_ip_mask; - req->firewall_del.delete_params.field_value[3].value.u16 = - rule.firewall.key.src_port_from; - req->firewall_del.delete_params.field_value[3].mask_range.u16 = - rule.firewall.key.src_port_to; - req->firewall_del.delete_params.field_value[4].value.u16 = - rule.firewall.key.dst_port_from; - req->firewall_del.delete_params.field_value[4].mask_range.u16 = - rule.firewall.key.dst_port_to; - req->firewall_del.delete_params.field_value[0].value.u8 = - rule.firewall.key.proto; - req->firewall_del.delete_params.field_value[0].mask_range.u8 = - rule.firewall.key.proto_mask; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, (void *) msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, (void **) &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data(msg); - - /* Check response */ - if (resp->result != 0) - printf("Request FIREWALL_DEL failed %u)\n", resp->result); - else { - TAILQ_REMOVE(&firewall_table, old_rule, entries); - rte_free(old_rule); - n_firewall_rules--; - } - - /* Free message buffer */ - rte_ctrlmbuf_free(msg); -} - -cmdline_parse_token_string_t cmd_firewall_del_firewall_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result, - firewall_string, "firewall"); - -cmdline_parse_token_string_t cmd_firewall_del_del_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_result, del_string, - "del"); - -cmdline_parse_token_ipaddr_t cmd_firewall_del_src_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, src_ip); -cmdline_parse_token_num_t cmd_firewall_del_src_ip_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_ip_mask, - UINT32); - -cmdline_parse_token_ipaddr_t cmd_firewall_del_dst_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_firewall_del_result, dst_ip); -cmdline_parse_token_num_t cmd_firewall_del_dst_ip_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_ip_mask, - UINT32); - -cmdline_parse_token_num_t cmd_firewall_del_src_port_from = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_from, - UINT16); -cmdline_parse_token_num_t cmd_firewall_del_src_port_to = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, src_port_to, - UINT16); - -cmdline_parse_token_num_t cmd_firewall_del_dst_port_from = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_from, - UINT16); -cmdline_parse_token_num_t cmd_firewall_del_dst_port_to = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, dst_port_to, - UINT16); - -cmdline_parse_token_num_t cmd_firewall_del_proto = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto, UINT8); -cmdline_parse_token_num_t cmd_firewall_del_proto_mask = - TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_result, proto_mask, - UINT8); - -cmdline_parse_inst_t cmd_firewall_del = { - .f = cmd_firewall_del_parsed, - .data = NULL, - .help_str = "Firewall rule delete", - .tokens = { - (void *)&cmd_firewall_del_firewall_string, - (void *)&cmd_firewall_del_del_string, - (void *)&cmd_firewall_del_src_ip, - (void *)&cmd_firewall_del_src_ip_mask, - (void *)&cmd_firewall_del_dst_ip, - (void *)&cmd_firewall_del_dst_ip_mask, - (void *)&cmd_firewall_del_src_port_from, - (void *)&cmd_firewall_del_src_port_to, - (void *)&cmd_firewall_del_dst_port_from, - (void *)&cmd_firewall_del_dst_port_to, - (void *)&cmd_firewall_del_proto, - (void *)&cmd_firewall_del_proto_mask, - NULL, - }, -}; - -/* *** Firewall - Print *** */ -struct cmd_firewall_print_result { - cmdline_fixed_string_t firewall_string; - cmdline_fixed_string_t print_string; -}; - -static void -cmd_firewall_print_parsed( - __attribute__((unused)) void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct app_rule *it; - - TAILQ_FOREACH(it, &firewall_table, entries) { - print_firewall_rule(it->firewall); - } -} - -cmdline_parse_token_string_t cmd_firewall_print_firewall_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result, - firewall_string, "firewall"); - -cmdline_parse_token_string_t cmd_firewall_print_print_string = - TOKEN_STRING_INITIALIZER(struct cmd_firewall_print_result, print_string, - "ls"); - -cmdline_parse_inst_t cmd_firewall_print = { - .f = cmd_firewall_print_parsed, - .data = NULL, - .help_str = "Firewall rules list", - .tokens = { - (void *)&cmd_firewall_print_firewall_string, - (void *)&cmd_firewall_print_print_string, - NULL, - }, -}; - -#endif - -/* *** Flow Classification - Add All *** */ -struct cmd_flow_add_all_result { - cmdline_fixed_string_t flow_string; - cmdline_fixed_string_t add_string; - cmdline_fixed_string_t all_string; -}; - -static void -cmd_flow_add_all_parsed( - __attribute__((unused)) void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - struct rte_ring *ring_req = - app_get_ring_req(app_get_first_core_id(APP_CORE_FC)); - struct rte_ring *ring_resp = - app_get_ring_resp(app_get_first_core_id(APP_CORE_FC)); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - memset(req, 0, sizeof(struct app_msg_req)); - - req->type = APP_MSG_REQ_FC_ADD_ALL; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request FLOW_ADD_ALL failed (%u)\n", resp->result); - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *)msg); -} - -cmdline_parse_token_string_t cmd_flow_add_all_flow_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, flow_string, - "flow"); - -cmdline_parse_token_string_t cmd_flow_add_all_add_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, add_string, - "add"); - -cmdline_parse_token_string_t cmd_flow_add_all_all_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_add_all_result, all_string, - "all"); - -cmdline_parse_inst_t cmd_flow_add_all = { - .f = cmd_flow_add_all_parsed, - .data = NULL, - .help_str = "Flow table initialization based on hard-coded rule", - .tokens = { - (void *)&cmd_flow_add_all_flow_string, - (void *)&cmd_flow_add_all_add_string, - (void *)&cmd_flow_add_all_all_string, - NULL, - }, -}; - -/* *** Flow Classification - Add *** */ -struct cmd_flow_add_result { - cmdline_fixed_string_t flow_string; - cmdline_fixed_string_t add_string; - cmdline_ipaddr_t src_ip; - cmdline_ipaddr_t dst_ip; - uint16_t src_port; - uint16_t dst_port; - uint8_t proto; - uint8_t port; -}; - -static void -cmd_flow_add_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_flow_add_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_FC); - - if (core_id == RTE_MAX_LCORE) { - printf("Flow classification not performed by any CPU core\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Check params */ - if (params->port >= app.n_ports) { - printf("Illegal value for port parameter (%u)\n", params->port); - return; - } - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.flow.key.src_ip = - rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr); - rule.flow.key.dst_ip = - rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr); - rule.flow.key.src_port = params->src_port; - rule.flow.key.dst_port = params->dst_port; - rule.flow.key.proto = params->proto; - rule.flow.port = params->port; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow); - if ((old_rule == NULL) && (n_flow_rules == app.max_flow_rules)) { - printf("Flow table is full.\n"); - return; - } - - printf("Adding flow: "); - print_flow_rule(rule.flow); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - memset(req, 0, sizeof(struct app_msg_req)); - - req->type = APP_MSG_REQ_FC_ADD; - req->flow_classif_add.key.ip_src = rte_bswap32(rule.flow.key.src_ip); - req->flow_classif_add.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip); - req->flow_classif_add.key.port_src = - rte_bswap16(rule.flow.key.src_port); - req->flow_classif_add.key.port_dst = - rte_bswap16(rule.flow.key.dst_port); - req->flow_classif_add.key.proto = rule.flow.key.proto; - req->flow_classif_add.port = rule.flow.port; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request FLOW_ADD failed (%u)\n", resp->result); - else { - if (old_rule == NULL) { - struct app_rule *new_rule = (struct app_rule *) - rte_zmalloc_socket("CLI", - sizeof(struct app_rule), - RTE_CACHE_LINE_SIZE, - rte_socket_id()); - - if (new_rule == NULL) - rte_panic("Unable to allocate new rule\n"); - - memcpy(new_rule, &rule, sizeof(rule)); - TAILQ_INSERT_TAIL(&flow_table, new_rule, entries); - n_flow_rules++; - } else - old_rule->flow.port = rule.flow.port; - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *)msg); -} - -cmdline_parse_token_string_t cmd_flow_add_flow_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, flow_string, - "flow"); - -cmdline_parse_token_string_t cmd_flow_add_add_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_add_result, add_string, "add"); - -cmdline_parse_token_ipaddr_t cmd_flow_add_src_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, src_ip); - -cmdline_parse_token_ipaddr_t cmd_flow_add_dst_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_flow_add_result, dst_ip); - -cmdline_parse_token_num_t cmd_flow_add_src_port = - TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, src_port, UINT16); - -cmdline_parse_token_num_t cmd_flow_add_dst_port = - TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, dst_port, UINT16); - -cmdline_parse_token_num_t cmd_flow_add_proto = - TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, proto, UINT8); - -cmdline_parse_token_num_t cmd_flow_add_port = - TOKEN_NUM_INITIALIZER(struct cmd_flow_add_result, port, UINT8); - -cmdline_parse_inst_t cmd_flow_add = { - .f = cmd_flow_add_parsed, - .data = NULL, - .help_str = "Flow add", - .tokens = { - (void *)&cmd_flow_add_flow_string, - (void *)&cmd_flow_add_add_string, - (void *)&cmd_flow_add_src_ip, - (void *)&cmd_flow_add_dst_ip, - (void *)&cmd_flow_add_src_port, - (void *)&cmd_flow_add_dst_port, - (void *)&cmd_flow_add_proto, - (void *)&cmd_flow_add_port, - NULL, - }, -}; - -/* *** Flow Classification - Del *** */ -struct cmd_flow_del_result { - cmdline_fixed_string_t flow_string; - cmdline_fixed_string_t del_string; - cmdline_ipaddr_t src_ip; - cmdline_ipaddr_t dst_ip; - uint16_t src_port; - uint16_t dst_port; - uint8_t proto; -}; - -static void -cmd_flow_del_parsed( - void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_flow_del_result *params = parsed_result; - struct app_rule rule, *old_rule; - struct app_msg_req *req; - struct app_msg_resp *resp; - void *msg; - int status; - - uint32_t core_id = app_get_first_core_id(APP_CORE_FC); - - if (core_id == RTE_MAX_LCORE) { - printf("Flow classification not performed by any CPU core.\n"); - return; - } - - struct rte_ring *ring_req = app_get_ring_req(core_id); - struct rte_ring *ring_resp = app_get_ring_resp(core_id); - - /* Create rule */ - memset(&rule, 0, sizeof(rule)); - rule.flow.key.src_ip = - rte_bswap32((uint32_t)params->src_ip.addr.ipv4.s_addr); - rule.flow.key.dst_ip = - rte_bswap32((uint32_t)params->dst_ip.addr.ipv4.s_addr); - rule.flow.key.src_port = params->src_port; - rule.flow.key.dst_port = params->dst_port; - rule.flow.key.proto = params->proto; - - /* Check rule existence */ - IS_RULE_PRESENT(old_rule, rule.flow.key, flow_table, flow); - if (old_rule == NULL) - return; - - printf("Deleting flow: "); - print_flow_rule(old_rule->flow); - - /* Allocate message buffer */ - msg = (void *)rte_ctrlmbuf_alloc(app.msg_pool); - if (msg == NULL) - rte_panic("Unable to allocate new message\n"); - - /* Fill request message */ - req = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - memset(req, 0, sizeof(struct app_msg_req)); - - req->type = APP_MSG_REQ_FC_DEL; - req->flow_classif_del.key.ip_src = rte_bswap32(rule.flow.key.src_ip); - req->flow_classif_del.key.ip_dst = rte_bswap32(rule.flow.key.dst_ip); - req->flow_classif_del.key.port_src = - rte_bswap32(rule.flow.key.src_port); - req->flow_classif_del.key.port_dst = - rte_bswap32(rule.flow.key.dst_port); - req->flow_classif_del.key.proto = rule.flow.key.proto; - - /* Send request */ - do { - status = rte_ring_sp_enqueue(ring_req, msg); - } while (status == -ENOBUFS); - - /* Wait for response */ - do { - status = rte_ring_sc_dequeue(ring_resp, &msg); - } while (status != 0); - resp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg); - - /* Check response */ - if (resp->result != 0) - printf("Request FLOW_DEL failed (%u)\n", resp->result); - else { - TAILQ_REMOVE(&flow_table, old_rule, entries); - rte_free(old_rule); - n_flow_rules--; - } - - /* Free message buffer */ - rte_ctrlmbuf_free((struct rte_mbuf *)msg); -} - -cmdline_parse_token_string_t cmd_flow_del_flow_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, flow_string, - "flow"); - -cmdline_parse_token_string_t cmd_flow_del_del_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_del_result, del_string, "del"); - -cmdline_parse_token_ipaddr_t cmd_flow_del_src_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, src_ip); - -cmdline_parse_token_ipaddr_t cmd_flow_del_dst_ip = - TOKEN_IPADDR_INITIALIZER(struct cmd_flow_del_result, dst_ip); - -cmdline_parse_token_num_t cmd_flow_del_src_port = - TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, src_port, UINT16); - -cmdline_parse_token_num_t cmd_flow_del_dst_port = - TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, dst_port, UINT16); - -cmdline_parse_token_num_t cmd_flow_del_proto = - TOKEN_NUM_INITIALIZER(struct cmd_flow_del_result, proto, UINT8); - -cmdline_parse_inst_t cmd_flow_del = { - .f = cmd_flow_del_parsed, - .data = NULL, - .help_str = "Flow delete", - .tokens = { - (void *)&cmd_flow_del_flow_string, - (void *)&cmd_flow_del_del_string, - (void *)&cmd_flow_del_src_ip, - (void *)&cmd_flow_del_dst_ip, - (void *)&cmd_flow_del_src_port, - (void *)&cmd_flow_del_dst_port, - (void *)&cmd_flow_del_proto, - NULL, - }, -}; - -/* *** Flow Classification - Print *** */ -struct cmd_flow_print_result { - cmdline_fixed_string_t flow_string; - cmdline_fixed_string_t print_string; -}; - -static void -cmd_flow_print_parsed( - __attribute__((unused)) void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct app_rule *it; - - TAILQ_FOREACH(it, &flow_table, entries) { - print_flow_rule(it->flow); - } -} - -cmdline_parse_token_string_t cmd_flow_print_flow_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, flow_string, - "flow"); - -cmdline_parse_token_string_t cmd_flow_print_print_string = - TOKEN_STRING_INITIALIZER(struct cmd_flow_print_result, print_string, - "ls"); - -cmdline_parse_inst_t cmd_flow_print = { - .f = cmd_flow_print_parsed, - .data = NULL, - .help_str = "Flow list", - .tokens = { - (void *)&cmd_flow_print_flow_string, - (void *)&cmd_flow_print_print_string, - NULL, - }, -}; - -/* *** QUIT *** */ -struct cmd_quit_result { - cmdline_fixed_string_t quit; -}; - -static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_quit(cl); -} - -cmdline_parse_token_string_t cmd_quit_quit = - TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); - -cmdline_parse_inst_t cmd_quit = { - .f = cmd_quit_parsed, - .data = NULL, - .help_str = "Exit application", - .tokens = { - (void *)&cmd_quit_quit, - NULL, - }, -}; - -/* List of commands */ -cmdline_parse_ctx_t main_ctx[] = { - (cmdline_parse_inst_t *)&cmd_flow_add, - (cmdline_parse_inst_t *)&cmd_flow_del, - (cmdline_parse_inst_t *)&cmd_flow_add_all, - (cmdline_parse_inst_t *)&cmd_flow_print, -#ifdef RTE_LIBRTE_ACL - (cmdline_parse_inst_t *)&cmd_firewall_add, - (cmdline_parse_inst_t *)&cmd_firewall_del, - (cmdline_parse_inst_t *)&cmd_firewall_print, -#endif - (cmdline_parse_inst_t *)&cmd_route_add, - (cmdline_parse_inst_t *)&cmd_route_del, - (cmdline_parse_inst_t *)&cmd_routing_print, - (cmdline_parse_inst_t *)&cmd_arp_add, - (cmdline_parse_inst_t *)&cmd_arp_del, - (cmdline_parse_inst_t *)&cmd_arp_print, - (cmdline_parse_inst_t *)&cmd_run_file, - (cmdline_parse_inst_t *)&cmd_link_enable, - (cmdline_parse_inst_t *)&cmd_link_disable, - (cmdline_parse_inst_t *)&cmd_quit, - NULL, -}; - -/* Main loop */ -void -app_main_loop_cmdline(void) -{ - struct cmdline *cl; - uint32_t core_id = rte_lcore_id(); - - RTE_LOG(INFO, USER1, "Core %u is running the command line interface\n", - core_id); - - n_arp_rules = 0; - n_routing_rules = 0; - n_firewall_rules = 0; - n_flow_rules = 0; - - app_init_rule_tables(); - - cl = cmdline_stdin_new(main_ctx, "pipeline> "); - if (cl == NULL) - return; - cmdline_interact(cl); - cmdline_stdin_exit(cl); -} diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c index 01e13d23a2..036b3169e8 100644 --- a/examples/ip_pipeline/init.c +++ b/examples/ip_pipeline/init.c @@ -44,6 +44,8 @@ #include "app.h" #include "pipeline.h" +#include "pipeline_common_fe.h" +#include "pipeline_master.h" #define APP_NAME_SIZE 32 @@ -1281,6 +1283,9 @@ int app_init(struct app_params *app) app_init_tm(app); app_init_msgq(app); + app_pipeline_common_cmd_push(app); + app_pipeline_type_register(app, &pipeline_master); + app_init_pipelines(app); app_init_threads(app); diff --git a/examples/ip_pipeline/pipeline/pipeline_common_be.c b/examples/ip_pipeline/pipeline/pipeline_common_be.c new file mode 100644 index 0000000000..50dcb69405 --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_common_be.c @@ -0,0 +1,206 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "pipeline_common_be.h" + +void * +pipeline_msg_req_ping_handler(__rte_unused struct pipeline *p, + void *msg) +{ + struct pipeline_msg_rsp *rsp = msg; + + rsp->status = 0; /* OK */ + + return rsp; +} + +void * +pipeline_msg_req_stats_port_in_handler(struct pipeline *p, + void *msg) +{ + struct pipeline_stats_msg_req *req = msg; + struct pipeline_stats_port_in_msg_rsp *rsp = msg; + uint32_t port_id; + + /* Check request */ + if (req->id >= p->n_ports_in) { + rsp->status = -1; + return rsp; + } + port_id = p->port_in_id[req->id]; + + /* Process request */ + rsp->status = rte_pipeline_port_in_stats_read(p->p, + port_id, + &rsp->stats, + 1); + + return rsp; +} + +void * +pipeline_msg_req_stats_port_out_handler(struct pipeline *p, + void *msg) +{ + struct pipeline_stats_msg_req *req = msg; + struct pipeline_stats_port_out_msg_rsp *rsp = msg; + uint32_t port_id; + + /* Check request */ + if (req->id >= p->n_ports_out) { + rsp->status = -1; + return rsp; + } + port_id = p->port_out_id[req->id]; + + /* Process request */ + rsp->status = rte_pipeline_port_out_stats_read(p->p, + port_id, + &rsp->stats, + 1); + + return rsp; +} + +void * +pipeline_msg_req_stats_table_handler(struct pipeline *p, + void *msg) +{ + struct pipeline_stats_msg_req *req = msg; + struct pipeline_stats_table_msg_rsp *rsp = msg; + uint32_t table_id; + + /* Check request */ + if (req->id >= p->n_tables) { + rsp->status = -1; + return rsp; + } + table_id = p->table_id[req->id]; + + /* Process request */ + rsp->status = rte_pipeline_table_stats_read(p->p, + table_id, + &rsp->stats, + 1); + + return rsp; +} + +void * +pipeline_msg_req_port_in_enable_handler(struct pipeline *p, + void *msg) +{ + struct pipeline_port_in_msg_req *req = msg; + struct pipeline_msg_rsp *rsp = msg; + uint32_t port_id; + + /* Check request */ + if (req->port_id >= p->n_ports_in) { + rsp->status = -1; + return rsp; + } + port_id = p->port_in_id[req->port_id]; + + /* Process request */ + rsp->status = rte_pipeline_port_in_enable(p->p, + port_id); + + return rsp; +} + +void * +pipeline_msg_req_port_in_disable_handler(struct pipeline *p, + void *msg) +{ + struct pipeline_port_in_msg_req *req = msg; + struct pipeline_msg_rsp *rsp = msg; + uint32_t port_id; + + /* Check request */ + if (req->port_id >= p->n_ports_in) { + rsp->status = -1; + return rsp; + } + port_id = p->port_in_id[req->port_id]; + + /* Process request */ + rsp->status = rte_pipeline_port_in_disable(p->p, + port_id); + + return rsp; +} + +void * +pipeline_msg_req_invalid_handler(__rte_unused struct pipeline *p, + void *msg) +{ + struct pipeline_msg_rsp *rsp = msg; + + rsp->status = -1; /* Error */ + + return rsp; +} + +int +pipeline_msg_req_handle(struct pipeline *p) +{ + uint32_t msgq_id; + + for (msgq_id = 0; msgq_id < p->n_msgq; msgq_id++) { + for ( ; ; ) { + struct pipeline_msg_req *req; + pipeline_msg_req_handler f_handle; + + req = pipeline_msg_recv(p, msgq_id); + if (req == NULL) + break; + + f_handle = (req->type < PIPELINE_MSG_REQS) ? + p->handlers[req->type] : + pipeline_msg_req_invalid_handler; + + if (f_handle == NULL) + f_handle = pipeline_msg_req_invalid_handler; + + pipeline_msg_send(p, + msgq_id, + f_handle(p, (void *) req)); + } + } + + return 0; +} diff --git a/examples/ip_pipeline/pipeline/pipeline_common_be.h b/examples/ip_pipeline/pipeline/pipeline_common_be.h new file mode 100644 index 0000000000..07fdca095e --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_common_be.h @@ -0,0 +1,163 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __INCLUDE_PIPELINE_COMMON_BE_H__ +#define __INCLUDE_PIPELINE_COMMON_BE_H__ + +#include +#include +#include + +#include "pipeline_be.h" + +struct pipeline; + +enum pipeline_msg_req_type { + PIPELINE_MSG_REQ_PING = 0, + PIPELINE_MSG_REQ_STATS_PORT_IN, + PIPELINE_MSG_REQ_STATS_PORT_OUT, + PIPELINE_MSG_REQ_STATS_TABLE, + PIPELINE_MSG_REQ_PORT_IN_ENABLE, + PIPELINE_MSG_REQ_PORT_IN_DISABLE, + PIPELINE_MSG_REQ_CUSTOM, + PIPELINE_MSG_REQS +}; + +typedef void *(*pipeline_msg_req_handler)(struct pipeline *p, void *msg); + +struct pipeline { + struct rte_pipeline *p; + uint32_t port_in_id[PIPELINE_MAX_PORT_IN]; + uint32_t port_out_id[PIPELINE_MAX_PORT_OUT]; + uint32_t table_id[PIPELINE_MAX_TABLES]; + struct rte_ring *msgq_in[PIPELINE_MAX_MSGQ_IN]; + struct rte_ring *msgq_out[PIPELINE_MAX_MSGQ_OUT]; + + uint32_t n_ports_in; + uint32_t n_ports_out; + uint32_t n_tables; + uint32_t n_msgq; + + pipeline_msg_req_handler handlers[PIPELINE_MSG_REQS]; + char name[PIPELINE_NAME_SIZE]; + uint32_t log_level; +}; + +enum pipeline_log_level { + PIPELINE_LOG_LEVEL_HIGH = 1, + PIPELINE_LOG_LEVEL_LOW, + PIPELINE_LOG_LEVELS +}; + +#define PLOG(p, level, fmt, ...) \ +do { \ + if (p->log_level >= PIPELINE_LOG_LEVEL_ ## level) \ + fprintf(stdout, "[%s] " fmt "\n", p->name, ## __VA_ARGS__);\ +} while (0) + +static inline void * +pipeline_msg_recv(struct pipeline *p, + uint32_t msgq_id) +{ + struct rte_ring *r = p->msgq_in[msgq_id]; + void *msg; + int status = rte_ring_sc_dequeue(r, &msg); + + if (status != 0) + return NULL; + + return msg; +} + +static inline void +pipeline_msg_send(struct pipeline *p, + uint32_t msgq_id, + void *msg) +{ + struct rte_ring *r = p->msgq_out[msgq_id]; + int status; + + do { + status = rte_ring_sp_enqueue(r, msg); + } while (status == -ENOBUFS); +} + +struct pipeline_msg_req { + enum pipeline_msg_req_type type; +}; + +struct pipeline_stats_msg_req { + enum pipeline_msg_req_type type; + uint32_t id; +}; + +struct pipeline_port_in_msg_req { + enum pipeline_msg_req_type type; + uint32_t port_id; +}; + +struct pipeline_custom_msg_req { + enum pipeline_msg_req_type type; + uint32_t subtype; +}; + +struct pipeline_msg_rsp { + int status; +}; + +struct pipeline_stats_port_in_msg_rsp { + int status; + struct rte_pipeline_port_in_stats stats; +}; + +struct pipeline_stats_port_out_msg_rsp { + int status; + struct rte_pipeline_port_out_stats stats; +}; + +struct pipeline_stats_table_msg_rsp { + int status; + struct rte_pipeline_table_stats stats; +}; + +void *pipeline_msg_req_ping_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_stats_port_in_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_stats_port_out_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_stats_table_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_port_in_enable_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_port_in_disable_handler(struct pipeline *p, void *msg); +void *pipeline_msg_req_invalid_handler(struct pipeline *p, void *msg); + +int pipeline_msg_req_handle(struct pipeline *p); + +#endif diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c new file mode 100644 index 0000000000..fcda0ce71f --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c @@ -0,0 +1,1333 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pipeline_common_fe.h" + +int +app_pipeline_ping(struct app_params *app, + uint32_t pipeline_id) +{ + struct app_pipeline_params *p; + struct pipeline_msg_req *req; + struct pipeline_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if (p == NULL) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_PING; + + /* Send request and wait for response */ + rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_pipeline_stats_port_in(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id, + struct rte_pipeline_port_in_stats *stats) +{ + struct app_pipeline_params *p; + struct pipeline_stats_msg_req *req; + struct pipeline_stats_port_in_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if ((app == NULL) || + (stats == NULL)) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if ((p == NULL) || + (port_id >= p->n_pktq_in)) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_STATS_PORT_IN; + req->id = port_id; + + /* Send request and wait for response */ + rsp = (struct pipeline_stats_port_in_msg_rsp *) + app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + if (status == 0) + memcpy(stats, &rsp->stats, sizeof(rsp->stats)); + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_pipeline_stats_port_out(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id, + struct rte_pipeline_port_out_stats *stats) +{ + struct app_pipeline_params *p; + struct pipeline_stats_msg_req *req; + struct pipeline_stats_port_out_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if ((app == NULL) || + (pipeline_id >= app->n_pipelines) || + (stats == NULL)) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if ((p == NULL) || + (port_id >= p->n_pktq_out)) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_STATS_PORT_OUT; + req->id = port_id; + + /* Send request and wait for response */ + rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + if (status == 0) + memcpy(stats, &rsp->stats, sizeof(rsp->stats)); + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_pipeline_stats_table(struct app_params *app, + uint32_t pipeline_id, + uint32_t table_id, + struct rte_pipeline_table_stats *stats) +{ + struct app_pipeline_params *p; + struct pipeline_stats_msg_req *req; + struct pipeline_stats_table_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if ((app == NULL) || + (stats == NULL)) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if (p == NULL) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_STATS_TABLE; + req->id = table_id; + + /* Send request and wait for response */ + rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + if (status == 0) + memcpy(stats, &rsp->stats, sizeof(rsp->stats)); + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_pipeline_port_in_enable(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id) +{ + struct app_pipeline_params *p; + struct pipeline_port_in_msg_req *req; + struct pipeline_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if ((p == NULL) || + (port_id >= p->n_pktq_in)) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_PORT_IN_ENABLE; + req->port_id = port_id; + + /* Send request and wait for response */ + rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_pipeline_port_in_disable(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id) +{ + struct app_pipeline_params *p; + struct pipeline_port_in_msg_req *req; + struct pipeline_msg_rsp *rsp; + int status = 0; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p); + if ((p == NULL) || + (port_id >= p->n_pktq_in)) + return -1; + + /* Message buffer allocation */ + req = app_msg_alloc(app); + if (req == NULL) + return -1; + + /* Fill in request */ + req->type = PIPELINE_MSG_REQ_PORT_IN_DISABLE; + req->port_id = port_id; + + /* Send request and wait for response */ + rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT); + if (rsp == NULL) + return -1; + + /* Check response */ + status = rsp->status; + + /* Message buffer free */ + app_msg_free(app, rsp); + + return status; +} + +int +app_link_config(struct app_params *app, + uint32_t link_id, + uint32_t ip, + uint32_t depth) +{ + struct app_link_params *p; + uint32_t i, netmask, host, bcast; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p); + if (p == NULL) { + APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link", + link_id); + return -1; + } + + if (p->state) { + APP_LOG(app, HIGH, "%s is UP, please bring it DOWN first", + p->name); + return -1; + } + + netmask = (~0) << (32 - depth); + host = ip & netmask; + bcast = host | (~netmask); + + if ((ip == 0) || + (ip == UINT32_MAX) || + (ip == host) || + (ip == bcast)) { + APP_LOG(app, HIGH, "Illegal IP address"); + return -1; + } + + for (i = 0; i < app->n_links; i++) { + struct app_link_params *link = &app->link_params[i]; + + if (strcmp(p->name, link->name) == 0) + continue; + + if (link->ip == ip) { + APP_LOG(app, HIGH, + "%s is already assigned this IP address", + p->name); + return -1; + } + } + + if ((depth == 0) || (depth > 32)) { + APP_LOG(app, HIGH, "Illegal value for depth parameter " + "(%" PRIu32 ")", + depth); + return -1; + } + + /* Save link parameters */ + p->ip = ip; + p->depth = depth; + + return 0; +} + +int +app_link_up(struct app_params *app, + uint32_t link_id) +{ + struct app_link_params *p; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p); + if (p == NULL) { + APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link", + link_id); + return -1; + } + + /* Check link state */ + if (p->state) { + APP_LOG(app, HIGH, "%s is already UP", p->name); + return 0; + } + + /* Check that IP address is valid */ + if (p->ip == 0) { + APP_LOG(app, HIGH, "%s IP address is not set", p->name); + return 0; + } + + app_link_up_internal(app, p); + + return 0; +} + +int +app_link_down(struct app_params *app, + uint32_t link_id) +{ + struct app_link_params *p; + + /* Check input arguments */ + if (app == NULL) + return -1; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p); + if (p == NULL) { + APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link", + link_id); + return -1; + } + + /* Check link state */ + if (p->state == 0) { + APP_LOG(app, HIGH, "%s is already DOWN", p->name); + return 0; + } + + app_link_down_internal(app, p); + + return 0; +} + +/* + * ping + */ + +struct cmd_ping_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t ping_string; +}; + +static void +cmd_ping_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + struct cmd_ping_result *params = parsed_result; + struct app_params *app = data; + int status; + + status = app_pipeline_ping(app, params->pipeline_id); + if (status != 0) + printf("Command failed\n"); +} + +cmdline_parse_token_string_t cmd_ping_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_ping_result, p_string, "p"); + +cmdline_parse_token_num_t cmd_ping_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_ping_result, pipeline_id, UINT32); + +cmdline_parse_token_string_t cmd_ping_ping_string = + TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping_string, "ping"); + +cmdline_parse_inst_t cmd_ping = { + .f = cmd_ping_parsed, + .data = NULL, + .help_str = "Pipeline ping", + .tokens = { + (void *) &cmd_ping_p_string, + (void *) &cmd_ping_pipeline_id, + (void *) &cmd_ping_ping_string, + NULL, + }, +}; + +/* + * stats port in + */ + +struct cmd_stats_port_in_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t stats_string; + cmdline_fixed_string_t port_string; + cmdline_fixed_string_t in_string; + uint32_t port_in_id; + +}; +static void +cmd_stats_port_in_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + struct cmd_stats_port_in_result *params = parsed_result; + struct app_params *app = data; + struct rte_pipeline_port_in_stats stats; + int status; + + status = app_pipeline_stats_port_in(app, + params->pipeline_id, + params->port_in_id, + &stats); + + if (status != 0) { + printf("Command failed\n"); + return; + } + + /* Display stats */ + printf("Pipeline %" PRIu32 " - stats for input port %" PRIu32 ":\n" + "\tPkts in: %" PRIu64 "\n" + "\tPkts dropped by AH: %" PRIu64 "\n" + "\tPkts dropped by other: %" PRIu64 "\n", + params->pipeline_id, + params->port_in_id, + stats.stats.n_pkts_in, + stats.n_pkts_dropped_by_ah, + stats.stats.n_pkts_drop); +} + +cmdline_parse_token_string_t cmd_stats_port_in_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, p_string, + "p"); + +cmdline_parse_token_num_t cmd_stats_port_in_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, pipeline_id, + UINT32); + +cmdline_parse_token_string_t cmd_stats_port_in_stats_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, stats_string, + "stats"); + +cmdline_parse_token_string_t cmd_stats_port_in_port_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, port_string, + "port"); + +cmdline_parse_token_string_t cmd_stats_port_in_in_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, in_string, + "in"); + + cmdline_parse_token_num_t cmd_stats_port_in_port_in_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, port_in_id, + UINT32); + +cmdline_parse_inst_t cmd_stats_port_in = { + .f = cmd_stats_port_in_parsed, + .data = NULL, + .help_str = "Pipeline input port stats", + .tokens = { + (void *) &cmd_stats_port_in_p_string, + (void *) &cmd_stats_port_in_pipeline_id, + (void *) &cmd_stats_port_in_stats_string, + (void *) &cmd_stats_port_in_port_string, + (void *) &cmd_stats_port_in_in_string, + (void *) &cmd_stats_port_in_port_in_id, + NULL, + }, +}; + +/* + * stats port out + */ + +struct cmd_stats_port_out_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t stats_string; + cmdline_fixed_string_t port_string; + cmdline_fixed_string_t out_string; + uint32_t port_out_id; +}; + +static void +cmd_stats_port_out_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + + struct cmd_stats_port_out_result *params = parsed_result; + struct app_params *app = data; + struct rte_pipeline_port_out_stats stats; + int status; + + status = app_pipeline_stats_port_out(app, + params->pipeline_id, + params->port_out_id, + &stats); + + if (status != 0) { + printf("Command failed\n"); + return; + } + + /* Display stats */ + printf("Pipeline %" PRIu32 " - stats for output port %" PRIu32 ":\n" + "\tPkts in: %" PRIu64 "\n" + "\tPkts dropped by AH: %" PRIu64 "\n" + "\tPkts dropped by other: %" PRIu64 "\n", + params->pipeline_id, + params->port_out_id, + stats.stats.n_pkts_in, + stats.n_pkts_dropped_by_ah, + stats.stats.n_pkts_drop); +} + +cmdline_parse_token_string_t cmd_stats_port_out_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, p_string, + "p"); + +cmdline_parse_token_num_t cmd_stats_port_out_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, pipeline_id, + UINT32); + +cmdline_parse_token_string_t cmd_stats_port_out_stats_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, stats_string, + "stats"); + +cmdline_parse_token_string_t cmd_stats_port_out_port_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, port_string, + "port"); + +cmdline_parse_token_string_t cmd_stats_port_out_out_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, out_string, + "out"); + +cmdline_parse_token_num_t cmd_stats_port_out_port_out_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, port_out_id, + UINT32); + +cmdline_parse_inst_t cmd_stats_port_out = { + .f = cmd_stats_port_out_parsed, + .data = NULL, + .help_str = "Pipeline output port stats", + .tokens = { + (void *) &cmd_stats_port_out_p_string, + (void *) &cmd_stats_port_out_pipeline_id, + (void *) &cmd_stats_port_out_stats_string, + (void *) &cmd_stats_port_out_port_string, + (void *) &cmd_stats_port_out_out_string, + (void *) &cmd_stats_port_out_port_out_id, + NULL, + }, +}; + +/* + * stats table + */ + +struct cmd_stats_table_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t stats_string; + cmdline_fixed_string_t table_string; + uint32_t table_id; +}; + +static void +cmd_stats_table_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + struct cmd_stats_table_result *params = parsed_result; + struct app_params *app = data; + struct rte_pipeline_table_stats stats; + int status; + + status = app_pipeline_stats_table(app, + params->pipeline_id, + params->table_id, + &stats); + + if (status != 0) { + printf("Command failed\n"); + return; + } + + /* Display stats */ + printf("Pipeline %" PRIu32 " - stats for table %" PRIu32 ":\n" + "\tPkts in: %" PRIu64 "\n" + "\tPkts in with lookup miss: %" PRIu64 "\n" + "\tPkts in with lookup hit dropped by AH: %" PRIu64 "\n" + "\tPkts in with lookup hit dropped by others: %" PRIu64 "\n" + "\tPkts in with lookup miss dropped by AH: %" PRIu64 "\n" + "\tPkts in with lookup miss dropped by others: %" PRIu64 "\n", + params->pipeline_id, + params->table_id, + stats.stats.n_pkts_in, + stats.stats.n_pkts_lookup_miss, + stats.n_pkts_dropped_by_lkp_hit_ah, + stats.n_pkts_dropped_lkp_hit, + stats.n_pkts_dropped_by_lkp_miss_ah, + stats.n_pkts_dropped_lkp_miss); +} + +cmdline_parse_token_string_t cmd_stats_table_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, p_string, + "p"); + +cmdline_parse_token_num_t cmd_stats_table_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, pipeline_id, + UINT32); + +cmdline_parse_token_string_t cmd_stats_table_stats_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, stats_string, + "stats"); + +cmdline_parse_token_string_t cmd_stats_table_table_string = + TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, table_string, + "table"); + +cmdline_parse_token_num_t cmd_stats_table_table_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, table_id, UINT32); + +cmdline_parse_inst_t cmd_stats_table = { + .f = cmd_stats_table_parsed, + .data = NULL, + .help_str = "Pipeline table stats", + .tokens = { + (void *) &cmd_stats_table_p_string, + (void *) &cmd_stats_table_pipeline_id, + (void *) &cmd_stats_table_stats_string, + (void *) &cmd_stats_table_table_string, + (void *) &cmd_stats_table_table_id, + NULL, + }, +}; + +/* + * port in enable + */ + +struct cmd_port_in_enable_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t port_string; + cmdline_fixed_string_t in_string; + uint32_t port_in_id; + cmdline_fixed_string_t enable_string; +}; + +static void +cmd_port_in_enable_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + struct cmd_port_in_enable_result *params = parsed_result; + struct app_params *app = data; + int status; + + status = app_pipeline_port_in_enable(app, + params->pipeline_id, + params->port_in_id); + + if (status != 0) + printf("Command failed\n"); +} + +cmdline_parse_token_string_t cmd_port_in_enable_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, p_string, + "p"); + +cmdline_parse_token_num_t cmd_port_in_enable_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, pipeline_id, + UINT32); + +cmdline_parse_token_string_t cmd_port_in_enable_port_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, port_string, + "port"); + +cmdline_parse_token_string_t cmd_port_in_enable_in_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, in_string, + "in"); + +cmdline_parse_token_num_t cmd_port_in_enable_port_in_id = + TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, port_in_id, + UINT32); + +cmdline_parse_token_string_t cmd_port_in_enable_enable_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, + enable_string, "enable"); + +cmdline_parse_inst_t cmd_port_in_enable = { + .f = cmd_port_in_enable_parsed, + .data = NULL, + .help_str = "Pipeline input port enable", + .tokens = { + (void *) &cmd_port_in_enable_p_string, + (void *) &cmd_port_in_enable_pipeline_id, + (void *) &cmd_port_in_enable_port_string, + (void *) &cmd_port_in_enable_in_string, + (void *) &cmd_port_in_enable_port_in_id, + (void *) &cmd_port_in_enable_enable_string, + NULL, + }, +}; + +/* + * port in disable + */ + +struct cmd_port_in_disable_result { + cmdline_fixed_string_t p_string; + uint32_t pipeline_id; + cmdline_fixed_string_t port_string; + cmdline_fixed_string_t in_string; + uint32_t port_in_id; + cmdline_fixed_string_t disable_string; +}; + +static void +cmd_port_in_disable_parsed( + void *parsed_result, + __rte_unused struct cmdline *cl, + void *data) +{ + struct cmd_port_in_disable_result *params = parsed_result; + struct app_params *app = data; + int status; + + status = app_pipeline_port_in_disable(app, + params->pipeline_id, + params->port_in_id); + + if (status != 0) + printf("Command failed\n"); +} + +cmdline_parse_token_string_t cmd_port_in_disable_p_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, p_string, + "p"); + +cmdline_parse_token_num_t cmd_port_in_disable_pipeline_id = + TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, pipeline_id, + UINT32); + +cmdline_parse_token_string_t cmd_port_in_disable_port_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, port_string, + "port"); + +cmdline_parse_token_string_t cmd_port_in_disable_in_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, in_string, + "in"); + +cmdline_parse_token_num_t cmd_port_in_disable_port_in_id = + TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, port_in_id, + UINT32); + +cmdline_parse_token_string_t cmd_port_in_disable_disable_string = + TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, + disable_string, "disable"); + +cmdline_parse_inst_t cmd_port_in_disable = { + .f = cmd_port_in_disable_parsed, + .data = NULL, + .help_str = "Pipeline input port disable", + .tokens = { + (void *) &cmd_port_in_disable_p_string, + (void *) &cmd_port_in_disable_pipeline_id, + (void *) &cmd_port_in_disable_port_string, + (void *) &cmd_port_in_disable_in_string, + (void *) &cmd_port_in_disable_port_in_id, + (void *) &cmd_port_in_disable_disable_string, + NULL, + }, +}; + +/* + * link config + */ + +static void +print_link_info(struct app_link_params *p) +{ + struct rte_eth_stats stats; + struct ether_addr *mac_addr; + uint32_t netmask = (~0) << (32 - p->depth); + uint32_t host = p->ip & netmask; + uint32_t bcast = host | (~netmask); + + memset(&stats, 0, sizeof(stats)); + rte_eth_stats_get(p->pmd_id, &stats); + + mac_addr = (struct ether_addr *) &p->mac_addr; + + printf("%s: flags=<%s>\n", + p->name, + (p->state) ? "UP" : "DOWN"); + + if (p->ip) + printf("\tinet %" PRIu32 ".%" PRIu32 + ".%" PRIu32 ".%" PRIu32 + " netmask %" PRIu32 ".%" PRIu32 + ".%" PRIu32 ".%" PRIu32 " " + "broadcast %" PRIu32 ".%" PRIu32 + ".%" PRIu32 ".%" PRIu32 "\n", + (p->ip >> 24) & 0xFF, + (p->ip >> 16) & 0xFF, + (p->ip >> 8) & 0xFF, + p->ip & 0xFF, + (netmask >> 24) & 0xFF, + (netmask >> 16) & 0xFF, + (netmask >> 8) & 0xFF, + netmask & 0xFF, + (bcast >> 24) & 0xFF, + (bcast >> 16) & 0xFF, + (bcast >> 8) & 0xFF, + bcast & 0xFF); + + printf("\tether %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 + ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n", + mac_addr->addr_bytes[0], + mac_addr->addr_bytes[1], + mac_addr->addr_bytes[2], + mac_addr->addr_bytes[3], + mac_addr->addr_bytes[4], + mac_addr->addr_bytes[5]); + + printf("\tRX packets %" PRIu64 + " bytes %" PRIu64 + "\n", + stats.ipackets, + stats.ibytes); + + printf("\tRX mcast %" PRIu64 + " fdirmatch %" PRIu64 + " fdirmiss %" PRIu64 + " lb-packets %" PRIu64 + " lb-bytes %" PRIu64 + " xon %" PRIu64 + " xoff %" PRIu64 "\n", + stats.imcasts, + stats.fdirmatch, + stats.fdirmiss, + stats.ilbpackets, + stats.ilbbytes, + stats.rx_pause_xon, + stats.rx_pause_xoff); + + printf("\tRX errors %" PRIu64 + " missed %" PRIu64 + " badcrc %" PRIu64 + " badlen %" PRIu64 + " no-mbuf %" PRIu64 + "\n", + stats.ierrors, + stats.imissed, + stats.ibadcrc, + stats.ibadlen, + stats.rx_nombuf); + + printf("\tTX packets %" PRIu64 + " bytes %" PRIu64 "\n", + stats.opackets, + stats.obytes); + + printf("\tTX lb-packets %" PRIu64 + " lb-bytes %" PRIu64 + " xon %" PRIu64 + " xoff %" PRIu64 + "\n", + stats.olbpackets, + stats.olbbytes, + stats.tx_pause_xon, + stats.tx_pause_xoff); + + printf("\tTX errors %" PRIu64 + "\n", + stats.oerrors); + + printf("\n"); +} + +struct cmd_link_config_result { + cmdline_fixed_string_t link_string; + uint32_t link_id; + cmdline_fixed_string_t config_string; + cmdline_ipaddr_t ip; + uint32_t depth; +}; + +static void +cmd_link_config_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + void *data) +{ + struct cmd_link_config_result *params = parsed_result; + struct app_params *app = data; + int status; + + uint32_t link_id = params->link_id; + uint32_t ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr); + uint32_t depth = params->depth; + + status = app_link_config(app, link_id, ip, depth); + if (status) + printf("Command failed\n"); + else { + struct app_link_params *p; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p); + print_link_info(p); + } +} + +cmdline_parse_token_string_t cmd_link_config_link_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_config_result, link_string, + "link"); + +cmdline_parse_token_num_t cmd_link_config_link_id = + TOKEN_NUM_INITIALIZER(struct cmd_link_config_result, link_id, UINT32); + +cmdline_parse_token_string_t cmd_link_config_config_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_config_result, config_string, + "config"); + +cmdline_parse_token_ipaddr_t cmd_link_config_ip = + TOKEN_IPV4_INITIALIZER(struct cmd_link_config_result, ip); + +cmdline_parse_token_num_t cmd_link_config_depth = + TOKEN_NUM_INITIALIZER(struct cmd_link_config_result, depth, UINT32); + +cmdline_parse_inst_t cmd_link_config = { + .f = cmd_link_config_parsed, + .data = NULL, + .help_str = "Link configuration", + .tokens = { + (void *)&cmd_link_config_link_string, + (void *)&cmd_link_config_link_id, + (void *)&cmd_link_config_config_string, + (void *)&cmd_link_config_ip, + (void *)&cmd_link_config_depth, + NULL, + }, +}; + +/* + * link up + */ + +struct cmd_link_up_result { + cmdline_fixed_string_t link_string; + uint32_t link_id; + cmdline_fixed_string_t up_string; +}; + +static void +cmd_link_up_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + void *data) +{ + struct cmd_link_up_result *params = parsed_result; + struct app_params *app = data; + int status; + + status = app_link_up(app, params->link_id); + if (status != 0) + printf("Command failed\n"); + else { + struct app_link_params *p; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", params->link_id, + p); + print_link_info(p); + } +} + +cmdline_parse_token_string_t cmd_link_up_link_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_up_result, link_string, + "link"); + +cmdline_parse_token_num_t cmd_link_up_link_id = + TOKEN_NUM_INITIALIZER(struct cmd_link_up_result, link_id, UINT32); + +cmdline_parse_token_string_t cmd_link_up_up_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_up_result, up_string, "up"); + +cmdline_parse_inst_t cmd_link_up = { + .f = cmd_link_up_parsed, + .data = NULL, + .help_str = "Link UP", + .tokens = { + (void *)&cmd_link_up_link_string, + (void *)&cmd_link_up_link_id, + (void *)&cmd_link_up_up_string, + NULL, + }, +}; + +/* + * link down + */ + +struct cmd_link_down_result { + cmdline_fixed_string_t link_string; + uint32_t link_id; + cmdline_fixed_string_t down_string; +}; + +static void +cmd_link_down_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + void *data) +{ + struct cmd_link_down_result *params = parsed_result; + struct app_params *app = data; + int status; + + status = app_link_down(app, params->link_id); + if (status != 0) + printf("Command failed\n"); + else { + struct app_link_params *p; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", params->link_id, + p); + print_link_info(p); + } +} + +cmdline_parse_token_string_t cmd_link_down_link_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_down_result, link_string, + "link"); + +cmdline_parse_token_num_t cmd_link_down_link_id = + TOKEN_NUM_INITIALIZER(struct cmd_link_down_result, link_id, UINT32); + +cmdline_parse_token_string_t cmd_link_down_down_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_down_result, down_string, + "down"); + +cmdline_parse_inst_t cmd_link_down = { + .f = cmd_link_down_parsed, + .data = NULL, + .help_str = "Link DOWN", + .tokens = { + (void *) &cmd_link_down_link_string, + (void *) &cmd_link_down_link_id, + (void *) &cmd_link_down_down_string, + NULL, + }, +}; + +/* + * link ls + */ + +struct cmd_link_ls_result { + cmdline_fixed_string_t link_string; + cmdline_fixed_string_t ls_string; +}; + +static void +cmd_link_ls_parsed( + __attribute__((unused)) void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + void *data) +{ + struct app_params *app = data; + uint32_t link_id; + + for (link_id = 0; link_id < app->n_links; link_id++) { + struct app_link_params *p; + + APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p); + print_link_info(p); + } +} + +cmdline_parse_token_string_t cmd_link_ls_link_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_ls_result, link_string, + "link"); + +cmdline_parse_token_string_t cmd_link_ls_ls_string = + TOKEN_STRING_INITIALIZER(struct cmd_link_ls_result, ls_string, "ls"); + +cmdline_parse_inst_t cmd_link_ls = { + .f = cmd_link_ls_parsed, + .data = NULL, + .help_str = "Link list", + .tokens = { + (void *)&cmd_link_ls_link_string, + (void *)&cmd_link_ls_ls_string, + NULL, + }, +}; + +/* + * quit + */ + +struct cmd_quit_result { + cmdline_fixed_string_t quit; +}; + +static void +cmd_quit_parsed( + __rte_unused void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + cmdline_quit(cl); +} + +static cmdline_parse_token_string_t cmd_quit_quit = + TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); + +static cmdline_parse_inst_t cmd_quit = { + .f = cmd_quit_parsed, + .data = NULL, + .help_str = "Quit", + .tokens = { + (void *) &cmd_quit_quit, + NULL, + }, +}; + +/* + * run + */ + +static void +app_run_file( + cmdline_parse_ctx_t *ctx, + const char *file_name) +{ + struct cmdline *file_cl; + int fd; + + fd = open(file_name, O_RDONLY); + if (fd < 0) { + printf("Cannot open file \"%s\"\n", file_name); + return; + } + + file_cl = cmdline_new(ctx, "", fd, 1); + cmdline_interact(file_cl); + close(fd); +} + +struct cmd_run_file_result { + cmdline_fixed_string_t run_string; + char file_name[APP_FILE_NAME_SIZE]; +}; + +static void +cmd_run_parsed( + void *parsed_result, + struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_run_file_result *params = parsed_result; + + app_run_file(cl->ctx, params->file_name); +} + +cmdline_parse_token_string_t cmd_run_run_string = + TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, run_string, + "run"); + +cmdline_parse_token_string_t cmd_run_file_name = + TOKEN_STRING_INITIALIZER(struct cmd_run_file_result, file_name, NULL); + +cmdline_parse_inst_t cmd_run = { + .f = cmd_run_parsed, + .data = NULL, + .help_str = "Run CLI script file", + .tokens = { + (void *) &cmd_run_run_string, + (void *) &cmd_run_file_name, + NULL, + }, +}; + +static cmdline_parse_ctx_t pipeline_common_cmds[] = { + (cmdline_parse_inst_t *) &cmd_quit, + (cmdline_parse_inst_t *) &cmd_run, + + (cmdline_parse_inst_t *) &cmd_link_config, + (cmdline_parse_inst_t *) &cmd_link_up, + (cmdline_parse_inst_t *) &cmd_link_down, + (cmdline_parse_inst_t *) &cmd_link_ls, + + (cmdline_parse_inst_t *) &cmd_ping, + (cmdline_parse_inst_t *) &cmd_stats_port_in, + (cmdline_parse_inst_t *) &cmd_stats_port_out, + (cmdline_parse_inst_t *) &cmd_stats_table, + (cmdline_parse_inst_t *) &cmd_port_in_enable, + (cmdline_parse_inst_t *) &cmd_port_in_disable, + NULL, +}; + +int +app_pipeline_common_cmd_push(struct app_params *app) +{ + uint32_t n_cmds, i; + + /* Check for available slots in the application commands array */ + n_cmds = RTE_DIM(pipeline_common_cmds) - 1; + if (n_cmds > APP_MAX_CMDS - app->n_cmds) + return -ENOMEM; + + /* Push pipeline commands into the application */ + memcpy(&app->cmds[app->n_cmds], + pipeline_common_cmds, + n_cmds * sizeof(cmdline_parse_ctx_t *)); + + for (i = 0; i < n_cmds; i++) + app->cmds[app->n_cmds + i]->data = app; + + app->n_cmds += n_cmds; + app->cmds[app->n_cmds] = NULL; + + return 0; +} diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h new file mode 100644 index 0000000000..693848d2cc --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.h @@ -0,0 +1,228 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __INCLUDE_PIPELINE_COMMON_FE_H__ +#define __INCLUDE_PIPELINE_COMMON_FE_H__ + +#include +#include +#include +#include + +#include "pipeline_common_be.h" +#include "pipeline.h" +#include "app.h" + +#ifndef MSG_TIMEOUT_DEFAULT +#define MSG_TIMEOUT_DEFAULT 1000 +#endif + +static inline struct app_pipeline_data * +app_pipeline_data(struct app_params *app, uint32_t id) +{ + struct app_pipeline_params *params; + + APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", id, params); + if (params == NULL) + return NULL; + + return &app->pipeline_data[params - app->pipeline_params]; +} + +static inline void * +app_pipeline_data_fe(struct app_params *app, uint32_t id) +{ + struct app_pipeline_data *pipeline_data; + + pipeline_data = app_pipeline_data(app, id); + if (pipeline_data == NULL) + return NULL; + + return pipeline_data->fe; +} + +static inline struct rte_ring * +app_pipeline_msgq_in_get(struct app_params *app, + uint32_t pipeline_id) +{ + struct app_msgq_params *p; + + APP_PARAM_FIND_BY_ID(app->msgq_params, + "MSGQ-REQ-PIPELINE", + pipeline_id, + p); + if (p == NULL) + return NULL; + + return app->msgq[p - app->msgq_params]; +} + +static inline struct rte_ring * +app_pipeline_msgq_out_get(struct app_params *app, + uint32_t pipeline_id) +{ + struct app_msgq_params *p; + + APP_PARAM_FIND_BY_ID(app->msgq_params, + "MSGQ-RSP-PIPELINE", + pipeline_id, + p); + if (p == NULL) + return NULL; + + return app->msgq[p - app->msgq_params]; +} + +static inline void * +app_msg_alloc(__rte_unused struct app_params *app) +{ + return rte_malloc(NULL, 2048, RTE_CACHE_LINE_SIZE); +} + +static inline void +app_msg_free(__rte_unused struct app_params *app, + void *msg) +{ + rte_free(msg); +} + +static inline void +app_msg_send(struct app_params *app, + uint32_t pipeline_id, + void *msg) +{ + struct rte_ring *r = app_pipeline_msgq_in_get(app, pipeline_id); + int status; + + do { + status = rte_ring_sp_enqueue(r, msg); + } while (status == -ENOBUFS); +} + +static inline void * +app_msg_recv(struct app_params *app, + uint32_t pipeline_id) +{ + struct rte_ring *r = app_pipeline_msgq_out_get(app, pipeline_id); + void *msg; + int status = rte_ring_sc_dequeue(r, &msg); + + if (status != 0) + return NULL; + + return msg; +} + +static inline void * +app_msg_send_recv(struct app_params *app, + uint32_t pipeline_id, + void *msg, + uint32_t timeout_ms) +{ + struct rte_ring *r_req = app_pipeline_msgq_in_get(app, pipeline_id); + struct rte_ring *r_rsp = app_pipeline_msgq_out_get(app, pipeline_id); + uint64_t hz = rte_get_tsc_hz(); + void *msg_recv; + uint64_t deadline; + int status; + + /* send */ + do { + status = rte_ring_sp_enqueue(r_req, (void *) msg); + } while (status == -ENOBUFS); + + /* recv */ + deadline = (timeout_ms) ? + (rte_rdtsc() + ((hz * timeout_ms) / 1000)) : + UINT64_MAX; + + do { + if (rte_rdtsc() > deadline) + return NULL; + + status = rte_ring_sc_dequeue(r_rsp, &msg_recv); + } while (status != 0); + + return msg_recv; +} + +int +app_pipeline_ping(struct app_params *app, + uint32_t pipeline_id); + +int +app_pipeline_stats_port_in(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id, + struct rte_pipeline_port_in_stats *stats); + +int +app_pipeline_stats_port_out(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id, + struct rte_pipeline_port_out_stats *stats); + +int +app_pipeline_stats_table(struct app_params *app, + uint32_t pipeline_id, + uint32_t table_id, + struct rte_pipeline_table_stats *stats); + +int +app_pipeline_port_in_enable(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id); + +int +app_pipeline_port_in_disable(struct app_params *app, + uint32_t pipeline_id, + uint32_t port_id); + +int +app_link_config(struct app_params *app, + uint32_t link_id, + uint32_t ip, + uint32_t depth); + +int +app_link_up(struct app_params *app, + uint32_t link_id); + +int +app_link_down(struct app_params *app, + uint32_t link_id); + +int +app_pipeline_common_cmd_push(struct app_params *app); + +#endif diff --git a/examples/ip_pipeline/pipeline/pipeline_master.c b/examples/ip_pipeline/pipeline/pipeline_master.c new file mode 100644 index 0000000000..1ccdad1481 --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_master.c @@ -0,0 +1,47 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pipeline_master.h" +#include "pipeline_master_be.h" + +static struct pipeline_fe_ops pipeline_master_fe_ops = { + .f_init = NULL, + .f_free = NULL, + .cmds = NULL, +}; + +struct pipeline_type pipeline_master = { + .name = "MASTER", + .be_ops = &pipeline_master_be_ops, + .fe_ops = &pipeline_master_fe_ops, +}; diff --git a/examples/ip_pipeline/pipeline/pipeline_master.h b/examples/ip_pipeline/pipeline/pipeline_master.h new file mode 100644 index 0000000000..3fe3030f85 --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_master.h @@ -0,0 +1,41 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __INCLUDE_PIPELINE_MASTER_H__ +#define __INCLUDE_PIPELINE_MASTER_H__ + +#include "pipeline.h" + +extern struct pipeline_type pipeline_master; + +#endif diff --git a/examples/ip_pipeline/pipeline/pipeline_master_be.c b/examples/ip_pipeline/pipeline/pipeline_master_be.c new file mode 100644 index 0000000000..ac0cbbc5ca --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_master_be.c @@ -0,0 +1,150 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "app.h" +#include "pipeline_master_be.h" + +struct pipeline_master { + struct app_params *app; + struct cmdline *cl; + int script_file_done; +} __rte_cache_aligned; + +static void* +pipeline_init(__rte_unused struct pipeline_params *params, void *arg) +{ + struct app_params *app = (struct app_params *) arg; + struct pipeline_master *p; + uint32_t size; + + /* Check input arguments */ + if (app == NULL) + return NULL; + + /* Memory allocation */ + size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_master)); + p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); + if (p == NULL) + return NULL; + + /* Initialization */ + p->app = app; + + p->cl = cmdline_stdin_new(app->cmds, "pipeline> "); + if (p->cl == NULL) { + rte_free(p); + return NULL; + } + + p->script_file_done = 0; + if (app->script_file == NULL) + p->script_file_done = 1; + + return (void *) p; +} + +static int +pipeline_free(void *pipeline) +{ + struct pipeline_master *p = (struct pipeline_master *) pipeline; + + if (p == NULL) + return -EINVAL; + + cmdline_stdin_exit(p->cl); + rte_free(p); + + return 0; +} + +static int +pipeline_run(void *pipeline) +{ + struct pipeline_master *p = (struct pipeline_master *) pipeline; + int status; + + if (p->script_file_done == 0) { + struct app_params *app = p->app; + int fd = open(app->script_file, O_RDONLY); + + if (fd < 0) + printf("Cannot open CLI script file \"%s\"\n", + app->script_file); + else { + struct cmdline *file_cl; + + printf("Running CLI script file \"%s\" ...\n", + app->script_file); + file_cl = cmdline_new(p->cl->ctx, "", fd, 1); + cmdline_interact(file_cl); + close(fd); + } + + p->script_file_done = 1; + } + + status = cmdline_poll(p->cl); + if (status < 0) + rte_panic("CLI poll error (%" PRId32 ")\n", status); + else if (status == RDLINE_EXITED) { + cmdline_stdin_exit(p->cl); + rte_exit(0, "Bye!\n"); + } + + return 0; +} + +static int +pipeline_timer(__rte_unused void *pipeline) +{ + return 0; +} + +struct pipeline_be_ops pipeline_master_be_ops = { + .f_init = pipeline_init, + .f_free = pipeline_free, + .f_run = pipeline_run, + .f_timer = pipeline_timer, + .f_track = NULL, +}; diff --git a/examples/ip_pipeline/pipeline/pipeline_master_be.h b/examples/ip_pipeline/pipeline/pipeline_master_be.h new file mode 100644 index 0000000000..00b71fe8e2 --- /dev/null +++ b/examples/ip_pipeline/pipeline/pipeline_master_be.h @@ -0,0 +1,41 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __INCLUDE_PIPELINE_MASTER_BE_H__ +#define __INCLUDE_PIPELINE_MASTER_BE_H__ + +#include "pipeline_common_be.h" + +extern struct pipeline_be_ops pipeline_master_be_ops; + +#endif