[spp] [PATCH 54/57] spp_vf: support new command
x-fn-spp at sl.ntt-tx.co.jp
x-fn-spp at sl.ntt-tx.co.jp
Thu Dec 28 05:56:01 CET 2017
From: Hiroyuki Nakamura <nakamura.hioryuki at po.ntt-tx.co.jp>
Newly support 'component' command.
* 'component' command provides start/stop function for component
such as forwarder, classifier etc.
* Support naming function for 'component' and
its name can be used for later command operations.
* Support core selection function for 'component'.
Newly support 'port' command.
* 'port' command provides function for creating port such as ring,
vhost, phy.
* Also provides function for assigning port to 'component'.
This can be done by specifying the name of 'component'.
* 'port' command initializes the port to be used for the first time.
Newly support 'exit' command.
* 'exit' command provides stop function for spp_vf process.
And modify 'classifier_table' command.
* Add operation types. (add/del)
* Add wait procedure for initialization to complete.
Also, to support above commands, the structure of management
data has been changed.
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/spp_vf.py | 6 +-
src/vf/Makefile | 2 +-
src/vf/classifier_mac.c | 251 ++++++----
src/vf/classifier_mac.h | 14 +-
src/vf/command_dec.c | 400 +++++++++++++--
src/vf/command_dec.h | 52 +-
src/vf/command_proc.c | 36 +-
src/vf/command_proc.h | 3 +-
src/vf/spp_config.c | 26 +-
src/vf/spp_forward.c | 199 +++++---
src/vf/spp_forward.h | 9 +-
src/vf/spp_vf.c | 1269 ++++++++++++++++++++++++++++++-----------------
src/vf/spp_vf.h | 199 +++++++-
13 files changed, 1718 insertions(+), 748 deletions(-)
diff --git a/src/spp_vf.py b/src/spp_vf.py
index 40310db..505a142 100755
--- a/src/spp_vf.py
+++ b/src/spp_vf.py
@@ -60,7 +60,7 @@ def connectionthread(name, client_id, conn, m2s, s2m):
#Receiving from secondary
try:
- data = conn.recv(1024) # 1024 stands for bytes of data to be received
+ data = conn.recv(2048) # 2048 stands for bytes of data to be received
if data:
s2m.put("recv:" + str(conn.fileno()) + ":" + "{" + data + "}")
else:
@@ -212,7 +212,7 @@ def primarythread(sock, main2primary, primary2main):
#Receiving from primary
try:
- data = conn.recv(1024) # 1024 stands for bytes of data to be received
+ data = conn.recv(2048) # 2048 stands for bytes of data to be received
if data:
primary2main.put("recv:" + str(addr) + ":" + "{" + data + "}")
else:
@@ -228,8 +228,6 @@ def primarythread(sock, main2primary, primary2main):
def close_all_secondary():
"""Exit all secondary processes"""
- return;
-
global SECONDARY_COUNT
tmp_list = []
diff --git a/src/vf/Makefile b/src/vf/Makefile
index 1284733..a2ac128 100644
--- a/src/vf/Makefile
+++ b/src/vf/Makefile
@@ -40,7 +40,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
APP = spp_vf
# all source are stored in SRCS-y
-SRCS-y := spp_vf.c spp_config.c classifier_mac.c spp_forward.c string_buffer.c command_conn.c command_dec.c command_proc.c ringlatencystats.c ../shared/common.c
+SRCS-y := spp_vf.c classifier_mac.c spp_forward.c string_buffer.c command_conn.c command_dec.c command_proc.c ringlatencystats.c ../shared/common.c
CFLAGS += $(WERROR_FLAGS) -O3
CFLAGS += -I$(SRCDIR)/../shared
diff --git a/src/vf/classifier_mac.c b/src/vf/classifier_mac.c
index e2aa715..937a8c0 100644
--- a/src/vf/classifier_mac.c
+++ b/src/vf/classifier_mac.c
@@ -40,7 +40,7 @@
/* interval that wait untill change update index
micro second */
-#define CHANGE_UPDATE_INDEX_WAIT_INTERVAL 10
+#define CHANGE_UPDATE_INDEX_WAIT_INTERVAL SPP_CHANGE_UPDATE_INTERVAL
/* interval that transmit burst packet, if buffer is not filled.
nano second */
@@ -65,12 +65,12 @@ static const size_t ETHER_ADDR_STR_BUF_SZ =
/* 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];
+ enum port_type if_type; /* interface type (see "enum port_type") */
+ int if_no; /* index of ports handled by classifier */
+ int if_no_global; /* interface number */
+ uint8_t port; /* port number used by dpdk */
+ uint16_t num_pkt; /* the number of packets in pkts[] */
+ struct rte_mbuf *pkts[MAX_PKT_BURST]; /* packet array to be classified */
};
/* classifier information */
@@ -79,6 +79,9 @@ struct classifier_mac_info {
int num_active_classified;
int active_classifieds[RTE_MAX_ETHPORTS];
int default_classified;
+ int n_classified_data_tx;
+ struct classified_data classified_data_rx;
+ struct classified_data classified_data_tx[RTE_MAX_ETHPORTS];
};
/* classifier management information */
@@ -86,7 +89,6 @@ struct classifier_mac_mng_info {
struct classifier_mac_info info[NUM_CLASSIFIER_MAC_INFO];
volatile int ref_index;
volatile int upd_index;
- struct classified_data classified_data[RTE_MAX_ETHPORTS];
};
/* classifier information per lcore */
@@ -109,20 +111,40 @@ is_used_mng_info(const struct classifier_mac_mng_info *mng_info)
/* initialize classifier information. */
static int
init_classifier_info(struct classifier_mac_info *classifier_info,
- const struct spp_core_info *core_info)
+ const struct spp_component_info *component_info)
{
int ret = -1;
int i;
struct rte_hash **classifier_table = &classifier_info->classifier_table;
struct ether_addr eth_addr;
char mac_addr_str[ETHER_ADDR_STR_BUF_SZ];
+ struct classified_data *classified_data_rx = &classifier_info->classified_data_rx;
+ struct classified_data *classified_data_tx = classifier_info->classified_data_tx;
+ struct spp_port_info *tx_port = NULL;
rte_hash_reset(*classifier_table);
classifier_info->num_active_classified = 0;
classifier_info->default_classified = -1;
+ classifier_info->n_classified_data_tx = component_info->num_tx_port;
+ if (component_info->num_rx_port != 0) {
+ classified_data_rx->if_type = component_info->rx_ports[0]->if_type;
+ classified_data_rx->if_no = 0;
+ classified_data_rx->if_no_global = component_info->rx_ports[0]->if_no;
+ classified_data_rx->port = component_info->rx_ports[0]->dpdk_port;
+ classified_data_rx->num_pkt = 0;
+ }
+
+ for (i = 0; i < component_info->num_tx_port; i++) {
+ tx_port = component_info->tx_ports[i];
- for (i = 0; i < core_info->num_tx_port; i++) {
- if (core_info->tx_ports[i].mac_addr == 0) {
+ /* store ports information */
+ classified_data_tx[i].if_type = tx_port->if_type;
+ classified_data_tx[i].if_no = i;
+ classified_data_tx[i].if_no_global = tx_port->if_no;
+ classified_data_tx[i].port = tx_port->dpdk_port;
+ classified_data_tx[i].num_pkt = 0;
+
+ if (component_info->tx_ports[i]->mac_addr == 0) {
continue;
}
@@ -131,19 +153,19 @@ init_classifier_info(struct classifier_mac_info *classifier_info,
num_active_classified++] = i;
/* store default classified */
- if (unlikely(core_info->tx_ports[i].mac_addr ==
- SPP_CONFIG_DEFAULT_CLASSIFIED_DMY_ADDR)) {
+ if (unlikely(tx_port->mac_addr ==
+ SPP_DEFAULT_CLASSIFIED_DMY_ADDR)) {
classifier_info->default_classified = i;
RTE_LOG(INFO, SPP_CLASSIFIER_MAC, "default classified. "
"if_type=%d, if_no=%d, dpdk_port=%d\n",
- core_info->tx_ports[i].if_type,
- core_info->tx_ports[i].if_no,
- core_info->tx_ports[i].dpdk_port);
+ tx_port->if_type,
+ tx_port->if_no,
+ tx_port->dpdk_port);
continue;
}
/* add entry to classifier mac table */
- rte_memcpy(ð_addr, &core_info->tx_ports[i].mac_addr, ETHER_ADDR_LEN);
+ rte_memcpy(ð_addr, &tx_port->mac_addr, ETHER_ADDR_LEN);
ether_format_addr(mac_addr_str, sizeof(mac_addr_str), ð_addr);
ret = rte_hash_add_key_data(*classifier_table,
@@ -160,9 +182,9 @@ init_classifier_info(struct classifier_mac_info *classifier_info,
RTE_LOG(INFO, SPP_CLASSIFIER_MAC, "Add entry to classifier mac table. "
"mac_addr=%s, if_type=%d, if_no=%d, dpdk_port=%d\n",
mac_addr_str,
- core_info->tx_ports[i].if_type,
- core_info->tx_ports[i].if_no,
- core_info->tx_ports[i].dpdk_port);
+ tx_port->if_type,
+ tx_port->if_no,
+ tx_port->dpdk_port);
}
return 0;
@@ -170,19 +192,25 @@ init_classifier_info(struct classifier_mac_info *classifier_info,
/* initialize classifier. */
static int
-init_classifier(const struct spp_core_info *core_info,
- struct classifier_mac_mng_info *classifier_mng_info,
- struct classified_data *classified_data)
+init_classifier(struct classifier_mac_mng_info *classifier_mng_info)
{
int ret = -1;
int i;
char hash_table_name[HASH_TABLE_NAME_BUF_SZ];
struct rte_hash **classifier_mac_table = NULL;
+ struct spp_component_info component_info;
memset(classifier_mng_info, 0, sizeof(struct classifier_mac_mng_info));
+ /*
+ * Set the same value for "ref_index" and "upd_index"
+ * so that it will not be changed from others during initialization,
+ * and update "upd_index" after initialization is completed.
+ * Therefore, this setting is consciously described.
+ */
classifier_mng_info->ref_index = 0;
- classifier_mng_info->upd_index = classifier_mng_info->ref_index + 1;
+ classifier_mng_info->upd_index = 0;
+ memset(&component_info, 0x00, sizeof(component_info));
#ifdef RTE_MACHINE_CPUFLAG_SSE4_2
RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC, "Enabled SSE4.2. use crc hash.\n");
@@ -222,21 +250,15 @@ init_classifier(const struct spp_core_info *core_info,
/* populate the classifier information at reference */
ret = init_classifier_info(&classifier_mng_info->
- info[classifier_mng_info->ref_index], core_info);
+ info[classifier_mng_info->ref_index], &component_info);
if (unlikely(ret != 0)) {
RTE_LOG(ERR, SPP_CLASSIFIER_MAC,
"Cannot initialize classifer mac table. ret=%d\n", ret);
return -1;
}
- /* 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].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;
- }
+ /* updating side can be set by completion of initialization. */
+ classifier_mng_info->upd_index = classifier_mng_info->ref_index + 1;
return 0;
}
@@ -270,7 +292,7 @@ transmit_packet(struct classified_data *classified_data)
#endif
/* transmit packets */
- n_tx = rte_eth_tx_burst(classified_data->tx_port, 0,
+ n_tx = rte_eth_tx_burst(classified_data->port, 0,
classified_data->pkts, classified_data->num_pkt);
/* free cannnot transmit packets */
@@ -279,12 +301,32 @@ transmit_packet(struct classified_data *classified_data)
rte_pktmbuf_free(classified_data->pkts[i]);
RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
"drop packets(tx). num=%hu, dpdk_port=%hhu\n",
- classified_data->num_pkt - n_tx, classified_data->tx_port);
+ classified_data->num_pkt - n_tx, classified_data->port);
}
classified_data->num_pkt = 0;
}
+/* transmit packet to one destination. */
+static inline void
+transmit_all_packet(struct classifier_mac_info *classifier_info)
+{
+ int i;
+ struct classified_data *classified_data_tx = classifier_info->classified_data_tx;
+
+ for (i = 0; i < classifier_info->n_classified_data_tx; i++) {
+ if (unlikely(classified_data_tx[i].num_pkt != 0)) {
+ RTE_LOG(INFO, SPP_CLASSIFIER_MAC,
+ "transimit all packets (drain). "
+ "index=%d, "
+ "num_pkt=%hu\n",
+ i,
+ classified_data_tx[i].num_pkt);
+ transmit_packet(&classified_data_tx[i]);
+ }
+ }
+}
+
/* set mbuf pointer to tx buffer
and transmit packet, if buffer is filled */
static inline void
@@ -300,7 +342,7 @@ push_packet(struct rte_mbuf *pkt, struct classified_data *classified_data)
classified_data->if_type,
classified_data->if_no_global,
classified_data->if_no,
- classified_data->tx_port,
+ classified_data->port,
classified_data->num_pkt);
transmit_packet(classified_data);
}
@@ -383,13 +425,18 @@ classify_packet(struct rte_mbuf **rx_pkts, uint16_t n_rx,
/* change update index at classifier management information */
static inline void
-change_update_index(struct classifier_mac_mng_info *classifier_mng_info, unsigned int lcore_id)
+change_update_index(struct classifier_mac_mng_info *classifier_mng_info, int id)
{
if (unlikely(classifier_mng_info->ref_index ==
classifier_mng_info->upd_index)) {
+
+ /* Transmit all packets for switching the using data. */
+ transmit_all_packet(classifier_mng_info->info +
+ classifier_mng_info->ref_index);
+
RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
- "Core[%u] Change update index.\n", lcore_id);
- classifier_mng_info->upd_index =
+ "Core[%u] Change update index.\n", id);
+ classifier_mng_info->ref_index =
(classifier_mng_info->upd_index + 1) %
NUM_CLASSIFIER_MAC_INFO;
}
@@ -406,22 +453,26 @@ spp_classifier_mac_init(void)
/* classifier(mac address) update component info. */
int
-spp_classifier_mac_update(struct spp_core_info *core_info)
+spp_classifier_mac_update(struct spp_component_info *component_info)
{
int ret = -1;
- unsigned int lcore_id = core_info->lcore_id;
-
+ int id = component_info->component_id;
struct classifier_mac_mng_info *classifier_mng_info =
- g_classifier_mng_info + lcore_id;
+ g_classifier_mng_info + id;
- struct classifier_mac_info *classifier_info =
- classifier_mng_info->info + classifier_mng_info->upd_index;
+ struct classifier_mac_info *classifier_info = NULL;
RTE_LOG(INFO, SPP_CLASSIFIER_MAC,
- "Core[%u] Start update component.\n", lcore_id);
+ "Component[%u] Start update component.\n", id);
+
+ /* wait until no longer access the new update side */
+ while(likely(classifier_mng_info->ref_index == classifier_mng_info->upd_index))
+ rte_delay_us_block(CHANGE_UPDATE_INDEX_WAIT_INTERVAL);
+
+ classifier_info = classifier_mng_info->info + classifier_mng_info->upd_index;
/* initialize update side classifier information */
- ret = init_classifier_info(classifier_info, core_info);
+ ret = init_classifier_info(classifier_info, component_info);
if (unlikely(ret != 0)) {
RTE_LOG(ERR, SPP_CLASSIFIER_MAC,
"Cannot update classifer mac. ret=%d\n", ret);
@@ -429,105 +480,96 @@ spp_classifier_mac_update(struct spp_core_info *core_info)
}
/* change index of reference side */
- classifier_mng_info->ref_index = classifier_mng_info->upd_index;
+ classifier_mng_info->upd_index = classifier_mng_info->ref_index;
/* wait until no longer access the new update side */
while(likely(classifier_mng_info->ref_index == classifier_mng_info->upd_index))
rte_delay_us_block(CHANGE_UPDATE_INDEX_WAIT_INTERVAL);
RTE_LOG(INFO, SPP_CLASSIFIER_MAC,
- "Core[%u] Complete update component.\n", lcore_id);
+ "Component[%u] Complete update component.\n", id);
return 0;
}
/* classifier(mac address) thread function. */
int
-spp_classifier_mac_do(void *arg)
+spp_classifier_mac_do(int id)
{
int ret = -1;
int i;
int n_rx;
unsigned int lcore_id = rte_lcore_id();
- struct spp_core_info *core_info = (struct spp_core_info *)arg;
struct classifier_mac_mng_info *classifier_mng_info =
- g_classifier_mng_info + rte_lcore_id();
+ g_classifier_mng_info + id;
struct classifier_mac_info *classifier_info = NULL;
struct rte_mbuf *rx_pkts[MAX_PKT_BURST];
- const int n_classified_data = core_info->num_tx_port;
- struct classified_data *classified_data = classifier_mng_info->classified_data;
+ struct classified_data *classified_data_rx = NULL;
+ struct classified_data *classified_data_tx = NULL;
uint64_t cur_tsc, prev_tsc = 0;
const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) /
US_PER_S * DRAIN_TX_PACKET_INTERVAL;
/* initialize */
- ret = init_classifier(core_info, classifier_mng_info, classified_data);
+ ret = init_classifier(classifier_mng_info);
if (unlikely(ret != 0))
return ret;
- /* to idle */
- core_info->status = SPP_CORE_IDLE;
- RTE_LOG(INFO, SPP_CLASSIFIER_MAC, "Core[%u] Start. (type = %d)\n",
- lcore_id, core_info->type);
-
- while(likely(core_info->status == SPP_CORE_IDLE) ||
- likely(core_info->status == SPP_CORE_FORWARD)) {
-
- while(likely(core_info->status == SPP_CORE_FORWARD)) {
- /* change index of update side */
- change_update_index(classifier_mng_info, lcore_id);
-
- /* decide classifier infomation of the current cycle */
- classifier_info = classifier_mng_info->info +
- classifier_mng_info->ref_index;
-
- /* drain tx packets, if buffer is not filled for interval */
- cur_tsc = rte_rdtsc();
- if (unlikely(cur_tsc - prev_tsc > drain_tsc)) {
- for (i = 0; i < n_classified_data; i++) {
- if (unlikely(classified_data[i].num_pkt != 0)) {
- RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
- "transimit packets (drain). "
- "index=%d, "
- "num_pkt=%hu, "
- "interval=%lu\n",
- i,
- classified_data[i].num_pkt,
- cur_tsc - prev_tsc);
- transmit_packet(&classified_data[i]);
- }
+ while(likely(spp_get_core_status(lcore_id) == SPP_CORE_FORWARD) &&
+ likely(spp_check_core_index(lcore_id) == 0)) {
+ /* change index of update side */
+ change_update_index(classifier_mng_info, id);
+
+ /* decide classifier infomation of the current cycle */
+ classifier_info = classifier_mng_info->info +
+ classifier_mng_info->ref_index;
+ classified_data_rx = &classifier_info->classified_data_rx;
+ classified_data_tx = classifier_info->classified_data_tx;
+
+ /* drain tx packets, if buffer is not filled for interval */
+ cur_tsc = rte_rdtsc();
+ if (unlikely(cur_tsc - prev_tsc > drain_tsc)) {
+ for (i = 0; i < classifier_info->n_classified_data_tx; i++) {
+ if (unlikely(classified_data_tx[i].num_pkt != 0)) {
+ RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
+ "transimit packets (drain). "
+ "index=%d, "
+ "num_pkt=%hu, "
+ "interval=%lu\n",
+ i,
+ classified_data_tx[i].num_pkt,
+ cur_tsc - prev_tsc);
+ transmit_packet(&classified_data_tx[i]);
}
- prev_tsc = cur_tsc;
}
+ prev_tsc = cur_tsc;
+ }
- /* retrieve packets */
- n_rx = rte_eth_rx_burst(core_info->rx_ports[0].dpdk_port, 0,
- rx_pkts, MAX_PKT_BURST);
- if (unlikely(n_rx == 0))
- continue;
+ /* retrieve packets */
+ n_rx = rte_eth_rx_burst(classified_data_rx->port, 0,
+ rx_pkts, MAX_PKT_BURST);
+ if (unlikely(n_rx == 0))
+ continue;
#ifdef SPP_RINGLATENCYSTATS_ENABLE
- if (core_info->rx_ports[0].if_type == RING)
- spp_ringlatencystats_calculate_latency(
- core_info->rx_ports[0].if_no, rx_pkts, n_rx);
+ if (classified_data_rx->if_type == RING)
+ spp_ringlatencystats_calculate_latency(
+ classified_data_rx->if_no, rx_pkts, n_rx);
#endif
- /* classify and transmit (filled) */
- classify_packet(rx_pkts, n_rx, classifier_info, classified_data);
- }
+ /* classify and transmit (filled) */
+ classify_packet(rx_pkts, n_rx, classifier_info, classified_data_tx);
}
/* just in case */
- change_update_index(classifier_mng_info, lcore_id);
+ change_update_index(classifier_mng_info, id);
/* uninitialize */
uninit_classifier(classifier_mng_info);
- core_info->status = SPP_CORE_STOP;
-
return 0;
}
@@ -542,7 +584,7 @@ int spp_classifier_mac_iterate_table(
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;
+ struct spp_port_index port;
char mac_addr_str[ETHER_ADDR_STR_BUF_SZ];
for (i = 0; i < RTE_MAX_LCORE; i++) {
@@ -553,7 +595,7 @@ int spp_classifier_mac_iterate_table(
classifier_info = classifier_mng_info->info +
classifier_mng_info->ref_index;
- classified_data = classifier_mng_info->classified_data;
+ classified_data = classifier_info->classified_data_tx;
RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
"Core[%u] Start iterate classifier table.\n", i);
@@ -565,10 +607,11 @@ int spp_classifier_mac_iterate_table(
(*params->element_proc)(
params->opaque,
SPP_CLASSIFIER_TYPE_MAC,
- SPP_CONFIG_DEFAULT_CLASSIFIED_SPEC_STR,
+ SPP_DEFAULT_CLASSIFIED_SPEC_STR,
&port);
}
+ next = 0;
while(1) {
ret = rte_hash_iterate(classifier_info->classifier_table,
&key, &data, &next);
diff --git a/src/vf/classifier_mac.h b/src/vf/classifier_mac.h
index b1d0198..f182668 100644
--- a/src/vf/classifier_mac.h
+++ b/src/vf/classifier_mac.h
@@ -2,7 +2,7 @@
#define _CLASSIFIER_MAC_H_
/* forward declaration */
-struct spp_core_info;
+struct spp_component_info;
struct spp_iterate_classifier_table_params;
/**
@@ -13,21 +13,21 @@ int spp_classifier_mac_init(void);
/**
* classifier(mac address) update component info.
*
- * @param core_info
- * point to struct spp_core_info.
+ * @param component_info
+ * point to struct spp_component_info.
*
* @ret_val 0 succeeded.
* @ret_val -1 failed.
*/
-int spp_classifier_mac_update(struct spp_core_info *core_info);
+int spp_classifier_mac_update(struct spp_component_info *component_info);
/**
* classifier(mac address) thread function.
*
- * @param arg
- * pointer to struct spp_core_info.
+ * @param id
+ * unique component ID.
*/
-int spp_classifier_mac_do(void *arg);
+int spp_classifier_mac_do(int id);
/**
* classifier(mac address) iterate classifier table.
diff --git a/src/vf/command_dec.c b/src/vf/command_dec.c
index 9363b8f..166901c 100644
--- a/src/vf/command_dec.c
+++ b/src/vf/command_dec.c
@@ -5,7 +5,6 @@
#include <rte_branch_prediction.h>
#include "spp_vf.h"
-#include "spp_config.h"
#include "command_dec.h"
#define RTE_LOGTYPE_SPP_COMMAND_PROC RTE_LOGTYPE_USER1
@@ -19,6 +18,28 @@ static const char *CLASSIFILER_TYPE_STRINGS[] = {
/* termination */ "",
};
+/* command action type string list
+ do it same as the order of enum spp_command_action (spp_vf.h) */
+static const char *COMMAND_ACTION_STRINGS[] = {
+ "none",
+ "start",
+ "stop",
+ "add",
+ "del",
+
+ /* termination */ "",
+};
+
+/* port rxtx string list
+ do it same as the order of enum spp_port_rxtx (spp_vf.h) */
+static const char *PORT_RXTX_STRINGS[] = {
+ "none",
+ "rx",
+ "tx",
+
+ /* termination */ "",
+};
+
/* set decode error */
inline int
set_decode_error(struct spp_command_decode_error *error,
@@ -75,13 +96,44 @@ get_arrary_index(const char *match, const char *list[])
return -1;
}
+/* Get unsigned int type value */
+static int
+get_uint_value( unsigned int *output,
+ const char *arg_val,
+ unsigned int min,
+ unsigned int max)
+{
+ unsigned int ret = 0;
+ char *endptr = NULL;
+ ret = strtoul(arg_val, &endptr, 0);
+ if (unlikely(endptr == arg_val) || unlikely(*endptr != '\0'))
+ return -1;
+
+ if (unlikely(ret < min) || unlikely(ret > max))
+ return -1;
+
+ *output = ret;
+ return 0;
+}
+
+/* decoding procedure of string */
+static int
+decode_str_value(char *output, const char *arg_val)
+{
+ if (strlen(arg_val) >= SPP_CMD_VALUE_BUFSZ)
+ return -1;
+
+ strcpy(output, arg_val);
+ return 0;
+}
+
/* decoding procedure of port */
static int
decode_port_value(void *output, const char *arg_val)
{
int ret = 0;
- struct spp_config_port_info *port = output;
- ret = spp_config_get_if_info(arg_val, &port->if_type, &port->if_no);
+ struct spp_port_index *port = output;
+ ret = spp_get_if_info(arg_val, &port->if_type, &port->if_no);
if (unlikely(ret != 0)) {
RTE_LOG(ERR, SPP_COMMAND_PROC, "Bad port. val=%s\n", arg_val);
return -1;
@@ -90,6 +142,188 @@ decode_port_value(void *output, const char *arg_val)
return 0;
}
+/* decoding procedure of core */
+static int
+decode_core_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ ret = get_uint_value(output, arg_val, 0, RTE_MAX_LCORE-1);
+ if (unlikely(ret < 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Bad core id. val=%s\n", arg_val);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* decoding procedure of action for component command */
+static int
+decode_component_action_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ ret = get_arrary_index(arg_val, COMMAND_ACTION_STRINGS);
+ if (unlikely(ret <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown component action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ if (unlikely(ret != SPP_CMD_ACTION_START) && unlikely(ret != SPP_CMD_ACTION_STOP)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown component action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ *(int *)output = ret;
+ return 0;
+}
+
+/* decoding procedure of action for component command */
+static int
+decode_component_name_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ struct spp_command_component *component = output;
+
+ /* "stop" has no core ID parameter. */
+ if (component->action == SPP_CMD_ACTION_START) {
+ ret = spp_get_component_id(arg_val);
+ if (unlikely(ret >= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC,
+ "Component name in used. val=%s\n",
+ arg_val);
+ return -1;
+ }
+ }
+
+ return decode_str_value(component->name, arg_val);
+}
+
+/* decoding procedure of core id for component command */
+static int
+decode_component_core_value(void *output, const char *arg_val)
+{
+ struct spp_command_component *component = output;
+
+ /* "stop" has no core ID parameter. */
+ if (component->action != SPP_CMD_ACTION_START)
+ return 0;
+
+ return decode_core_value(&component->core, arg_val);
+}
+
+/* decoding procedure of type for component command */
+static int
+decode_component_type_value(void *output, const char *arg_val)
+{
+ enum spp_component_type org_type, set_type;
+ struct spp_command_component *component = output;
+
+ /* "stop" has no type parameter. */
+ if (component->action != SPP_CMD_ACTION_START)
+ return 0;
+
+ set_type = spp_change_component_type(arg_val);
+ if (unlikely(set_type <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC,
+ "Unknown component type. val=%s\n",
+ arg_val);
+ return -1;
+ }
+
+ org_type = spp_get_component_type_update(component->core);
+ if ((org_type != SPP_COMPONENT_UNUSE) && (org_type != set_type)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC,
+ "Component type does not match. val=%s (org=%d, new=%d)\n",
+ arg_val, org_type, set_type);
+ return -1;
+ }
+
+ component->type = set_type;
+ return 0;
+}
+
+/* decoding procedure of action for port command */
+static int
+decode_port_action_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ ret = get_arrary_index(arg_val, COMMAND_ACTION_STRINGS);
+ if (unlikely(ret <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown port action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ if (unlikely(ret != SPP_CMD_ACTION_ADD) && unlikely(ret != SPP_CMD_ACTION_DEL)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown port action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ *(int *)output = ret;
+ return 0;
+}
+
+/* decoding procedure of port for port command */
+static int
+decode_port_port_value(void *output, const char *arg_val)
+{
+ int ret = -1;
+ struct spp_port_index tmp_port;
+ struct spp_command_port *port = output;
+
+ ret = decode_port_value(&tmp_port, arg_val);
+ if (ret < 0)
+ return -1;
+
+ if ((port->action == SPP_CMD_ACTION_ADD) &&
+ (spp_check_used_port(tmp_port.if_type, tmp_port.if_no, SPP_PORT_RXTX_RX) >= 0) &&
+ (spp_check_used_port(tmp_port.if_type, tmp_port.if_no, SPP_PORT_RXTX_TX) >= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Port in used. (port command) val=%s\n", arg_val);
+ return -1;
+ }
+
+ port->port.if_type = tmp_port.if_type;
+ port->port.if_no = tmp_port.if_no;
+ return 0;
+}
+
+/* decoding procedure of rxtx type for port command */
+static int
+decode_port_rxtx_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ struct spp_command_port *port = output;
+
+ ret = get_arrary_index(arg_val, PORT_RXTX_STRINGS);
+ if (unlikely(ret <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown port rxtx. val=%s\n", arg_val);
+ return -1;
+ }
+
+ if ((port->action == SPP_CMD_ACTION_ADD) &&
+ (spp_check_used_port(port->port.if_type, port->port.if_no, ret) >= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Port in used. (port command) val=%s\n", arg_val);
+ return -1;
+ }
+
+ port->rxtx = ret;
+ return 0;
+}
+
+/* decoding procedure of component name for port command */
+static int
+decode_port_name_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+
+ ret = spp_get_component_id(arg_val);
+ if (unlikely(ret < 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown component name. val=%s\n",
+ arg_val);
+ return -1;
+ }
+
+ return decode_str_value(output, arg_val);
+}
+
/* decoding procedure of mac address string */
static int
decode_mac_addr_str_value(void *output, const char *arg_val)
@@ -98,10 +332,10 @@ decode_mac_addr_str_value(void *output, const char *arg_val)
const char *str_val = arg_val;
/* if default specification, convert to internal dummy address */
- if (unlikely(strcmp(str_val, SPP_CONFIG_DEFAULT_CLASSIFIED_SPEC_STR) == 0))
- str_val = SPP_CONFIG_DEFAULT_CLASSIFIED_DMY_ADDR_STR;
+ if (unlikely(strcmp(str_val, SPP_DEFAULT_CLASSIFIED_SPEC_STR) == 0))
+ str_val = SPP_DEFAULT_CLASSIFIED_DMY_ADDR_STR;
- ret = spp_config_change_mac_str_to_int64(str_val);
+ ret = spp_change_mac_str_to_int64(str_val);
if (unlikely(ret < 0)) {
RTE_LOG(ERR, SPP_COMMAND_PROC, "Bad mac address string. val=%s\n",
str_val);
@@ -112,26 +346,46 @@ decode_mac_addr_str_value(void *output, const char *arg_val)
return 0;
}
-/* decoding procedure of classifier type */
+/* decoding procedure of action for classifier_table command */
+static int
+decode_classifier_action_value(void *output, const char *arg_val)
+{
+ int ret = 0;
+ ret = get_arrary_index(arg_val, COMMAND_ACTION_STRINGS);
+ if (unlikely(ret <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown port action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ if (unlikely(ret != SPP_CMD_ACTION_ADD) && unlikely(ret != SPP_CMD_ACTION_DEL)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown port action. val=%s\n", arg_val);
+ return -1;
+ }
+
+ *(int *)output = ret;
+ return 0;
+}
+
+/* decoding procedure of type for classifier_table command */
static int
decode_classifier_type_value(void *output, const char *arg_val)
{
- int ret = 0;
+ int ret = 0;
ret = get_arrary_index(arg_val, CLASSIFILER_TYPE_STRINGS);
- if (unlikely(ret <= 0)) {
- RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown classifier type. val=%s\n", arg_val);
- return -1;
- }
+ if (unlikely(ret <= 0)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Unknown classifier type. val=%s\n", arg_val);
+ return -1;
+ }
- *(int *)output = ret;
- return 0;
+ *(int *)output = ret;
+ return 0;
}
-/* decode procedure for classifier value */
+/* decoding procedure of value for classifier_table command */
static int
decode_classifier_value_value(void *output, const char *arg_val)
{
- int ret = -1;
+ int ret = -1;
struct spp_command_classifier_table *classifier_table = output;
switch(classifier_table->type) {
case SPP_CLASSIFIER_TYPE_MAC:
@@ -140,37 +394,70 @@ decode_classifier_value_value(void *output, const char *arg_val)
default:
break;
}
- return ret;
+ return ret;
}
-/* decode procedure for classifier port */
+/* decoding procedure of port for classifier_table command */
static int
decode_classifier_port_value(void *output, const char *arg_val)
{
- struct spp_config_port_info *port = output;
+ int ret = 0;
+ struct spp_command_classifier_table *classifier_table = output;
+ struct spp_port_index tmp_port;
+ int64_t mac_addr = 0;
+
+ ret = decode_port_value(&tmp_port, arg_val);
+ if (ret < 0)
+ return -1;
+
+ if (spp_check_added_port(tmp_port.if_type, tmp_port.if_no) == 0) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC, "Port not added. val=%s\n", arg_val);
+ return -1;
+ }
+
+ if (unlikely(classifier_table->action == SPP_CMD_ACTION_ADD)) {
+ if (!spp_check_mac_used_port(0, tmp_port.if_type, tmp_port.if_no)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC,
+ "Port in used. (classifier_table command) val=%s\n",
+ arg_val);
+ return -1;
+ }
+ } else if (unlikely(classifier_table->action == SPP_CMD_ACTION_DEL)) {
+ mac_addr = spp_change_mac_str_to_int64(classifier_table->value);
+ if (mac_addr < 0)
+ return -1;
- if (strcmp(arg_val, SPP_CMD_UNUSE) == 0) {
- port->if_type = UNDEF;
- port->if_no = 0;
- return 0;
- }
+ if (!spp_check_mac_used_port((uint64_t)mac_addr, tmp_port.if_type, tmp_port.if_no)) {
+ RTE_LOG(ERR, SPP_COMMAND_PROC,
+ "Port in used. (classifier_table command) val=%s\n",
+ arg_val);
+ return -1;
+ }
+ }
- return decode_port_value(port, arg_val);
+ classifier_table->port.if_type = tmp_port.if_type;
+ classifier_table->port.if_no = tmp_port.if_no;
+ return 0;
}
#define DECODE_PARAMETER_LIST_EMPTY { NULL, 0, NULL }
/* parameter list for decoding */
struct decode_parameter_list {
- const char *name;
- size_t offset;
- int (*func)(void *output, const char *arg_val);
+ const char *name;
+ size_t offset;
+ int (*func)(void *output, const char *arg_val);
};
/* parameter list for each command */
static struct decode_parameter_list parameter_list[][SPP_CMD_MAX_PARAMETERS] = {
{ /* classifier_table */
{
+ .name = "action",
+ .offset = offsetof(struct spp_command, spec.classifier_table.action),
+ .func = decode_classifier_action_value
+ },
+ {
.name = "type",
.offset = offsetof(struct spp_command, spec.classifier_table.type),
.func = decode_classifier_type_value
@@ -182,7 +469,7 @@ static struct decode_parameter_list parameter_list[][SPP_CMD_MAX_PARAMETERS] = {
},
{
.name = "port",
- .offset = offsetof(struct spp_command, spec.classifier_table.port),
+ .offset = offsetof(struct spp_command, spec.classifier_table),
.func = decode_classifier_port_value
},
DECODE_PARAMETER_LIST_EMPTY,
@@ -190,6 +477,53 @@ static struct decode_parameter_list parameter_list[][SPP_CMD_MAX_PARAMETERS] = {
{ DECODE_PARAMETER_LIST_EMPTY }, /* flush */
{ DECODE_PARAMETER_LIST_EMPTY }, /* _get_client_id */
{ DECODE_PARAMETER_LIST_EMPTY }, /* status */
+ { DECODE_PARAMETER_LIST_EMPTY }, /* exit */
+ { /* component */
+ {
+ .name = "action",
+ .offset = offsetof(struct spp_command, spec.component.action),
+ .func = decode_component_action_value
+ },
+ {
+ .name = "component name",
+ .offset = offsetof(struct spp_command, spec.component),
+ .func = decode_component_name_value
+ },
+ {
+ .name = "core",
+ .offset = offsetof(struct spp_command, spec.component),
+ .func = decode_component_core_value
+ },
+ {
+ .name = "component type",
+ .offset = offsetof(struct spp_command, spec.component),
+ .func = decode_component_type_value
+ },
+ DECODE_PARAMETER_LIST_EMPTY,
+ },
+ { /* port */
+ {
+ .name = "action",
+ .offset = offsetof(struct spp_command, spec.port.action),
+ .func = decode_port_action_value
+ },
+ {
+ .name = "port",
+ .offset = offsetof(struct spp_command, spec.port),
+ .func = decode_port_port_value
+ },
+ {
+ .name = "port rxtx",
+ .offset = offsetof(struct spp_command, spec.port),
+ .func = decode_port_rxtx_value
+ },
+ {
+ .name = "component name",
+ .offset = offsetof(struct spp_command, spec.port.name),
+ .func = decode_port_name_value
+ },
+ DECODE_PARAMETER_LIST_EMPTY,
+ },
{ DECODE_PARAMETER_LIST_EMPTY }, /* termination */
};
@@ -227,10 +561,13 @@ struct decode_command_list {
/* command list */
static struct decode_command_list command_list[] = {
- { "classifier_table", 4, 4, decode_comand_parameter_in_list }, /* classifier_table */
+ { "classifier_table", 5, 5, decode_comand_parameter_in_list }, /* classifier_table */
{ "flush", 1, 1, NULL }, /* flush */
{ "_get_client_id", 1, 1, NULL }, /* _get_client_id */
{ "status", 1, 1, NULL }, /* status */
+ { "exit", 1, 1, NULL }, /* exit */
+ { "component", 3, 5, decode_comand_parameter_in_list }, /* port */
+ { "port", 5, 5, decode_comand_parameter_in_list }, /* port */
{ "", 0, 0, NULL } /* termination */
};
@@ -310,6 +647,9 @@ spp_command_decode_request(struct spp_command_request *request, const char *requ
case SPP_CMDTYPE_STATUS:
request->is_requested_status = 1;
break;
+ case SPP_CMDTYPE_EXIT:
+ request->is_requested_exit = 1;
+ break;
default:
/* nothing to do */
break;
diff --git a/src/vf/command_dec.h b/src/vf/command_dec.h
index 8850485..359f5e5 100644
--- a/src/vf/command_dec.h
+++ b/src/vf/command_dec.h
@@ -1,6 +1,8 @@
#ifndef _COMMAND_DEC_H_
#define _COMMAND_DEC_H_
+//#include "spp_vf.h"
+
/* max number of command per request */
#define SPP_CMD_MAX_COMMANDS 32
@@ -16,9 +18,6 @@
/* string that specify unused */
#define SPP_CMD_UNUSE "unuse"
-/* component type */
-#define spp_component_type spp_core_type
-
/* decode error code */
enum spp_command_decode_error_code {
/* not use 0, in general 0 is ok */
@@ -36,31 +35,17 @@ enum spp_command_type {
SPP_CMDTYPE_FLUSH,
SPP_CMDTYPE_CLIENT_ID,
SPP_CMDTYPE_STATUS,
+ SPP_CMDTYPE_EXIT,
+ SPP_CMDTYPE_COMPONENT,
+ SPP_CMDTYPE_PORT,
};
-#if 0 /* not supported yet */
-/* "add" command parameters */
-struct spp_command_add {
- int num_port;
- struct spp_config_port_info ports[RTE_MAX_ETHPORTS];
-};
-
-/* "component" command specific parameters */
-struct spp_command_component {
- enum spp_component_type type;
- unsigned int core_id;
- int num_rx_port;
- int num_tx_port;
- struct spp_config_port_info rx_ports[RTE_MAX_ETHPORTS];
- struct spp_config_port_info tx_ports[RTE_MAX_ETHPORTS];
-};
-#endif
-
/* "classifier_table" command specific parameters */
struct spp_command_classifier_table {
+ enum spp_command_action action;
enum spp_classifier_type type;
char value[SPP_CMD_VALUE_BUFSZ];
- struct spp_config_port_info port;
+ struct spp_port_index port;
};
/* "flush" command specific parameters */
@@ -68,17 +53,31 @@ struct spp_command_flush {
/* nothing specific */
};
+/* "component" command parameters */
+struct spp_command_component {
+ enum spp_command_action action;
+ char name[SPP_CMD_NAME_BUFSZ];
+ unsigned int core;
+ enum spp_component_type type;
+};
+
+/* "port" command parameters */
+struct spp_command_port {
+ enum spp_command_action action;
+ struct spp_port_index port;
+ enum spp_port_rxtx rxtx;
+ char name[SPP_CMD_NAME_BUFSZ];
+};
+
/* command parameters */
struct spp_command {
enum spp_command_type type;
union {
-#if 0 /* not supported yet */
- struct spp_command_add add;
- struct spp_command_component component;
-#endif
struct spp_command_classifier_table classifier_table;
struct spp_command_flush flush;
+ struct spp_command_component component;
+ struct spp_command_port port;
} spec;
};
@@ -90,6 +89,7 @@ struct spp_command_request {
int is_requested_client_id;
int is_requested_status;
+ int is_requested_exit;
};
/* decode error information */
diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c
index ef1ae81..0a45874 100644
--- a/src/vf/command_proc.c
+++ b/src/vf/command_proc.c
@@ -7,7 +7,6 @@
#include <jansson.h>
#include "spp_vf.h"
-#include "spp_config.h"
#include "string_buffer.h"
#include "command_conn.h"
#include "command_dec.h"
@@ -40,6 +39,7 @@ execute_command(const struct spp_command *command)
case SPP_CMDTYPE_CLASSIFIER_TABLE:
RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute classifier_table command.\n");
ret = spp_update_classifier_table(
+ command->spec.classifier_table.action,
command->spec.classifier_table.type,
command->spec.classifier_table.value,
&command->spec.classifier_table.port);
@@ -50,6 +50,25 @@ execute_command(const struct spp_command *command)
ret = spp_flush();
break;
+ case SPP_CMDTYPE_COMPONENT:
+ RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute component command.\n");
+ ret = spp_update_component(
+ command->spec.component.action,
+ command->spec.component.name,
+ command->spec.component.core,
+ command->spec.component.type);
+ break;
+
+ case SPP_CMDTYPE_PORT:
+ RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute port command. (act = %d)\n",
+ command->spec.port.action);
+ ret = spp_update_port(
+ command->spec.port.action,
+ &command->spec.port.port,
+ command->spec.port.rxtx,
+ command->spec.port.name);
+ break;
+
default:
RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute other command. type=%d\n", command->type);
/* nothing to do here */
@@ -230,12 +249,12 @@ int append_classifier_element_value(
void *opaque,
__rte_unused enum spp_classifier_type type,
const char *data,
- const struct spp_config_port_info *port)
+ const struct spp_port_index *port)
{
json_t *parent_obj = (json_t *)opaque;
char port_str[64];
- spp_config_format_port_string(port_str, port->if_type, port->if_no);
+ spp_format_port_string(port_str, port->if_type, port->if_no);
json_array_append_new(parent_obj, json_pack(
"{ssssss}",
@@ -416,7 +435,7 @@ process_request(int *sock, const char *request_str, size_t request_str_len)
/* send error response */
send_decode_error_response(sock, &request, &decode_error);
RTE_LOG(DEBUG, SPP_COMMAND_PROC, "End command request processing.\n");
- return ret;
+ return 0;
}
RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Command request is valid. "
@@ -438,6 +457,13 @@ process_request(int *sock, const char *request_str, size_t request_str_len)
command_results[i].code = CRES_SUCCESS;
}
+ if (request.is_requested_exit) {
+ /* Terminated by process exit command. */
+ /* Other route is normal end because it responds to command. */
+ RTE_LOG(INFO, SPP_COMMAND_PROC, "No response with process exit command.");
+ return -1;
+ }
+
/* send response */
send_command_result_response(sock, &request, command_results);
@@ -489,5 +515,5 @@ spp_command_proc_do(void)
ret = process_request(&sock, msgbuf, msg_ret);
spp_strbuf_remove_front(msgbuf, msg_ret);
- return 0;
+ return ret;
}
diff --git a/src/vf/command_proc.h b/src/vf/command_proc.h
index 37e55ad..05cb1f1 100644
--- a/src/vf/command_proc.h
+++ b/src/vf/command_proc.h
@@ -20,7 +20,8 @@ spp_command_proc_init(const char *controller_ip, int controller_port);
* process command from controller.
*
* @retval 0 succeeded.
- * @retval -1 failed.
+ * @retval -1 process termination is required.
+ * (occurred connection failure, or received exit command)
*/
int
spp_command_proc_do(void);
diff --git a/src/vf/spp_config.c b/src/vf/spp_config.c
index 55129ac..9170281 100644
--- a/src/vf/spp_config.c
+++ b/src/vf/spp_config.c
@@ -136,11 +136,11 @@ config_get_str_value(const json_t *obj, const char *path, char *value)
static void
config_init_data(struct spp_config_area *config)
{
- /* Clear config area with zero */
+ /* Clear config area with zero */
memset(config, 0x00, sizeof(struct spp_config_area));
int core_cnt, port_cnt, table_cnt;
- /* Set all of interface type of ports and mac tables to UNDEF */
+ /* Set all of interface type of ports and mac tables to UNDEF */
for (core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) {
config->proc.functions[core_cnt].rx_ports[port_cnt].if_type = UNDEF;
@@ -188,7 +188,7 @@ spp_config_get_if_info(const char *port, enum port_type *if_type, int *if_no)
return -1;
}
- /* Change type of number of interface */
+ /* Change type of number of interface */
int ret_no = strtol(no_str, &endptr, 0);
if (unlikely(no_str == endptr) || unlikely(*endptr != '\0')) {
/* No IF number */
@@ -321,7 +321,7 @@ config_load_classifier_table(const json_t *obj,
}
classifier_table->num_table = array_num;
- /* Setup for each of mac tables */
+ /* Setup for each of mac tables */
struct spp_config_mac_table_element *tmp_table = NULL;
char if_str[SPP_CONFIG_STR_LEN];
int table_cnt = 0;
@@ -346,10 +346,10 @@ config_load_classifier_table(const json_t *obj,
return -1;
}
- /**
- * If mac address is set to 'default', replace it to reserved
- * dummy address for validation.
- */
+ /**
+ * If mac address is set to 'default', replace it to reserved
+ * dummy address for validation.
+ */
if (unlikely(strcmp(tmp_table->mac_addr_str,
SPP_CONFIG_DEFAULT_CLASSIFIED_SPEC_STR) == 0))
strcpy(tmp_table->mac_addr_str,
@@ -375,7 +375,7 @@ config_load_classifier_table(const json_t *obj,
table_cnt, JSONPATH_PORT);
return -1;
}
- /* And separate it to type and number */
+ /* And separate it to type and number */
int ret_if = spp_config_get_if_info(if_str, &tmp_table->port.if_type,
&tmp_table->port.if_no);
if (unlikely(ret_if != 0)) {
@@ -433,7 +433,7 @@ config_set_rx_port(enum spp_core_type type, json_t *obj,
return -1;
}
- /* Check if the size of array is not over RTE_MAX_ETHPORTS */
+ /* Check if the size of array is not over RTE_MAX_ETHPORTS */
int port_num = json_array_size(array_obj);
if (unlikely(port_num <= 0) ||
unlikely(port_num > RTE_MAX_ETHPORTS)) {
@@ -557,7 +557,7 @@ config_set_tx_port(enum spp_core_type type, json_t *obj,
return -1;
}
- /* Check if the size of array is not over RTE_MAX_ETHPORTS */
+ /* Check if the size of array is not over RTE_MAX_ETHPORTS */
int port_num = json_array_size(array_obj);
if (unlikely(port_num <= 0) ||
unlikely(port_num > RTE_MAX_ETHPORTS)) {
@@ -579,7 +579,7 @@ config_set_tx_port(enum spp_core_type type, json_t *obj,
return -1;
}
- /* Get sending port */
+ /* Get sending port */
if (unlikely(!json_is_string(elements_obj))) {
RTE_LOG(ERR, APP, "Not a string. (path = %s, No = %d, route = classifier)\n",
JSONPATH_TX_PORT, array_cnt);
@@ -587,7 +587,7 @@ config_set_tx_port(enum spp_core_type type, json_t *obj,
}
strcpy(if_str, json_string_value(elements_obj));
- /* Separate it to interface type and number */
+ /* Separate it to interface type and number */
int ret_if = spp_config_get_if_info(if_str, &tmp_tx_port->if_type,
&tmp_tx_port->if_no);
if (unlikely(ret_if != 0)) {
diff --git a/src/vf/spp_forward.c b/src/vf/spp_forward.c
index afe7c03..8a0980a 100644
--- a/src/vf/spp_forward.c
+++ b/src/vf/spp_forward.c
@@ -1,3 +1,5 @@
+#include <rte_cycles.h>
+
#include "spp_vf.h"
#include "ringlatencystats.h"
#include "spp_forward.h"
@@ -5,21 +7,106 @@
#define RTE_LOGTYPE_FORWARD RTE_LOGTYPE_USER1
/* A set of port info of rx and tx */
-struct rxtx {
- struct spp_core_port_info rx;
- struct spp_core_port_info tx;
+struct forward_rxtx {
+ struct spp_port_info rx;
+ struct spp_port_info tx;
+};
+
+struct forward_path {
+ int num;
+ struct forward_rxtx ports[RTE_MAX_ETHPORTS];
+};
+
+struct forward_info {
+ enum spp_component_type type;
+ volatile int ref_index;
+ volatile int upd_index;
+ struct forward_path path[SPP_INFO_AREA_MAX];
};
-/* Set destination port as source */
+struct forward_info g_forward_info[RTE_MAX_LCORE];
+
+/* Clear info */
+void
+spp_forward_init(void)
+{
+ int cnt = 0;
+ memset(&g_forward_info, 0x00, sizeof(g_forward_info));
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ g_forward_info[cnt].ref_index = 0;
+ g_forward_info[cnt].upd_index = 1;
+ }
+}
+
+/* Clear info for one element. */
static void
-set_use_interface(struct spp_core_port_info *dst,
- struct spp_core_port_info *src)
+clear_forward_info(int id)
{
- dst->if_type = src->if_type;
- dst->if_no = src->if_no;
- dst->dpdk_port = src->dpdk_port;
+ struct forward_info *info = &g_forward_info[id];
+ info->type = SPP_COMPONENT_UNUSE;
+ memset(&g_forward_info[id].path, 0x00, sizeof(struct forward_path));
}
+/* Update forward info */
+int
+spp_forward_update(struct spp_component_info *component)
+{
+ int cnt = 0;
+ int num_rx = component->num_rx_port;
+ int num_tx = component->num_tx_port;
+ int max = (num_rx > num_tx)?num_rx*num_tx:num_tx;
+ struct forward_info *info = &g_forward_info[component->component_id];
+ struct forward_path *path = &info->path[info->upd_index];
+
+ /* Forward component allows only one receiving port. */
+ if ((component->type == SPP_COMPONENT_FORWARD) && unlikely(num_rx > 1)) {
+ RTE_LOG(ERR, FORWARD, "Component[%d] Setting error. (type = %d, rx = %d)\n",
+ component->component_id, component->type, num_rx);
+ return -1;
+ }
+
+ /* Component allows only one transmit port. */
+ if (unlikely(num_tx != 0) && unlikely(num_tx != 1)) {
+ RTE_LOG(ERR, FORWARD, "Component[%d] Setting error. (type = %d, tx = %d)\n",
+ component->component_id, component->type, num_tx);
+ return -1;
+ }
+
+ clear_forward_info(component->component_id);
+
+ RTE_LOG(INFO, FORWARD,
+ "Component[%d] Start update component. (type = %d)\n",
+ component->component_id, component->type);
+
+ info->type = component->type;
+ path->num = component->num_rx_port;
+ for (cnt = 0; cnt < num_rx; cnt++)
+ memcpy(&path->ports[cnt].rx, component->rx_ports[cnt],
+ sizeof(struct spp_port_info));
+
+ /* Transmit port is set according with larger num_rx / num_tx. */
+ for (cnt = 0; cnt < max; cnt++)
+ memcpy(&path->ports[cnt].tx, component->tx_ports[0],
+ sizeof(struct spp_port_info));
+
+ info->upd_index = info->ref_index;
+ while(likely(info->ref_index == info->upd_index))
+ rte_delay_us_block(SPP_CHANGE_UPDATE_INTERVAL);
+
+ RTE_LOG(INFO, FORWARD, "Component[%d] Complete update component. (type = %d)\n",
+ component->component_id, component->type);
+
+ return 0;
+}
+
+/* Change index of forward info */
+static inline void
+change_forward_index(int id)
+{
+ struct forward_info *info = &g_forward_info[id];
+ if (info->ref_index == info->upd_index)
+ info->ref_index = (info->upd_index+1)%SPP_INFO_AREA_MAX;
+}
/**
* Forwarding packets as forwarder or merger
*
@@ -27,75 +114,49 @@ set_use_interface(struct spp_core_port_info *dst,
* as an argument of void and typecasted to spp_config_info.
*/
int
-spp_forward(void *arg)
+spp_forward(int id)
{
- unsigned int lcore_id = rte_lcore_id();
- struct spp_core_info *core_info = (struct spp_core_info *)arg;
- int if_cnt, rxtx_num = 0;
- struct rxtx patch[RTE_MAX_ETHPORTS];
-
- /* Decide the destination of forwarding */
- rxtx_num = core_info->num_rx_port;
- for (if_cnt = 0; if_cnt < rxtx_num; if_cnt++) {
- set_use_interface(&patch[if_cnt].rx,
- &core_info->rx_ports[if_cnt]);
- /* Forwarding type is supposed to forwarder or merger */
- if (core_info->type == SPP_CONFIG_FORWARD) {
- set_use_interface(&patch[if_cnt].tx,
- &core_info->tx_ports[if_cnt]);
- } else {
- set_use_interface(&patch[if_cnt].tx,
- &core_info->tx_ports[0]);
- }
- }
+ int cnt, num, buf;
+ int nb_rx = 0;
+ int nb_tx = 0;
+ struct forward_info *info = &g_forward_info[id];
+ struct forward_path *path = NULL;
+ struct spp_port_info *rx;
+ struct spp_port_info *tx;
+ struct rte_mbuf *bufs[MAX_PKT_BURST];
- core_info->status = SPP_CORE_IDLE;
- RTE_LOG(INFO, FORWARD, "Core[%d] Start. (type = %d)\n", lcore_id,
- core_info->type);
+ change_forward_index(id);
+ path = &info->path[info->ref_index];
+ num = path->num;
- int cnt, nb_rx, nb_tx, buf;
- struct spp_core_port_info *rx;
- struct spp_core_port_info *tx;
- struct rte_mbuf *bufs[MAX_PKT_BURST];
- while (likely(core_info->status == SPP_CORE_IDLE) ||
- likely(core_info->status == SPP_CORE_FORWARD)) {
- while (likely(core_info->status == SPP_CORE_FORWARD)) {
- for (cnt = 0; cnt < rxtx_num; cnt++) {
- rx = &patch[cnt].rx;
- tx = &patch[cnt].tx;
-
- /* Receive packets */
- nb_rx = rte_eth_rx_burst(rx->dpdk_port, 0, bufs, MAX_PKT_BURST);
- if (unlikely(nb_rx == 0)) {
- continue;
- }
+ for (cnt = 0; cnt < num; cnt++) {
+ rx = &path->ports[cnt].rx;
+ tx = &path->ports[cnt].tx;
+
+ /* Receive packets */
+ nb_rx = rte_eth_rx_burst(rx->dpdk_port, 0, bufs, MAX_PKT_BURST);
+ if (unlikely(nb_rx == 0))
+ continue;
#ifdef SPP_RINGLATENCYSTATS_ENABLE
- if (rx->if_type == RING) {
- spp_ringlatencystats_calculate_latency(rx->if_no,
- bufs, nb_rx);
- }
- if (tx->if_type == RING) {
- spp_ringlatencystats_add_time_stamp(tx->if_no,
- bufs, nb_rx);
- }
+ if (rx->if_type == RING)
+ spp_ringlatencystats_calculate_latency(rx->if_no,
+ bufs, nb_rx);
+
+ if (tx->if_type == RING)
+ spp_ringlatencystats_add_time_stamp(tx->if_no,
+ bufs, nb_rx);
#endif /* SPP_RINGLATENCYSTATS_ENABLE */
- /* Send packets */
- nb_tx = rte_eth_tx_burst(tx->dpdk_port, 0, bufs, nb_rx);
+ /* Send packets */
+ if (tx->dpdk_port >= 0)
+ nb_tx = rte_eth_tx_burst(tx->dpdk_port, 0, bufs, nb_rx);
- /* Discard remained packets to release mbuf */
- if (unlikely(nb_tx < nb_rx)) {
- for (buf = nb_tx; buf < nb_rx; buf++) {
- rte_pktmbuf_free(bufs[buf]);
- }
- }
- }
+ /* Discard remained packets to release mbuf */
+ if (unlikely(nb_tx < nb_rx)) {
+ for (buf = nb_tx; buf < nb_rx; buf++)
+ rte_pktmbuf_free(bufs[buf]);
}
}
-
- RTE_LOG(INFO, FORWARD, "Core[%d] End. (type = %d)\n", lcore_id,
- core_info->type);
- core_info->status = SPP_CORE_STOP;
return 0;
}
diff --git a/src/vf/spp_forward.h b/src/vf/spp_forward.h
index 33208bf..729dbe8 100644
--- a/src/vf/spp_forward.h
+++ b/src/vf/spp_forward.h
@@ -1,9 +1,16 @@
#ifndef __SPP_FORWARD_H__
#define __SPP_FORWARD_H__
+
+void spp_forward_init(void);
+
+void spp_forward_init_info(int id);
+
+int spp_forward_update(struct spp_component_info *component);
+
/*
* Merge/Forward
*/
-int spp_forward(void *arg);
+int spp_forward(int id);
#endif /* __SPP_FORWARD_H__ */
diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c
index c7268e5..d6eb7b2 100644
--- a/src/vf/spp_vf.c
+++ b/src/vf/spp_vf.c
@@ -5,6 +5,7 @@
#include <rte_eth_ring.h>
#include <rte_eth_vhost.h>
#include <rte_memzone.h>
+#include <rte_cycles.h>
#include "spp_vf.h"
#include "ringlatencystats.h"
@@ -16,13 +17,16 @@
#define SPP_CORE_STATUS_CHECK_MAX 5
#define SPP_RING_LATENCY_STATS_SAMPLING_INTERVAL 1000000
+#define CORE_TYPE_CLASSIFIER_MAC_STR "classifier_mac"
+#define CORE_TYPE_MERGE_STR "merge"
+#define CORE_TYPE_FORWARD_STR "forward"
+
/* getopt_long return value for long option */
enum SPP_LONGOPT_RETVAL {
SPP_LONGOPT_RETVAL__ = 127,
/* add below */
/* TODO(yasufum) add description what and why add below */
- SPP_LONGOPT_RETVAL_CONFIG,
SPP_LONGOPT_RETVAL_CLIENT_ID,
SPP_LONGOPT_RETVAL_VHOST_CLIENT
};
@@ -35,37 +39,41 @@ struct startup_param {
int vhost_client;
};
-/* Status of patch and its cores, mac address assinged for it and port info */
-struct patch_info {
- int use_flg;
- int dpdk_port; /* TODO(yasufum) add desc for what is this */
- 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;
-};
-
-/* Manage number of interfaces and patch information as global variable */
+/* Manage number of interfaces and port information as global variable */
/* TODO(yasufum) refactor, change if to iface */
struct if_info {
int num_nic;
int num_vhost;
int num_ring;
- struct patch_info nic_patchs[RTE_MAX_ETHPORTS];
- struct patch_info vhost_patchs[RTE_MAX_ETHPORTS];
- struct patch_info ring_patchs[RTE_MAX_ETHPORTS];
+ struct spp_port_info nic[RTE_MAX_ETHPORTS];
+ struct spp_port_info vhost[RTE_MAX_ETHPORTS];
+ struct spp_port_info ring[RTE_MAX_ETHPORTS];
+};
+
+/* Manage component running in core as global variable */
+struct core_info {
+ volatile enum spp_component_type type;
+ int num;
+ int id[RTE_MAX_LCORE];
+};
+
+/* Manage core status and component information as global variable */
+struct core_mng_info {
+ volatile enum spp_core_status status;
+ volatile int ref_index;
+ volatile int upd_index;
+ struct core_info core[SPP_INFO_AREA_MAX];
};
/* Declare global variables */
-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]; /* TODO(yasufum) add desc how it is used and why changed core is kept */
+static unsigned int g_main_lcore_id = 0xffffffff;
+static struct startup_param g_startup_param;
+static struct if_info g_if_info;
+static struct spp_component_info g_component_info[RTE_MAX_LCORE];
+static struct core_mng_info g_core_info[RTE_MAX_LCORE];
-static char config_file_path[PATH_MAX];
+static int g_change_core[RTE_MAX_LCORE]; /* TODO(yasufum) add desc how it is used and why changed component is kept */
+static int g_change_component[RTE_MAX_LCORE];
/* Print help message */
static void
@@ -73,11 +81,9 @@ usage(const char *progname)
{
RTE_LOG(INFO, APP, "Usage: %s [EAL args] --"
" --client-id CLIENT_ID"
- " [--config CONFIG_FILE_PATH]"
" -s SERVER_IP:SERVER_PORT"
" [--vhost-client]\n"
" --client-id CLIENT_ID : My client ID\n"
- " --config CONFIG_FILE_PATH : specific config file path\n"
" -s SERVER_IP:SERVER_PORT : Access information to the server\n"
" --vhost-client : Run vhost on client\n"
, progname);
@@ -99,8 +105,8 @@ add_ring_pmd(int ring_id)
/* Create ring pmd */
ring_port_id = rte_eth_from_ring(ring);
- RTE_LOG(DEBUG, APP, "ring port id %d\n", ring_port_id);
-
+ RTE_LOG(INFO, APP, "ring port add. (no = %d / port = %d)\n",
+ ring_id, ring_port_id);
return ring_port_id;
}
@@ -178,26 +184,30 @@ add_vhost_pmd(int index, int client)
return ret;
}
- RTE_LOG(DEBUG, APP, "vhost port id %d\n", vhost_port_id);
-
+ RTE_LOG(INFO, APP, "vhost port add. (no = %d / port = %d)\n",
+ index, vhost_port_id);
return vhost_port_id;
}
+/* Get core status */
+enum spp_core_status
+spp_get_core_status(unsigned int lcore_id)
+{
+ return g_core_info[lcore_id].status;
+}
+
/**
* Check status of all of cores is same as given
*
* It returns -1 as status mismatch if status is not same.
- * If status is SPP_CONFIG_UNUSE, check is skipped.
+ * If core is in use, status will be checked.
*/
static int
check_core_status(enum spp_core_status status)
{
- int cnt; /* increment core id */
- for (cnt = 0; cnt < SPP_CONFIG_CORE_MAX; cnt++) {
- if (g_core_info[cnt].type == SPP_CONFIG_UNUSE) {
- continue;
- }
- if (g_core_info[cnt].status != status) {
+ unsigned int lcore_id = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ if (g_core_info[lcore_id].status != status) {
/* Status is mismatched */
return -1;
}
@@ -225,18 +235,26 @@ check_core_status_wait(enum spp_core_status status)
return -1;
}
+/* Set core status */
+static void
+set_core_status(unsigned int lcore_id,
+ enum spp_core_status status)
+{
+ g_core_info[lcore_id].status = status;
+}
+
/* Set all core to given status */
static void
-set_core_status(enum spp_core_status status)
+set_all_core_status(enum spp_core_status status)
{
- int core_cnt = 0; /* increment core id */
- for(core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
- g_core_info[core_cnt].status = status;
+ unsigned int lcore_id = 0;
+ RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ g_core_info[lcore_id].status = status;
}
}
/**
- * Set all of core status to SPP_CORE_STOP_REQUEST if received signal
+ * Set all of component status to SPP_CORE_STOP_REQUEST if received signal
* is SIGTERM or SIGINT
*/
static void
@@ -246,7 +264,8 @@ stop_process(int signal) {
return;
}
- set_core_status(SPP_CORE_STOP_REQUEST);
+ g_core_info[g_main_lcore_id].status = SPP_CORE_STOP_REQUEST;
+ set_all_core_status(SPP_CORE_STOP_REQUEST);
}
/**
@@ -265,7 +284,7 @@ parse_app_client_id(const char *client_id_str, int *client_id)
if (unlikely(client_id_str == endptr) || unlikely(*endptr != '\0'))
return -1;
- if (id >= SPP_CLIENT_MAX)
+ if (id >= RTE_MAX_LCORE)
return -1;
*client_id = id;
@@ -310,7 +329,6 @@ parse_app_args(int argc, char *argv[])
char *argvopt[argcopt];
const char *progname = argv[0];
static struct option lgopts[] = {
- { "config", required_argument, NULL, SPP_LONGOPT_RETVAL_CONFIG },
{ "client-id", required_argument, NULL, SPP_LONGOPT_RETVAL_CLIENT_ID },
{ "vhost-client", no_argument, NULL, SPP_LONGOPT_RETVAL_VHOST_CLIENT },
{ 0 },
@@ -333,13 +351,6 @@ parse_app_args(int argc, char *argv[])
while ((opt = getopt_long(argc, argvopt, "s:", lgopts,
&option_index)) != EOF) {
switch (opt) {
- case SPP_LONGOPT_RETVAL_CONFIG:
- if (optarg[0] == '\0' || strlen(optarg) >= sizeof(config_file_path)) {
- usage(progname);
- return -1;
- }
- strcpy(config_file_path, optarg);
- break;
case SPP_LONGOPT_RETVAL_CLIENT_ID:
if (parse_app_client_id(optarg, &g_startup_param.client_id) != 0) {
usage(progname);
@@ -371,9 +382,8 @@ parse_app_args(int argc, char *argv[])
return -1;
}
RTE_LOG(INFO, APP,
- "app opts (client_id=%d,config=%s,server=%s:%d,vhost_client=%d)\n",
+ "app opts (client_id=%d,server=%s:%d,vhost_client=%d)\n",
g_startup_param.client_id,
- config_file_path,
g_startup_param.server_ip,
g_startup_param.server_port,
g_startup_param.vhost_client);
@@ -381,25 +391,25 @@ parse_app_args(int argc, char *argv[])
}
/**
- * Return patch info of given type and num of interface
+ * Return port info of given type and num of interface
*
* It returns NULL value if given type is invalid.
*
* TODO(yasufum) refactor name of func to be more understandable (area?)
* TODO(yasufum) refactor, change if to iface.
*/
-static struct patch_info *
+static struct spp_port_info *
get_if_area(enum port_type if_type, int if_no)
{
switch (if_type) {
case PHY:
- return &g_if_info.nic_patchs[if_no];
+ return &g_if_info.nic[if_no];
break;
case VHOST:
- return &g_if_info.vhost_patchs[if_no];
+ return &g_if_info.vhost[if_no];
break;
case RING:
- return &g_if_info.ring_patchs[if_no];
+ return &g_if_info.ring[if_no];
break;
default:
return NULL;
@@ -408,8 +418,9 @@ get_if_area(enum port_type if_type, int if_no)
}
/**
- * Initialize all of patch info by assingning -1
+ * Initialize g_if_info
*
+ * Clear g_if_info and set initial value.
* TODO(yasufum) refactor, change if to iface.
*/
static void
@@ -418,336 +429,90 @@ init_if_info(void)
int port_cnt; /* increment ether ports */
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;
+ g_if_info.nic[port_cnt].if_type = UNDEF;
+ g_if_info.nic[port_cnt].if_no = port_cnt;
+ g_if_info.nic[port_cnt].dpdk_port = -1;
+ g_if_info.vhost[port_cnt].if_type = UNDEF;
+ g_if_info.vhost[port_cnt].if_no = port_cnt;
+ g_if_info.vhost[port_cnt].dpdk_port = -1;
+ g_if_info.ring[port_cnt].if_type = UNDEF;
+ g_if_info.ring[port_cnt].if_no = port_cnt;
+ g_if_info.ring[port_cnt].dpdk_port = -1;
}
}
/**
- * Initialize g_core_info and its port info
- *
- * Clear g_core_info and set interface type of its port info to UNDEF.
- * TODO(yasufum) refactor, change if to iface.
+ * Initialize g_component_info
*/
static void
-init_core_info(void)
+init_component_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;
- }
+ int cnt;
+ memset(&g_component_info, 0x00, sizeof(g_component_info));
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ g_component_info[cnt].component_id = cnt;
}
- memset(g_change_core, 0x00, sizeof(g_change_core));
+ memset(g_change_component, 0x00, sizeof(g_change_component));
}
/**
- * Set properties of g_core_info from config
- *
- * TODO(yasufum) refactor, change if to iface.
+ * Initialize g_core_info
*/
-static int
-set_from_proc_info(struct spp_config_area *config)
+static void
+init_core_info(void)
{
- int core_cnt, rx_start, rx_cnt, tx_start, tx_cnt;
- enum port_type if_type;
- int if_no;
- struct spp_config_functions *core_func = NULL;
- struct spp_core_info *core_info = NULL;
- struct patch_info *patch_info = NULL;
- for (core_cnt = 0; core_cnt < config->proc.num_func; core_cnt++) {
- core_func = &config->proc.functions[core_cnt];
- core_info = &g_core_info[core_func->core_no];
-
- if (core_func->type == SPP_CONFIG_UNUSE) {
- continue;
- }
-
- /* Check if type of core_info is SPP_CONFIG_FORWARD because this
- * this type is only available for several settings.
- */
- if ((core_info->type != SPP_CONFIG_UNUSE) &&
- ((core_info->type != SPP_CONFIG_FORWARD) ||
- (core_func->type != SPP_CONFIG_FORWARD))) {
- RTE_LOG(ERR, APP, "Core in use. (core = %d, type = %d/%d)\n",
- core_func->core_no,
- core_func->type, core_info->type);
- return -1;
- }
-
- core_info->type = core_func->type;
- if (!rte_lcore_is_enabled(core_func->core_no)) {
- /* CPU mismatch */
- RTE_LOG(ERR, APP, "CPU mismatch (cpu = %u)\n",
- core_func->core_no);
- return -1;
- }
-
- rx_start = core_info->num_rx_port;
- core_info->num_rx_port += core_func->num_rx_port;
- for (rx_cnt = 0; rx_cnt < core_func->num_rx_port; rx_cnt++) {
- if_type = core_func->rx_ports[rx_cnt].if_type;
- if_no = core_func->rx_ports[rx_cnt].if_no;
-
- core_info->rx_ports[rx_start + rx_cnt].if_type = if_type;
- core_info->rx_ports[rx_start + rx_cnt].if_no = if_no;
-
- /* Retrieve patch corresponding to type and number of the interface */
- patch_info = get_if_area(if_type, if_no);
-
- patch_info->use_flg = 1;
- if (unlikely(patch_info->rx_core != NULL)) {
- RTE_LOG(ERR, APP, "Used RX port (core = %d, if_type = %d, if_no = %d)\n",
- core_func->core_no, if_type, if_no);
- return -1;
- }
-
- /* Hold core info is to be referred for updating this information */
- patch_info->rx_core_no = core_func->core_no;
- patch_info->rx_core = &core_info->rx_ports[rx_start + rx_cnt];
- }
-
- /* Set TX port */
- tx_start = core_info->num_tx_port;
- core_info->num_tx_port += core_func->num_tx_port;
- for (tx_cnt = 0; tx_cnt < core_func->num_tx_port; tx_cnt++) {
- if_type = core_func->tx_ports[tx_cnt].if_type;
- if_no = core_func->tx_ports[tx_cnt].if_no;
-
- core_info->tx_ports[tx_start + tx_cnt].if_type = if_type;
- core_info->tx_ports[tx_start + tx_cnt].if_no = if_no;
-
- patch_info = get_if_area(if_type, if_no);
-
- patch_info->use_flg = 1;
- if (unlikely(patch_info->tx_core != NULL)) {
- RTE_LOG(ERR, APP, "Used TX port (core = %d, if_type = %d, if_no = %d)\n",
- core_func->core_no, if_type, if_no);
- return -1;
- }
-
- /* Hold core info is to be referred for updating this information */
- patch_info->tx_core_no = core_func->core_no;
- patch_info->tx_core = &core_info->tx_ports[tx_start + tx_cnt];
- }
+ int cnt = 0;
+ memset(&g_core_info, 0x00, sizeof(g_core_info));
+ set_all_core_status(SPP_CORE_STOP);
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ g_core_info[cnt].ref_index = 0;
+ g_core_info[cnt].upd_index = 1;
}
-
- return 0;
+ memset(g_change_core, 0x00, sizeof(g_change_core));
}
/**
- * Load mac table entries from config and setup patches
+ * Setup port info of port on host
*
* TODO(yasufum) refactor, change if to iface.
*/
static int
-set_from_classifier_table(struct spp_config_area *config)
+set_nic_interface(void)
{
- enum port_type if_type;
- int if_no = 0;
- int mac_cnt = 0;
- struct spp_config_mac_table_element *mac_table = NULL;
- struct patch_info *patch_info = NULL;
- for (mac_cnt = 0; mac_cnt < config->classifier_table.num_table; mac_cnt++) {
- mac_table = &config->classifier_table.mac_tables[mac_cnt];
-
- if_type = mac_table->port.if_type;
- if_no = mac_table->port.if_no;
-
- /* Retrieve patch corresponding to type and number of the interface */
- patch_info = get_if_area(if_type, if_no);
-
- if (unlikely(patch_info->use_flg == 0)) {
- RTE_LOG(ERR, APP, "Not used interface (if_type = %d, if_no = %d)\n",
- if_type, if_no);
- return -1;
- }
+ int nic_cnt = 0;
- /* Set mac address from the table for destination tx, not need for rx */
- 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);
- }
- }
- return 0;
-}
-
-/**
- * Setup patch info of port on host
- *
- * TODO(yasufum) refactor, change if to iface.
- */
-static int
-set_nic_interface(struct spp_config_area *config __attribute__ ((unused)))
-{
/* NIC Setting */
g_if_info.num_nic = rte_eth_dev_count();
if (g_if_info.num_nic > RTE_MAX_ETHPORTS) {
g_if_info.num_nic = RTE_MAX_ETHPORTS;
}
- int nic_cnt, nic_num = 0;
- struct patch_info *patch_info = NULL;
- for (nic_cnt = 0; nic_cnt < RTE_MAX_ETHPORTS; nic_cnt++) {
- patch_info = &g_if_info.nic_patchs[nic_cnt];
- patch_info->dpdk_port = nic_cnt;
-
- /* Skip for no used nic */
- if (patch_info->use_flg == 0) {
- continue;
- }
-
- if (patch_info->rx_core != NULL) {
- patch_info->rx_core->dpdk_port = nic_cnt;
- }
- if (patch_info->tx_core != NULL) {
- patch_info->tx_core->dpdk_port = nic_cnt;
- }
-
- nic_num++;
- }
-
- if (unlikely(nic_num > g_if_info.num_nic)) {
- RTE_LOG(ERR, APP, "NIC Setting mismatch. (IF = %d, config = %d)\n",
- nic_num, g_if_info.num_nic);
- return -1;
+ for (nic_cnt = 0; nic_cnt < g_if_info.num_nic; nic_cnt++) {
+ g_if_info.nic[nic_cnt].dpdk_port = nic_cnt;
}
return 0;
}
/**
- * Setup vhost interfaces from config
- *
- * TODO(yasufum) refactor, change if to iface.
- */
-static int
-set_vhost_interface(struct spp_config_area *config)
-{
- int vhost_cnt, vhost_num = 0;
- g_if_info.num_vhost = config->proc.num_vhost;
- struct patch_info *patch_info = NULL;
- for (vhost_cnt = 0; vhost_cnt < RTE_MAX_ETHPORTS; vhost_cnt++) {
- patch_info = &g_if_info.vhost_patchs[vhost_cnt];
- if (patch_info->use_flg == 0) {
- /* Not Used */
- continue;
- }
-
- int dpdk_port = add_vhost_pmd(vhost_cnt, g_startup_param.vhost_client);
- if (unlikely(dpdk_port < 0)) {
- RTE_LOG(ERR, APP, "VHOST add failed. (no = %d)\n",
- vhost_cnt);
- return -1;
- }
- patch_info->dpdk_port = dpdk_port;
-
- if (patch_info->rx_core != NULL) {
- patch_info->rx_core->dpdk_port = dpdk_port;
- }
- if (patch_info->tx_core != NULL) {
- patch_info->tx_core->dpdk_port = dpdk_port;
- }
- vhost_num++;
- }
- if (unlikely(vhost_num > g_if_info.num_vhost)) {
- RTE_LOG(ERR, APP, "VHOST Setting mismatch. (IF = %d, config = %d)\n",
- vhost_num, g_if_info.num_vhost);
- return -1;
- }
- return 0;
-}
-
-/**
- * Setup ring interfaces from config
- *
- * TODO(yasufum) refactor, change if to iface.
- */
-static int
-set_ring_interface(struct spp_config_area *config)
-{
- int ring_cnt, ring_num = 0;
- g_if_info.num_ring = config->proc.num_ring;
- struct patch_info *patch_info = NULL;
- for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) {
- patch_info = &g_if_info.ring_patchs[ring_cnt];
-
- if (patch_info->use_flg == 0) {
- /* Skip for no used nic */
- continue;
- }
-
- int dpdk_port = add_ring_pmd(ring_cnt);
- if (unlikely(dpdk_port < 0)) {
- RTE_LOG(ERR, APP, "RING add failed. (no = %d)\n",
- ring_cnt);
- return -1;
- }
- patch_info->dpdk_port = dpdk_port;
-
- if (patch_info->rx_core != NULL) {
- patch_info->rx_core->dpdk_port = dpdk_port;
- }
- if (patch_info->tx_core != NULL) {
- patch_info->tx_core->dpdk_port = dpdk_port;
- }
- ring_num++;
- }
- if (unlikely(ring_num > g_if_info.num_ring)) {
- RTE_LOG(ERR, APP, "RING Setting mismatch. (IF = %d, config = %d)\n",
- ring_num, g_if_info.num_ring);
- return -1;
- }
- return 0;
-}
-
-/**
* Setup management info for spp_vf
*
* TODO(yasufum) refactor, change if to iface.
* TODO(yasufum) refactor, change function name from manage to mng or management
*/
static int
-init_manage_data(struct spp_config_area *config)
+init_manage_data(void)
{
/* Initialize interface and core infomation */
init_if_info();
init_core_info();
+ init_component_info();
- /* Load config for resource assingment and network configuration */
- int ret_proc = set_from_proc_info(config);
- if (unlikely(ret_proc != 0)) {
- return -1;
- }
- int ret_classifier = set_from_classifier_table(config);
- if (unlikely(ret_classifier != 0)) {
- return -1;
- }
-
- int ret_nic = set_nic_interface(config);
+ int ret_nic = set_nic_interface();
if (unlikely(ret_nic != 0)) {
return -1;
}
- int ret_vhost = set_vhost_interface(config);
- if (unlikely(ret_vhost != 0)) {
- return -1;
- }
-
- int ret_ring = set_ring_interface(config);
- if (unlikely(ret_ring != 0)) {
- return -1;
- }
-
return 0;
}
@@ -772,7 +537,7 @@ print_ring_latency_stats(void)
printf("RING Latency\n");
printf(" RING");
for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) {
- if (g_if_info.ring_patchs[ring_cnt].use_flg == 0) {
+ if (g_if_info.ring[ring_cnt].if_type == UNDEF) {
continue;
}
spp_ringlatencystats_get_stats(ring_cnt, &stats[ring_cnt]);
@@ -783,7 +548,7 @@ print_ring_latency_stats(void)
for (stats_cnt = 0; stats_cnt < SPP_RINGLATENCYSTATS_STATS_SLOT_COUNT; stats_cnt++) {
printf("%3dns", stats_cnt);
for (ring_cnt = 0; ring_cnt < RTE_MAX_ETHPORTS; ring_cnt++) {
- if (g_if_info.ring_patchs[ring_cnt].use_flg == 0) {
+ if (g_if_info.ring[ring_cnt].if_type == UNDEF) {
continue;
}
@@ -800,7 +565,7 @@ print_ring_latency_stats(void)
* Remove sock file
*/
static void
-del_vhost_sockfile(struct patch_info *vhost_patchs)
+del_vhost_sockfile(struct spp_port_info *vhost)
{
int cnt;
@@ -809,7 +574,7 @@ del_vhost_sockfile(struct patch_info *vhost_patchs)
return;
for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
- if (likely(vhost_patchs[cnt].use_flg == 0)) {
+ if (likely(vhost[cnt].if_type == UNDEF)) {
/* Skip removing if it is not using vhost */
continue;
}
@@ -818,6 +583,95 @@ del_vhost_sockfile(struct patch_info *vhost_patchs)
}
}
+/* Get component type of target core */
+enum spp_component_type
+spp_get_component_type(unsigned int lcore_id)
+{
+ struct core_mng_info *info = &g_core_info[lcore_id];
+ return info->core[info->ref_index].type;
+}
+
+/* Get component type being updated on target core */
+enum spp_component_type
+spp_get_component_type_update(unsigned int lcore_id)
+{
+ struct core_mng_info *info = &g_core_info[lcore_id];
+ return info->core[info->upd_index].type;
+}
+
+/* Get core ID of target component */
+unsigned int
+spp_get_component_core(int component_id)
+{
+ struct spp_component_info *info = &g_component_info[component_id];
+ return info->lcore_id;
+}
+
+/* Get usage area of target core */
+static struct core_info *
+get_core_info(unsigned int lcore_id)
+{
+ struct core_mng_info *info = &g_core_info[lcore_id];
+ return &(info->core[info->ref_index]);
+}
+
+/* Check core index change */
+int
+spp_check_core_index(unsigned int lcore_id)
+{
+ struct core_mng_info *info = &g_core_info[lcore_id];
+ return info->ref_index == info->upd_index;
+}
+
+/* Main process of slave core */
+static int
+slave_main(void *arg __attribute__ ((unused)))
+{
+ int ret = 0;
+ int cnt = 0;
+ unsigned int lcore_id = rte_lcore_id();
+ enum spp_core_status status = SPP_CORE_STOP;
+ struct core_mng_info *info = &g_core_info[lcore_id];
+ struct core_info *core = get_core_info(lcore_id);
+
+ RTE_LOG(INFO, APP, "Core[%d] Start.\n", lcore_id);
+ set_core_status(lcore_id, SPP_CORE_IDLE);
+
+ while((status = spp_get_core_status(lcore_id)) != SPP_CORE_STOP_REQUEST) {
+ if (status != SPP_CORE_FORWARD)
+ continue;
+
+ if (spp_check_core_index(lcore_id)) {
+ /* Setting with the flush command trigger. */
+ info->ref_index = (info->upd_index+1)%SPP_INFO_AREA_MAX;
+ core = get_core_info(lcore_id);
+ }
+
+ for (cnt = 0; cnt < core->num; cnt++) {
+ if (spp_get_component_type(lcore_id) == SPP_COMPONENT_CLASSIFIER_MAC) {
+ /* Classifier loops inside the function. */
+ ret = spp_classifier_mac_do(core->id[cnt]);
+ break;
+ } else {
+ /* Forward / Merge returns at once. */
+ /* It is for processing multiple components. */
+ ret = spp_forward(core->id[cnt]);
+ if (unlikely(ret != 0))
+ break;
+ }
+ }
+ if (unlikely(ret != 0)) {
+ RTE_LOG(ERR, APP, "Core[%d] Component Error. (id = %d)\n",
+ lcore_id, core->id[cnt]);
+ break;
+ }
+ }
+
+ set_core_status(lcore_id, SPP_CORE_STOP);
+ RTE_LOG(INFO, APP, "Core[%d] End.\n", lcore_id);
+ return ret;
+}
+
/* TODO(yasufum) refactor, change if to iface. */
/* TODO(yasufum) change test using ut_main(), or add desccription for what and why use it */
/* TODO(yasufum) change to return -1 explicity if error is occured. */
@@ -842,10 +696,6 @@ ut_main(int argc, char *argv[])
signal(SIGTERM, stop_process);
signal(SIGINT, stop_process);
- /* Setup config wiht default file path */
- strcpy(config_file_path, SPP_CONFIG_FILE_PATH);
-
- unsigned int main_lcore_id = 0xffffffff;
while(1) {
int ret_dpdk = rte_eal_init(argc, argv);
if (unlikely(ret_dpdk < 0)) {
@@ -864,17 +714,10 @@ ut_main(int argc, char *argv[])
break;
}
- RTE_LOG(INFO, APP, "Load config file(%s)\n", config_file_path);
-
- int ret_config = spp_config_load_file(config_file_path, 0, &g_config);
- if (unlikely(ret_config != 0)) {
- break;
- }
-
/* Get lcore id of main thread to set its status after */
- main_lcore_id = rte_lcore_id();
+ g_main_lcore_id = rte_lcore_id();
- int ret_manage = init_manage_data(&g_config);
+ int ret_manage = init_manage_data();
if (unlikely(ret_manage != 0)) {
break;
}
@@ -884,7 +727,9 @@ ut_main(int argc, char *argv[])
break;
}
- /* Setup connection for accepting commands from controller */
+ spp_forward_init();
+
+ /* Setup connection for accepting commands from controller */
int ret_command_init = spp_command_proc_init(
g_startup_param.server_ip,
g_startup_param.server_port);
@@ -903,37 +748,29 @@ ut_main(int argc, char *argv[])
/* Start worker threads of classifier and forwarder */
unsigned int lcore_id = 0;
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
- if (g_core_info[lcore_id].type == SPP_CONFIG_CLASSIFIER_MAC) {
- rte_eal_remote_launch(spp_classifier_mac_do,
- (void *)&g_core_info[lcore_id],
- lcore_id);
- } else {
- rte_eal_remote_launch(spp_forward,
- (void *)&g_core_info[lcore_id],
- lcore_id);
- }
+ rte_eal_remote_launch(slave_main, NULL, lcore_id);
}
- /* Set the status of main thread to idle */
- g_core_info[main_lcore_id].status = SPP_CORE_IDLE;
+ /* Set the status of main thread to idle */
+ g_core_info[g_main_lcore_id].status = SPP_CORE_IDLE;
int ret_wait = check_core_status_wait(SPP_CORE_IDLE);
if (unlikely(ret_wait != 0)) {
break;
}
/* Start forwarding */
- set_core_status(SPP_CORE_FORWARD);
+ set_all_core_status(SPP_CORE_FORWARD);
RTE_LOG(INFO, APP, "My ID %d start handling message\n", 0);
RTE_LOG(INFO, APP, "[Press Ctrl-C to quit ...]\n");
/* Enter loop for accepting commands */
int ret_do = 0;
#ifndef USE_UT_SPP_VF
- while(likely(g_core_info[main_lcore_id].status != SPP_CORE_STOP_REQUEST)) {
+ while(likely(g_core_info[g_main_lcore_id].status != SPP_CORE_STOP_REQUEST)) {
#else
{
#endif
- /* Receive command */
+ /* Receive command */
ret_do = spp_command_proc_do();
if (unlikely(ret_do != 0)) {
break;
@@ -947,6 +784,7 @@ ut_main(int argc, char *argv[])
}
if (unlikely(ret_do != 0)) {
+ set_all_core_status(SPP_CORE_STOP_REQUEST);
break;
}
@@ -955,16 +793,16 @@ ut_main(int argc, char *argv[])
}
/* Finalize to exit */
- if (main_lcore_id == rte_lcore_id())
+ if (g_main_lcore_id == rte_lcore_id())
{
- g_core_info[main_lcore_id].status = SPP_CORE_STOP;
+ g_core_info[g_main_lcore_id].status = SPP_CORE_STOP;
int ret_core_end = check_core_status_wait(SPP_CORE_STOP);
if (unlikely(ret_core_end != 0)) {
RTE_LOG(ERR, APP, "Core did not stop.\n");
}
/* Remove vhost sock file if it is not running in vhost-client mode */
- del_vhost_sockfile(g_if_info.vhost_patchs);
+ del_vhost_sockfile(g_if_info.vhost);
}
#ifdef SPP_RINGLATENCYSTATS_ENABLE
@@ -982,123 +820,478 @@ spp_get_client_id(void)
}
/**
- * Check mac address used on the interface for registering or removing
+ * Check mac address used on the port for registering or removing
*
* TODO(yasufum) refactor, change if to iface.
*/
-static int
-check_mac_used_interface(uint64_t mac_addr, enum port_type *if_type, int *if_no)
+int
+spp_check_mac_used_port(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;
+ struct spp_port_info *port_info = get_if_area(if_type, if_no);
+ return (mac_addr == port_info->mac_addr);
+}
+
+/*
+ * Check if port has been added.
+ */
+int
+spp_check_added_port(enum port_type if_type, int if_no)
+{
+ struct spp_port_info *port = get_if_area(if_type, if_no);
+ return port->if_type != UNDEF;
+}
+
+/*
+ * Check if component is using port.
+ */
+int
+spp_check_used_port(enum port_type if_type, int if_no, enum spp_port_rxtx rxtx)
+{
+ int cnt, port_cnt, max = 0;
+ struct spp_component_info *component = NULL;
+ struct spp_port_info **port_array = NULL;
+ struct spp_port_info *port = get_if_area(if_type, if_no);
+
+ if (port == NULL)
+ return SPP_RET_NG;
+
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ component = &g_component_info[cnt];
+ if (component->type == SPP_COMPONENT_UNUSE)
+ continue;
+
+ if (rxtx == SPP_PORT_RXTX_RX) {
+ max = component->num_rx_port;
+ port_array = component->rx_ports;
+ } else if (rxtx == SPP_PORT_RXTX_TX) {
+ max = component->num_tx_port;
+ port_array = component->tx_ports;
}
- if (unlikely(g_if_info.ring_patchs[cnt].mac_addr == mac_addr)) {
- *if_type = RING;
- *if_no = cnt;
- return 0;
+ for (port_cnt = 0; port_cnt < max; port_cnt++) {
+ if (unlikely(port_array[port_cnt] == port))
+ return cnt;
}
}
- return -1;
+
+ return SPP_RET_NG;
+}
+
+/*
+ * Set port change to component.
+ */
+static void
+set_component_change_port(struct spp_port_info *port, enum spp_port_rxtx rxtx)
+{
+ int ret = 0;
+ if ((rxtx == SPP_PORT_RXTX_RX) || (rxtx == SPP_PORT_RXTX_ALL)) {
+ ret = spp_check_used_port(port->if_type, port->if_no, SPP_PORT_RXTX_RX);
+ if (ret >= 0)
+ g_change_component[ret] = 1;
+ }
+
+ if ((rxtx == SPP_PORT_RXTX_TX) || (rxtx == SPP_PORT_RXTX_ALL)) {
+ ret = spp_check_used_port(port->if_type, port->if_no, SPP_PORT_RXTX_TX);
+ if (ret >= 0)
+ g_change_component[ret] = 1;
+ }
}
int
spp_update_classifier_table(
+ enum spp_command_action action,
enum spp_classifier_type type,
const char *data,
- const struct spp_config_port_info *port)
+ const struct spp_port_index *port)
{
- enum port_type if_type = UNDEF;
- int if_no = 0;
- struct patch_info *patch_info = NULL;
+ struct spp_port_info *port_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);
+ ret_mac = spp_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;
- }
+ port_info = get_if_area(port->if_type, port->if_no);
+ if (unlikely(port_info == NULL)) {
+ RTE_LOG(ERR, APP, "No port. ( port = %d:%d )\n",
+ port->if_type, port->if_no);
+ return SPP_RET_NG;
+ }
+ if (unlikely(port_info->if_type == UNDEF)) {
+ RTE_LOG(ERR, APP, "Port not added. ( port = %d:%d )\n",
+ port->if_type, port->if_no);
+ return SPP_RET_NG;
+ }
- 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);
+ if (action == SPP_CMD_ACTION_DEL) {
+ /* Delete */
+ if ((port_info->mac_addr != 0) &&
+ unlikely(port_info->mac_addr != mac_addr)) {
+ RTE_LOG(ERR, APP, "MAC address is different. ( mac = %s )\n",
+ data);
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);
- }
+ port_info->mac_addr = 0;
+ memset(port_info->mac_addr_str, 0x00, SPP_MIN_STR_LEN);
}
- else
- {
+ else if (action == SPP_CMD_ACTION_ADD) {
/* 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;
- }
+ if (unlikely(port_info->mac_addr != 0)) {
+ RTE_LOG(ERR, APP, "Port in used. ( port = %d:%d )\n",
+ port->if_type, port->if_no);
+ return SPP_RET_NG;
}
- 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);
+ port_info->mac_addr = mac_addr;
+ strcpy(port_info->mac_addr_str, data);
+ }
+ }
+
+ /* TODO(yasufum) add desc how it is used and why changed core is kept */
+ set_component_change_port(port_info, SPP_PORT_RXTX_TX);
+ return SPP_RET_OK;
+}
+
+/* Get free component */
+static int
+get_free_component(void)
+{
+ int cnt = 0;
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ if (g_component_info[cnt].type == SPP_COMPONENT_UNUSE)
+ return cnt;
+ }
+ return -1;
+}
+
+/* Get name matching component */
+int
+spp_get_component_id(const char *name)
+{
+ int cnt = 0;
+ if (name[0] == '\0')
+ return SPP_RET_NG;
+
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ if (strcmp(name, g_component_info[cnt].name) == 0)
+ return cnt;
+ }
+ return SPP_RET_NG;
+}
+
+static int
+get_del_core_element(int info, int num, int *array)
+{
+ int cnt;
+ int match = -1;
+ int max = num;
+
+ for (cnt = 0; cnt < max; cnt++) {
+ if (info == array[cnt])
+ match = cnt;
+ }
+
+ if (match < 0)
+ return -1;
+
+ /* Last element is excluded from movement. */
+ max--;
+
+ for (cnt = match; cnt < max; cnt++) {
+ array[cnt] = array[cnt+1];
+ }
+
+ /* Last element is cleared. */
+ array[cnt] = 0;
+ return 0;
+}
+
+/* Component command to execute it */
+int
+spp_update_component(
+ enum spp_command_action action,
+ const char *name,
+ unsigned int lcore_id,
+ enum spp_component_type type)
+{
+ int ret = SPP_RET_NG;
+ int ret_del = -1;
+ int component_id = 0;
+ unsigned int tmp_lcore_id = 0;
+ struct spp_component_info *component = NULL;
+ struct core_info *core = NULL;
+ struct core_mng_info *info = NULL;
+
+ switch (action) {
+ case SPP_CMD_ACTION_START:
+ info = &g_core_info[lcore_id];
+ if (info->status == SPP_CORE_UNUSE) {
+ RTE_LOG(ERR, APP, "Core unavailable.\n");
+ return SPP_RET_NG;
+ }
+
+ component_id = spp_get_component_id(name);
+ if (component_id >= 0) {
+ RTE_LOG(ERR, APP, "Component name in used.\n");
+ return SPP_RET_NG;
+ }
+
+ component_id = get_free_component();
+ if (component_id < 0) {
+ RTE_LOG(ERR, APP, "Component upper limit is over.\n");
+ return SPP_RET_NG;
+ }
+
+ core = &info->core[info->upd_index];
+ if ((core->type != SPP_COMPONENT_UNUSE) && (core->type != type)) {
+ RTE_LOG(ERR, APP, "Component type is error.\n");
+ return SPP_RET_NG;
+ }
+
+ component = &g_component_info[component_id];
+ memset(component, 0x00, sizeof(struct spp_component_info));
+ strcpy(component->name, name);
+ component->type = type;
+ component->lcore_id = lcore_id;
+ component->component_id = component_id;
+
+ core->type = type;
+ core->id[core->num] = component_id;
+ core->num++;
+ ret = SPP_RET_OK;
+ tmp_lcore_id = lcore_id;
+ break;
+
+ case SPP_CMD_ACTION_STOP:
+ component_id = spp_get_component_id(name);
+ if (component_id < 0)
+ return SPP_RET_OK;
+
+ component = &g_component_info[component_id];
+ tmp_lcore_id = component->lcore_id;
+ memset(component, 0x00, sizeof(struct spp_component_info));
+
+ info = &g_core_info[tmp_lcore_id];
+ core = &info->core[info->upd_index];
+ ret_del = get_del_core_element(component_id,
+ core->num, core->id);
+ if (ret_del >= 0)
+ /* If deleted, decrement number. */
+ core->num--;
+
+ if (core->num == 0)
+ core->type = SPP_COMPONENT_UNUSE;
+
+ ret = SPP_RET_OK;
+ break;
+
+ default:
+ break;
+ }
+
+ g_change_core[tmp_lcore_id] = 1;
+ return ret;
+}
+
+static int
+check_port_element(
+ struct spp_port_info *info,
+ int num,
+ struct spp_port_info *array[])
+{
+ int cnt = 0;
+ int match = -1;
+ for (cnt = 0; cnt < num; cnt++) {
+ if (info == array[cnt])
+ match = cnt;
+ }
+ return match;
+}
+
+static int
+get_del_port_element(
+ struct spp_port_info *info,
+ int num,
+ struct spp_port_info *array[])
+{
+ int cnt = 0;
+ int match = -1;
+ int max = num;
+
+ match = check_port_element(info, num, array);
+ if (match < 0)
+ return -1;
+
+ /* Last element is excluded from movement. */
+ max--;
+
+ for (cnt = match; cnt < max; cnt++) {
+ array[cnt] = array[cnt+1];
+ }
+
+ /* Last element is cleared. */
+ array[cnt] = NULL;
+ return 0;
+}
+
+/* Port add or del to execute it */
+int
+spp_update_port(enum spp_command_action action,
+ const struct spp_port_index *port,
+ enum spp_port_rxtx rxtx,
+ const char *name)
+{
+ int ret = SPP_RET_NG;
+ int ret_check = -1;
+ int ret_del = -1;
+ int component_id = 0;
+ struct spp_component_info *component = NULL;
+ struct spp_port_info *port_info = NULL;
+ int *num = NULL;
+ struct spp_port_info **ports = NULL;
+
+ component_id = spp_get_component_id(name);
+ if (component_id < 0) {
+ RTE_LOG(ERR, APP, "Unknown component by port command. (component = %s)\n",
+ name);
+ return SPP_RET_NG;
+ }
+
+ component = &g_component_info[component_id];
+ port_info = get_if_area(port->if_type, port->if_no);
+ if (rxtx == SPP_PORT_RXTX_RX) {
+ num = &component->num_rx_port;
+ ports = component->rx_ports;
+ } else {
+ num = &component->num_tx_port;
+ ports = component->tx_ports;
+ }
+
+ switch (action) {
+ case SPP_CMD_ACTION_ADD:
+ ret_check = check_port_element(port_info, *num, ports);
+ if (ret_check >= 0)
+ return SPP_RET_OK;
+
+ if (*num >= RTE_MAX_ETHPORTS) {
+ RTE_LOG(ERR, APP, "Port upper limit is over.\n");
+ break;
+ }
+
+ port_info->if_type = port->if_type;
+ ports[*num] = port_info;
+ (*num)++;
+
+ ret = SPP_RET_OK;
+ break;
+
+ case SPP_CMD_ACTION_DEL:
+ ret_del = get_del_port_element(port_info, *num, ports);
+ if (ret_del == 0)
+ (*num)--; /* If deleted, decrement number. */
+ ret = SPP_RET_OK;
+ break;
+ default:
+ break;
+ }
+
+ g_change_component[component_id] = 1;
+ return ret;
+}
+
+/* Flush initial setting of each interface. */
+static int
+flush_port(void)
+{
+ int ret = 0;
+ int cnt = 0;
+ struct spp_port_info *port = NULL;
+
+ /* Initialize added vhost. */
+ for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+ port = &g_if_info.vhost[cnt];
+ if ((port->if_type != UNDEF) && (port->dpdk_port < 0)) {
+ ret = add_vhost_pmd(port->if_no, g_startup_param.vhost_client);
+ if (ret < 0)
return SPP_RET_NG;
- }
+ port->dpdk_port = ret;
+ }
+ }
- 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;
- }
+ /* Initialize added ring. */
+ for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+ port = &g_if_info.ring[cnt];
+ if ((port->if_type != UNDEF) && (port->dpdk_port < 0)) {
+ ret = add_ring_pmd(port->if_no);
+ if (ret < 0)
+ return SPP_RET_NG;
+ port->dpdk_port = ret;
+ }
+ }
+ return SPP_RET_OK;
+}
- 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;
- }
+/* Flush changed core. */
+static void
+flush_core(void)
+{
+ int cnt = 0;
+ struct core_mng_info *info = NULL;
- 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);
- }
+ /* Changed core has changed index. */
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ if (g_change_core[cnt] != 0) {
+ info = &g_core_info[cnt];
+ info->upd_index = info->ref_index;
+ }
+ }
+
+ /* Waiting for changed core change. */
+ for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ if (g_change_core[cnt] != 0) {
+ info = &g_core_info[cnt];
+ while(likely(info->ref_index == info->upd_index))
+ rte_delay_us_block(SPP_CHANGE_UPDATE_INTERVAL);
+
+ memcpy(&info->core[info->upd_index],
+ &info->core[info->ref_index],
+ sizeof(struct core_info));
}
}
+}
- /* TODO(yasufum) add desc how it is used and why changed core is kept */
- g_change_core[patch_info->tx_core_no] = 1;
+/* Flush chagned component */
+static int
+flush_component(void)
+{
+ int ret = 0;
+ int cnt = 0;
+ struct spp_component_info *component_info = NULL;
+
+ for(cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+ if (g_change_component[cnt] == 0)
+ continue;
+
+ component_info = &g_component_info[cnt];
+ if (component_info->type == SPP_COMPONENT_CLASSIFIER_MAC) {
+ ret = spp_classifier_mac_update(component_info);
+ } else {
+ ret = spp_forward_update(component_info);
+ }
+ if (unlikely(ret < 0)) {
+ RTE_LOG(ERR, APP, "Flush error. ( component = %s, type = %d)\n",
+ component_info->name, component_info->type);
+ return SPP_RET_NG;
+ }
+ }
return SPP_RET_OK;
}
@@ -1106,26 +1299,24 @@ spp_update_classifier_table(
int
spp_flush(void)
{
- int core_cnt = 0; /* increment core id */
- int ret_classifier = 0;
- struct spp_core_info *core_info = NULL;
+ int ret = -1;
- for(core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
- if (g_change_core[core_cnt] == 0)
- continue;
+ /* Initial setting of each interface. */
+ ret = flush_port();
+ if (ret < 0)
+ return ret;
- 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;
- }
- }
- }
+ /* Flush of core index. */
+ flush_core();
+ memset(g_change_core, 0x00, sizeof(g_change_core));
+
+ /* Flush of component */
+ ret = flush_component();
+ if (ret < 0)
+ return ret;
/* Finally, zero-clear g_change_core */
- memset(g_change_core, 0x00, sizeof(g_change_core));
+ memset(g_change_component, 0x00, sizeof(g_change_component));
return SPP_RET_OK;
}
@@ -1143,3 +1334,151 @@ spp_iterate_classifier_table(
return SPP_RET_OK;
}
+
+/**
+ * Sepeparate port id of combination of iface type and number and
+ * assign to given argment, if_type and if_no.
+ *
+ * For instance, 'ring:0' is separated to 'ring' and '0'.
+ *
+ * TODO(yasufum) change if to iface
+ */
+int
+spp_get_if_info(const char *port, enum port_type *if_type, int *if_no)
+{
+ enum port_type type = UNDEF;
+ const char *no_str = NULL;
+ char *endptr = NULL;
+
+ /* Find out which type of interface from port */
+ if (strncmp(port, SPP_IFTYPE_NIC_STR ":", strlen(SPP_IFTYPE_NIC_STR)+1) == 0) {
+ /* NIC */
+ type = PHY;
+ no_str = &port[strlen(SPP_IFTYPE_NIC_STR)+1];
+ } else if (strncmp(port, SPP_IFTYPE_VHOST_STR ":", strlen(SPP_IFTYPE_VHOST_STR)+1) == 0) {
+ /* VHOST */
+ type = VHOST;
+ no_str = &port[strlen(SPP_IFTYPE_VHOST_STR)+1];
+ } else if (strncmp(port, SPP_IFTYPE_RING_STR ":", strlen(SPP_IFTYPE_RING_STR)+1) == 0) {
+ /* RING */
+ type = RING;
+ no_str = &port[strlen(SPP_IFTYPE_RING_STR)+1];
+ } else {
+ /* OTHER */
+ RTE_LOG(ERR, APP, "Unknown interface type. (port = %s)\n", port);
+ return -1;
+ }
+
+ /* Change type of number of interface */
+ int ret_no = strtol(no_str, &endptr, 0);
+ if (unlikely(no_str == endptr) || unlikely(*endptr != '\0')) {
+ /* No IF number */
+ RTE_LOG(ERR, APP, "No interface number. (port = %s)\n", port);
+ return -1;
+ }
+
+ *if_type = type;
+ *if_no = ret_no;
+
+ RTE_LOG(DEBUG, APP, "Port = %s => Type = %d No = %d\n",
+ port, *if_type, *if_no);
+ return 0;
+}
+
+/**
+ * Generate a formatted string of conbination from interface type and
+ * number and assign to given 'port'
+ */
+int spp_format_port_string(char *port, enum port_type if_type, int if_no)
+{
+ const char* if_type_str;
+
+ switch (if_type) {
+ case PHY:
+ if_type_str = SPP_IFTYPE_NIC_STR;
+ break;
+ case RING:
+ if_type_str = SPP_IFTYPE_RING_STR;
+ break;
+ case VHOST:
+ if_type_str = SPP_IFTYPE_VHOST_STR;
+ break;
+ default:
+ return -1;
+ }
+
+ sprintf(port, "%s:%d", if_type_str, if_no);
+
+ return 0;
+}
+
+/**
+ * Change mac address of 'aa:bb:cc:dd:ee:ff' to int64 and return it
+ */
+int64_t
+spp_change_mac_str_to_int64(const char *mac)
+{
+ int64_t ret_mac = 0;
+ int64_t token_val = 0;
+ int token_cnt = 0;
+ char tmp_mac[SPP_MIN_STR_LEN];
+ char *str = tmp_mac;
+ char *saveptr = NULL;
+ char *endptr = NULL;
+
+ RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s)\n", mac);
+
+ strcpy(tmp_mac, mac);
+ while(1) {
+ /* Split by colon(':') */
+ char *ret_tok = strtok_r(str, ":", &saveptr);
+ if (unlikely(ret_tok == NULL)) {
+ break;
+ }
+
+ /* Check for mal-formatted address */
+ if (unlikely(token_cnt >= ETHER_ADDR_LEN)) {
+ RTE_LOG(ERR, APP, "MAC address format error. (mac = %s)\n",
+ mac);
+ return -1;
+ }
+
+ /* Convert string to hex value */
+ int ret_tol = strtol(ret_tok, &endptr, 16);
+ if (unlikely(ret_tok == endptr) || unlikely(*endptr != '\0')) {
+ break;
+ }
+
+ /* Append separated value to the result */
+ token_val = (int64_t)ret_tol;
+ ret_mac |= token_val << (token_cnt * 8);
+ token_cnt++;
+ str = NULL;
+ }
+
+ RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s => 0x%08lx)\n",
+ mac, ret_mac);
+ return ret_mac;
+}
+
+/**
+ * Return the type of forwarder as a member of enum of spp_component_type
+ */
+enum spp_component_type
+spp_change_component_type(const char *type_str)
+{
+ if(strncmp(type_str, CORE_TYPE_CLASSIFIER_MAC_STR,
+ strlen(CORE_TYPE_CLASSIFIER_MAC_STR)+1) == 0) {
+ /* Classifier */
+ return SPP_COMPONENT_CLASSIFIER_MAC;
+ } else if (strncmp(type_str, CORE_TYPE_MERGE_STR,
+ strlen(CORE_TYPE_MERGE_STR)+1) == 0) {
+ /* Merger */
+ return SPP_COMPONENT_MERGE;
+ } else if (strncmp(type_str, CORE_TYPE_FORWARD_STR,
+ strlen(CORE_TYPE_FORWARD_STR)+1) == 0) {
+ /* Forwarder */
+ return SPP_COMPONENT_FORWARD;
+ }
+ return SPP_COMPONENT_UNUSE;
+}
diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h
index b0da048..90a2886 100644
--- a/src/vf/spp_vf.h
+++ b/src/vf/spp_vf.h
@@ -2,18 +2,42 @@
#define __SPP_VF_H__
#include "common.h"
-#include "spp_config.h"
-#define SPP_CLIENT_MAX 128
+#define SPP_IFTYPE_NIC_STR "phy"
+#define SPP_IFTYPE_VHOST_STR "vhost"
+#define SPP_IFTYPE_RING_STR "ring"
+
+#define SPP_CLIENT_MAX 128
+#define SPP_INFO_AREA_MAX 2
+#define SPP_MIN_STR_LEN 32
+#define SPP_NAME_STR_LEN 128
+
+#define SPP_CHANGE_UPDATE_INTERVAL 10
+
+#define SPP_DEFAULT_CLASSIFIED_SPEC_STR "default"
+#define SPP_DEFAULT_CLASSIFIED_DMY_ADDR_STR "00:00:00:00:00:01"
+#define SPP_DEFAULT_CLASSIFIED_DMY_ADDR 0x010000000000
/*
- * State on core
+ * State on component
*/
enum spp_core_status {
+ SPP_CORE_UNUSE,
SPP_CORE_STOP,
SPP_CORE_IDLE,
SPP_CORE_FORWARD,
- SPP_CORE_STOP_REQUEST
+ SPP_CORE_STOP_REQUEST,
+ SPP_CORE_IDLE_REQUEST
+};
+
+/*
+ * Process type for each component
+ */
+enum spp_component_type {
+ SPP_COMPONENT_UNUSE,
+ SPP_COMPONENT_CLASSIFIER_MAC,
+ SPP_COMPONENT_MERGE,
+ SPP_COMPONENT_FORWARD,
};
/*
@@ -30,34 +54,68 @@ enum spp_classifier_type {
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 type (rx or tx) */
+enum spp_port_rxtx {
+ SPP_PORT_RXTX_NONE,
+ SPP_PORT_RXTX_RX,
+ SPP_PORT_RXTX_TX,
+ SPP_PORT_RXTX_ALL,
+};
+
+/* command setting type */
+enum spp_command_action {
+ SPP_CMD_ACTION_NONE,
+ SPP_CMD_ACTION_START,
+ SPP_CMD_ACTION_STOP,
+ SPP_CMD_ACTION_ADD,
+ SPP_CMD_ACTION_DEL,
+};
+
+/*
+ * Interface information structure
+ */
+struct spp_port_index {
+ enum port_type if_type;
+ int if_no;
};
/*
- * Port info on core
+ * Port info
*/
-struct spp_core_port_info {
+struct spp_port_info {
enum port_type if_type;
int if_no;
int dpdk_port;
uint64_t mac_addr;
- char mac_addr_str[SPP_CONFIG_STR_LEN];
+ char mac_addr_str[SPP_MIN_STR_LEN];
};
/*
+ * Component info
+ */
+struct spp_component_info {
+ char name[SPP_NAME_STR_LEN];
+ enum spp_component_type type;
+ unsigned int lcore_id;
+ int component_id;
+ int num_rx_port;
+ int num_tx_port;
+ struct spp_port_info *rx_ports[RTE_MAX_ETHPORTS];
+ struct spp_port_info *tx_ports[RTE_MAX_ETHPORTS];
+};
+
+#if 0
+/*
* 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;
- int num_tx_port;
- struct spp_core_port_info rx_ports[RTE_MAX_ETHPORTS];
- struct spp_core_port_info tx_ports[RTE_MAX_ETHPORTS];
+ enum spp_core_status status;
+ int num_component;
+ int component_id[SPP_CONFIG_CORE_MAX];
};
+#endif
/*
* Get client ID
@@ -69,11 +127,33 @@ int spp_get_client_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, const struct spp_config_port_info *port);
+int spp_update_classifier_table(
+ enum spp_command_action action,
+ enum spp_classifier_type type,
+ const char *data,
+ const struct spp_port_index *port);
+
+/*
+ * Update component
+ * OK : SPP_RET_OK(0)
+ * NG : SPP_RET_NG(-1)
+ */
+int spp_update_component(
+ enum spp_command_action action,
+ const char *name, unsigned int lcore_id,
+ enum spp_component_type type);
+
+/*
+ * Update port
+ * OK : SPP_RET_OK(0)
+ * NG : SPP_RET_NG(-1)
+ */
+int spp_update_port(
+ enum spp_command_action action,
+ const struct spp_port_index *port,
+ enum spp_port_rxtx rxtx,
+ const char *name);
/*
* Flush SPP component
@@ -87,7 +167,7 @@ typedef int (*spp_iterate_classifier_element_proc)(
void *opaque,
enum spp_classifier_type type,
const char *data,
- const struct spp_config_port_info *port);
+ const struct spp_port_index *port);
/* iterate classifier table parameters */
struct spp_iterate_classifier_table_params {
@@ -100,4 +180,79 @@ struct spp_iterate_classifier_table_params {
*/
int spp_iterate_classifier_table(struct spp_iterate_classifier_table_params *params);
+/* Get core status */
+enum spp_core_status spp_get_core_status(unsigned int lcore_id);
+
+/* Get component type of target core */
+enum spp_component_type spp_get_component_type(unsigned int lcore_id);
+
+/* Get component type being updated on target core */
+enum spp_component_type spp_get_component_type_update(unsigned int lcore_id);
+
+/*
+ * Get core ID of target component
+ * RETURN : core ID
+ */
+unsigned int spp_get_component_core(int component_id);
+
+/*
+ * Check core index change
+ * RETURN : True if index has changed.
+ */
+int spp_check_core_index(unsigned int lcore_id);
+
+/*
+ * Get name matching component ID
+ * OK : component ID
+ * NG : SPP_RET_NG
+ */
+int spp_get_component_id(const char *name);
+
+/**
+ * Check mac address used on the port for registering or removing
+ * RETURN : True if target MAC address matches MAC address of port.
+ */
+int spp_check_mac_used_port(uint64_t mac_addr, enum port_type if_type, int if_no);
+
+/*
+ * Check if port has been added.
+ * RETURN : True if port has been added.
+ */
+int spp_check_added_port(enum port_type if_type, int if_no);
+
+/*
+ * Check if component is using port.
+ * OK : match component ID
+ * NG : SPP_RET_NG
+ */
+int spp_check_used_port(enum port_type if_type, int if_no, enum spp_port_rxtx rxtx);
+
+/*
+ * Change mac address string to int64
+ * OK : int64 that store mac address
+ * NG : -1
+ */
+int64_t spp_change_mac_str_to_int64(const char *mac);
+
+/*
+ * Extract if-type/if-number from port string
+ *
+ * OK : 0
+ * NG : -1
+ */
+int spp_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_format_port_string(char *port, enum port_type if_type, int if_no);
+
+/*
+ * Change component type from string to type value.
+ */
+enum spp_component_type spp_change_component_type(const char *type_str);
+
#endif /* __SPP_VF_H__ */
--
1.9.1
More information about the spp
mailing list