From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail04.ics.ntt-tx.co.jp (mail05.ics.ntt-tx.co.jp [210.232.35.69]) by dpdk.org (Postfix) with ESMTP id 9144E1B3D8 for ; Fri, 8 Feb 2019 09:46:00 +0100 (CET) Received: from gwchk03.silk.ntt-tx.co.jp (gwchk03.silk.ntt-tx.co.jp [10.107.0.111]) by mail04.ics.ntt-tx.co.jp (unknown) with ESMTP id x188jw0O008983; Fri, 8 Feb 2019 17:45:59 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id x188jwP8025807; Fri, 8 Feb 2019 17:45:58 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id TAA25063; Fri, 8 Feb 2019 17:44:38 +0900 Received: from imss04.silk.ntt-tx.co.jp (localhost [127.0.0.1]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188icBv030819; Fri, 8 Feb 2019 17:44:38 +0900 Received: from mgate02.silk.ntt-tx.co.jp (smtp02.silk.ntt-tx.co.jp [10.107.0.37]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188ic6d030814; Fri, 8 Feb 2019 17:44:38 +0900 Message-Id: <201902080844.x188ic6d030814@imss04.silk.ntt-tx.co.jp> Received: from localhost by mgate02.silk.ntt-tx.co.jp (unknown) id x188icg0028979 ; Fri, 8 Feb 2019 17:44:38 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp Cc: spp@dpdk.org Date: Fri, 8 Feb 2019 17:44:34 +0900 X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> References: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> X-TM-AS-MML: No Subject: [spp] [PATCH v2 3/7] spp_pcap: add management function X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2019 08:46:01 -0000 From: Hideyuki Yamashita Add data or interface management function for spp_pcap. Signed-off-by: Hideyuki Yamashita Signed-off-by: Naoki Takada --- src/pcap/spp_proc.c | 289 ++++++++++++++++++++++++++++++++ src/pcap/spp_proc.h | 389 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 678 insertions(+) create mode 100644 src/pcap/spp_proc.c create mode 100644 src/pcap/spp_proc.h diff --git a/src/pcap/spp_proc.c b/src/pcap/spp_proc.c new file mode 100644 index 0000000..ab08337 --- /dev/null +++ b/src/pcap/spp_proc.c @@ -0,0 +1,289 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation + */ + +#include +#include + +#include +#include + +#include "spp_proc.h" + +#define RTE_LOGTYPE_SPP_PROC RTE_LOGTYPE_USER2 + +/* Manage data to addoress */ +struct manage_data_addr_info { + struct startup_param *p_startup_param; + struct iface_info *p_iface_info; + struct core_mng_info *p_core_info; + int *p_capture_request; + int *p_capture_status; + unsigned int main_lcore_id; +}; + +/* Declare global variables */ +/* Logical core ID for main process */ +static struct manage_data_addr_info g_mng_data_addr; + +/* generation of the ring port */ +int +add_ring_pmd(int ring_id) +{ + struct rte_ring *ring; + int ring_port_id; + + /* Lookup ring of given id */ + ring = rte_ring_lookup(get_rx_queue_name(ring_id)); + if (unlikely(ring == NULL)) { + RTE_LOG(ERR, SPP_PROC, + "Cannot get RX ring - is server process running?\n"); + return SPP_RET_NG; + } + + /* Create ring pmd */ + ring_port_id = rte_eth_from_ring(ring); + RTE_LOG(INFO, SPP_PROC, "ring port add. (no = %d / port = %d)\n", + ring_id, ring_port_id); + return ring_port_id; +} + +/* Get core status */ +enum spp_core_status +spp_get_core_status(unsigned int lcore_id) +{ + return (g_mng_data_addr.p_core_info + lcore_id)->status; +} + +/** + * Check status of all of cores is same as given + * + * It returns SPP_RET_NG as status mismatch if status is not same. + * If core is in use, status will be checked. + */ +static int +check_core_status(enum spp_core_status status) +{ + unsigned int lcore_id = 0; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if ((g_mng_data_addr.p_core_info + lcore_id)->status != + status) { + /* Status is mismatched */ + return SPP_RET_NG; + } + } + return SPP_RET_OK; +} + +int +check_core_status_wait(enum spp_core_status status) +{ + int cnt = 0; + for (cnt = 0; cnt < SPP_CORE_STATUS_CHECK_MAX; cnt++) { + sleep(1); + int ret = check_core_status(status); + if (ret == 0) + return SPP_RET_OK; + } + + RTE_LOG(ERR, SPP_PROC, + "Status check time out. (status = %d)\n", status); + return SPP_RET_NG; +} + +/* Set core status */ +void +set_core_status(unsigned int lcore_id, + enum spp_core_status status) +{ + (g_mng_data_addr.p_core_info + lcore_id)->status = status; +} + +/* Set all core to given status */ +void +set_all_core_status(enum spp_core_status status) +{ + unsigned int lcore_id = 0; + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + (g_mng_data_addr.p_core_info + lcore_id)->status = status; + } +} + +/** + * Set all of component status to SPP_CORE_STOP_REQUEST if received signal + * is SIGTERM or SIGINT + */ +void +stop_process(int signal) +{ + if (unlikely(signal != SIGTERM) && + unlikely(signal != SIGINT)) { + return; + } + + (g_mng_data_addr.p_core_info + g_mng_data_addr.main_lcore_id)->status = + SPP_CORE_STOP_REQUEST; + set_all_core_status(SPP_CORE_STOP_REQUEST); +} + +/** + * Return port info of given type and num of interface + * + * It returns NULL value if given type is invalid. + */ +struct spp_port_info * +get_iface_info(enum port_type iface_type, int iface_no) +{ + struct iface_info *iface_info = g_mng_data_addr.p_iface_info; + + switch (iface_type) { + case PHY: + return &iface_info->nic[iface_no]; + case RING: + return &iface_info->ring[iface_no]; + default: + return NULL; + } +} + +/** + * Initialize g_iface_info + * + * Clear g_iface_info and set initial value. + */ +static void +init_iface_info(void) +{ + int port_cnt; /* increment ether ports */ + struct iface_info *p_iface_info = g_mng_data_addr.p_iface_info; + memset(p_iface_info, 0x00, sizeof(struct iface_info)); + for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) { + p_iface_info->nic[port_cnt].iface_type = UNDEF; + p_iface_info->nic[port_cnt].iface_no = port_cnt; + p_iface_info->nic[port_cnt].dpdk_port = -1; + p_iface_info->nic[port_cnt].class_id.vlantag.vid = + ETH_VLAN_ID_MAX; + p_iface_info->ring[port_cnt].iface_type = UNDEF; + p_iface_info->ring[port_cnt].iface_no = port_cnt; + p_iface_info->ring[port_cnt].dpdk_port = -1; + p_iface_info->ring[port_cnt].class_id.vlantag.vid = + ETH_VLAN_ID_MAX; + } +} + +/* Initialize g_core_info */ +static void +init_core_info(void) +{ + struct core_mng_info *p_core_info = g_mng_data_addr.p_core_info; + memset(p_core_info, 0x00, + sizeof(struct core_mng_info)*RTE_MAX_LCORE); + set_all_core_status(SPP_CORE_STOP); + *g_mng_data_addr.p_capture_request = SPP_CAPTURE_IDLE; + *g_mng_data_addr.p_capture_status = SPP_CAPTURE_IDLE; +} + +/* Setup port info of port on host */ +static int +set_nic_interface(void) +{ + int nic_cnt = 0; + struct iface_info *p_iface_info = g_mng_data_addr.p_iface_info; + + /* NIC Setting */ + p_iface_info->num_nic = rte_eth_dev_count_avail(); + if (p_iface_info->num_nic > RTE_MAX_ETHPORTS) + p_iface_info->num_nic = RTE_MAX_ETHPORTS; + + for (nic_cnt = 0; nic_cnt < p_iface_info->num_nic; nic_cnt++) { + p_iface_info->nic[nic_cnt].iface_type = PHY; + p_iface_info->nic[nic_cnt].dpdk_port = nic_cnt; + } + + return SPP_RET_OK; +} + +/* Setup management info for spp_pcap */ +int +init_mng_data(void) +{ + /* Initialize interface and core information */ + init_iface_info(); + init_core_info(); + + int ret_nic = set_nic_interface(); + if (unlikely(ret_nic != SPP_RET_OK)) + return SPP_RET_NG; + + return SPP_RET_OK; +} + +/** + * Generate a formatted string of combination from interface type and + * number and assign to given 'port' + */ +int spp_format_port_string(char *port, enum port_type iface_type, int iface_no) +{ + const char *iface_type_str; + + switch (iface_type) { + case PHY: + iface_type_str = SPP_IFTYPE_NIC_STR; + break; + case RING: + iface_type_str = SPP_IFTYPE_RING_STR; + break; + default: + return SPP_RET_NG; + } + + sprintf(port, "%s:%d", iface_type_str, iface_no); + + return SPP_RET_OK; +} + +/* Set mange data address */ +int spp_set_mng_data_addr(struct startup_param *startup_param_addr, + struct iface_info *iface_addr, + struct core_mng_info *core_mng_addr, + int *capture_request_addr, + int *capture_status_addr, + unsigned int main_lcore_id) +{ + if (startup_param_addr == NULL || iface_addr == NULL || + core_mng_addr == NULL || + capture_request_addr == NULL || + capture_status_addr == NULL || + main_lcore_id == 0xffffffff) + return SPP_RET_NG; + + g_mng_data_addr.p_startup_param = startup_param_addr; + g_mng_data_addr.p_iface_info = iface_addr; + g_mng_data_addr.p_core_info = core_mng_addr; + g_mng_data_addr.p_capture_request = capture_request_addr; + g_mng_data_addr.p_capture_status = capture_status_addr; + g_mng_data_addr.main_lcore_id = main_lcore_id; + + return SPP_RET_OK; +} + +/* Get manage data address */ +void spp_get_mng_data_addr(struct startup_param **startup_param_addr, + struct iface_info **iface_addr, + struct core_mng_info **core_mng_addr, + int **capture_request_addr, + int **capture_status_addr) +{ + + if (startup_param_addr != NULL) + *startup_param_addr = g_mng_data_addr.p_startup_param; + if (iface_addr != NULL) + *iface_addr = g_mng_data_addr.p_iface_info; + if (core_mng_addr != NULL) + *core_mng_addr = g_mng_data_addr.p_core_info; + if (capture_request_addr != NULL) + *capture_request_addr = g_mng_data_addr.p_capture_request; + if (capture_status_addr != NULL) + *capture_status_addr = g_mng_data_addr.p_capture_status; + +} diff --git a/src/pcap/spp_proc.h b/src/pcap/spp_proc.h new file mode 100644 index 0000000..6da5c5e --- /dev/null +++ b/src/pcap/spp_proc.h @@ -0,0 +1,389 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _SPP_PROC_H_ +#define _SPP_PROC_H_ + +/** + * @file + * SPP process + * + * SPP component common function. + */ + +#include +#include "shared/common.h" + +/* Max number of core status check */ +#define SPP_CORE_STATUS_CHECK_MAX 5 + +/** The length of shortest character string */ +#define SPP_MIN_STR_LEN 32 + +/** The length of NAME string */ +#define SPP_NAME_STR_LEN 128 + +/** Maximum number of port abilities available */ +#define SPP_PORT_ABILITY_MAX 4 + +/** Identifier string for each interface */ +#define SPP_IFTYPE_NIC_STR "phy" +#define SPP_IFTYPE_RING_STR "ring" + +/* State on core */ +enum spp_core_status { + SPP_CORE_UNUSE, /**< Not used */ + SPP_CORE_STOP, /**< Stopped */ + SPP_CORE_IDLE, /**< Idling */ + SPP_CORE_FORWARD, /**< Forwarding */ + SPP_CORE_STOP_REQUEST, /**< Request stopping */ + SPP_CORE_IDLE_REQUEST /**< Request idling */ +}; + +/* State on capture */ +enum spp_capture_status { + SPP_CAPTURE_IDLE, /* Idling */ + SPP_CAPTURE_RUNNING /* Running */ +}; + +enum spp_return_value { + SPP_RET_OK = 0, /**< succeeded */ + SPP_RET_NG = -1, /**< failed */ +}; + +/** + * Port type (rx or tx) to indicate which direction packet goes + * (e.g. receiving or transmitting) + */ +enum spp_port_rxtx { + SPP_PORT_RXTX_NONE, /**< none */ + SPP_PORT_RXTX_RX, /**< rx port */ + SPP_PORT_RXTX_TX, /**< tx port */ + SPP_PORT_RXTX_ALL, /**< rx/tx port */ +}; + +/* Process type for each component */ +enum spp_component_type { + SPP_COMPONENT_UNUSE, /**< Not used */ + SPP_COMPONENT_CLASSIFIER_MAC, /**< Classifier_mac */ + SPP_COMPONENT_MERGE, /**< Merger */ + SPP_COMPONENT_FORWARD, /**< Forwarder */ + SPP_COMPONENT_MIRROR, /**< Mirror */ +}; + +/** + * Port ability operation which indicates vlan tag operation on the port + * (e.g. add vlan tag or delete vlan tag) + */ +enum spp_port_ability_ope { + SPP_PORT_ABILITY_OPE_NONE, /**< none */ + SPP_PORT_ABILITY_OPE_ADD_VLANTAG, /**< add VLAN tag */ + SPP_PORT_ABILITY_OPE_DEL_VLANTAG, /**< delete VLAN tag */ +}; + +/* getopt_long return value for long option */ +enum SPP_LONGOPT_RETVAL { + SPP_LONGOPT_RETVAL__ = 127, + + /* + * Return value definition for getopt_long() + * Only for long option + */ + SPP_LONGOPT_RETVAL_CLIENT_ID, /* --client-id */ + SPP_LONGOPT_RETVAL_OUTPUT, /* --output */ + SPP_LONGOPT_RETVAL_LIMIT_FILE_SIZE /* --limit_file_size */ +}; + +/* Interface information structure */ +struct spp_port_index { + enum port_type iface_type; /**< Interface type (phy/ring) */ + int iface_no; /**< Interface number */ +}; + +/** VLAN tag information */ +struct spp_vlantag_info { + int vid; /**< VLAN ID */ + int pcp; /**< Priority Code Point */ + int tci; /**< Tag Control Information */ +}; + +/** + * Data for each port ability which indicates vlantag related information + * for the port + */ +union spp_ability_data { + /** VLAN tag information */ + struct spp_vlantag_info vlantag; +}; + +/** Port ability information */ +struct spp_port_ability { + enum spp_port_ability_ope ope; /**< Operation */ + enum spp_port_rxtx rxtx; /**< rx/tx identifier */ + union spp_ability_data data; /**< Port ability data */ +}; + +/** Port class identifier for classifying */ +struct spp_port_class_identifier { + uint64_t mac_addr; /**< Mac address (binary) */ + char mac_addr_str[SPP_MIN_STR_LEN]; /**< Mac address (text) */ + struct spp_vlantag_info vlantag; /**< VLAN tag information */ +}; + +/* Port info */ +struct spp_port_info { + enum port_type iface_type; /**< Interface type (phy/vhost/ring) */ + int iface_no; /**< Interface number */ + int dpdk_port; /**< DPDK port number */ + struct spp_port_class_identifier class_id; + /**< Port class identifier */ + struct spp_port_ability ability[SPP_PORT_ABILITY_MAX]; + /**< Port ability */ +}; + +/* Component info */ +struct spp_component_info { + char name[SPP_NAME_STR_LEN]; /**< Component name */ + enum spp_component_type type; /**< Component type */ + unsigned int lcore_id; /**< Logical core ID for component */ + int component_id; /**< Component ID */ + int num_rx_port; /**< The number of rx ports */ + int num_tx_port; /**< The number of tx ports */ + struct spp_port_info *rx_ports[RTE_MAX_ETHPORTS]; + /**< Array of pointers to rx ports */ + struct spp_port_info *tx_ports[RTE_MAX_ETHPORTS]; + /**< Array of pointers to tx ports */ +}; + +/* Manage given options as global variable */ +struct startup_param { + int client_id; /* Client ID */ + char server_ip[INET_ADDRSTRLEN]; + /* IP address stiring of spp-ctl */ + int server_port; /* Port Number of spp-ctl */ +}; + +/* Manage interfaces and port information as global variable */ +struct iface_info { + int num_nic; /* The number of phy */ + int num_ring; /* The number of ring */ + struct spp_port_info nic[RTE_MAX_ETHPORTS]; + /* Port information of phy */ + struct spp_port_info ring[RTE_MAX_ETHPORTS]; + /* Port information of ring */ +}; + +/* Manage core status and component information as global variable */ +struct core_mng_info { + /* Status of cpu core */ + volatile enum spp_core_status status; +}; + +struct spp_iterate_core_params; +/** + * definition of iterated core element procedure function + * which is member of spp_iterate_core_params structure. + * Above structure is used when listing core information + * (e.g) create resonse to status command. + */ +typedef int (*spp_iterate_core_element_proc)( + struct spp_iterate_core_params *params, + const unsigned int lcore_id, + const char *name, + const char *type, + const int num_rx, + const struct spp_port_index *rx_ports, + const int num_tx, + const struct spp_port_index *tx_ports); + +/** + * iterate core table parameters which is + * used when listing core table content + * (e.g.) create response to status command. + */ +struct spp_iterate_core_params { + /** Output buffer */ + char *output; + + /** The function for creating core information */ + spp_iterate_core_element_proc element_proc; +}; + +/** + * added ring_pmd + * + * @param ring_id + * added ring id. + * + * @retval 0~ ring_port_id. + * @retval -1 failed. + */ +int add_ring_pmd(int ring_id); + +/** + * Get core status + * + * @param lcore_id + * Logical core ID. + * + * @return + * Status of specified logical core. + */ +enum spp_core_status spp_get_core_status(unsigned int lcore_id); + +/** + * Run check_core_status() for SPP_CORE_STATUS_CHECK_MAX times with + * interval time (1sec) + * + * @param status + * wait check status. + * + * @retval 0 succeeded. + * @retval -1 failed. + */ +int check_core_status_wait(enum spp_core_status status); + +/** + * Set core status + * + * @param lcore_id + * Logical core ID. + * @param status + * set status. + * + */ +void set_core_status(unsigned int lcore_id, enum spp_core_status status); + +/** + * Set all core status to given + * + * @param status + * set status. + * + */ +void set_all_core_status(enum spp_core_status status); + +/** + * Set all of component status to SPP_CORE_STOP_REQUEST if received signal + * is SIGTERM or SIGINT + * + * @param signl + * received signal. + * + */ +void stop_process(int signal); + +/** + * Return port info of given type and num of interface + * + * @param iface_type + * Interface type to be validated. + * @param iface_no + * Interface number to be validated. + * + * @retval !NULL spp_port_info. + * @retval NULL failed. + */ +struct spp_port_info * +get_iface_info(enum port_type iface_type, int iface_no); + +/** + * Setup management info for spp_vf + */ +int init_mng_data(void); + +/** + * Get component type of target core + * + * @param lcore_id + * Logical core ID. + * + * @return + * Type of component executed on specified logical core + */ +enum spp_component_type +spp_get_component_type(unsigned int lcore_id); + +/* Get core information which is in use */ +struct core_info *get_core_info(unsigned int lcore_id); + +/** + * Port type to string + * + * @param port + * Character string of Port type to be converted. + * @param iface_type + * port interface type + * @param iface_no + * interface no + * + * @retval SPP_RET_OK succeeded. + * @retval SPP_RET_NG failed. + */ +int +spp_format_port_string(char *port, enum port_type iface_type, int iface_no); + +/** + * Port type to string + * + * @param port + * Character string of Port type to be converted. + * @param iface_type + * port interface type + * @param iface_no + * interface no + * + * @retval SPP_RET_OK succeeded. + * @retval SPP_RET_NG failed. + */ +int +spp_format_port_string(char *port, enum port_type iface_type, int iface_no); + +/** + * Set mange data address + * + * @param startup_param_addr + * g_startup_param address + * @param iface_addr + * g_iface_info address + * @param core_mng_addr + * g_core_info address + * @param capture_request_addr + * g_capture_request address + * @param capture_status_addr + * g_capture_status address + * @param main_lcore_id + * main_lcore_id mask + * + * @retval SPP_RET_OK succeeded. + * @retval SPP_RET_NG failed. + */ +int spp_set_mng_data_addr(struct startup_param *startup_param_addr, + struct iface_info *iface_addr, + struct core_mng_info *core_mng_addr, + int *capture_request_addr, + int *capture_status_addr, + unsigned int main_lcore_id); + +/** + * Get mange data address + * + * @param iface_addr + * g_startup_param write address + * @param iface_addr + * g_iface_info write address + * @param core_mng_addr + * g_core_mng_info write address + * @param change_core_addr + * g_capture_request write address + * @param change_component_addr + * g_capture_status write address + */ +void spp_get_mng_data_addr(struct startup_param **startup_param_addr, + struct iface_info **iface_addr, + struct core_mng_info **core_mng_addr, + int **capture_request_addr, + int **capture_status_addr); + +#endif /* _SPP_PROC_H_ */ -- 2.17.1