[spp] [PATCH 08/57] spp_vf: modify data struct for upd command
x-fn-spp at sl.ntt-tx.co.jp
x-fn-spp at sl.ntt-tx.co.jp
Thu Dec 28 05:55:15 CET 2017
From: Hiroyuki Nakamura <nakamura.hioryuki at po.ntt-tx.co.jp>
spp_vf supports command for modifying classifier table.
* Modify internal data structure to support this command.
Signed-off-by: Kentaro Watanabe <watanabe.kentaro.z01 at as.ntt-tx.co.jp>
Signed-off-by: Yasufum Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
---
src/vf/spp_vf.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/vf/spp_vf.h | 47 +++++++++-
2 files changed, 307 insertions(+), 14 deletions(-)
diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c
index 830aaaa..4fb25a4 100644
--- a/src/vf/spp_vf.c
+++ b/src/vf/spp_vf.c
@@ -1,3 +1,4 @@
+#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
@@ -21,19 +22,26 @@ enum SPP_LONGOPT_RETVAL {
/* add below */
SPP_LONGOPT_RETVAL_CONFIG,
+ SPP_LONGOPT_RETVAL_PROCESS_ID
};
/* struct */
struct startup_param {
uint64_t cpu;
+ int process_id;
+ char server_ip[INET_ADDRSTRLEN];
+ int server_port;
};
struct patch_info {
- int use_flg;
- int dpdk_port;
- struct spp_config_mac_table_element *mac_info;
- struct spp_core_port_info *rx_core;
- struct spp_core_port_info *tx_core;
+ int use_flg;
+ int dpdk_port;
+ int rx_core_no;
+ int tx_core_no;
+ char mac_addr_str[SPP_CONFIG_STR_LEN];
+ uint64_t mac_addr;
+ struct spp_core_port_info *rx_core;
+ struct spp_core_port_info *tx_core;
};
struct if_info {
@@ -49,6 +57,7 @@ static struct spp_config_area g_config;
static struct startup_param g_startup_param;
static struct if_info g_if_info;
static struct spp_core_info g_core_info[SPP_CONFIG_CORE_MAX];
+static int g_change_core[SPP_CONFIG_CORE_MAX];
static char config_file_path[PATH_MAX];
@@ -58,9 +67,10 @@ static char config_file_path[PATH_MAX];
static void
usage(const char *progname)
{
- RTE_LOG(INFO, APP, "Usage: %s [EAL args] -- [--config CONFIG_FILE_PATH]\n"
- " --config CONFIG_FILE_PATH: specific config file path\n"
- "\n"
+ RTE_LOG(INFO, APP, "Usage: %s [EAL args] -- --process-id PROC_ID [--config CONFIG_FILE_PATH] -s SERVER_IP:SERVER_PORT\n"
+ " --process-id PROCESS_ID : My process ID\n"
+ " --config CONFIG_FILE_PATH : specific config file path\n"
+ " -s SERVER_IP:SERVER_PORT : Access information to the server\n"
, progname);
}
@@ -294,6 +304,47 @@ parse_dpdk_args(int argc, char *argv[])
}
/*
+ * Parses the process ID of the application argument.
+ */
+static int
+parse_app_process_id(const char *process_id_str, int *process_id)
+{
+ int id = 0;
+ char *endptr = NULL;
+
+ id = strtol(process_id_str, &endptr, 0);
+ if (unlikely(process_id_str == endptr) || unlikely(*endptr != '\0'))
+ return -1;
+
+ *process_id = id;
+ RTE_LOG(DEBUG, APP, "Set process id = %d\n", *process_id);
+ return 0;
+}
+
+/*
+ * Parses server information of application arguments.
+ */
+static int
+parse_app_server(const char *server_str, char *server_ip, int *server_port)
+{
+ const char delim[2] = ":";
+ int pos = 0;
+ int port = 0;
+ char *endptr = NULL;
+
+ pos = strcspn(server_str, delim);
+ port = strtol(&server_str[pos+1], &endptr, 0);
+ if (unlikely(&server_str[pos+1] == endptr) || unlikely(*endptr != '\0'))
+ return -1;
+
+ memcpy(server_ip, server_str, pos);
+ *server_port = port;
+ RTE_LOG(DEBUG, APP, "Set server ip = %s\n", server_ip);
+ RTE_LOG(DEBUG, APP, "Set server port = %d\n", *server_port);
+ return 0;
+}
+
+/*
* Parse the application arguments to the client app.
*/
static int
@@ -306,8 +357,9 @@ parse_app_args(int argc, char *argv[])
const char *progname = argv[0];
static struct option lgopts[] = {
{ "config", required_argument, NULL, SPP_LONGOPT_RETVAL_CONFIG },
+ { "process-id", required_argument, NULL, SPP_LONGOPT_RETVAL_PROCESS_ID },
{ 0 },
- };
+ };
/* getoptを使用するとargvが並び変わるみたいなので、コピーを実施 */
for (cnt = 0; cnt < argcopt; cnt++) {
@@ -317,7 +369,7 @@ parse_app_args(int argc, char *argv[])
/* Check application parameter */
optind = 0;
opterr = 0;
- while ((opt = getopt_long(argc, argvopt, "", lgopts,
+ while ((opt = getopt_long(argc, argvopt, "s:", lgopts,
&option_index)) != EOF) {
switch (opt) {
case SPP_LONGOPT_RETVAL_CONFIG:
@@ -327,11 +379,31 @@ parse_app_args(int argc, char *argv[])
}
strcpy(config_file_path, optarg);
break;
+ case SPP_LONGOPT_RETVAL_PROCESS_ID:
+ if (parse_app_process_id(optarg, &g_startup_param.process_id) != 0) {
+ usage(progname);
+ return -1;
+ }
+ break;
+ case 's':
+ if (parse_app_server(optarg, g_startup_param.server_ip,
+ &g_startup_param.server_port) != 0) {
+ usage(progname);
+ return -1;
+ }
+ break;
default:
+ usage(progname);
+ return -1;
break;
}
}
+ RTE_LOG(INFO, APP, "application arguments value. (process id = %d, config = %s, server = %s:%d)\n",
+ g_startup_param.process_id,
+ config_file_path,
+ g_startup_param.server_ip,
+ g_startup_param.server_port);
return 0;
}
@@ -364,7 +436,16 @@ get_if_area(enum port_type if_type, int if_no)
static void
init_if_info(void)
{
+ int port_cnt;
memset(&g_if_info, 0x00, sizeof(g_if_info));
+ for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) {
+ g_if_info.nic_patchs[port_cnt].rx_core_no = -1;
+ g_if_info.nic_patchs[port_cnt].tx_core_no = -1;
+ g_if_info.vhost_patchs[port_cnt].rx_core_no = -1;
+ g_if_info.vhost_patchs[port_cnt].tx_core_no = -1;
+ g_if_info.ring_patchs[port_cnt].rx_core_no = -1;
+ g_if_info.ring_patchs[port_cnt].tx_core_no = -1;
+ }
}
/*
@@ -376,11 +457,13 @@ init_core_info(void)
memset(&g_core_info, 0x00, sizeof(g_core_info));
int core_cnt, port_cnt;
for (core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
+ g_core_info[core_cnt].lcore_id = core_cnt;
for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) {
g_core_info[core_cnt].rx_ports[port_cnt].if_type = UNDEF;
g_core_info[core_cnt].tx_ports[port_cnt].if_type = UNDEF;
}
}
+ memset(g_change_core, 0x00, sizeof(g_change_core));
}
/*
@@ -440,7 +523,8 @@ set_form_proc_info(struct spp_config_area *config)
}
/* IF情報からCORE情報を変更する場合用に設定 */
- patch_info->rx_core = &core_info->rx_ports[rx_start + rx_cnt];
+ patch_info->rx_core_no = core_cnt;
+ patch_info->rx_core = &core_info->rx_ports[rx_start + rx_cnt];
}
/* Set TX port */
@@ -464,7 +548,8 @@ set_form_proc_info(struct spp_config_area *config)
}
/* IF情報からCORE情報を変更する場合用に設定 */
- patch_info->tx_core = &core_info->tx_ports[tx_start + tx_cnt];
+ patch_info->tx_core_no = core_cnt;
+ patch_info->tx_core = &core_info->tx_ports[tx_start + tx_cnt];
}
}
@@ -508,7 +593,8 @@ set_from_classifier_table(struct spp_config_area *config)
/* CORE情報側にもMACアドレスの情報設定 */
/* MACアドレスは送信側のみに影響する為、送信側のみ設定 */
- patch_info->mac_info = mac_table;
+ patch_info->mac_addr = mac_table->mac_addr;
+ strcpy(patch_info->mac_addr_str, mac_table->mac_addr_str);
if (unlikely(patch_info->tx_core != NULL)) {
patch_info->tx_core->mac_addr = mac_table->mac_addr;
strcpy(patch_info->tx_core->mac_addr_str, mac_table->mac_addr_str);
@@ -864,6 +950,8 @@ ut_main(int argc, char *argv[])
#else
{
#endif
+ /* コマンド受付追加予定箇所 */
+ /* 戻り値等があれば、判定文も追加予定 */
sleep(1);
#ifdef SPP_RINGLATENCYSTATS_ENABLE /* RING滞留時間 */
@@ -896,3 +984,163 @@ ut_main(int argc, char *argv[])
RTE_LOG(INFO, APP, "spp_vf exit.\n");
return ret;
}
+
+/*
+ * Get process ID
+ */
+int
+spp_get_process_id(void)
+{
+ return g_startup_param.process_id;
+}
+
+/*
+ * Check the MAC address used on the interface
+ */
+static int
+check_mac_used_interface(uint64_t mac_addr, enum port_type *if_type, int *if_no)
+{
+ int cnt = 0;
+ for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+ if (unlikely(g_if_info.nic_patchs[cnt].mac_addr == mac_addr)) {
+ *if_type = PHY;
+ *if_no = cnt;
+ return 0;
+ }
+ if (unlikely(g_if_info.vhost_patchs[cnt].mac_addr == mac_addr)) {
+ *if_type = VHOST;
+ *if_no = cnt;
+ return 0;
+ }
+ if (unlikely(g_if_info.ring_patchs[cnt].mac_addr == mac_addr)) {
+ *if_type = RING;
+ *if_no = cnt;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/*
+ * Update Classifier_table
+ */
+int
+spp_update_classifier_table(
+ enum spp_classifier_type type,
+ const char *data,
+ struct spp_config_port_info *port)
+{
+ enum port_type if_type = UNDEF;
+ int if_no = 0;
+ struct patch_info *patch_info = NULL;
+ int64_t ret_mac = 0;
+ uint64_t mac_addr = 0;
+ int ret_used = 0;
+
+ if (type == SPP_CLASSIFIER_TYPE_MAC) {
+ RTE_LOG(DEBUG, APP, "update_classifier_table ( type = mac, data = %s, port = %d:%d )\n",
+ data, port->if_type, port->if_no);
+
+ ret_mac = spp_config_change_mac_str_to_int64(data);
+ if (unlikely(ret_mac == -1)) {
+ RTE_LOG(ERR, APP, "MAC address format error. ( mac = %s )\n", data);
+ return SPP_RET_NG;
+ }
+
+ mac_addr = (uint64_t)ret_mac;
+
+ ret_used = check_mac_used_interface(mac_addr, &if_type, &if_no);
+ if (port->if_type == UNDEF) {
+ /* Delete(unuse) */
+ if (ret_used < 0) {
+ RTE_LOG(DEBUG, APP, "No MAC address. ( mac = %s )\n", data);
+ return SPP_RET_OK;
+ }
+
+ patch_info = get_if_area(if_type, if_no);
+ if (unlikely(patch_info == NULL)) {
+ RTE_LOG(ERR, APP, "No port. ( port = %d:%d )\n", port->if_type, port->if_no);
+ return SPP_RET_NG;
+ }
+
+ patch_info->mac_addr = 0;
+ memset(patch_info->mac_addr_str, 0x00, SPP_CONFIG_STR_LEN);
+ if (patch_info->tx_core != NULL) {
+ patch_info->tx_core->mac_addr = 0;
+ memset(patch_info->tx_core->mac_addr_str, 0x00, SPP_CONFIG_STR_LEN);
+ }
+ }
+ else
+ {
+ /* Setting */
+ if (unlikely(ret_used == 0)) {
+ if (likely(port->if_type == if_type) && likely(port->if_no == if_no)) {
+ RTE_LOG(DEBUG, APP, "Same MAC address and port. ( mac = %s, port = %d:%d )\n",
+ data, if_type, if_no);
+ return SPP_RET_OK;
+ }
+ else
+ {
+ RTE_LOG(ERR, APP, "MAC address in used. ( mac = %s )\n", data);
+ return SPP_RET_USED_MAC;
+ }
+ }
+
+ patch_info = get_if_area(port->if_type, port->if_no);
+ if (unlikely(patch_info == NULL)) {
+ RTE_LOG(ERR, APP, "No port. ( port = %d:%d )\n", port->if_type, port->if_no);
+ return SPP_RET_NG;
+ }
+
+ if (unlikely(patch_info->use_flg != 0)) {
+ RTE_LOG(ERR, APP, "Port not added. ( port = %d:%d )\n", port->if_type, port->if_no);
+ return SPP_RET_NOT_ADD_PORT;
+ }
+
+ if (unlikely(patch_info->mac_addr != 0)) {
+ RTE_LOG(ERR, APP, "Port in used. ( port = %d:%d )\n", port->if_type, port->if_no);
+ return SPP_RET_USED_PORT;
+ }
+
+ patch_info->mac_addr = mac_addr;
+ strcpy(patch_info->mac_addr_str, data);
+ if (patch_info->tx_core != NULL) {
+ patch_info->tx_core->mac_addr = mac_addr;
+ strcpy(patch_info->tx_core->mac_addr_str, data);
+ }
+ }
+ }
+
+ /* 更新コマンドで設定した場合、コア毎に変更有無を保持 */
+ g_change_core[patch_info->tx_core_no] = 1;
+ return SPP_RET_OK;
+}
+
+/*
+ * Flush SPP component
+ */
+int
+spp_flush(void)
+{
+ int core_cnt = 0;
+ int ret_classifier = 0;
+ struct spp_core_info *core_info = NULL;
+
+ for(core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
+ if (g_change_core[core_cnt] == 0)
+ continue;
+
+ core_info = &g_core_info[core_cnt];
+ if (core_info->type == SPP_CONFIG_CLASSIFIER_MAC) {
+// ret_classifier = spp_classifier_mac_update(core_info);
+ if (unlikely(ret_classifier < 0)) {
+ RTE_LOG(ERR, APP, "Flush error. ( component = classifier_mac)\n");
+ return SPP_RET_NG;
+ }
+ }
+ }
+
+ /* 更新完了により変更したコアをクリア */
+ memset(g_change_core, 0x00, sizeof(g_change_core));
+ return SPP_RET_OK;
+}
diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h
index c0faa57..f9707d7 100644
--- a/src/vf/spp_vf.h
+++ b/src/vf/spp_vf.h
@@ -4,6 +4,8 @@
#include "common.h"
#include "spp_config.h"
+#define SPP_PROCESS_MAX 128
+
/*
* State on core
*/
@@ -15,10 +17,29 @@ enum spp_core_status {
};
/*
+ * Classifier Type
+ */
+enum spp_classifier_type {
+ SPP_CLASSIFIER_TYPE_NONE,
+ SPP_CLASSIFIER_TYPE_MAC
+};
+
+/*
+ * API Return value
+ */
+enum spp_return_value {
+ SPP_RET_OK = 0,
+ SPP_RET_NG = -1,
+ SPP_RET_USED_MAC = -2,
+ SPP_RET_NOT_ADD_PORT = -3,
+ SPP_RET_USED_PORT = -4
+};
+
+/*
* Port info on core
*/
struct spp_core_port_info {
- enum port_type if_type;
+ enum port_type if_type;
int if_no;
int dpdk_port;
uint64_t mac_addr;
@@ -29,6 +50,7 @@ struct spp_core_port_info {
* Core info
*/
struct spp_core_info {
+ unsigned int lcore_id;
volatile enum spp_core_status status;
enum spp_core_type type;
int num_rx_port;
@@ -37,4 +59,27 @@ struct spp_core_info {
struct spp_core_port_info tx_ports[RTE_MAX_ETHPORTS];
};
+/*
+ * Get process ID
+ * RETURN : PROCESS ID(0~127)
+ */
+int spp_get_process_id(void);
+
+/*
+ * Update Classifier_table
+ * OK : SPP_RET_OK(0)
+ * NG : SPP_RET_NG(-1)
+ * : SPP_RET_USED_MAC(-2)
+ * : SPP_RET_NOT_ADD_PORT(-3)
+ * : SPP_RET_USED_PORT(-4)
+ */
+int spp_update_classifier_table(enum spp_classifier_type type, const char *data, struct spp_config_port_info *port);
+
+/*
+ * Flush SPP component
+ * OK : SPP_RET_OK(0)
+ * NG : SPP_RET_NG(-1)
+ */
+int spp_flush(void);
+
#endif /* __SPP_VF_H__ */
--
1.9.1
More information about the spp
mailing list