summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/FindDPDK.cmake2
-rw-r--r--service/CMakeLists.txt2
-rw-r--r--service/include/sc_common.h4
-rw-r--r--service/include/sc_vdev.h16
-rw-r--r--service/src/core.c31
-rw-r--r--service/src/phydev.c32
-rw-r--r--service/src/swdirect.c203
-rw-r--r--service/src/vdev.c53
8 files changed, 210 insertions, 133 deletions
diff --git a/cmake/FindDPDK.cmake b/cmake/FindDPDK.cmake
index 046a5fd..60539d3 100644
--- a/cmake/FindDPDK.cmake
+++ b/cmake/FindDPDK.cmake
@@ -106,7 +106,7 @@ endif()
# Additional library
file(GLOB DPDK_LIBRARY_GEN "${DPDK_LIBRARY_DIR}/librte*.a" "${DPDK_LIBRARY_DIR}/libeth*.a")
-set(DPDK_LIBRARY -Wl,--whole-archive ${DPDK_LIBRARY_GEN} -Wl,--no-whole-archive rt m dl)
+set(DPDK_LIBRARY -Wl,--whole-archive ${DPDK_LIBRARY_GEN} -Wl,--no-whole-archive rt m dl pcap)
# Force Include
set(DPDK_FORCE_INCLUDE "-include ${DPDK_INCLUDE_DIR}/rte_config.h")
diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt
index 6910dde..5f86d34 100644
--- a/service/CMakeLists.txt
+++ b/service/CMakeLists.txt
@@ -5,7 +5,7 @@ include_directories(${DPDK_INCLUDE_DIR})
include_directories(include)
add_definitions(${DPDK_C_PREDEFINED})
-add_executable(zcpd src/core.c src/phydev.c src/mrb.c src/ldbc.c src/hwinfo.c src/vdev.c)
+add_executable(zcpd src/core.c src/phydev.c src/mrb.c src/ldbc.c src/hwinfo.c src/vdev.c src/swdirect.c)
target_link_libraries(zcpd MESA_prof_load_static ${DPDK_LIBRARY} ${SYSTEMD_LIBRARIES})
target_link_libraries(zcpd rt pthread dl infra)
target_include_directories(zcpd INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/")
diff --git a/service/include/sc_common.h b/service/include/sc_common.h
index ba2369d..25dce4f 100644
--- a/service/include/sc_common.h
+++ b/service/include/sc_common.h
@@ -67,6 +67,7 @@ TAILQ_HEAD(sc_ctrlzone_list, sc_ctrlzone);
struct phydev_main;
struct hwinfo_main;
struct vdev_main;
+struct sw_direct_main;
/* Service Instance */
struct sc_main
@@ -96,6 +97,9 @@ struct sc_main
struct mrb_main * mrb_pool_main;
/* ���豸���� */
struct vdev_main * vdev_main;
+
+ /* ����ģ�� --- ��·���� */
+ struct sw_direct_main * sw_direct_main;
};
struct sc_main * sc_main_get(); \ No newline at end of file
diff --git a/service/include/sc_vdev.h b/service/include/sc_vdev.h
index 16ab005..ff18a41 100644
--- a/service/include/sc_vdev.h
+++ b/service/include/sc_vdev.h
@@ -47,13 +47,15 @@ struct vdev
struct vdev * vdev_lookup(struct vdev_main * v_main, const char * symbol);
// ���豸������ѯ
-int vdev_iterate(struct vdev_main * v_main, struct vdev ** iterate);
+int vdev_iterate(struct vdev_main * v_main, struct vdev ** vdev_result, unsigned int * next);
// �������豸��IP��ַ
-int vdev_set_inaddr(struct vdev * vdev, struct in_addr in_addr, struct in_addr in_mask);
+int vdev_set_inaddr(struct vdev * vdev, struct in_addr in_addr, struct in_addr in_mask,
+ struct in_addr gateway);
// ��ȡ���豸��IP��ַ
-int vdev_get_inaddr(struct vdev * vdev, struct in_addr * in_addr, struct in_addr * in_mask);
+int vdev_get_inaddr(struct vdev * vdev, struct in_addr * in_addr, struct in_addr * in_mask,
+ struct in_addr * gateway);
// �������豸��MTU
int vdev_set_mtu(struct vdev * vdev, unsigned int mtu);
@@ -83,4 +85,10 @@ int vdev_data_create(struct vdev_main* v_main, const char * symbol,
unsigned int sz_tunnel, unsigned int sz_buffer,
struct rte_mempool * indirect_pool);
-int vdev_main_init(struct sc_main * sc); \ No newline at end of file
+int vdev_main_init(struct sc_main * sc);
+
+int vdev_usercfg_query_vdev_list(struct sc_main * sc, const char * str_vdev_type,
+ char vdevsyms[MR_SYMBOL_MAX][MR_VDEV_MAX], unsigned int * nr_vdevsyms);
+
+int vdev_usercfg_query_vdev_setup(struct sc_main * sc, const char * devsym,
+ unsigned int * sz_tunnel, unsigned int * sz_buffer); \ No newline at end of file
diff --git a/service/src/core.c b/service/src/core.c
index b0fcd52..153b856 100644
--- a/service/src/core.c
+++ b/service/src/core.c
@@ -47,10 +47,8 @@ const char service_git_version[] = "";
#endif
unsigned int g_logger_to_stdout = 1;
-unsigned int g_logger_level = LOG_DEBUG;
+unsigned int g_logger_level = LOG_INFO;
-extern void * sc_runtime_thread(void * args);
-extern void sc_stage_config(struct sc_main * instance);
static struct sc_main * g_sc_main = NULL;
/* 写入Command参数 */
@@ -163,6 +161,17 @@ static void sc_eal_init(struct sc_main * sc, const char * cmd)
WRITE_ARG(cmd);
+ /* 读CPU掩码 */
+ char str_cores[MR_STRING_MAX];
+ ret = MESA_load_profile_string_nodef(sc->local_cfgfile, "service",
+ "iocore", str_cores, sizeof(str_cores));
+
+ if (ret >= 0)
+ {
+ WRITE_ARG("-l");
+ WRITE_ARG(str_cores);
+ }
+
char str_virtaddr[MR_STRING_MAX];
ret = MESA_load_profile_string_nodef(sc->local_cfgfile, "eal",
"virtaddr", str_virtaddr, sizeof(str_virtaddr));
@@ -185,11 +194,19 @@ static void sc_eal_init(struct sc_main * sc, const char * cmd)
ret = rte_eal_init(eal_argc, eal_argv);
MR_VERIFY_2(ret >= 0, "Cannot init EAL Enviorment, Failed");
+ /* After EAL, copy some parameters to sc_main */
+ unsigned int lcore_id = 0;
+ RTE_LCORE_FOREACH(lcore_id)
+ {
+ sc->cpu_mask |= 1ULL << lcore_id;
+ }
+
return;
}
extern int hwinfo_init(struct sc_main * sc);
extern int phydev_init(struct sc_main * sc);
+extern int sw_direct_init(struct sc_main * sc);
int main(int argc, char * argv[])
{
@@ -278,7 +295,13 @@ int main(int argc, char * argv[])
MR_ERROR("Virtual devices initialization failed. ");
exit(EXIT_FAILURE);
}
-
+
+ if(sw_direct_init(sc) != RT_SUCCESS)
+ {
+ MR_ERROR("Direct switch module initialization failed. ");
+ exit(EXIT_FAILURE);
+ }
+
sc_launch_thread(sc);
assert(0);
return 0;
diff --git a/service/src/phydev.c b/service/src/phydev.c
index 2e836b1..cc7a754 100644
--- a/service/src/phydev.c
+++ b/service/src/phydev.c
@@ -87,25 +87,15 @@ static int phydev_info_dump(struct phydev * dev)
ether_format_addr(str_phy_addr, sizeof(str_phy_addr),
&dev->info.phy_ether_addr);
- MR_INFO(
- "\n"
- "Physical Device %s: PortID = %d\n"
- " Physical Hwaddr : %s\n"
- " MTU: %u\n"
- " Promisc : %s\n"
- " VLAN-Filter: %s\n"
- " VLAN-Strip: %s\n"
- " Drop-En: %s\n"
- " RSSMode: %s\n",
- dev->symbol, dev->port_id,
- str_phy_addr,
- dev->mtu,
- __str_enable_or_disable(dev->promisc),
- __str_enable_or_disable(dev->en_vlan_filter),
- __str_enable_or_disable(dev->en_vlan_strip),
- __str_enable_or_disable(dev->en_drop),
- __str_rssmode(dev->info.rssmode));
-
+ MR_INFO(" ");
+ MR_INFO("Physical Device %s: PortID = %d", dev->symbol, dev->port_id);
+ MR_INFO(" Physical Hwaddr : %s", str_phy_addr);
+ MR_INFO(" MTU: %u", dev->mtu);
+ MR_INFO(" Promisc : %s", __str_enable_or_disable(dev->promisc));
+ MR_INFO(" VLAN-Filter: %s", __str_enable_or_disable(dev->en_vlan_filter));
+ MR_INFO(" VLAN-Strip: %s", __str_enable_or_disable(dev->en_vlan_strip));
+ MR_INFO(" Drop-En: %s", __str_enable_or_disable(dev->en_drop));
+ MR_INFO(" RSSMode: %s", __str_rssmode(dev->info.rssmode));
return 0;
}
@@ -416,7 +406,6 @@ struct phydev * phydev_alloc(struct phydev_main * phydev_main, unsigned int port
return phydev;
}
-
/* 早期设备扫描,从HWFILE中获取设备定义的信息 */
static int phydev_early_scan(struct sc_main * sc, struct phydev_main * phydev_main)
{
@@ -454,7 +443,7 @@ static int phydev_scan(struct phydev_main * phydev_main)
char str_macaddr[MR_SYMBOL_MAX];
ether_format_addr(str_macaddr, sizeof(str_macaddr), &phydev->info.phy_ether_addr);
- MR_INFO("PCI device scan: physical device %s, PORT_ID=%d, MAC: %s",
+ MR_DEBUG("PCI device scan: physical device %s, PORT_ID=%d, MAC: %s",
phydev->symbol, port_id, str_macaddr);
}
@@ -498,7 +487,6 @@ int phydev_init(struct sc_main * sc)
return RT_ERR;
}
- MR_INFO("Physical devices initialization successfully. ");
return RT_SUCCESS;
}
diff --git a/service/src/swdirect.c b/service/src/swdirect.c
index 6b557a1..165fcdf 100644
--- a/service/src/swdirect.c
+++ b/service/src/swdirect.c
@@ -1,90 +1,115 @@
-/*
- * ǰ�ý�����������·����
- * ������������������һһ��Ӧ��ӳ�佻��
- *
- * \author Qiuwen Lu
- * \date 2017-02-21
- */
-
-
-#include <common.h>
-#include <sc_common.h>
-#include <sc_phydev.h>
-#include <MESA_prof_load.h>
-#include <unistd.h>
-#include <rte_string_fns.h>
-#include "sc_vdev.h"
-
-struct __dev_pair
-{
- struct phydev * phydev;
- struct vdev * vdev;
-};
-
-#define SW_DIRECT_MAX_PAIR 256
-
-struct sw_direct_main
-{
- struct __dev_pair dev_pair[SW_DIRECT_MAX_PAIR];
- unsigned int nr_dev_pair;
-};
-
-static int __vdev_setup(struct sc_main * sc, const char * vdevsym)
-{
- /* ��ѯ�����豸��Ӧ�����豸 */
- struct phydev * phydev = phydev_lookup(sc->phydev_main, vdevsym);
- if(phydev == NULL)
- {
- MR_ERROR("physical device corresponding to virtual "
- "device %s does not existed.", vdevsym); return RT_ERR;
- }
-
- /* ��������� */
- unsigned int nr_rxstream = mask_popcnt(sc->cpu_mask);
- unsigned int nr_txstream = mask_popcnt(sc->cpu_mask);
-
- /* ������Ӧ�������豸 */
- struct vdev vdev_create_param = { 0 };
- struct vdev * vdev = vdev_data_create(sc->vdev_main, vdevsym,
- nr_rxstream, nr_txstream,
-
-
-
-
- return RT_SUCCESS;
-}
-
-
-int sw_direct_init(struct sc_main * sc)
-{
- const char * cfgfile = sc->local_cfgfile;
- int ret = 0;
-
- /* �������豸���ã����豸�������豸һһ��Ӧ */
- char str_direct_devices[MR_STRING_MAX];
- MESA_load_profile_string_def(cfgfile, "device", "sw_direct_device",
- str_direct_devices, sizeof(str_direct_devices), "");
-
- /* */
-
-
- char * str_vdev_symbol[MR_TOKENS_MAX];
- int nr_str_tokens = rte_strsplit(str_direct_devices, sizeof(str_direct_devices),
- str_vdev_symbol, MR_TOKENS_MAX, ',');
-
- if (nr_str_tokens <= 0)
- {
- MR_INFO("No devices used by direct-line switch module. ");
- return RT_SUCCESS;
- }
-
- for(int i = 0; i < nr_str_tokens; i++)
- {
- ret = __vdev_setup(sc, str_vdev_symbol[i]);
- if (ret != RT_SUCCESS) return ret;
- }
-
-
-
- return RT_SUCCESS;
+/*
+ * 前置交换机——线路交换
+ * 物理网卡和虚拟网卡一一对应,映射交换
+ *
+ * \author Qiuwen Lu
+ * \date 2017-02-21
+ */
+
+
+#include <common.h>
+#include <sc_common.h>
+#include <sc_phydev.h>
+#include <rte_malloc.h>
+#include <sc_vdev.h>
+#include <sc_mrb.h>
+
+struct __dev_pair
+{
+ struct phydev * phydev;
+ struct vdev * vdev;
+};
+
+#define SW_DIRECT_MAX_PAIR 256
+
+struct sw_direct_main
+{
+ struct __dev_pair dev_pair[SW_DIRECT_MAX_PAIR];
+ unsigned int nr_dev_pair;
+};
+
+static int __vdev_setup(struct sc_main * sc, const char * vdevsym)
+{
+ /* 查询虚拟设备对应物理设备 */
+ struct phydev * phydev = phydev_lookup(sc->phydev_main, vdevsym);
+ if(phydev == NULL)
+ {
+ MR_ERROR("physical device corresponding to virtual "
+ "device %s does not existed.", vdevsym); return RT_ERR;
+ }
+
+ /* 计算队列数 */
+ unsigned int nr_rxstream = mask_popcnt(sc->cpu_mask);
+ unsigned int nr_txstream = mask_popcnt(sc->cpu_mask);
+
+ /* 查询队列缓冲区大小 */
+ unsigned int sz_tunnel, sz_buffer;
+ vdev_usercfg_query_vdev_setup(sc, vdevsym, &sz_tunnel, &sz_buffer);
+
+ /* 查询Indirect Pool,使用与物理设备对应的Indirect Pool */
+ //TODO: 对应关系
+
+ struct rte_mempool * indirect_pool;
+ indirect_pool = mrb_indirect_mempool_locate(sc->mrb_pool_main, vdevsym, 0, 0);
+ if(indirect_pool == NULL)
+ {
+ MR_ERROR("Indirect mempool for virtual device %s is not existed. ", vdevsym);
+ goto err;
+ }
+
+ /* 创建对应的虚拟设备 */
+ int ret = vdev_data_create(sc->vdev_main, vdevsym, nr_rxstream, nr_txstream,
+ sz_tunnel, sz_buffer, indirect_pool);
+
+ if (ret < 0) goto err;
+
+ /* 加入转发列表中 */
+ struct sw_direct_main * sw_main = sc->sw_direct_main;
+ struct vdev * vdev = vdev_lookup(sc->vdev_main, vdevsym);
+ MR_VERIFY_2(vdev != NULL, "vdev_lookup() returns NULL.");
+
+ sw_main->dev_pair[sw_main->nr_dev_pair].phydev = phydev;
+ sw_main->dev_pair[sw_main->nr_dev_pair].vdev = vdev;
+ sw_main->nr_dev_pair++;
+
+ /* 显示虚设备信息 */
+ MR_INFO(" ");
+ MR_INFO("In direct forward switch, virtual device %s: ", vdevsym);
+ MR_INFO(" linked physical devices : %s", phydev->symbol);
+ MR_INFO(" RX queues by service : %d", nr_rxstream);
+ MR_INFO(" TX queues by service : %d", nr_txstream);
+ MR_INFO(" deliver tunnel size : %d", sz_tunnel);
+ MR_INFO(" deliver tunnel buffer : %d", sz_buffer);
+
+ return RT_SUCCESS;
+
+err:
+ MR_ERROR("Creating virtual device %s failed. ", vdevsym);
+ return RT_ERR;
+}
+
+
+int sw_direct_init(struct sc_main * sc)
+{
+ sc->sw_direct_main = ZMALLOC(sizeof(struct sw_direct_main));
+ MR_VERIFY_MALLOC(sc->sw_direct_main);
+
+ /* 加载虚设备配置,虚设备和物理设备一一对应 */
+ char vdevsyms[MR_SYMBOL_MAX][MR_VDEV_MAX];
+ unsigned int nr_vdevsyms = 0;
+ vdev_usercfg_query_vdev_list(sc, "sw_direct_device", vdevsyms, &nr_vdevsyms);
+
+ if(nr_vdevsyms == 0)
+ {
+ MR_INFO("No devices used by direct-forward switchs, Ignore. ");
+ return RT_SUCCESS;
+ }
+
+ for(int i = 0; i < nr_vdevsyms; i++)
+ {
+ int ret = __vdev_setup(sc, vdevsyms[i]);
+ if (ret != RT_SUCCESS) return ret;
+ }
+
+ return RT_SUCCESS;
} \ No newline at end of file
diff --git a/service/src/vdev.c b/service/src/vdev.c
index 8fe85ab..9d84873 100644
--- a/service/src/vdev.c
+++ b/service/src/vdev.c
@@ -13,6 +13,7 @@
#include <sys/queue.h>
#include <rte_ring.h>
#include <rte_malloc.h>
+#include <rte_string_fns.h>
#include <assert.h>
#include <common.h>
#include <vnode.h>
@@ -132,14 +133,24 @@ err_out:
/* =========================================================================================== */
-struct vdev * vdev_lookup(struct vdev_main * v_main, const char * symbol)
+
+int vdev_iterate(struct vdev_main * v_main, struct vdev ** vdev_result, unsigned int * next)
{
- return NULL;
+ if (*next >= v_main->vdev_max_idx) return -ENOENT;
+ else *vdev_result = &v_main->_vdev_array[(*next)++]->vdev;
+ return 0;
}
-int vdev_iterate(struct vdev_main * v_main, struct vdev ** iterate)
+struct vdev * vdev_lookup(struct vdev_main * v_main, const char * symbol)
{
- return 0;
+ struct vdev * vdev = NULL; unsigned int next = 0;
+ while(vdev_iterate(v_main, &vdev, &next) >= 0)
+ {
+ if (strncmp(vdev->symbol, symbol, sizeof(vdev->symbol)) != 0) continue;
+ return vdev;
+ }
+
+ return NULL;
}
// 设置虚设备的IP地址
@@ -256,6 +267,7 @@ int vdev_data_create(struct vdev_main* v_main, const char * symbol,
vdev_info = &_vdev->vdev;
/* 填充_vdev信息 */
+ snprintf(vdev_info->symbol, sizeof(vdev_info->symbol), "%s", symbol);
_vdev->nr_rxstream = nr_rxstream;
_vdev->nr_txstream = nr_txstream;
@@ -334,18 +346,18 @@ errout:
#undef _ERR_VERIFY
}
-#include <rte_string_fns.h>
+
/* 虚设备用户配置查询 */
int vdev_usercfg_query_vdev_list(struct sc_main * sc, const char * str_vdev_type,
char vdevsyms[MR_SYMBOL_MAX][MR_VDEV_MAX], unsigned int * nr_vdevsyms)
{
- char str_direct_devices[MR_STRING_MAX];
- MESA_load_profile_string_def(sc->local_cfgfile, "device", str_direct_devices,
+ char str_direct_devices[MR_STRING_MAX];
+ MESA_load_profile_string_def(sc->local_cfgfile, "device", str_vdev_type,
str_direct_devices, sizeof(str_direct_devices), "");
-
- char * str_vdev_symbol[MR_TOKENS_MAX];
- int nr_str_tokens = rte_strsplit(str_direct_devices, sizeof(str_direct_devices),
+
+ char * str_vdev_symbol[MR_TOKENS_MAX];
+ int nr_str_tokens = rte_strsplit(str_direct_devices, sizeof(str_direct_devices),
str_vdev_symbol, MR_TOKENS_MAX, ',');
for (int i = 0; i < nr_str_tokens; i++)
@@ -358,9 +370,26 @@ int vdev_usercfg_query_vdev_list(struct sc_main * sc, const char * str_vdev_type
return RT_SUCCESS;
}
-int vdev_usercfg_query_vdev_setup()
+int vdev_usercfg_query_vdev_setup(struct sc_main * sc, const char * devsym,
+ unsigned int * sz_tunnel, unsigned int * sz_buffer)
{
- return 0;
+ unsigned int default_sz_tunnel;
+ unsigned int default_sz_buffer;
+
+ MESA_load_profile_uint_def(sc->local_cfgfile, "device", "sz_tunnel",
+ &default_sz_tunnel, VDEV_DEFAULT_SZ_TUNNEL);
+ MESA_load_profile_uint_def(sc->local_cfgfile, "device", "sz_buffer",
+ &default_sz_buffer, VDEV_DEFAULT_SZ_BUFFER);
+
+ char str_dev_section[MR_SYMBOL_MAX];
+ snprintf(str_dev_section, sizeof(str_dev_section), "device:%s", devsym);
+
+ MESA_load_profile_uint_def(sc->local_cfgfile, str_dev_section, "sz_tunnel",
+ sz_tunnel, default_sz_tunnel);
+ MESA_load_profile_uint_def(sc->local_cfgfile, str_dev_section, "sz_buffer",
+ sz_buffer, default_sz_buffer);
+
+ return RT_SUCCESS;
}
int vdev_main_init(struct sc_main * sc)