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 082B51B00B for ; Thu, 28 Dec 2017 05:56:12 +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 vBS4uA7R025204 for unknown; Thu, 28 Dec 2017 13:56:10 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id vBS4u8Or027387 for unknown; Thu, 28 Dec 2017 13:56:08 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id PAA27378; Thu, 28 Dec 2017 13:56:08 +0900 Received: from imss03.silk.ntt-tx.co.jp (localhost [127.0.0.1]) by imss03.silk.ntt-tx.co.jp (unknown) with ESMTP id vBS4u7vr011125 for unknown; Thu, 28 Dec 2017 13:56:07 +0900 Received: from mgate01.silk.ntt-tx.co.jp (smtp02.silk.ntt-tx.co.jp [10.107.0.37]) by imss03.silk.ntt-tx.co.jp (unknown) with ESMTP id vBS4u7MM011097 for unknown; Thu, 28 Dec 2017 13:56:07 +0900 Message-Id: <201712280456.vBS4u7MM011097@imss03.silk.ntt-tx.co.jp> Received: from localhost by mgate01.silk.ntt-tx.co.jp (unknown) id vBS4u4bD025622 ; Thu, 28 Dec 2017 13:56:06 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: spp@dpdk.org Date: Thu, 28 Dec 2017 13:55:46 +0900 X-Mailer: git-send-email 1.9.1 In-Reply-To: <4aae78ff-3b6c-cdfe-a8b7-24ec08b73935@lab.ntt.co.jp> References: <4aae78ff-3b6c-cdfe-a8b7-24ec08b73935@lab.ntt.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-TM-AS-MML: No Subject: [spp] [PATCH 39/57] spp_vf: add status command 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: Thu, 28 Dec 2017 04:56:16 -0000 From: Hiroyuki Nakamura * classifier_mac.c: Add new data and associated operations. * classifier_mac.c: Add new API to get classifier status information. * command_dec.c: Add command type for new decoding rule. * command_proc.c: Add status for preparing command response. Signed-off-by: Daiki Yamashita Signed-off-by: Yasufum Ogawa --- src/vf/classifier_mac.c | 100 ++++++++++++++++++++++++++++++++++------ src/vf/classifier_mac.h | 12 +++++ src/vf/command_dec.c | 4 ++ src/vf/command_dec.h | 2 + src/vf/command_proc.c | 118 +++++++++++++++++++++++++++++++++++++----------- src/vf/spp_config.c | 26 +++++++++++ src/vf/spp_config.h | 8 ++++ src/vf/spp_vf.c | 22 +++++++++ src/vf/spp_vf.h | 18 ++++++++ 9 files changed, 268 insertions(+), 42 deletions(-) diff --git a/src/vf/classifier_mac.c b/src/vf/classifier_mac.c index e69347f..81a20ac 100644 --- a/src/vf/classifier_mac.c +++ b/src/vf/classifier_mac.c @@ -61,6 +61,16 @@ static const size_t HASH_TABLE_NAME_BUF_SZ = static const size_t ETHER_ADDR_STR_BUF_SZ = ETHER_ADDR_LEN * 2 + (ETHER_ADDR_LEN - 1) + 1; +/* classified data (destination port, target packets, etc) */ +struct classified_data { + enum port_type if_type; + int if_no; + int if_no_global; + uint8_t tx_port; + uint16_t num_pkt; + struct rte_mbuf *pkts[MAX_PKT_BURST]; +}; + /* classifier information */ struct classifier_mac_info { struct rte_hash *classifier_table; @@ -74,15 +84,7 @@ struct classifier_mac_mng_info { struct classifier_mac_info info[NUM_CLASSIFIER_MAC_INFO]; volatile int ref_index; volatile int upd_index; -}; - -/* classified data (destination port, target packets, etc) */ -struct classified_data { - enum port_type if_type; - int if_no; - uint8_t tx_port; - uint16_t num_pkt; - struct rte_mbuf *pkts[MAX_PKT_BURST]; + struct classified_data classified_data[RTE_MAX_ETHPORTS]; }; /* classifier information per lcore */ @@ -94,6 +96,12 @@ static struct classifier_mac_mng_info g_classifier_mng_info[RTE_MAX_LCORE]; but since we want to start at 0. */ static rte_atomic16_t g_hash_table_count = RTE_ATOMIC16_INIT(0xff); +static inline int +is_used_mng_info(const struct classifier_mac_mng_info *mng_info) +{ + return (mng_info != NULL && mng_info->info[0].classifier_table != NULL); +} + /* initialize classifier information. */ static int init_classifier_info(struct classifier_mac_info *classifier_info, @@ -219,10 +227,11 @@ init_classifier(const struct spp_core_info *core_info, /* store ports information */ for (i = 0; i < core_info->num_tx_port; i++) { - classified_data[i].if_type = core_info->tx_ports[i].if_type; - classified_data[i].if_no = i; - classified_data[i].tx_port = core_info->tx_ports[i].dpdk_port; - classified_data[i].num_pkt = 0; + classified_data[i].if_type = core_info->tx_ports[i].if_type; + classified_data[i].if_no = i; + classified_data[i].if_no_global = core_info->tx_ports[i].if_no; + classified_data[i].tx_port = core_info->tx_ports[i].dpdk_port; + classified_data[i].num_pkt = 0; } return 0; @@ -283,8 +292,9 @@ push_packet(struct rte_mbuf *pkt, struct classified_data *classified_data) if (unlikely(classified_data->num_pkt == MAX_PKT_BURST)) { RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC, "transimit packets (buffer is filled). " - "if_type=%d, if_no=%d, tx_port=%hhd, num_pkt=%hu\n", + "if_type=%d, if_no={%d,%d}, tx_port=%hhd, num_pkt=%hu\n", classified_data->if_type, + classified_data->if_no_global, classified_data->if_no, classified_data->tx_port, classified_data->num_pkt); @@ -375,6 +385,15 @@ change_update_index(struct classifier_mac_mng_info *classifier_mng_info, unsigne } } +/* classifier(mac address) initialize globals. */ +int +spp_classifier_mac_init(void) +{ + memset(g_classifier_mng_info, 0, sizeof(g_classifier_mng_info)); + + return 0; +} + /* classifier(mac address) update component info. */ int spp_classifier_mac_update(struct spp_core_info *core_info) @@ -428,7 +447,7 @@ spp_classifier_mac_do(void *arg) struct rte_mbuf *rx_pkts[MAX_PKT_BURST]; const int n_classified_data = core_info->num_tx_port; - struct classified_data classified_data[n_classified_data]; + struct classified_data *classified_data = classifier_mng_info->classified_data; uint64_t cur_tsc, prev_tsc = 0; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / @@ -501,3 +520,54 @@ spp_classifier_mac_do(void *arg) return 0; } + +/* classifier(mac address) iterate classifier table. */ +int spp_classifier_mac_iterate_table( + struct spp_iterate_classifier_table_params *params) +{ + int ret, i; + const void *key; + void *data; + uint32_t next = 0; + struct classifier_mac_mng_info *classifier_mng_info; + struct classifier_mac_info *classifier_info; + struct classified_data *classified_data; + struct spp_config_port_info port; + char mac_addr_str[ETHER_ADDR_STR_BUF_SZ]; + + for (i = 0; i < RTE_MAX_LCORE; i++) { + classifier_mng_info = g_classifier_mng_info + i; + if (! is_used_mng_info(classifier_mng_info)) + continue; + + classifier_info = classifier_mng_info->info + + classifier_mng_info->ref_index; + + classified_data = classifier_mng_info->classified_data; + + RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC, + "Core[%u] Start iterate classifier table.\n", i); + + while(1) { + ret = rte_hash_iterate(classifier_info->classifier_table, + &key, &data, &next); + + if (unlikely(ret < 0)) + break; + + ether_format_addr(mac_addr_str, sizeof(mac_addr_str), + (const struct ether_addr *)key); + + port.if_type = (classified_data + (long)data)->if_type; + port.if_no = (classified_data + (long)data)->if_no_global; + + (*params->element_proc)( + params->opaque, + SPP_CLASSIFIER_TYPE_MAC, + mac_addr_str, + &port); + } + } + + return 0; +} diff --git a/src/vf/classifier_mac.h b/src/vf/classifier_mac.h index 98f47a5..b1d0198 100644 --- a/src/vf/classifier_mac.h +++ b/src/vf/classifier_mac.h @@ -3,6 +3,12 @@ /* forward declaration */ struct spp_core_info; +struct spp_iterate_classifier_table_params; + +/** + * classifier(mac address) initialize globals. + */ +int spp_classifier_mac_init(void); /** * classifier(mac address) update component info. @@ -23,4 +29,10 @@ int spp_classifier_mac_update(struct spp_core_info *core_info); */ int spp_classifier_mac_do(void *arg); +/** + * classifier(mac address) iterate classifier table. + */ +int spp_classifier_mac_iterate_table( + struct spp_iterate_classifier_table_params *params); + #endif /* _CLASSIFIER_MAC_H_ */ diff --git a/src/vf/command_dec.c b/src/vf/command_dec.c index 3295618..bc8829f 100644 --- a/src/vf/command_dec.c +++ b/src/vf/command_dec.c @@ -26,6 +26,7 @@ static const char *COMMAND_TYPE_STRINGS[] = { "stop", #endif "process", + "status", /* termination */ "", }; @@ -422,6 +423,9 @@ spp_command_decode_request(struct spp_command_request *request, const char *requ case SPP_CMDTYPE_PROCESS: request->is_requested_process = 1; break; + case SPP_CMDTYPE_STATUS: + request->is_requested_status = 1; + break; default: /* nothing to do */ break; diff --git a/src/vf/command_dec.h b/src/vf/command_dec.h index 25e1ea0..42a0168 100644 --- a/src/vf/command_dec.h +++ b/src/vf/command_dec.h @@ -40,6 +40,7 @@ enum spp_command_type { SPP_CMDTYPE_STOP, #endif SPP_CMDTYPE_PROCESS, + SPP_CMDTYPE_STATUS, }; #if 0 /* not supported yet */ @@ -93,6 +94,7 @@ struct spp_command_request { struct spp_command commands[SPP_CMD_MAX_COMMANDS]; int is_requested_process; + int is_requested_status; }; /* decode error information */ diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c index 50418cc..a627277 100644 --- a/src/vf/command_proc.c +++ b/src/vf/command_proc.c @@ -50,13 +50,8 @@ execute_command(const struct spp_command *command) ret = spp_flush(); break; - case SPP_CMDTYPE_PROCESS: - RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute process command.\n"); - /* nothing to do here */ - break; - default: - RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown command. type=%d\n", command->type); + RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute other command. type=%d\n", command->type); /* nothing to do here */ break; } @@ -229,6 +224,73 @@ append_response_process_value(json_t *parent_obj) return 0; } +/* append classifier element value */ +static +int append_classifier_element_value( + void *opaque, + __rte_unused enum spp_classifier_type type, + const char *data, + const struct spp_config_port_info *port) +{ + json_t *parent_obj = (json_t *)opaque; + + char port_str[64]; + spp_config_format_if_info(port_str, port->if_type, port->if_no); + + json_array_append_new(parent_obj, json_pack( + "{ssssss}", + "type", "mac", + "value", data, + "port", port_str)); + + return 0; +} + +/* append info value(status response) to specified json object */ +static int +append_response_info_value(json_t *parent_obj) +{ + int ret = -1; + json_t *info_obj, *tab_obj; + struct spp_iterate_classifier_table_params itr_params; + + /* create classifier_table array */ + tab_obj = json_array(); + if (unlikely(tab_obj == NULL)) + return -1; + + itr_params.opaque = tab_obj; + itr_params.element_proc = append_classifier_element_value; + + ret = spp_iterate_classifier_table(&itr_params); + if (unlikely(ret != 0)) { + json_decref(tab_obj); + return -1; + } + + /* set classifier_table object in info object */ + info_obj = json_object(); + if (unlikely(info_obj == NULL)) { + json_decref(tab_obj); + return -1; + } + + ret = json_object_set_new(info_obj, "classifier_table", tab_obj); + if (unlikely(ret != 0)) { + json_decref(tab_obj); + return -1; + } + + /* set info object in parent object */ + ret = json_object_set_new(parent_obj, "info", info_obj); + if (unlikely(ret != 0)) { + json_decref(info_obj); + return -1; + } + + return 0; +} + /* send response for decode error */ static void send_decode_error_response(int *sock, const struct spp_command_request *request, @@ -244,10 +306,6 @@ send_decode_error_response(int *sock, const struct spp_command_request *request, return; } - /* ** - * output order of object in string is inverse to addition order - * **/ - /* create & append result array */ ret = append_response_decode_results_object(top_obj, request, decode_error); if (unlikely(ret != 0)) { @@ -257,10 +315,10 @@ send_decode_error_response(int *sock, const struct spp_command_request *request, } /* serialize */ - msg = json_dumps(top_obj, JSON_INDENT(2)); + msg = json_dumps(top_obj, JSON_INDENT(2) | JSON_PRESERVE_ORDER); json_decref(top_obj); - RTE_LOG(INFO, SPP_COMMAND_PROC, "Make command response (decode error). " + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Make command response (decode error). " "response_str=\n%s\n", msg); /* send response to requester */ @@ -288,9 +346,13 @@ send_command_result_response(int *sock, const struct spp_command_request *reques return; } - /* ** - * output order of object in string is inverse to addition order - * **/ + /* create & append result array */ + ret = append_response_command_results_object(top_obj, request, command_results); + if (unlikely(ret != 0)) { + RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response."); + json_decref(top_obj); + return; + } /* append process information value */ if (request->is_requested_process) { @@ -302,19 +364,21 @@ send_command_result_response(int *sock, const struct spp_command_request *reques } } - /* create & append result array */ - ret = append_response_command_results_object(top_obj, request, command_results); - if (unlikely(ret != 0)) { - RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response."); - json_decref(top_obj); - return; + /* append info value */ + if (request->is_requested_status) { + ret = append_response_info_value(top_obj); + if (unlikely(ret != 0)) { + RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response."); + json_decref(top_obj); + return; + } } /* serialize */ - msg = json_dumps(top_obj, JSON_INDENT(2)); + msg = json_dumps(top_obj, JSON_INDENT(2) | JSON_PRESERVE_ORDER); json_decref(top_obj); - RTE_LOG(INFO, SPP_COMMAND_PROC, "Make command response (command result). " + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Make command response (command result). " "response_str=\n%s\n", msg); /* send response to requester */ @@ -342,7 +406,7 @@ process_request(int *sock, const char *request_str, size_t request_str_len) memset(&decode_error, 0, sizeof(struct spp_command_decode_error)); memset(command_results, 0, sizeof(command_results)); - RTE_LOG(INFO, SPP_COMMAND_PROC, "Start command request processing. " + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Start command request processing. " "request_str=\n%.*s\n", (int)request_str_len, request_str); /* decode request message */ @@ -351,11 +415,11 @@ process_request(int *sock, const char *request_str, size_t request_str_len) if (unlikely(ret != 0)) { /* send error response */ send_decode_error_response(sock, &request, &decode_error); - RTE_LOG(INFO, SPP_COMMAND_PROC, "End command request processing.\n"); + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "End command request processing.\n"); return ret; } - RTE_LOG(INFO, SPP_COMMAND_PROC, "Command request is valid. " + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Command request is valid. " "num_command=%d, num_valid_command=%d\n", request.num_command, request.num_valid_command); @@ -377,7 +441,7 @@ process_request(int *sock, const char *request_str, size_t request_str_len) /* send response */ send_command_result_response(sock, &request, command_results); - RTE_LOG(INFO, SPP_COMMAND_PROC, "End command request processing.\n"); + RTE_LOG(DEBUG, SPP_COMMAND_PROC, "End command request processing.\n"); return 0; } diff --git a/src/vf/spp_config.c b/src/vf/spp_config.c index 663a609..01f279a 100644 --- a/src/vf/spp_config.c +++ b/src/vf/spp_config.c @@ -198,6 +198,32 @@ spp_config_get_if_info(const char *port, enum port_type *if_type, int *if_no) } /* + * IF種別とIF番号からIF情報文字列を作成する + */ +int spp_config_format_if_info(char *port, enum port_type if_type, int if_no) +{ + const char* if_type_str; + + switch (if_type) { + case PHY: + if_type_str = SPP_CONFIG_IFTYPE_NIC; + break; + case RING: + if_type_str = SPP_CONFIG_IFTYPE_RING; + break; + case VHOST: + if_type_str = SPP_CONFIG_IFTYPE_VHOST; + break; + default: + return -1; + } + + sprintf(port, "%s%d", if_type_str, if_no); + + return 0; +} + +/* * MAC addressを文字列から数値へ変換 */ int64_t diff --git a/src/vf/spp_config.h b/src/vf/spp_config.h index 69f6a3f..a9bcb85 100644 --- a/src/vf/spp_config.h +++ b/src/vf/spp_config.h @@ -109,6 +109,14 @@ int64_t spp_config_change_mac_str_to_int64(const char *mac); int spp_config_get_if_info(const char *port, enum port_type *if_type, int *if_no); /* + * Format port string form if-type/if-number + * + * OK : 0 + * NG : -1 + */ +int spp_config_format_if_info(char *port, enum port_type if_type, int if_no); + +/* * Load config file * OK : 0 * NG : -1 diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c index 23c1bd9..18533d1 100644 --- a/src/vf/spp_vf.c +++ b/src/vf/spp_vf.c @@ -877,6 +877,12 @@ ut_main(int argc, char *argv[]) } /* 他機能部初期化 */ + /* MAC振分初期化 */ + int ret_classifier_mac_init = spp_classifier_mac_init(); + if (unlikely(ret_classifier_mac_init != 0)) { + break; + } + /* コマンド機能部初期化 */ int ret_command_init = spp_command_proc_init( g_startup_param.server_ip, @@ -1130,3 +1136,19 @@ spp_flush(void) memset(g_change_core, 0x00, sizeof(g_change_core)); return SPP_RET_OK; } + +/* + * Iterate Classifier_table + */ +int spp_iterate_classifier_table(struct spp_iterate_classifier_table_params *params) +{ + int ret; + + ret = spp_classifier_mac_iterate_table(params); + if (unlikely(ret != 0)) { + RTE_LOG(ERR, APP, "Cannot iterate classfier_mac_table.\n"); + return SPP_RET_NG; + } + + return SPP_RET_OK; +} diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h index 4ca4568..bbdb904 100644 --- a/src/vf/spp_vf.h +++ b/src/vf/spp_vf.h @@ -82,4 +82,22 @@ int spp_update_classifier_table(enum spp_classifier_type type, const char *data, */ int spp_flush(void); +/* definition of iterated classifier element procedure function */ +typedef int (*spp_iterate_classifier_element_proc)( + void *opaque, + enum spp_classifier_type type, + const char *data, + const struct spp_config_port_info *port); + +/* iterate classifier table parameters */ +struct spp_iterate_classifier_table_params { + void *opaque; + spp_iterate_classifier_element_proc element_proc; +}; + +/* + * Iterate Classifier_table + */ +int spp_iterate_classifier_table(struct spp_iterate_classifier_table_params *params); + #endif /* __SPP_VF_H__ */ -- 1.9.1