diff options
| -rw-r--r-- | cmake/FindDPDK.cmake | 2 | ||||
| -rw-r--r-- | service/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | service/include/sc_common.h | 4 | ||||
| -rw-r--r-- | service/include/sc_vdev.h | 16 | ||||
| -rw-r--r-- | service/src/core.c | 31 | ||||
| -rw-r--r-- | service/src/phydev.c | 32 | ||||
| -rw-r--r-- | service/src/swdirect.c | 203 | ||||
| -rw-r--r-- | service/src/vdev.c | 53 |
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) |
