summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/src
diff options
context:
space:
mode:
authorsharath reddy <bs.reddy@huawei.com>2019-06-04 11:53:49 +0530
committersharath reddy <bs.reddy@huawei.com>2019-06-04 20:38:30 +0530
commit2a42ad20b9730706ad371ae3787d4597c4e42276 (patch)
treefa01cd312586ea007468e7233f94c0ce53d75873 /stacks/lwip_stack/src
parenta826fe833d3f2a8fe2673fa05811fe1a22baf045 (diff)
Feature: 19.04 part-2DMM-2
Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9 Signed-off-by: sharath reddy <bs.reddy@huawei.com>
Diffstat (limited to 'stacks/lwip_stack/src')
-rw-r--r--stacks/lwip_stack/src/CMakeLists.txt61
-rw-r--r--stacks/lwip_stack/src/alarm/CMakeLists.txt38
-rw-r--r--stacks/lwip_stack/src/alarm/alarm.c857
-rw-r--r--stacks/lwip_stack/src/alarm/alarm.h80
-rw-r--r--stacks/lwip_stack/src/alarm/alarm_api.h107
-rw-r--r--stacks/lwip_stack/src/include/common_func.h140
-rw-r--r--stacks/lwip_stack/src/include/common_mem_api.h134
-rw-r--r--stacks/lwip_stack/src/include/common_mem_base_type.h85
-rw-r--r--stacks/lwip_stack/src/include/common_mem_buf.h78
-rw-r--r--stacks/lwip_stack/src/include/common_mem_common.h25
-rw-r--r--stacks/lwip_stack/src/include/common_mem_mbuf.h40
-rw-r--r--stacks/lwip_stack/src/include/common_mem_mempool.h25
-rw-r--r--stacks/lwip_stack/src/include/common_mem_pal_memconfig.h26
-rw-r--r--stacks/lwip_stack/src/include/common_mem_rwlock.h25
-rw-r--r--stacks/lwip_stack/src/include/common_mem_spinlock.h38
-rw-r--r--stacks/lwip_stack/src/include/nsfw_msg.h201
-rw-r--r--stacks/lwip_stack/src/include/nsfw_msg_api.h305
-rw-r--r--stacks/lwip_stack/src/include/nsfw_mt_config.h63
-rw-r--r--stacks/lwip_stack/src/include/nsfw_rti.h49
-rw-r--r--stacks/lwip_stack/src/include/nstack_dmm_adpt.h64
-rw-r--r--stacks/lwip_stack/src/io_adpt/CMakeLists.txt41
-rw-r--r--stacks/lwip_stack/src/io_adpt/dpdk.c2499
-rw-r--r--stacks/lwip_stack/src/mem/CMakeLists.txt36
-rw-r--r--stacks/lwip_stack/src/mem/include/common_mem_memzone.h25
-rw-r--r--stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h204
-rw-r--r--stacks/lwip_stack/src/mem/include/common_sys_config.h46
-rw-r--r--stacks/lwip_stack/src/mem/lib_common_mem/common_api.c163
-rw-r--r--stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c299
-rw-r--r--stacks/lwip_stack/src/mem/lib_common_mem/common_func.c211
-rw-r--r--stacks/lwip_stack/src/mem/lwip_mem_api.c86
-rw-r--r--stacks/lwip_stack/src/mem/lwip_mem_desc.c80
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c44
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h22
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c529
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h70
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c434
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h38
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c989
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h51
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c48
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h22
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c800
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h135
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c843
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h60
-rw-r--r--stacks/lwip_stack/src/nStackMain/CMakeLists.txt66
-rw-r--r--stacks/lwip_stack/src/nStackMain/main.c457
-rw-r--r--stacks/lwip_stack/src/sbr/CMakeLists.txt37
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_err.h190
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_index_ring.c212
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_index_ring.h61
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_protocol_api.h102
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.c87
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.h155
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_socket.c1324
-rw-r--r--stacks/lwip_stack/src/tools/CMakeLists.txt26
-rw-r--r--stacks/lwip_stack/src/tools/dump_tool.c611
-rw-r--r--stacks/lwip_stack/src/tools/dump_tool.h81
58 files changed, 13625 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/CMakeLists.txt b/stacks/lwip_stack/src/CMakeLists.txt
new file mode 100644
index 0000000..1bf74ec
--- /dev/null
+++ b/stacks/lwip_stack/src/CMakeLists.txt
@@ -0,0 +1,61 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+SET(RTP_DIRECTORIES "${PROJECT_SOURCE_DIR}/src/include/")
+
+INCLUDE_DIRECTORIES(
+ framework/log/
+ framework/include/
+ framework/common/include/
+ framework/common/base/include/
+ ${RTP_DIRECTORIES}
+ ${RTP_DIRECTORIES}/generic
+ ../../SecureC/include/
+ ../../../thirdparty/glog/glog-0.3.5/src/
+)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fPIC -m64 -mssse3 -std=gnu89")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wshadow -Wfloat-equal -Wformat=2")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector -fstack-protector-all")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,relro,-z,now -Wl,--disable-new-dtags,--rpath,../lib64")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack -mcmodel=medium")
+
+if(WITH_HAL_LIB)
+SET(RTP_CONFIG ${PROJECT_SOURCE_DIR}/src/include/rtp_config.h)
+else()
+ SET(RTP_CONFIG ${CMAKE_CURRENT_LIST_DIR}/mem/include/common_sys_config.h)
+endif()
+SET(COMPLE_CONFIG ${CMAKE_CURRENT_LIST_DIR}/../../../src/framework/include/common/compile_config.h)
+ADD_DEFINITIONS(-include ${RTP_CONFIG})
+ADD_DEFINITIONS(-include ${COMPLE_CONFIG})
+ADD_DEFINITIONS(-D_GNU_SOURCE)
+ADD_DEFINITIONS(-DDPDK_MODULE=0)
+#ADD_DEFINITIONS(-DNSTACK_RSRDMA)
+LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC})
+
+if(WITH_SECUREC_LIB)
+LINK_LIBRARIES(pthread dl securec)
+else()
+LINK_LIBRARIES(pthread dl)
+endif()
+
+#ADD_SUBDIRECTORY(maintain)
+ADD_SUBDIRECTORY(sbr)
+ADD_SUBDIRECTORY(io_adpt)
+ADD_SUBDIRECTORY(nStackMain)
+ADD_SUBDIRECTORY(tools)
+ADD_SUBDIRECTORY(alarm)
+ADD_SUBDIRECTORY(mem)
diff --git a/stacks/lwip_stack/src/alarm/CMakeLists.txt b/stacks/lwip_stack/src/alarm/CMakeLists.txt
new file mode 100644
index 0000000..d46220a
--- /dev/null
+++ b/stacks/lwip_stack/src/alarm/CMakeLists.txt
@@ -0,0 +1,38 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+FILE(GLOB_RECURSE ALARM *.c)
+
+LINK_LIBRARIES(m dl rt nStackFw)
+if(WITH_SECUREC_LIB)
+INCLUDE_DIRECTORIES(
+ ./
+ ${JSON_C_SRC}
+ ${SECUREC_SRC}
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+)
+else()
+INCLUDE_DIRECTORIES(
+ ./
+ ${JSON_C_SRC}
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+)
+endif()
+ADD_LIBRARY(nStackAlarm STATIC ${ALARM})
diff --git a/stacks/lwip_stack/src/alarm/alarm.c b/stacks/lwip_stack/src/alarm/alarm.c
new file mode 100644
index 0000000..82e7e54
--- /dev/null
+++ b/stacks/lwip_stack/src/alarm/alarm.c
@@ -0,0 +1,857 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "types.h"
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "alarm.h"
+#include "alarm_api.h"
+#include<time.h>
+#include<sys/time.h>
+#include "nsfw_init_api.h"
+#include "nstack_log.h"
+#include "json.h"
+#include "nstack_securec.h"
+#include <stdlib.h>
+#include "nstack_dmm_adpt.h"
+
+char g_vmid[MAX_VMID_LEN + 1] = "agent-node-x";
+
+extern nsfw_timer_info *nsfw_timer_reg_timer(u32 timer_type, void *data,
+ nsfw_timer_proc_fun fun,
+ struct timespec time_left);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+// note:the first element is reserved
+alarm_data g_alarm_data[ALARM_EVENT_MAX] = { };
+
+alarm_result ms_alarm_check_func(void *para)
+{
+ alarm_result ret_alarm;
+ int para_value = (long) para;
+
+ ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_MAIN_ABNORMAL;
+
+ if (para_value == ALARM_PRODUCT)
+ {
+ ret_alarm.alarm_flag_get = ALARM_PRODUCT;
+ }
+ else if (para_value == ALARM_CLEAN)
+ {
+ ret_alarm.alarm_flag_get = ALARM_CLEAN;
+ }
+ else
+ {
+ ret_alarm.alarm_id_get = ALARM_EVENT_MAX;
+ }
+
+ ret_alarm.alarm_reason_get = ALARM_REASON_NSMAIN;
+
+ return ret_alarm;
+
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : period check alarm expire handle function
+********************************************************************/
+
+int ns_alarm_timer_resend_fun(u32 timer_type, void *argv)
+{
+ int i;
+ struct timespec time_left;
+ alarm_data *alarm_value;
+
+ for (i = ALARM_EVENT_BASE; i < ALARM_EVENT_MAX; i++)
+ {
+ alarm_value = &g_alarm_data[i];
+
+ if ((alarm_value->valid_flag == 1)
+ && (alarm_value->send_succ_flag == ALARM_SEND_FAIL))
+ {
+ /* nStack only send nsMain normal alarm */
+ ns_send_alarm_inner(alarm_value->_alarm_id,
+ (void *) (alarm_value->_alarm_flag), 1, 0);
+ }
+ }
+
+ time_left.tv_sec = ALARM_RESEND_TIMER_LENGTH;
+ time_left.tv_nsec = 0;
+ nsfw_timer_info *timer_info =
+ nsfw_timer_reg_timer(0, NULL, ns_alarm_timer_resend_fun, time_left);
+ if (NULL == timer_info)
+ {
+ NSAM_LOGERR("nsfw_timer_reg_timer fail");
+ }
+
+ return 0;
+}
+
+void ns_alarm_set_sendFlag(enum_alarm_id alarmId, int flag)
+{
+ if ((alarmId <= 0) || (alarmId >= ALARM_EVENT_MAX)
+ || (0 == g_alarm_data[alarmId].valid_flag)
+ || ((flag != ALARM_SEND_FAIL) && (flag != ALARM_SEND_SUCC)))
+ {
+ NSAM_LOGERR("alarm_id is invalid or not reg or flag invalid");
+ return;
+ }
+ g_alarm_data[alarmId].send_succ_flag = flag;
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : alarm module init
+********************************************************************/
+int ns_alarm_module_init(void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ enum_alarm_id i = ALARM_EVENT_BASE;
+ alarm_reason j = ALARM_REASON_BEGIN;
+ const char *pst_vm_id = NULL;
+ alarm_para tcp_alarm_para;
+ struct timespec time_left;
+
+ for (i = ALARM_EVENT_BASE; i < ALARM_EVENT_MAX; i++)
+ {
+ g_alarm_data[i]._alarm_type = ALARM_SEND_ONCE;
+
+ for (j = ALARM_REASON_BEGIN; j < ALARM_REASON_MAX; j++)
+ {
+ g_alarm_data[i]._alarm_para.func_alarm_check[j] = NULL;
+ g_alarm_data[i]._alarm_para.alarm_reason_set[j] =
+ ALARM_REASON_MAX;
+ g_alarm_data[i].alarm_time_laps[j] = 0;
+ }
+ g_alarm_data[i]._alarm_para.period_alarm.time_length = 0;
+ g_alarm_data[i]._alarm_id = i;
+ g_alarm_data[i].valid_flag = 0;
+ g_alarm_data[i]._alarm_flag = ALARM_CLEAN;
+ g_alarm_data[i].alarm_reason_cnt = 0;
+ g_alarm_data[i].send_succ_flag = ALARM_SEND_SUCC;
+ }
+
+ switch (proc_type)
+ {
+ case NSFW_PROC_MAIN:
+ case NSFW_PROC_CTRL:
+
+ /* modify ip address to vm id */
+ pst_vm_id = getenv("VM_ID");
+
+ if (INVALID_STR_LEN(pst_vm_id, MIN_VM_ID_LEN, MAX_VM_ID_LEN))
+ {
+ NSAM_LOGWAR
+ ("invalid VM_ID,please check env VM_ID]vm_id=%s, proc_type=%u",
+ pst_vm_id, proc_type);
+ }
+ else
+ {
+ int retVal = strncpy_s(g_vmid, MAX_VMID_LEN + 1, pst_vm_id,
+ strlen(pst_vm_id));
+
+ if (EOK != retVal)
+ {
+ NSAM_LOGERR("STRNCPY_S failed]ret=%d", retVal);
+ }
+ }
+
+ tcp_alarm_para.period_alarm.time_length = 0; /* 5 second period */
+ tcp_alarm_para.alarm_reason_count = 1; /*both resource */
+
+ tcp_alarm_para.func_alarm_check[0] = ms_alarm_check_func;
+ tcp_alarm_para.alarm_reason_set[0] = ALARM_REASON_NSMAIN;
+ (void) ns_reg_alarm(ALARM_EVENT_NSTACK_MAIN_ABNORMAL,
+ ALARM_SEND_ONCE, &tcp_alarm_para);
+
+ time_left.tv_sec = ALARM_INIT_RESEND_TIMER_LENGTH;
+ time_left.tv_nsec = 0;
+ nsfw_timer_info *timer_info =
+ nsfw_timer_reg_timer(0, NULL, ns_alarm_timer_resend_fun,
+ time_left);
+ if (NULL == timer_info)
+ {
+ NSAM_LOGERR("nsfw_timer_reg_timer fail");
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+#define JSON_NEW_OBJ(obj, cb, para1, para2)\
+ {\
+ obj = json_object_new_object();\
+ if (obj == NULL)\
+ {\
+ (void)cb(para1);\
+ (void)cb(para2);\
+ return -1;\
+ }\
+ }
+
+#define JSON_NEW_STRING_OBJ(str, obj, cb, para1, para2)\
+ {\
+ obj = json_object_new_string((str));\
+ if (obj == NULL)\
+ {\
+ (void)cb(para1);\
+ (void)cb(para2);\
+ return -1;\
+ }\
+ }
+
+#define JSON_NEW_STRING_OBJ_1(val, obj, cb, para1, para2,para3)\
+ {\
+ obj = json_object_new_string((val));\
+ if (obj == NULL)\
+ {\
+ (void)cb(para1);\
+ (void)cb(para2);\
+ (void)cb(para3);\
+ return -1;\
+ }\
+ }
+
+#define JSON_NEW_INT_OBJ(val, obj, cb, para1, para2)\
+ {\
+ obj = json_object_new_int((val));\
+ if (obj == NULL)\
+ {\
+ (void)cb(para1);\
+ (void)cb(para2);\
+ return -1;\
+ }\
+ }
+
+/*****************************************************************************
+* Prototype : ns_get_alarm_body
+* Description : get body by alarm parameter
+* Input : char *buf
+* int buf_len
+* alarm_result alarm_res
+* Output : None
+* Return Value : int
+*****************************************************************************/
+int ns_get_alarm_body(char *buf, int buf_len, alarm_result alarm_res)
+{
+#define ALARM_NAME_LENGTH 100
+#define COMPONENT_NAME "nStack"
+ int retVal;
+ size_t str_len;
+ int alarm_id = alarm_res.alarm_id_get + 27000;
+ struct timeval t_val;
+ struct tm now_time;
+ char *alarm_string = NULL, *alarm_reason_info = NULL, *alarm_desc = NULL;
+ json_object *temp_jso = NULL, *alarm_info = NULL;
+ alarm_info_s_out *alarmpara_out = NULL;
+ int perceivedSeverity_value = 0;
+ char *action_string = NULL;
+ if (buf == NULL || (buf_len < (int) sizeof(alarm_info_s_out)))
+ {
+ NSAM_LOGERR("input para invalid");
+ return -1;
+ }
+ alarmpara_out = (alarm_info_s_out *) buf;
+
+ /*use sizeof(alarmpara_out->alarmId) instead of devil figure 16 */
+ retVal =
+ sprintf_s(alarmpara_out->alarmId, sizeof(alarmpara_out->alarmId),
+ "%d", alarm_id);
+ if (-1 == retVal)
+ {
+ NSAM_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return -1;
+ }
+
+ (void) gettimeofday(&t_val, NULL);
+ time_t t_sec = (time_t) t_val.tv_sec;
+ /*return value check */
+ if (NULL == localtime_r(&t_sec, &now_time))
+ {
+ NSAM_LOGERR("localtime_r failed]");
+ return -1;
+ }
+
+ /*use sizeof(alarmpara_out->alarmtime) instead of devil figure 32 */
+ retVal =
+ sprintf_s(alarmpara_out->alarmtime, sizeof(alarmpara_out->alarmtime),
+ "%4d%02d%02d%02d%02d%02d%06ld", now_time.tm_year + 1900,
+ now_time.tm_mon + 1, now_time.tm_mday, now_time.tm_hour,
+ now_time.tm_min, now_time.tm_sec, (long) t_val.tv_usec);
+ if (-1 == retVal)
+ {
+ NSAM_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return -1;
+ }
+
+ retVal =
+ strncpy_s(alarmpara_out->comptentname,
+ sizeof(alarmpara_out->comptentname), COMPONENT_NAME,
+ strlen(COMPONENT_NAME));
+ if (EOK != retVal)
+ {
+ NSAM_LOGERR("STRNCPY_S failed]ret=%d", retVal);
+ return -1;
+ }
+
+ switch (alarm_res.alarm_reason_get)
+ {
+ case ALARM_REASON_SOCKET:
+ /* alarmName and reason info is incorrect */
+ alarm_reason_info = "socketResource";
+ if (alarm_res.alarm_flag_get == ALARM_PRODUCT)
+ {
+ alarm_string = "networkResourceOverload";
+ alarm_desc = "more than 80 percent used";
+ perceivedSeverity_value = 2;
+ action_string = "alarm";
+ }
+ else
+ {
+ alarm_string = "networkResourceNormal";
+ alarm_desc = "less than 60 percent used";
+ perceivedSeverity_value = 5;
+ action_string = "clear";
+ }
+
+ break;
+ case ALARM_REASON_MSG_BUF:
+ alarm_reason_info = "SendBufResource";
+ if (alarm_res.alarm_flag_get == ALARM_PRODUCT)
+ {
+ alarm_string = "networkResourceOverload";
+ alarm_desc = "more than 80 percent used";
+ perceivedSeverity_value = 2;
+ action_string = "alarm";
+ }
+ else
+ {
+ alarm_string = "networkResourceNormal";
+ alarm_desc = "less than 60 percent used";
+ perceivedSeverity_value = 5;
+ action_string = "clear";
+ }
+
+ break;
+ case ALARM_REASON_NSMAIN:
+ /* process status alarm change from event to alarm/clear */
+ alarm_reason_info = "networkProcStatus";
+ if (alarm_res.alarm_flag_get == ALARM_PRODUCT)
+ {
+ alarm_string = "network-data-down";
+ alarm_desc = "networkProcDown";
+ perceivedSeverity_value = 2;
+ action_string = "alarm";
+ }
+ else
+ {
+ alarm_string = "network-data-up";
+ alarm_desc = "networkProcUp";
+ perceivedSeverity_value = 5;
+ action_string = "clear";
+ }
+
+ break;
+ default:
+ NSAM_LOGERR("alarm_reason incorrect]ret=%d",
+ alarm_res.alarm_reason_get);
+ return -1;
+ }
+
+ str_len = 0;
+
+ json_object *alarmlist = json_object_new_object();
+ if (NULL == alarmlist)
+ {
+ NSAM_LOGERR("alarmlist is NULL");
+ return -1;
+ }
+
+ json_object *alarmItem = json_object_new_object();
+
+ if (NULL == alarmItem)
+ {
+ NSAM_LOGERR("alarmItem is NULL");
+ (void) json_object_put(alarmlist);
+ return -1;
+ }
+
+ JSON_NEW_STRING_OBJ("ICTS_BASE=1", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "neDN", temp_jso);
+ JSON_NEW_STRING_OBJ("service", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "neType", temp_jso);
+ JSON_NEW_STRING_OBJ("ICTS_BASE", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "neName", temp_jso);
+ JSON_NEW_STRING_OBJ("service", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "objectClass", temp_jso);
+ JSON_NEW_STRING_OBJ("nStack", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "moDN", temp_jso);
+ JSON_NEW_STRING_OBJ("nStack", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "moName", temp_jso);
+ JSON_NEW_STRING_OBJ("default", temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "userId", temp_jso);
+
+ JSON_NEW_INT_OBJ(alarm_id, temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "alarmId", temp_jso);
+
+ JSON_NEW_INT_OBJ(10001, temp_jso, json_object_put, alarmlist, alarmItem);
+ json_object_object_add(alarmItem, "groupId", temp_jso);
+
+ JSON_NEW_STRING_OBJ(g_vmid, temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "objectInstance", temp_jso);
+ JSON_NEW_INT_OBJ(8, temp_jso, json_object_put, alarmlist, alarmItem);
+ json_object_object_add(alarmItem, "eventType", temp_jso);
+
+ JSON_NEW_STRING_OBJ(alarm_string, temp_jso, json_object_put, alarmlist,
+ alarmItem);
+ json_object_object_add(alarmItem, "alarmName", temp_jso);
+
+ JSON_NEW_INT_OBJ(perceivedSeverity_value, temp_jso, json_object_put,
+ alarmlist, alarmItem);
+
+ json_object_object_add(alarmItem, "perceivedSeverity", temp_jso);
+
+ JSON_NEW_OBJ(alarm_info, json_object_put, alarmlist, alarmItem);
+ JSON_NEW_STRING_OBJ_1(alarm_reason_info, temp_jso, json_object_put,
+ alarmlist, alarmItem, alarm_info);
+ json_object_object_add(alarm_info, "reason", temp_jso);
+ JSON_NEW_STRING_OBJ_1(alarm_desc, temp_jso, json_object_put, alarmlist,
+ alarmItem, alarm_info);
+ json_object_object_add(alarm_info, "desc", temp_jso);
+ json_object_object_add(alarmItem, "alarmInfo", alarm_info);
+
+ JSON_NEW_STRING_OBJ(action_string, temp_jso, json_object_put, alarmlist,
+ alarmItem);
+
+ json_object_object_add(alarmlist, "data", alarmItem);
+
+ json_object_object_add(alarmlist, "action", temp_jso);
+
+ const char *str = json_object_to_json_string(alarmlist);
+ if (str == NULL)
+ {
+ NSMON_LOGERR("json_object_to_json_string fail");
+ (void) json_object_put(alarmlist);
+ return -1;
+ }
+
+ str_len = strlen(str);
+
+ if (str_len >= ALARM_PARA_LENGTH_OUTER)
+ {
+ NSAM_LOGERR("str_len >= ALARM_PARA_LENGTH_OUTER");
+ (void) json_object_put(alarmlist);
+ return -1;
+ }
+
+ retVal =
+ strncpy_s(alarmpara_out->alarmcontent, ALARM_PARA_LENGTH_OUTER, str,
+ str_len + 1);
+
+ if (EOK != retVal)
+ {
+ NSAM_LOGERR("STRNCPY_S failed]ret=%d", retVal);
+ (void) json_object_put(alarmlist);
+ return -1;
+ }
+
+ (void) json_object_put(alarmlist);
+
+ return 0;
+
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : send alarm to thirdparty alarm module, now only log
+********************************************************************/
+int ns_send_alarm_to_alarm_module(alarm_result alarm_res)
+{
+ int retVal = -1;
+
+ nsfw_mgr_msg *req_msg =
+ nsfw_mgr_msg_alloc(MGR_MSG_LARGE_ALARM_RSP, NSFW_PROC_ALARM);
+
+ if (NULL == req_msg)
+ {
+ NSAM_LOGERR("mgr_msg_alloc fail]alarm_id=%d", alarm_res.alarm_id_get);
+ return -1;
+ }
+
+ if (req_msg->msg_len < (NSFW_MGR_MSG_HDR_LEN + sizeof(alarm_info_s_out)))
+ {
+ NSAM_LOGERR("mgr_msg_alloc length fail]alarm_id=%d",
+ alarm_res.alarm_id_get);
+ nsfw_mgr_msg_free(req_msg);
+ return -1;
+ }
+ /* husky agent receive alarm info using fixed length */
+ req_msg->msg_len = (NSFW_MGR_MSG_HDR_LEN + sizeof(alarm_info_s_out));
+
+ retVal =
+ ns_get_alarm_body((char *) req_msg->msg_body,
+ NSFW_MGR_LARGE_MSG_BODY_LEN, alarm_res);
+
+ if (-1 == retVal)
+ {
+ NSAM_LOGERR("ns_get_alarm_body fail]alarm_id=%d",
+ alarm_res.alarm_id_get);
+ nsfw_mgr_msg_free(req_msg);
+ return -1;
+ }
+
+ u8 ret = nsfw_mgr_send_msg(req_msg);
+
+ if (FALSE == ret)
+ {
+ NSAM_LOGERR("nsfw_mgr_send_msg fail]alarm_id=%d,reason=%d,flag=%d",
+ alarm_res.alarm_id_get, alarm_res.alarm_reason_get,
+ alarm_res.alarm_flag_get);
+ ns_alarm_set_sendFlag(alarm_res.alarm_id_get, ALARM_SEND_FAIL);
+ nsfw_mgr_msg_free(req_msg);
+ return -1;
+ }
+
+ NSAM_LOGINF("nsfw_mgr_send_msg succ]alarm_id=%d,reason=%d,flag=%d",
+ alarm_res.alarm_id_get, alarm_res.alarm_reason_get,
+ alarm_res.alarm_flag_get);
+ ns_alarm_set_sendFlag(alarm_res.alarm_id_get, ALARM_SEND_SUCC);
+
+ nsfw_mgr_msg_free(req_msg);
+
+ return 0;
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : alarm product common func
+********************************************************************/
+void
+ns_send_alarm_inner(enum_alarm_id alarm_id, void *para, int check_times,
+ int check_state_flag)
+{
+ alarm_data *alarm_value = NULL;
+ alarm_result alarm_id_report;
+ int alarm_idx;
+ int alarm_loop;
+ int temp_alarm_time_laps;
+ int abnormal_alarm_flag = 0, normal_alarm_flag =
+ 0, total_abnormal_alarm_flag = 0;
+ int need_check_flag = check_state_flag;
+ int ret = 0;
+
+ if ((alarm_id <= 0) || (alarm_id >= ALARM_EVENT_MAX)
+ || (0 == g_alarm_data[alarm_id].valid_flag))
+ {
+ NSAM_LOGERR("alarm_id is invalid or not reg");
+ return;
+ }
+
+ alarm_id_report.alarm_id_get = ALARM_EVENT_MAX;
+
+ alarm_idx = alarm_id;
+
+ alarm_value = &g_alarm_data[alarm_idx];
+
+ for (alarm_loop = 0; alarm_loop < alarm_value->alarm_reason_cnt;
+ alarm_loop++)
+ {
+ abnormal_alarm_flag = 0;
+ if (ALARM_PERIOD_CHECK == alarm_value->_alarm_type)
+ {
+ if (NULL ==
+ alarm_value->_alarm_para.func_alarm_check_period[alarm_loop])
+ {
+ NSAM_LOGERR
+ ("alarm id func_alarm_check is invalid]alarm_id=%d",
+ alarm_id);
+ return;
+ }
+ alarm_id_report =
+ alarm_value->
+ _alarm_para.func_alarm_check_period[alarm_loop] ();
+ }
+ else if (ALARM_SEND_ONCE == alarm_value->_alarm_type)
+ {
+ if (NULL == alarm_value->_alarm_para.func_alarm_check[alarm_loop])
+ {
+ NSAM_LOGERR
+ ("alarm id func_alarm_check is invalid]alarm_id=%d",
+ alarm_id);
+ return;
+ }
+ alarm_id_report =
+ alarm_value->_alarm_para.func_alarm_check[alarm_loop] (para);
+ }
+
+ if ((alarm_id_report.alarm_id_get <= ALARM_EVENT_BASE)
+ || alarm_id_report.alarm_id_get >= ALARM_EVENT_MAX)
+ {
+ NSAM_LOGDBG("don't satisfy alarm condition");
+ return;
+ }
+
+ alarm_idx = alarm_id_report.alarm_id_get;
+
+ if (ALARM_EVENT_NSTACK_MAIN_ABNORMAL == alarm_idx)
+ {
+ need_check_flag = 0;
+ }
+ /* for send current status alarm, needn't check count also status. */
+ /* for sending current state alarm, needn't check current state */
+ if ((alarm_id_report.alarm_flag_get == ALARM_PRODUCT)
+ && (((alarm_value->alarm_time_laps[alarm_loop] < check_times)
+ && (alarm_value->_alarm_flag != ALARM_PRODUCT))
+ || (need_check_flag == 0)))
+ {
+ if ((0 == check_state_flag)
+ || ++(alarm_value->alarm_time_laps[alarm_loop]) >=
+ check_times)
+ {
+ alarm_value->_alarm_flag = ALARM_PRODUCT;
+ abnormal_alarm_flag = 1;
+ total_abnormal_alarm_flag++;
+ }
+
+ }
+ else if ((alarm_id_report.alarm_flag_get == ALARM_CLEAN)
+ && ((alarm_value->_alarm_flag == ALARM_PRODUCT)
+ || (need_check_flag == 0)))
+ {
+ if ((1 == check_state_flag)
+ && (alarm_value->alarm_time_laps[alarm_loop] > 0))
+ {
+ --alarm_value->alarm_time_laps[alarm_loop];
+ }
+ if ((alarm_value->alarm_time_laps[alarm_loop] <= 0)
+ || (0 == check_state_flag))
+ {
+ normal_alarm_flag++;
+ }
+ }
+
+ temp_alarm_time_laps = alarm_value->alarm_time_laps[alarm_loop];
+
+ /* can't product same alarm multi times */
+ /* only overload alarm can send */
+ if (abnormal_alarm_flag != 1)
+ {
+ NSAM_LOGDBG
+ ("don't satisfy alarm condition]alarm_idx=%d,alarm_time_laps=%d",
+ alarm_idx, temp_alarm_time_laps);
+ continue;
+ }
+
+ ret = ns_send_alarm_to_alarm_module(alarm_id_report);
+
+ if (-1 == ret)
+ {
+ ns_alarm_set_sendFlag(alarm_id, ALARM_SEND_FAIL);
+ }
+ else
+ {
+ ns_alarm_set_sendFlag(alarm_id, ALARM_SEND_SUCC);
+ }
+ /* for alarm current status, only can send one */
+ /* if it have multi-scearo, only can send a overload alarm */
+ if (0 == need_check_flag)
+ {
+ break;
+ }
+
+ }
+
+ if ((total_abnormal_alarm_flag == 0)
+ && (alarm_value->alarm_reason_cnt == normal_alarm_flag))
+ {
+ alarm_value->_alarm_flag = ALARM_CLEAN;
+ ret = ns_send_alarm_to_alarm_module(alarm_id_report);
+ if (-1 == ret)
+ {
+ ns_alarm_set_sendFlag(alarm_id, ALARM_SEND_FAIL);
+ }
+ else
+ {
+ ns_alarm_set_sendFlag(alarm_id, ALARM_SEND_SUCC);
+ }
+ }
+
+ return;
+
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : API, any app want to product alarm,need call this function
+********************************************************************/
+void ns_send_alarm(enum_alarm_id alarm_id, void *para)
+{
+ ns_send_alarm_inner(alarm_id, para, 1, 1);
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : period check alarm expire handle function
+********************************************************************/
+int ns_alarm_timer_proc_fun(u32 timer_type, void *argv)
+{
+ struct timespec time_left;
+ if (NULL == argv)
+ {
+ NSAM_LOGERR("abnormal: argv is NULL ");
+ return -1;
+ }
+
+ alarm_data *alarm_value = (alarm_data *) argv;
+
+ if (alarm_value->_alarm_type == ALARM_PERIOD_CHECK)
+ {
+ ns_send_alarm_inner(alarm_value->_alarm_id, NULL,
+ ALARM_PERIOD_CHECK_TIMES, 1);
+ time_left.tv_sec = alarm_value->_alarm_para.period_alarm.time_length;
+ time_left.tv_nsec = 0;
+ nsfw_timer_info *timer_info =
+ nsfw_timer_reg_timer(0, (void *) (u64) alarm_value,
+ ns_alarm_timer_proc_fun, time_left);
+ if (NULL == timer_info)
+ {
+ NSAM_LOGERR("nsfw_timer_reg_timer fail");
+ return -1;
+ }
+ }
+ NSAM_LOGDBG("abnormal: alarm is not period ");
+
+ return 0;
+
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : app reg alarm info to alarm module
+********************************************************************/
+int
+ns_reg_alarm(enum_alarm_id alarm_id, alarm_type alarmType,
+ alarm_para * alarmPara)
+{
+ alarm_data *alarm_value = NULL;
+ alarm_reason loop = ALARM_REASON_BEGIN;
+ struct timespec time_left;
+
+ if ((alarm_id <= ALARM_EVENT_BASE) || (alarm_id >= ALARM_EVENT_MAX)
+ || (NULL == alarmPara)
+ || (alarmPara->alarm_reason_count > ALARM_REASON_MAX))
+ {
+ NSAM_LOGERR("para invalid]alarm_id=%d ", alarm_id);
+ return -1;
+ }
+
+ for (loop = ALARM_REASON_BEGIN; loop < alarmPara->alarm_reason_count;
+ loop++)
+ {
+ if (NULL == alarmPara->func_alarm_check[loop])
+ {
+ NSAM_LOGERR("para invalid]func_alarm_check=NULL,loop=%d", loop);
+ return -1;
+ }
+ }
+
+ alarm_value = &g_alarm_data[alarm_id];
+ alarm_value->_alarm_type = alarmType;
+ alarm_value->_alarm_para.period_alarm.time_length =
+ alarmPara->period_alarm.time_length;
+ alarm_value->_alarm_id = alarm_id;
+ alarm_value->alarm_reason_cnt = alarmPara->alarm_reason_count;
+ alarm_value->_alarm_flag = ALARM_CLEAN;
+
+ for (loop = ALARM_REASON_BEGIN; loop < alarmPara->alarm_reason_count;
+ loop++)
+ {
+ alarm_value->alarm_time_laps[loop] =
+ alarmPara->alarm_reason_set[loop];
+ alarm_value->_alarm_para.func_alarm_check[loop] =
+ alarmPara->func_alarm_check[loop];
+ alarm_value->_alarm_para.func_alarm_check_period[loop] =
+ alarmPara->func_alarm_check_period[loop];
+ alarm_value->alarm_time_laps[loop] = 0;
+ }
+
+ alarm_value->valid_flag = 1;
+
+ if (ALARM_PERIOD_CHECK == alarmType)
+ {
+ time_left.tv_sec = alarm_value->_alarm_para.period_alarm.time_length;
+ time_left.tv_nsec = 0;
+ nsfw_timer_info *timer_info =
+ nsfw_timer_reg_timer(0, (void *) (u64) alarm_value,
+ ns_alarm_timer_proc_fun, time_left);
+ if (NULL == timer_info)
+ {
+ NSAM_LOGERR("nsfw_timer_reg_timer fail");
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+* Copyright 2017, Huawei Tech. Co., Ltd.
+* ALL RIGHTS RESERVED
+*Description : send alarm as per current state
+********************************************************************/
+void ns_send_init_alarm(enum_alarm_id alarm_id)
+{
+ if ((alarm_id <= 0) || (alarm_id >= ALARM_EVENT_MAX))
+ {
+ NSAM_LOGDBG("alarm_id is invalid");
+ return;
+ }
+ ns_send_alarm_inner(alarm_id,
+ (void *) (g_alarm_data[alarm_id]._alarm_flag), 1, 0);
+}
+
+NSFW_MODULE_NAME(NSFW_ALARM_MODULE)
+NSFW_MODULE_PRIORITY(10)
+NSFW_MODULE_DEPENDS(NSFW_TIMER_MODULE) NSFW_MODULE_INIT(ns_alarm_module_init)
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/stacks/lwip_stack/src/alarm/alarm.h b/stacks/lwip_stack/src/alarm/alarm.h
new file mode 100644
index 0000000..6c55400
--- /dev/null
+++ b/stacks/lwip_stack/src/alarm/alarm.h
@@ -0,0 +1,80 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _ALARM_H_
+#define _ALARM_H_
+
+#include <stdint.h>
+#include "alarm_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/* alarm clean time = 1*3 */
+
+#define ALARM_RESEND_TIMER_LENGTH 60
+#define ALARM_INIT_RESEND_TIMER_LENGTH 40
+
+#define ALARM_SEND_SUCC 1
+#define ALARM_SEND_FAIL 0
+
+#define ALARM_PARA_LENGTH_OUTER 2048
+
+#define ALARM_PERIOD_CHECK_TIMES 3
+
+#define MAX_VMID_LEN 256
+
+#define MIN_VM_ID_LEN 1
+#define MAX_VM_ID_LEN 256
+
+#define INVALID_STR_LEN(_str, _min_len, _maxlen) (NULL == _str || strlen(_str) < _min_len || strlen(_str) > _maxlen)
+
+typedef struct _alarm_data
+{
+ alarm_para _alarm_para;
+ alarm_type _alarm_type;
+ enum_alarm_id _alarm_id;
+ int alarm_time_laps[ALARM_REASON_MAX];
+ alarm_flag _alarm_flag;
+ int alarm_reason_cnt;
+ int valid_flag;
+ int send_succ_flag;
+
+} alarm_data;
+
+typedef struct _alarm_info_s_out
+{
+ char alarmId[16];
+ char comptentname[32];
+ char alarmtime[32];
+ char alarmcontent[ALARM_PARA_LENGTH_OUTER];
+} alarm_info_s_out;
+
+int ns_send_alarm_to_alarm_module(alarm_result alarm_res);
+
+void ns_send_alarm_inner(enum_alarm_id alarm_id, void *para, int check_times,
+ int check_state_flag);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/alarm/alarm_api.h b/stacks/lwip_stack/src/alarm/alarm_api.h
new file mode 100644
index 0000000..c9dcafb
--- /dev/null
+++ b/stacks/lwip_stack/src/alarm/alarm_api.h
@@ -0,0 +1,107 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _ALARM_API_H_
+#define _ALARM_API_H_
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define NSFW_ALARM_MODULE "nstack_alarm"
+
+/* alarm ID for every event, when need add new alarm, here add a alarm_id define */
+typedef enum _alarm_id
+{
+ ALARM_EVENT_BASE,
+ ALARM_EVENT_NSTACK_RESOURCE_ALARM,
+ ALARM_EVENT_NSTACK_NO_USE,
+ ALARM_EVENT_NSTACK_MAIN_ABNORMAL,
+ ALARM_EVENT_MAX
+} enum_alarm_id;
+
+/* support both type alarm:
+ 1. support other module call func:ns_send_alarm to product alarm;
+ 2. alarm module call function periodly to check whether need product alarm */
+typedef enum _alarm_type
+{
+ ALARM_PERIOD_CHECK,
+ ALARM_SEND_ONCE
+} alarm_type;
+
+typedef enum _alarm_flag
+{
+ ALARM_PRODUCT,
+ ALARM_CLEAN,
+ ALARM_MAX
+} alarm_flag;
+
+typedef enum _alarm_reason
+{
+ ALARM_REASON_BEGIN,
+ ALARM_REASON_SOCKET = 0,
+ ALARM_REASON_MSG_BUF,
+ ALARM_REASON_NSMAIN,
+ ALARM_REASON_MAX
+} alarm_reason;
+
+typedef struct _alarm_result
+{
+ enum_alarm_id alarm_id_get;
+ alarm_reason alarm_reason_get;
+ alarm_flag alarm_flag_get;
+} alarm_result;
+
+/* check whether need product alarm,if return 0, then product alarm */
+typedef alarm_result(*alarm_check_func) (void *para);
+typedef alarm_result(*alarm_check_func_period) (void);
+
+typedef struct _alarm_para
+{
+ union
+ {
+ int time_length;
+ } period_alarm;
+ union
+ {
+ alarm_check_func func_alarm_check[ALARM_REASON_MAX];
+ alarm_check_func_period func_alarm_check_period[ALARM_REASON_MAX];
+ };
+
+ alarm_reason alarm_reason_set[ALARM_REASON_MAX];
+ int alarm_reason_count;
+
+} alarm_para;
+
+/* for any alarm added, firstly call following function to reg */
+int ns_reg_alarm(enum_alarm_id alarm_id, alarm_type _alarm_type,
+ alarm_para * _alarm_para);
+
+void ns_send_init_alarm(enum_alarm_id alarm_id);
+
+/* other module call this func to product alarm, here para is same as alarm_check_func's para */
+void ns_send_alarm(enum_alarm_id alarm_id, void *para);
+int ns_alarm_module_init(void *param);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/common_func.h b/stacks/lwip_stack/src/include/common_func.h
new file mode 100644
index 0000000..db1aee7
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_func.h
@@ -0,0 +1,140 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _RTE_COMM_FUNC_H_
+#define _RTE_COMM_FUNC_H_
+
+#ifdef HAL_LIB
+
+#else
+#include "common_mem_rwlock.h"
+
+#define common_mem_rwlock_t rte_rwlock_t
+#define common_mem_spinlock_t rte_spinlock_t
+ //typedef rte_rwlock_t common_mem_rwlock_t;
+
+#define nsfw_write_lock(plock) rte_rwlock_write_lock(plock)
+#define nsfw_write_unlock(plock) rte_rwlock_write_unlock(plock)
+#define nsfw_read_lock(plock) rte_rwlock_read_lock(plock)
+#define nsfw_read_unlock(plock) rte_rwlock_read_unlock(plock)
+
+#define common_mem_align32pow2 rte_align32pow2
+
+#define common_mem_atomic32_cmpset rte_atomic32_cmpset
+#define common_mem_pause rte_pause
+
+#define COMMON_MEM_MAX_MEMZONE RTE_MAX_MEMZONE
+
+#define common_mem_atomic32_t rte_atomic32_t
+
+#define common_mem_memseg rte_memseg
+#define common_mem_mem_config rte_mem_config
+
+#define common_mem_pal_get_configuration rte_eal_get_configuration
+
+ //#define commem_mem_pal_module_info rte_eal_module_info
+ //
+#define common_mem_pal_init rte_eal_init
+
+#define COMMON_MEM_MEMPOOL_NAMESIZE RTE_MEMPOOL_NAMESIZE
+
+#define common_mem_memzone_lookup rte_memzone_lookup
+#define common_mem_memzone rte_memzone
+#define common_mem_atomic32_add_return rte_atomic32_add_return
+
+#define common_mem_spinlock_init rte_spinlock_init
+#define common_mem_spinlock_lock rte_spinlock_lock
+#define common_mem_spinlock_unlock rte_spinlock_unlock
+
+#define common_mem_memzone_free rte_memzone_free
+#define common_mem_pktmbuf_pool_create rte_pktmbuf_pool_create
+
+#define common_mem_pktmbuf_alloc rte_pktmbuf_alloc
+
+#define common_mem_mempool rte_mempool
+
+#define common_mem_pktmbuf_free rte_pktmbuf_free
+#define common_mem_mbuf rte_mbuf
+
+#define common_mem_mempool_lookup rte_mempool_lookup
+
+#define common_mem_ring_get_memsize rte_ring_get_memsize
+#define common_mem_ring rte_ring
+
+#define COMMON_MEM_MAX_MEMSEG RTE_MAX_MEMSEG
+
+#define common_mem_memzone_reserve rte_memzone_reserve
+#define common_mem_rwlock_read_lock rte_rwlock_read_lock
+#define common_mem_rwlock_read_unlock rte_rwlock_read_unlock
+
+#define common_mem_rwlock_write_lock rte_rwlock_write_lock
+#define common_mem_rwlock_write_unlock rte_rwlock_write_unlock
+#define common_mem_spinlock_trylock rte_spinlock_trylock
+
+#define common_mem_socket_id rte_socket_id
+#define common_mem_malloc_socket_stats rte_malloc_socket_stats
+
+#define COMMON_MEM_MIN RTE_MIN
+
+#define common_pal_module_init nscomm_pal_module_init
+#define common_memzone_data_reserve_name nscomm_memzone_data_reserve_name
+#define common_memzone_data_lookup_name nscomm_memzone_data_lookup_name
+
+#define common_dump_stack rte_dump_stack
+#define COMMON_PKTMBUF_HEADROOM RTE_PKTMBUF_HEADROOM
+
+#define common_pktmbuf_mtod rte_pktmbuf_mtod
+#define common_memcpy rte_memcpy
+#define common_spinlock_try_lock_with_pid dmm_spinlock_try_lock_with_pid
+#define common_spinlock_unlock rte_spinlock_unlock
+#define common_atomic64_t rte_atomic64_t
+#define common_atomic64_inc rte_atomic64_inc
+#define common_atomic64_read rte_atomic64_read
+#define common_atomic64_dec rte_atomic64_dec
+#define common_mbuf_refcnt_set rte_mbuf_refcnt_set
+#define common_mbuf_refcnt_read rte_mbuf_refcnt_read
+#define common_exit rte_exit
+#define COMMON_CACHE_LINE_SIZE RTE_CACHE_LINE_SIZE
+#define common_eal_process_type rte_eal_process_type
+#define COMMON_PROC_PRIMARY RTE_PROC_PRIMARY
+
+void dmm_addr_print(void);
+
+#define NSFW_NAME_LENCHECK_RET(name, desc) \
+ { \
+ i32 inamelen = strlen(name); \
+ if (inamelen >= NSFW_MEM_APPNAME_LENTH) \
+ { \
+ NSRTP_LOGERR("name length check fail]desc=%s,name len=%d,expected max=%d", \
+ #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \
+ return NSFW_MEM_ERR; \
+ } \
+ }
+
+#define NSFW_NAME_LENCHECK_RET_NULL(name, desc) \
+ { \
+ i32 inamelen = strlen(name); \
+ if (inamelen >= NSFW_MEM_APPNAME_LENTH) \
+ { \
+ NSRTP_LOGERR("name length check fail]desc=%s,name len=%d,expected max=%d", \
+ #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \
+ return NULL; \
+ } \
+ }
+
+#endif
+
+#endif // _RTE_COMM_FUNC_H_
diff --git a/stacks/lwip_stack/src/include/common_mem_api.h b/stacks/lwip_stack/src/include/common_mem_api.h
new file mode 100644
index 0000000..a799677
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_api.h
@@ -0,0 +1,134 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __COMMON_MEM_API_H__
+#define __COMMON_MEM_API_H__
+
+#ifdef HAL_LIB
+#else
+
+#include "rte_atomic.h"
+#include "common_mem_spinlock.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <semaphore.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifndef NSTACK_LINT_CODE_DISABLE
+#define NSTACK_LINT_CODE_DISABLE(code) /*lint -e#code */
+#endif
+
+#ifndef NSTACK_LINT_CODE_ENABLE
+#define NSTACK_LINT_CODE_ENABLE(code) /*lint +e#code */
+#endif
+
+#define SYS_MBOX_NULL (sys_mbox_t)0
+
+typedef sem_t *sys_sem_t_v1;
+typedef sem_t sys_sem_st_v1;
+typedef struct queue *sys_mbox_t;
+
+typedef rte_spinlock_t *sys_sem_t_v2;
+typedef rte_spinlock_t sys_sem_st_v2;
+
+#ifndef u32_t
+typedef uint32_t u32_t;
+#endif
+
+#ifndef u8_t
+typedef uint8_t u8_t;
+#endif
+
+#ifndef s8_t
+typedef int8_t s8_t;
+#endif
+
+#ifndef err_t
+typedef s8_t err_t;
+#endif
+
+/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
+#define SYS_ARCH_TIMEOUT 0xffffffffUL
+
+/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate.
+ * For now we use the same magic value, but we allow this to change in future.
+ */
+#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT
+
+void sys_sem_signal_s_v2(sys_sem_t_v2 sem);
+void sys_sem_init_v2(sys_sem_t_v2 sem);
+u32_t sys_arch_sem_trywait_v2(sys_sem_t_v2 * sem);
+
+u32_t sys_arch_sem_wait_s_v2(sys_sem_t_v2 sem);
+
+#define SYS_HOST_INITIAL_PID 1
+extern volatile pid_t g_sys_host_pid;
+pid_t sys_get_hostpid_from_file(pid_t pid);
+
+u32_t sys_now(void);
+
+#define sys_sem_t sys_sem_t_v2
+#define sys_sem_st sys_sem_st_v2
+#define sys_sem_new(sem, count) sys_sem_new_v2(sem, count)
+#define sys_sem_free(sem) sys_sem_free_v2(sem)
+#define sys_sem_signal(sem) sys_sem_signal_v2(sem)
+#define sys_arch_sem_wait(sem, timeout) sys_arch_sem_wait_v2(sem)
+#define sys_arch_sem_trywait(sem) sys_arch_sem_trywait_v2(sem)
+
+#define sys_sem_init(sem) sys_sem_init_v2(sem)
+#define sys_sem_s_signal(sem) sys_sem_signal_s_v2(sem)
+#define sys_arch_sem_s_wait(sem, timeout) sys_arch_sem_wait_s_v2(sem)
+#define sys_arch_lock_with_pid(sem) (void)sys_arch_lock_with_pid_v2(sem)
+
+#define BUF_SIZE_FILEPATH 256
+#define STR_PID "pid:"
+#define READ_FILE_BUFLEN 512
+
+extern pid_t sys_get_hostpid_from_file(pid_t pid);
+extern pid_t get_hostpid_from_file(u32_t pid);
+extern void get_exec_name_by_pid(pid_t pid, char *task_name,
+ int task_name_len);
+
+static inline u32_t sys_arch_lock_with_pid_v2(sys_sem_t_v2 sem)
+{
+ if (SYS_HOST_INITIAL_PID == g_sys_host_pid)
+ (void) sys_get_hostpid_from_file(getpid());
+ dmm_spinlock_lock_with_pid(sem, g_sys_host_pid);
+ return 0;
+}
+
+#define NSTACK_SEM_MALLOC(sys_sem,count) \
+{ \
+ rte_spinlock_init(&(sys_sem)); \
+ if (!(count)) \
+ { \
+ rte_spinlock_lock(&(sys_sem)); \
+ } \
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#endif
+
+#endif /* __COMMON_MEM_API_H__ */
diff --git a/stacks/lwip_stack/src/include/common_mem_base_type.h b/stacks/lwip_stack/src/include/common_mem_base_type.h
new file mode 100644
index 0000000..01707d9
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_base_type.h
@@ -0,0 +1,85 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_BASE_TYPE_H_
+#define _COMMON_MEM_BASE_TYPE_H_
+
+#ifdef HAL_LIB
+
+#else
+
+#define ALIGN_TYPE uint64_t
+#define PTR_ALIGN_TYPE uint64_t
+
+/*alignment define*/
+#define ALIGNMENT_DEF(name, type, aligntype) \
+ union { \
+ type name; \
+ aligntype name##_align; \
+ }
+
+#define PTR_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, PTR_ALIGN_TYPE)
+
+#define OTHER_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, ALIGN_TYPE)
+
+/*
+ * * List definitions.
+ * */
+#define DMM_LIST_HEAD(name, type) \
+struct name { \
+ PTR_ALIGNMENT_DEF(lh_first, struct type *); /* first element */ \
+}
+
+#define DMM_LIST_ENTRY(type) \
+struct { \
+ PTR_ALIGNMENT_DEF(le_next, struct type *); /* next element */\
+ PTR_ALIGNMENT_DEF(le_prev, struct type **); /* address of previous next element */ \
+}
+
+/*
+ * * Tail queue definitions.
+ * */
+#define _DMM_TAILQ_HEAD(name, type, qual) \
+struct name { \
+ PTR_ALIGNMENT_DEF(tqh_first, qual type *); /* first element */ \
+ PTR_ALIGNMENT_DEF(tqh_last, qual type * qual *); /* addr of last next element */ \
+}
+
+#define DMM_TAILQ_HEAD(name, type) _DMM_TAILQ_HEAD(name, struct type,)
+
+#define _DMM_TAILQ_ENTRY(type, qual) \
+struct { \
+ PTR_ALIGNMENT_DEF(tqe_next, qual type *); /* next element */\
+ PTR_ALIGNMENT_DEF(tqe_prev, qual type * qual*); /* address of previous next element */\
+}
+#define DMM_TAILQ_ENTRY(type) _DMM_TAILQ_ENTRY(struct type,)
+
+/*
+ * * Singly-linked Tail queue declarations.
+ * */
+#define DMM_STAILQ_HEAD(name, type) \
+ struct name { \
+ PTR_ALIGNMENT_DEF(stqh_first, struct type *); /* first element */ \
+ PTR_ALIGNMENT_DEF(stqh_last, struct type **); /* addr of last next element */ \
+ }
+
+#define DMM_STAILQ_ENTRY(type) \
+ struct { \
+ PTR_ALIGNMENT_DEF(stqe_next, struct type *); /* next element */ \
+ }
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/common_mem_buf.h b/stacks/lwip_stack/src/include/common_mem_buf.h
new file mode 100644
index 0000000..9ba0008
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_buf.h
@@ -0,0 +1,78 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_BUF_H_
+#define _COMMON_MEM_BUF_H_
+
+#ifdef HAL_LIB
+#else
+
+#include "nsfw_mem_api.h"
+#include "common_mem_base_type.h"
+#include "types.h"
+
+typedef enum __DMM_PROC_TYPE
+{
+ DMM_PROC_T_AUTO = 0, /*auto detect */
+ DMM_PROC_T_PRIMARY = 1, /* set to primary */
+ DMM_PROC_T_SECONDARY = 2, /* set to secondary */
+ DMM_PROC_T_INVALID
+} DMM_PROC_TYPE;
+
+#define DMM_MBUF_RET_OK 0
+#define DMM_MBUF_RET_ERR 1
+
+#define LCORE_MAX 128
+#define LCORE_MASK_PER (sizeof(int) * 8)
+#define LCORE_MASK_MAX (LCORE_MAX/LCORE_MASK_PER)
+
+#define LCORE_MASK_SET(ilcoremask, value) \
+ if (value < LCORE_MAX) \
+ { \
+ ilcoremask[(value/LCORE_MASK_PER)] = (int) ( (ilcoremask[(value/LCORE_MASK_PER)]) | (1< (value%LCORE_MASK_PER))); \
+ } \
+
+#define DMM_HUGTBL_ENABLE 0
+#define DMM_HUGTBL_DISABLE 1
+
+typedef struct __common_pal_module_info
+{
+ int ishare_mem_size; /*shared memory size */
+ int ilcoremask[LCORE_MASK_MAX];
+ /**/ unsigned char uchugeflag;
+ unsigned char ucproctype;
+ unsigned char ucinstance;
+ unsigned char ucresrv2;
+} common_mem_pal_module_info;
+
+/**
+ * rte pal module init.
+ *
+ *
+ * @param name
+ * The name of the buf pool.
+ */
+int nscomm_pal_module_init(nsfw_mem_para * para,
+ common_mem_pal_module_info * pinfo, u8 app_mode);
+
+void *nscomm_memzone_data_reserve_name(const char *name, size_t len,
+ int socket_id);
+
+void *nscomm_memzone_data_lookup_name(const char *name);
+
+#endif
+
+#endif /* _COMMON_MEM_BUF_H_ */
diff --git a/stacks/lwip_stack/src/include/common_mem_common.h b/stacks/lwip_stack/src/include/common_mem_common.h
new file mode 100644
index 0000000..1e4cf56
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_common.h
@@ -0,0 +1,25 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_COMMON_H_
+#define _COMMON_MEM_COMMON_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_common.h"
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/common_mem_mbuf.h b/stacks/lwip_stack/src/include/common_mem_mbuf.h
new file mode 100644
index 0000000..ee8cfa2
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_mbuf.h
@@ -0,0 +1,40 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/*******************************************************************
+ Copyright 2017 - 2047, Huawei Tech. Co., Ltd.
+ ALL RIGHTS RESERVED
+
+Filename : common_mem_mbuf.h
+Description :
+Version : 1.1
+********************************************************************/
+
+#ifndef _COMMON_MEM_MBUF_H_
+#define _COMMON_MEM_MBUF_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_mbuf.h"
+#include "common_func.h"
+
+typedef uint32_t(*dmm_mbuf_item_fun) (void *data, void *argv);
+int32_t dmm_pktmbuf_pool_iterator(struct common_mem_mempool *mp,
+ uint32_t start, uint32_t end,
+ dmm_mbuf_item_fun fun, void *argv);
+#endif
+
+#endif /* _COMMON_MEM_MBUF_H_ */
diff --git a/stacks/lwip_stack/src/include/common_mem_mempool.h b/stacks/lwip_stack/src/include/common_mem_mempool.h
new file mode 100644
index 0000000..58a8e82
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_mempool.h
@@ -0,0 +1,25 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_MEMPOOL_H_
+#define _COMMON_MEM_MEMPOOL_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_mempool.h"
+#endif
+
+#endif /* _COMMON_MEM_MEMPOOL_H_ */
diff --git a/stacks/lwip_stack/src/include/common_mem_pal_memconfig.h b/stacks/lwip_stack/src/include/common_mem_pal_memconfig.h
new file mode 100644
index 0000000..65b6e04
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_pal_memconfig.h
@@ -0,0 +1,26 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_PAL_MEMCONFIG_H_
+#define _COMMON_MEM_PAL_MEMCONFIG_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_eal_memconfig.h"
+
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/common_mem_rwlock.h b/stacks/lwip_stack/src/include/common_mem_rwlock.h
new file mode 100644
index 0000000..2eed259
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_rwlock.h
@@ -0,0 +1,25 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_RWLOCK_H_
+#define _COMMON_MEM_RWLOCK_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_rwlock.h"
+#endif
+
+#endif /* _COMMON_MEM_RWLOCK_H_ */
diff --git a/stacks/lwip_stack/src/include/common_mem_spinlock.h b/stacks/lwip_stack/src/include/common_mem_spinlock.h
new file mode 100644
index 0000000..482e87b
--- /dev/null
+++ b/stacks/lwip_stack/src/include/common_mem_spinlock.h
@@ -0,0 +1,38 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_SPINLOCK_X86_64_H_
+#define _COMMON_MEM_SPINLOCK_X86_64_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_spinlock.h"
+
+static inline void dmm_spinlock_lock_with_pid(rte_spinlock_t * sl, int pid)
+{
+ while (!__sync_bool_compare_and_swap(&sl->locked, 0, pid))
+ while (sl->locked)
+ rte_pause();
+}
+
+static inline int dmm_spinlock_try_lock_with_pid(rte_spinlock_t * sl, int pid)
+{
+ return __sync_bool_compare_and_swap(&sl->locked, 0, pid);
+}
+
+#endif
+
+#endif /* _COMMON_MEM_SPINLOCK_X86_64_H_ */
diff --git a/stacks/lwip_stack/src/include/nsfw_msg.h b/stacks/lwip_stack/src/include/nsfw_msg.h
new file mode 100644
index 0000000..9efa694
--- /dev/null
+++ b/stacks/lwip_stack/src/include/nsfw_msg.h
@@ -0,0 +1,201 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef MSG_H
+#define MSG_H
+#include "types.h"
+#include "common_mem_api.h"
+#include "nsfw_rti.h"
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define MAX_MSG_SIZE 512
+COMPAT_PROTECT_RETURN(MAX_MSG_SIZE, 512);
+#define MAX_MSG_PARAM_SIZE 128
+COMPAT_PROTECT_RETURN(MAX_MSG_PARAM_SIZE, 128);
+
+#define MSG_ASYN_POST 0
+#define MSG_SYN_POST 1
+
+typedef struct
+{
+ u16 module_type;
+ u16 major_type;
+ u16 minor_type;
+ u16 op_type; /* MSG_SYN_POST or MSG_ASYN_POST */
+ sys_sem_st op_completed;
+ i32 err;
+ PRIMARY_ADDR void *msg_from; /* use it to free msg */
+ i64 receiver;
+ i64 comm_receiver;
+ nsfw_res res_chk;
+ u32 src_pid;
+ u32 recycle_pid; /* use it in recycle */
+ u64 span_pid;
+ i64 extend_member_bit;
+} msg_param;
+
+typedef struct msg_t
+{
+ msg_param param;
+ i8 msg_param_pad[MAX_MSG_PARAM_SIZE - sizeof(msg_param)]; /* sizeof(msg_param) + sizeof(msg_param_pad) = MAX_MSG_PARAM_SIZE */
+ i64 buffer[(MAX_MSG_SIZE - MAX_MSG_PARAM_SIZE) / 8];
+}
+data_com_msg;
+
+#define MAX_MODULE_TYPE 64
+#define MAX_MAJOR_TYPE 256
+#define MAX_MINOR_TYPE 256
+
+struct rti_queue
+{
+ /* corresponding to enum spl_tcpip_msg_type */
+ volatile u64 tcpip_msg_enq[MAX_MAJOR_TYPE];
+ volatile u64 tcpip_msg_enq_fail[MAX_MAJOR_TYPE];
+ u64 tcpip_msg_deq[MAX_MAJOR_TYPE];
+
+ /* corresponding to enum api_msg_type, this is sub-type of SPL_TCPIP_NEW_MSG_API */
+ volatile u64 api_msg_enq[MAX_MINOR_TYPE];
+ volatile u64 api_msg_enq_fail[MAX_MINOR_TYPE];
+ u64 api_msg_deq[MAX_MINOR_TYPE];
+
+ u64 extend_member_bit;
+};
+
+enum MSG_MODULE_TYPE
+{
+ MSG_MODULE_IP,
+ MSG_MODULE_SBR,
+ MSG_MODULE_HAL,
+ MSG_MODULE_SPL,
+ MSG_MODULE_TIMER,
+ MSG_MODULE_MT,
+ MSG_MODULE_DFX,
+ MSG_MODULE_MAX = MAX_MODULE_TYPE
+};
+
+typedef int (*msg_fun) (data_com_msg * m);
+
+/* *INDENT-OFF* */
+extern msg_fun g_msg_module_fun_array[MAX_MODULE_TYPE];
+extern msg_fun g_msg_module_major_fun_array[MAX_MODULE_TYPE][MAX_MAJOR_TYPE];
+extern msg_fun g_msg_module_major_minor_fun_array[MAX_MODULE_TYPE][MAX_MAJOR_TYPE][MAX_MINOR_TYPE];
+extern msg_fun g_msg_unsupport_fun;
+/* *INDENT-ON* */
+
+#define REGIST_MSG_MODULE_FUN(module, fun) \
+ static void regist_ ## module ## _function (void) \
+ __attribute__((__constructor__)); \
+ static void regist_ ## module ## _function (void) \
+ { \
+ g_msg_module_fun_array[module] = fun; \
+ } \
+
+#define REGIST_MSG_MODULE_MAJOR_FUN(module, major, fun) \
+ static void regist_ ## module ## major ## _function (void) \
+ __attribute__((__constructor__)); \
+ static void regist_ ## module ## major ## _function (void) \
+ { \
+ g_msg_module_major_fun_array[module][major] = fun; \
+ } \
+
+#define REGIST_MSG_MODULE_MAJOR_MINOR_FUN(module, major, minor, fun) \
+ static void regist_ ## module ## major ## minor ## _function (void) \
+ __attribute__((__constructor__)); \
+ static void regist_ ## module ## major ## minor ## _function (void) \
+ { \
+ g_msg_module_major_minor_fun_array[module][major][minor] = fun; \
+ } \
+
+#define REGIST_MSG_UNSUPPORT_FUN(fun) \
+ static void regist_msg_unsupport_function (void) \
+ __attribute__((__constructor__)); \
+ static void regist_msg_unsupport_function (void) \
+ { \
+ g_msg_unsupport_fun = fun; \
+ }
+
+static inline int unsupport_msg(data_com_msg * m)
+{
+ if (g_msg_unsupport_fun)
+ {
+ return g_msg_unsupport_fun(m);
+ }
+
+ return -1;
+}
+
+/*****************************************************************************
+* Prototype : call_msg_fun
+* Description : call msg fun
+* Input : data_com_msg* m
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int call_msg_fun(data_com_msg * m)
+{
+ u16 module = m->param.module_type;
+ u16 major = m->param.major_type;
+ u16 minor = m->param.minor_type;
+
+ if ((module >= MAX_MODULE_TYPE) || (major >= MAX_MAJOR_TYPE)
+ || (minor >= MAX_MINOR_TYPE))
+ {
+ return unsupport_msg(m);
+ }
+
+ nsfw_rti_stat_macro(NSFW_STAT_PRIMARY_DEQ, m);
+
+ if (g_msg_module_fun_array[module]
+ && (g_msg_module_fun_array[module] (m) != 0))
+ {
+ return -1;
+ }
+
+ if (g_msg_module_major_fun_array[module][major]
+ && (g_msg_module_major_fun_array[module][major] (m) != 0))
+ {
+ return -1;
+ }
+
+ if (g_msg_module_major_minor_fun_array[module][major][minor])
+ {
+ return g_msg_module_major_minor_fun_array[module][major][minor] (m);
+ }
+
+ if (!g_msg_module_fun_array[module]
+ && !g_msg_module_major_fun_array[module][major]
+ && !g_msg_module_major_minor_fun_array[module][major][minor])
+ {
+ return unsupport_msg(m);
+ }
+
+ return 0;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/nsfw_msg_api.h b/stacks/lwip_stack/src/include/nsfw_msg_api.h
new file mode 100644
index 0000000..b7e0d1c
--- /dev/null
+++ b/stacks/lwip_stack/src/include/nsfw_msg_api.h
@@ -0,0 +1,305 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef MSG_API_H
+#define MSG_API_H
+#include "nsfw_msg.h"
+#include "nsfw_mem_api.h"
+#include "nstack_log.h"
+#include "nsfw_rti.h"
+#include "common_mem_api.h"
+#include "nsfw_recycle_api.h"
+#include "common_pal_bitwide_adjust.h"
+#include "pid_common.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define SET_MSG_ERR(m, error) ((m)->param.err = (error))
+#define GET_MSG_ERR(m) ((m)->param.err)
+
+/* for sync message from sbr we should signal sem */
+#define SYNC_MSG_ACK(m) sys_sem_s_signal(&((m)->param.op_completed))
+
+/* for async message from sbr we should free the message */
+#define ASYNC_MSG_FREE(m) msg_free(m)
+
+#define MSG_ENTRY(_ptr, _type, _member) container_of((void *)_ptr, _type, _member)
+
+#ifndef NSTACK_STATIC_CHECK
+/*****************************************************************************
+* Prototype : msg_malloc
+* Description : malloc msg
+* Input : mring_handle mhandle
+* Output : None
+* Return Value : static inline data_com_msg*
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline data_com_msg *msg_malloc(mring_handle mhandle)
+{
+ if (!mhandle)
+ {
+ NSFW_LOGERR("mhandle is null");
+ return NULL;
+ }
+
+ data_com_msg *m = NULL;
+ if (nsfw_mem_ring_dequeue(mhandle, (void **) &m) != 1)
+ {
+ return NULL;
+ }
+
+ m->param.recycle_pid = get_sys_pid();
+ res_alloc(&m->param.res_chk);
+ return m;
+}
+
+/*****************************************************************************
+* Prototype : msg_free
+* Description : free msg
+* Input : data_com_msg* m
+* mring_handle mhandle
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline void msg_free(data_com_msg * m)
+{
+ if (!m)
+ {
+ NSFW_LOGERR("m is NULL");
+ return;
+ }
+
+ mring_handle mhandle = ADDR_SHTOL(m->param.msg_from);
+ if (!mhandle)
+ {
+ return;
+ }
+
+ if (res_free(&m->param.res_chk))
+ {
+ NSFW_LOGERR("m refree!]m=%p", m);
+ return;
+ }
+
+ m->param.recycle_pid = 0;
+
+ if (nsfw_mem_ring_enqueue(mhandle, (void *) m) != 1)
+ {
+ NSFW_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ }
+}
+
+/*****************************************************************************
+* Prototype : msg_post
+* Description : post msg
+* Input : data_com_msg* m
+* mring_handle mhandle
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline int msg_post(data_com_msg * m, mring_handle mhandle)
+{
+ int ret;
+ if (!m || !mhandle)
+ {
+ NSFW_LOGERR("param is not ok]m=%p,mhandle=%p", m, mhandle);
+ return -1;
+ }
+
+ while (1)
+ {
+ ret = nsfw_mem_ring_enqueue(mhandle, (void *) m);
+ switch (ret)
+ {
+ case 1:
+ if (MSG_SYN_POST == m->param.op_type)
+ {
+ sys_arch_sem_s_wait(&m->param.op_completed, 0);
+ }
+
+ return 0;
+ case 0:
+ continue;
+ default:
+ nsfw_rti_stat_macro(NSFW_STAT_PRIMARY_ENQ_FAIL, m);
+ return -1;
+ }
+ }
+}
+
+#define MSG_POST_FAILED 50
+/*****************************************************************************
+* Prototype : msg_post_with_lock_rel
+* Description : post msg to tcpip thread in mgrcom thread
+* Input : data_com_msg* m
+* mring_handle mhandle
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline int
+msg_post_with_lock_rel(data_com_msg * m, mring_handle mhandle)
+{
+ int ret;
+ int try_count = 0;
+ if (!m || !mhandle)
+ {
+ NSFW_LOGERR("param is not ok]m=%p,mhandle=%p", m, mhandle);
+ return -1;
+ }
+
+ while (1)
+ {
+ ret = nsfw_mem_ring_enqueue(mhandle, (void *) m);
+ switch (ret)
+ {
+ case 1:
+ if (MSG_SYN_POST == m->param.op_type)
+ {
+ sys_arch_sem_s_wait(&m->param.op_completed, 0);
+ }
+
+ return 0;
+ case 0:
+ try_count++;
+ if (try_count > MSG_POST_FAILED)
+ {
+ try_count = 0;
+ nsfw_recycle_rechk_lock();
+ }
+ sys_sleep_ns(0, 1000000);
+ continue;
+ default:
+ nsfw_rti_stat_macro(NSFW_STAT_PRIMARY_ENQ_FAIL, m);
+ return -1;
+ }
+ }
+}
+
+/*****************************************************************************
+* Prototype : msg_try_post
+* Description : try post msg
+* Input : data_com_msg* m
+* mring_handle mhandle
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline int msg_try_post(data_com_msg * m, mring_handle mhandle)
+{
+ if (!m || !mhandle)
+ {
+ NSFW_LOGERR("param is not ok]m=%p,mhandle=%p", m, mhandle);
+ return -1;
+ }
+
+ int ret = nsfw_mem_ring_enqueue(mhandle, (void *) m);
+ if (1 == ret)
+ {
+ if (MSG_SYN_POST == m->param.op_type)
+ {
+ sys_arch_sem_s_wait(&m->param.op_completed, 0);
+ }
+
+ return 0;
+ }
+
+ return -1;
+}
+
+/*****************************************************************************
+* Prototype : msg_fetch
+* Description : fetch msg
+* Input : mring_handle mhandle
+* data_com_msg** m
+* u32 num
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline int msg_fetch(mring_handle mhandle, data_com_msg ** m, u32 num)
+{
+ if (!m || !mhandle)
+ {
+ NSFW_LOGERR("param is not ok]m=%p,mhandle=%p", m, mhandle);
+ return -1;
+ }
+
+ int ret;
+ while (1)
+ {
+ ret = nsfw_mem_ring_dequeuev(mhandle, (void *) m, num);
+ if (ret > 0)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : msg_try_fetch
+* Description : try fetch msg
+* Input : mring_handle mhandle
+* data_com_msg** m
+* u32 num
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*****************************************************************************/
+static inline int
+msg_try_fetch(mring_handle mhandle, data_com_msg ** m, u32 num)
+{
+ if (!m || !mhandle)
+ {
+ NSFW_LOGERR("param is not ok]m=%p,mhandle=%p", m, mhandle);
+ return -1;
+ }
+
+ return nsfw_mem_ring_dequeuev(mhandle, (void *) m, num);
+}
+
+#else
+data_com_msg *msg_malloc(mring_handle mhandle);
+void msg_free(data_com_msg * m);
+int msg_post(data_com_msg * m, mring_handle mhandle);
+int msg_try_post(data_com_msg * m, mring_handle mhandle);
+int msg_fetch(mring_handle mhandle, data_com_msg ** m, u32 num);
+int msg_try_fetch(mring_handle mhandle, data_com_msg ** m, u32 num);
+int msg_post_with_lock_rel(data_com_msg * m, mring_handle mhandle);
+#endif
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/nsfw_mt_config.h b/stacks/lwip_stack/src/include/nsfw_mt_config.h
new file mode 100644
index 0000000..3735be4
--- /dev/null
+++ b/stacks/lwip_stack/src/include/nsfw_mt_config.h
@@ -0,0 +1,63 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _FW_MT_CONFIG_H
+#define _FW_MT_CONFIG_H
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#include "nsfw_maintain_api.h"
+
+/* socket num config */
+#define SOCKET_NUM_PER_THREAD 1024 /* socket number per thread */
+
+#define APP_POOL_NUM 32
+
+#define DEF_HAL_RX_RING_SIZE 2048
+
+/* stackx recv ring size config */
+#define DEF_SPL_MAX_RING_SIZE 1024
+
+/* pcb number config */
+#define DEF_TCP_PCB_NUM 4096 /* tcp pcb number, per thread */
+#define DEF_UDP_PCB_NUM 512 /* udp pcb number, per thread */
+#define DEF_RAW_PCB_NUM 600 /* raw pcb number, per thread */
+
+#define DEF_ARP_QUEUE_NUM 300
+
+/* tx mbuf pool size config */
+#define DEF_TX_MBUF_POOL_SIZE (4*POOL_RING_BASE_SIZE)
+
+/* rx mbuf pool size config */
+#define DEF_RX_MBUF_POOL_SIZE (8*POOL_RING_BASE_SIZE) /* rx mbuf pool size */
+
+/* stackx internal msg number config */
+#define DEF_TX_MSG_POOL_SIZE (DEF_TX_MBUF_POOL_SIZE*APP_POOL_NUM + MAX_VF_NUM*DEF_RX_MBUF_POOL_SIZE + DEF_RING_BASE_SIZE)
+
+/* mbox ring size config */
+#define DEF_MBOX_RING_SIZE (DEF_RING_BASE_SIZE/4)
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/nsfw_rti.h b/stacks/lwip_stack/src/include/nsfw_rti.h
new file mode 100644
index 0000000..f6eb1b8
--- /dev/null
+++ b/stacks/lwip_stack/src/include/nsfw_rti.h
@@ -0,0 +1,49 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef RTI_H
+#define RTI_H
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define nsfw_rti_stat_macro(type, m) if (1 == g_dfx_switch) { nsfw_rti_stat(type, m); }
+
+typedef enum nsfw_rti_stat_type
+{
+ NSFW_STAT_PRIMARY_ENQ,
+ NSFW_STAT_PRIMARY_ENQ_FAIL,
+ NSFW_STAT_PRIMARY_DEQ,
+} nsfw_rti_stat_type_t;
+
+struct rti_queue;
+struct msg_t;
+
+extern char g_dfx_switch;
+extern struct rti_queue *g_nsfw_rti_primary_stat;
+
+void nsfw_rti_stat(nsfw_rti_stat_type_t statType, const struct msg_t *m);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/include/nstack_dmm_adpt.h b/stacks/lwip_stack/src/include/nstack_dmm_adpt.h
new file mode 100644
index 0000000..7e6e9cb
--- /dev/null
+++ b/stacks/lwip_stack/src/include/nstack_dmm_adpt.h
@@ -0,0 +1,64 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#ifndef __NSTACK_DMM_ADPT_H__
+#define __NSTACK_DMM_ADPT_H__
+
+typedef enum
+{
+ NSTACK_MODEL_TYPE1 = 1, /*nSocket and stack belong to the same process */
+ NSTACK_MODEL_TYPE2 = 2, /*nSocket and stack belong to different processes,
+ *and nStack don't take care the communication between stack and stack adpt
+ */
+ NSTACK_MODEL_TYPE3 = 3, /*nSocket and stack belong to different processes, and sbr was supplied to communicate whit stack */
+ NSTACK_MODEL_TYPE_SIMPLE_STACK = 4, /* like TYPE1, DMM will NOT provide SBR or pipeline mode, just allocate 32M, and use dpdk file
+ * prefix to support multiple running app under DMM */
+ NSTACK_MODEL_INVALID,
+} nstack_model_deploy_type;
+
+#define NSTACK_DMM_MODULE "nstack_dmm_module"
+
+typedef struct nsfw_com_attr
+{
+ int policy;
+ int pri;
+} nsfw_com_attr;
+
+typedef struct __nstack_dmm_para
+{
+ nstack_model_deploy_type deploy_type;
+ int proc_type;
+ nsfw_com_attr attr;
+ int argc;
+ char **argv;
+} nstack_dmm_para;
+
+extern int nstack_adpt_init(nstack_dmm_para * para);
+extern int nstack_event_callback(void *pdata, int events);
+
+#endif
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/stacks/lwip_stack/src/io_adpt/CMakeLists.txt b/stacks/lwip_stack/src/io_adpt/CMakeLists.txt
new file mode 100644
index 0000000..53915f1
--- /dev/null
+++ b/stacks/lwip_stack/src/io_adpt/CMakeLists.txt
@@ -0,0 +1,41 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+FILE(GLOB_RECURSE HAL *.c)
+
+if(WITH_SECUREC_LIB)
+INCLUDE_DIRECTORIES(
+ ./
+ ${JSON_C_SRC}
+ ${SECUREC_SRC}
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+)
+else()
+SET(PAL_H_DIRECTORIES "/usr/include/dpdk/")
+INCLUDE_DIRECTORIES(
+ ${PAL_H_DIRECTORIES}
+ ./
+ ${JSON_C_SRC}
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/hal/
+)
+endif()
+ADD_LIBRARY(nStackHal STATIC ${HAL})
+LINK_LIBRARIES(m dl rt nStackFw)
diff --git a/stacks/lwip_stack/src/io_adpt/dpdk.c b/stacks/lwip_stack/src/io_adpt/dpdk.c
new file mode 100644
index 0000000..e662a21
--- /dev/null
+++ b/stacks/lwip_stack/src/io_adpt/dpdk.c
@@ -0,0 +1,2499 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdint.h>
+#include <sched.h>
+#include <dlfcn.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fnmatch.h>
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+
+#include <rte_config.h>
+#include <rte_ethdev.h>
+#include <rte_mbuf.h>
+#include <rte_eth_bond.h>
+#include "nstack_log.h"
+#include "nsfw_init_api.h"
+#include "common_mem_mbuf.h"
+#include "common_mem_mempool.h"
+#include "common_func.h"
+#include "hal.h"
+#include "nstack_securec.h"
+#include <rte_ethdev_driver.h>
+
+#define DPDK_NON_ROOT_USER_NAME "paas"
+#define DPDK_TOOL_ENV "DPDK_TOOL_DIR"
+#define DPDK_NIC_LIST_FILE "%s/ip_module/.nstack_dpdk_nic_list"
+#define SOCKET_ID_0 0
+
+NSTACK_STATIC struct passwd *dpdk_non_root_user;
+NSTACK_STATIC char dpdk_tool_path[HAL_MAX_PATH_LEN] = { 0 };
+
+/* Default configuration for rx and tx thresholds etc. */
+NSTACK_STATIC const struct rte_eth_rxconf rx_conf_default_igb = {
+ .rx_thresh = {
+ .pthresh = 8,
+ .hthresh = 8,
+ .wthresh = 1, //not bigger than 1
+ },
+};
+
+/*
+ * These default values are optimized for use with the Intel(R) 82576 1 GbE
+ * Controller and the DPDK e1000 PMD. Consider using other values for other
+ * network controllers and/or network drivers.
+ */
+NSTACK_STATIC const struct rte_eth_txconf tx_conf_default_igb = {
+ .tx_thresh = {
+ .pthresh = 8,
+ .hthresh = 1,
+ .wthresh = 16,
+ },
+ .tx_free_thresh = 0, /* Use PMD default values */
+ .tx_rs_thresh = 0, /* Use PMD default values */
+};
+
+/*
+ * RX and TX Prefetch, Host, and Write-back threshold values should be
+ * carefully set for optimal performance. Consult the network
+ * controller's datasheet and supporting DPDK documentation for guidance
+ * on how these parameters should be set.
+ */
+
+/* Default configuration for rx and tx thresholds etc. */
+NSTACK_STATIC const struct rte_eth_rxconf rx_conf_default_ixgbe = {
+ .rx_thresh = {
+ .pthresh = 8,
+ .hthresh = 8,
+ .wthresh = 4,
+ },
+ .rx_free_thresh = 0,
+};
+
+/*
+ * These default values are optimized for use with the Intel(R) 82599 10 GbE
+ * Controller and the DPDK ixgbe PMD. Consider using other values for other
+ * network controllers and/or network drivers.
+ */
+NSTACK_STATIC const struct rte_eth_txconf tx_conf_default_ixgbe = {
+ .tx_thresh = {
+ .pthresh = 36,
+ .hthresh = 0,
+ .wthresh = 0,
+ },
+ .tx_free_thresh = 0, /* Use PMD default values */
+ .tx_rs_thresh = 0, /* Use PMD default values */
+ .txq_flags = 0,
+};
+
+/* the port configuration of normal port */
+NSTACK_STATIC struct rte_eth_conf port_conf_default_normal = {
+ .rxmode = {
+ .mq_mode = ETH_RSS,
+ .max_rx_pkt_len = ETHER_MAX_LEN,
+ .split_hdr_size = 0,
+ .header_split = 0,
+ .hw_ip_checksum = 1,
+ .hw_vlan_filter = 1,
+ .hw_vlan_strip = 1,
+ .jumbo_frame = 0,
+ .hw_strip_crc = 0,
+ },
+ .rx_adv_conf = {
+ .rss_conf = {
+ .rss_key = NULL,
+ .rss_hf = (ETH_RSS_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP), //rss hash key
+ },
+ },
+ .txmode = {
+ .mq_mode = ETH_DCB_NONE,
+ },
+ .intr_conf = {
+ .lsc = 0,
+ },
+};
+
+/* the port configuration of virtio port */
+NSTACK_STATIC struct rte_eth_conf port_conf_default_virtio = {
+ .rxmode = {
+ .mq_mode = ETH_RSS,
+ .max_rx_pkt_len = ETHER_MAX_LEN,
+ .split_hdr_size = 0,
+ .header_split = 0,
+ .hw_ip_checksum = 0, /* Virtio NIC doesn't support HW IP CheckSUM */
+ .hw_vlan_filter = 1,
+ .hw_vlan_strip = 1,
+ .jumbo_frame = 0,
+ .hw_strip_crc = 0,
+ },
+ .rx_adv_conf = {
+ .rss_conf = {
+ .rss_key = NULL,
+ .rss_hf = (ETH_RSS_IPV4 | ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP), //rss hash key
+ },
+ },
+ .txmode = {
+ .mq_mode = ETH_DCB_NONE,
+ },
+ .intr_conf = {
+ .lsc = 0,
+ },
+};
+
+/* the port configuration of bond port */
+NSTACK_STATIC struct rte_eth_conf port_conf_default_bond = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_NONE,
+ .max_rx_pkt_len = ETHER_MAX_LEN,
+ .split_hdr_size = 0,
+ .header_split = 0,
+ /**< Header Split disabled */
+ .hw_ip_checksum = 0,
+ /**< IP checksum offload enabled */
+ .hw_vlan_filter = 1,
+ /**< VLAN filtering enabled */
+ .hw_vlan_strip = 1,
+ .jumbo_frame = 0,
+ /**< Jumbo Frame Support disabled */
+ .hw_strip_crc = 0,
+ /**< CRC stripped by hardware */
+ },
+ .rx_adv_conf = {
+ .rss_conf = {
+ .rss_key = NULL,
+ .rss_hf = ETH_RSS_IP,
+ },
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+};
+
+NSTACK_STATIC struct rte_eth_conf port_conf_default_vhost = {
+ .rxmode = {
+ .hw_ip_checksum = 0, /* vhost nic doesn't support hw_ip_checksum and hw_vlan_filter */
+ .hw_vlan_filter = 0,
+ }
+};
+
+/*****************************************************************************
+* Prototype : dpdk_mbuf_to_file
+* Description : write the packet data into a file
+* Input : uint16_t pkt_number
+* struct rte_mbuf **pkts
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+NSTACK_STATIC void
+dpdk_mbuf_to_file(uint16_t pkt_number, struct rte_mbuf **pkts)
+{
+ char line[100] = { 0 };
+ FILE *f = NULL;
+ struct rte_mbuf *p = NULL;
+ uint16_t len = 0, offset, i;
+ uint16_t pktlen = 0;
+ uint16_t start = 0;
+ uint16_t number = 0;
+ unsigned char *data = NULL;
+
+ f = fopen("/var/log/nStack/packet.txt", "a+");
+ if (f == NULL)
+ {
+ NSHAL_LOGERR("can not open the file:%s", "packet.txt");
+ return;
+ }
+
+ for (i = 0; i < pkt_number; i++)
+ {
+ pktlen = 0;
+ p = pkts[i];
+ while (p)
+ {
+ len = 0;
+ data = rte_pktmbuf_mtod(p, unsigned char *);
+ while (len < p->data_len)
+ {
+ start = pktlen % 16; /* start of the line */
+ if (start == 0)
+ {
+ number = snprintf_s(line, sizeof(line), sizeof(line) - 1,
+ "%08X", len);
+ }
+
+ for (offset = 0;
+ ((offset + start) < 16)
+ && ((len + offset) < p->data_len); offset++)
+ {
+ number +=
+ snprintf_s(line + number, sizeof(line),
+ sizeof(line) - 1, " %02X",
+ data[len + offset]);
+ }
+
+ fprintf(f, "%s", line);
+ if ((offset + start) == 16)
+ fprintf(f, "\n");
+
+ len += offset;
+ pktlen += offset;
+ (void) memset_s(line, sizeof(line), 0, sizeof(line));
+ }
+
+ p = p->next;
+
+ }
+ fprintf(f, "\n");
+ }
+
+ fclose(f);
+ return;
+}
+
+/*****************************************************************************
+* Prototype : hal_rte_eth_rx_burst
+* Description : a copy of rte_eth_rx_burst, because this function invokes
+ a global(rte_eth_devices), which cannt be access by dlsym
+ symbols
+* Input : uint8_t port_id
+* uint16_t queue_id
+* struct rte_mbuf **rx_pkts
+* const uint16_t nb_pkts
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+NSTACK_STATIC inline uint16_t
+hal_rte_eth_rx_burst(uint8_t port_id, uint16_t queue_id,
+ struct rte_mbuf ** rx_pkts, const uint16_t nb_pkts)
+{
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+ struct rte_eth_rxtx_callback *cb;
+#endif
+ int16_t nb_rx;
+ char *pst_capture_packet = NULL;
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+ if (NULL == dev->rx_pkt_burst)
+ {
+ NSHAL_LOGERR("dev->rx_pkt_burst is NULL,dev=%p", dev);
+ return 0;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, 0);
+
+ if (queue_id >= dev->data->nb_rx_queues)
+ {
+ RTE_PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", queue_id);
+ return 0;
+ }
+#endif
+ nb_rx = (*dev->rx_pkt_burst) (dev->data->rx_queues[queue_id],
+ rx_pkts, nb_pkts);
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+ cb = dev->post_rx_burst_cbs[queue_id];
+
+ if (unlikely(cb != NULL))
+ {
+ do
+ {
+ nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
+ nb_pkts, cb->param);
+ cb = cb->next;
+ }
+ while (cb != NULL);
+ }
+#endif
+
+ //pst_capture_packet = getenv ("NSTACK_CAPTURE_PACKET");
+ if (pst_capture_packet && strcmp(pst_capture_packet, "1") == 0)
+ {
+ dpdk_mbuf_to_file(nb_rx, rx_pkts);
+ }
+ return (uint16_t) nb_rx;
+}
+
+/*****************************************************************************
+* Prototype : hal_rte_eth_tx_burst
+* Description : a copy of rte_eth_tx_burst, because this function invokes
+
+* Input : uint8_t port_id
+* uint16_t queue_id
+* struct rte_mbuf **tx_pkts
+* uint16_t nb_pkts
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+NSTACK_STATIC inline uint16_t
+hal_rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
+ struct rte_mbuf ** tx_pkts, uint16_t nb_pkts)
+{
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+ struct rte_eth_rxtx_callback *cb;
+#endif
+ int16_t nb_tx = 0;
+ char *pst_capture_packet = NULL;
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+ if (NULL == dev->tx_pkt_burst)
+ {
+ NSHAL_LOGERR("dev->tx_pkt_burst is NULL");
+ return 0;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->tx_pkt_burst, 0);
+
+ if (queue_id >= dev->data->nb_tx_queues)
+ {
+ RTE_PMD_DEBUG_TRACE("Invalid TX queue_id=%d\n", queue_id);
+ return 0;
+ }
+#endif
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+ cb = dev->pre_tx_burst_cbs[queue_id];
+
+ if (unlikely(cb != NULL))
+ {
+ do
+ {
+ nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts, nb_pkts,
+ cb->param);
+ cb = cb->next;
+ }
+ while (cb != NULL);
+ }
+#endif
+
+ nb_tx = (*dev->tx_pkt_burst) (dev->data->tx_queues[queue_id], tx_pkts,
+ nb_pkts);
+
+ //pst_capture_packet = getenv ("NSTACK_CAPTURE_PACKET");
+ if (pst_capture_packet && strcmp(pst_capture_packet, "1") == 0)
+ {
+ dpdk_mbuf_to_file(nb_tx, tx_pkts);
+ }
+
+ return nb_tx;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_hugepage_size
+ Description : get the free hugepage size
+ Input : the dir of the nstack hugepage
+ Output : free hugepage size
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+int dpdk_read_hugepage_size(int *freehuge)
+{
+ int fd_huge;
+ int len;
+ char buf[5] = { '\0' };
+ fd_huge =
+ open("/sys/kernel/mm/hugepages/hugepages-1048576kB/free_hugepages",
+ O_RDONLY);
+ if (fd_huge < 0)
+ {
+ NSHAL_LOGERR("errno=%d", errno);
+ return -1;
+ }
+
+ len = read(fd_huge, buf, sizeof(buf));
+ if (len < 0)
+ {
+ NSHAL_LOGERR("errno=%d", errno);
+ close(fd_huge); //fix codeDEX 124547
+ return -1;
+ }
+ *freehuge = buf[0] - '0';
+ NSHAL_LOGINF("hugepage size=%d", *freehuge);
+ close(fd_huge);
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_clear_hugedir
+ Description : clear the hugepage which is used by dpdk
+ Input : the dir of the nstack hugepage
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_clear_hugedir(const char *hugedir)
+{
+ DIR *dir;
+ struct dirent *dirent_dpdk;
+ int dir_fd, fd, lck_result, lk_result;
+ const char filter[] = "*mapns*"; /* matches hugepage files */
+
+ /* open directory */
+ dir = opendir(hugedir);
+ if (!dir)
+ {
+ NSHAL_LOGERR("the path %s is not exist, errno = %d", hugedir, errno);
+ goto error;
+ }
+ dir_fd = dirfd(dir);
+
+ dirent_dpdk = readdir(dir);
+ if (!dirent_dpdk)
+ {
+ NSHAL_LOGERR("the dir %s can not read, errno = %d", hugedir, errno);
+ goto error;
+ }
+
+ while (dirent_dpdk != NULL)
+ {
+ /* skip files that don't match the hugepage pattern */
+ if (fnmatch(filter, dirent_dpdk->d_name, 0) > 0)
+ {
+ NSHAL_LOGWAR("the file name %s is not match mapns, errno = %d",
+ dirent_dpdk->d_name, errno);
+ dirent_dpdk = readdir(dir);
+ continue;
+ }
+
+ /* try and lock the file */
+ fd = openat(dir_fd, dirent_dpdk->d_name, O_RDONLY);
+
+ /* skip to next file */
+ if (fd == -1)
+ {
+ NSHAL_LOGERR("the file name %s can not be lock, errno = %d",
+ dirent_dpdk->d_name, errno);
+ dirent_dpdk = readdir(dir);
+ continue;
+ }
+
+ /* non-blocking lock */
+ lck_result = flock(fd, LOCK_EX | LOCK_NB);
+
+ /* if lock succeeds, unlock and remove the file */
+ if (lck_result != -1)
+ {
+ NSHAL_LOGWAR
+ ("the file name %s can be lock and will delete, errno = %d",
+ dirent_dpdk->d_name, errno);
+ lck_result = flock(fd, LOCK_UN);
+ if (-1 == lck_result)
+ NSHAL_LOGERR("the file name %s unlock fail, errno = %d",
+ dirent_dpdk->d_name, errno);
+ lk_result = unlinkat(dir_fd, dirent_dpdk->d_name, 0);
+ if (-1 == lk_result)
+ NSHAL_LOGERR("the file name %s is unlinkat fail, errno = %d",
+ dirent_dpdk->d_name, errno);
+ }
+ close(fd);
+ dirent_dpdk = readdir(dir);
+ }
+
+ (void) closedir(dir);
+ return 0;
+
+ error:
+ if (dir)
+ (void) closedir(dir);
+
+ return -1;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_init_global
+ Description : DPDK global init
+ Input : int argc
+ char** argv
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_init_global(int argc, char **argv)
+{
+ //int ret;
+ const char hugepath[] = "/mnt/nstackhuge";
+ //int freeHuge = 0;
+ //int retryCount = 10;
+
+ if (-1 == dpdk_clear_hugedir(hugepath))
+ {
+ NSHAL_LOGERR("clear hugedir fail, try again!");
+ sys_sleep_ns(0, 100000000);
+ (void) dpdk_clear_hugedir(hugepath);
+ }
+ NSHAL_LOGINF("init global succ");
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_init_env
+ Description : init dpdk run env
+ Input : void
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_init_env(void)
+{
+ int ret;
+ size_t len_size;
+ char *dpdk_env;
+ char *dpdk_path;
+
+ /* Get dpdk_tool_path */
+ dpdk_env = getenv(DPDK_TOOL_ENV);
+ if (NULL == dpdk_env)
+ {
+ NSHAL_LOGERR("please set enviroment:%s before start this stack"
+ "\nthe value of the %s must be the path of dpdk tools",
+ DPDK_TOOL_ENV, DPDK_TOOL_ENV);
+ return -1;
+ }
+
+ /* modify ugly len_size judgement and strcpy */
+ /* check len_size for malloc */
+ len_size = strlen(dpdk_env);
+ if (0 == len_size || len_size >= HAL_MAX_PATH_LEN)
+ {
+ NSHAL_LOGERR("fail to dpdk_env strlen(DPDK_TOOL_ENV)");
+ return -1;
+ }
+
+ /* DPDK_TOOL_ENV's value will be use as popen's paramter,we need check's validity */
+ dpdk_path = realpath(dpdk_env, NULL);
+ if (NULL == dpdk_path)
+ {
+ NSHAL_LOGERR("env:%s value incorrect]value=%s,errno=%d",
+ DPDK_TOOL_ENV, dpdk_env, errno);
+ return -1;
+ }
+
+ len_size = strlen(dpdk_path);
+ if (0 == len_size || len_size >= HAL_MAX_PATH_LEN)
+ {
+ NSHAL_LOGERR("fail to dpdk_path strlen(DPDK_TOOL_ENV)");
+ return -1;
+ }
+
+ ret = strcpy_s(dpdk_tool_path, HAL_MAX_PATH_LEN, dpdk_path);
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRCPY_S failed]ret=%d", ret);
+ return -1;
+ }
+
+ if (!hal_is_script_valid(dpdk_tool_path))
+ {
+ NSHAL_LOGERR("dpdk_tool_path is invalid]dpdk_tool_path=%s",
+ dpdk_tool_path);
+ return -1;
+ }
+
+ /* get non-root user's id */
+ dpdk_non_root_user = getpwnam(DPDK_NON_ROOT_USER_NAME);
+ if (dpdk_non_root_user)
+ {
+ NSHAL_LOGINF("non-root]name=%s,uid=%u,gid=%u,errno=%d",
+ dpdk_non_root_user->pw_name, dpdk_non_root_user->pw_uid,
+ dpdk_non_root_user->pw_gid, errno);
+ }
+ else
+ {
+ NSHAL_LOGERR("non-root]cannot find user %s", DPDK_NON_ROOT_USER_NAME);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_init_local
+ Description : DPDK local init
+ Input : void
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_init_local(void)
+{
+ int ret;
+
+ ret = dpdk_init_env();
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("dpdk_init_env failed");
+ return -1;
+ }
+
+ NSHAL_LOGINF("init local succ");
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_set_port
+ Description : check and save the port num
+ Input : netif_inst_t* inst
+ int port
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_set_port(netif_inst_t * inst, uint8_t port)
+{
+ if (port >= rte_eth_dev_count())
+ {
+ NSHAL_LOGERR
+ ("the number of port=%d is more than rte_eth_dev_count=%d", port,
+ rte_eth_dev_count());
+ return -1;
+ }
+
+ inst->data.dpdk_if.port_id = port;
+
+ return 0;
+
+}
+
+/*****************************************************************************
+ Prototype : dpdk_set_nic_type
+ Description : check and save nic type
+ Input : netif_inst_t* inst
+ const char* type
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_set_nic_type(netif_inst_t * inst, const char *type)
+{
+ int ret;
+
+ ret =
+ strcpy_s(inst->data.dpdk_if.nic_type,
+ sizeof(inst->data.dpdk_if.nic_type), type);
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("strcpy_s set nic_type failed]ret=%d", ret);
+ return -1;
+ }
+
+ /*
+ * *nic_type is first checked at read_ipmoduleoperateadd_configuration,
+ * *thus here we dont boring validating it once more and just return.
+ * */
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_set_nic_name
+ Description : check and save nic name
+ Input : netif_inst_t* inst
+ const char* name
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_set_nic_name(netif_inst_t * inst, const char *name)
+{
+ int ret;
+
+ /* sizeof(pointer) always = 8 in 64 bit system */
+ ret =
+ strcpy_s(inst->data.dpdk_if.nic_name,
+ sizeof(inst->data.dpdk_if.nic_name), name);
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRCPY_S set nic_name failed]ret=%d", ret);
+ return -1;
+ }
+
+ if (!hal_is_script_valid(inst->data.dpdk_if.nic_name))
+ {
+ NSHAL_LOGERR("nic_name is invalid");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_driver_name
+ Description : get and save driver name
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_get_driver_name(netif_inst_t * inst)
+{
+ int ret_len, ret;
+ char script_cmmd[HAL_SCRIPT_LENGTH];
+ char driver_name[HAL_SCRIPT_LENGTH] = { 0 };
+
+ ret = hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "readlink -f /sys/class/net/" "%s"
+ "/device/driver| awk -F'/' '{print $6}'",
+ inst->data.dpdk_if.nic_name);
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("hal_snprintf failed");
+ return -1;
+ }
+
+ ret_len =
+ hal_run_script(script_cmmd, driver_name, sizeof(driver_name) - 1);
+
+ if (ret_len > HAL_MAX_DRIVER_NAME_LEN)
+ {
+ ret_len = HAL_MAX_DRIVER_NAME_LEN;
+ }
+
+ if (ret_len <= 0)
+ {
+ NSHAL_LOGERR("%s does't have a driver", driver_name);
+
+ ret =
+ strncpy_s(inst->data.dpdk_if.driver_name,
+ sizeof(inst->data.dpdk_if.driver_name), "NULL",
+ sizeof("NULL"));
+
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRNCPY_S failed]ret=%d.", ret);
+ return -1;
+ }
+
+ return -1;
+ }
+ else
+ {
+ ret =
+ strncpy_s(inst->data.dpdk_if.driver_name,
+ sizeof(inst->data.dpdk_if.driver_name), driver_name,
+ ret_len);
+
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRNCPY_S failed]ret=%d.", ret);
+ return -1;
+ }
+
+ inst->data.dpdk_if.driver_name[(ret_len - 1)] = '\0';
+
+ return 0;
+ }
+}
+
+/*****************************************************************************
+ Prototype : dpdk_set_pci_permission
+ Description : set pci permission
+ Input : char *pci_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_set_pci_permission(char *pci_addr)
+{
+ DIR *dir_desc;
+ char file_path[HAL_SCRIPT_LENGTH] = { 0 }, dir_path[HAL_SCRIPT_LENGTH] =
+ {
+ 0};
+ struct dirent *ent;
+ struct stat statbuf;
+ int ret;
+
+ ret =
+ snprintf_s(dir_path, sizeof(dir_path), sizeof(dir_path) - 1,
+ "/sys/bus/pci/devices/%s", pci_addr);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("SNPRINTF_S fail");
+ return -1;
+ }
+
+ if ((dir_desc = opendir(dir_path)) == NULL)
+ {
+ NSHAL_LOGERR("opendir fail:errno=%d", errno);
+ return -1;
+ }
+
+ while ((ent = readdir(dir_desc)) != NULL)
+ {
+ if (strstr(ent->d_name, "resource"))
+ {
+ ret =
+ snprintf_s(file_path, sizeof(file_path),
+ sizeof(file_path) - 1, "%s/%s", dir_path,
+ ent->d_name);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("SNPRINTF_S fail");
+ (void) closedir(dir_desc);
+ return -1;
+ }
+
+ if (!lstat(file_path, &statbuf) && !S_ISDIR(statbuf.st_mode))
+ {
+ ret =
+ chown(file_path, dpdk_non_root_user->pw_uid,
+ dpdk_non_root_user->pw_gid);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chown fail]file_path=%s,ret=%d,errno=%d",
+ file_path, ret, errno);
+ (void) closedir(dir_desc);
+ return -1;
+ }
+ NSHAL_LOGWAR("chown succ]file_path=%s,ret=%d", file_path,
+ ret);
+ ret = chmod(file_path, 0640);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chmod fail]file_path=%s,ret=%d,errno=%d",
+ file_path, ret, errno);
+ (void) closedir(dir_desc);
+ return -1;
+ }
+ NSHAL_LOGWAR("chmod succ]file_path=%s,ret=%d", file_path,
+ ret);
+ }
+ }
+ }
+
+ (void) closedir(dir_desc);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_pci_addr
+ Description : get and save pci addr
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_get_pci_addr(netif_inst_t * inst)
+{
+ int ret, pci_len;
+ struct ethtool_drvinfo edata = { 0 };
+ struct ifreq ifr;
+ int fd = -1;
+
+ /* use ioctl to get pci address instead of call dpdk-devbind.py to reduce time cost */
+ ret = memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("MEMSET_S fail");
+ return -1;
+ }
+ edata.cmd = ETHTOOL_GDRVINFO;
+ ret =
+ strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name),
+ inst->data.dpdk_if.nic_name);
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRCPY_S fail");
+ return -1;
+ }
+
+ ifr.ifr_data = (char *) (&edata);
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ NSHAL_LOGERR("cannot init socket, errno=%d", errno);
+ return -1;
+ }
+ if (ioctl(fd, SIOCETHTOOL, &ifr) < 0)
+ {
+ NSHAL_LOGERR("ioctl to the device %s err, errno=%d",
+ inst->data.dpdk_if.nic_name, errno);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ pci_len = strlen(edata.bus_info);
+ if (pci_len == 0
+ || pci_len > (int) sizeof(inst->data.dpdk_if.pci_addr) - 1)
+ {
+ NSHAL_LOGERR("does't have a pci_addr");
+ inst->data.dpdk_if.pci_addr[0] = '\0';
+ return -1;
+ }
+
+ NSHAL_LOGINF("nic_name=%s,nic_pci_addr=%s", inst->data.dpdk_if.nic_name,
+ edata.bus_info);
+
+ ret =
+ strncpy_s(inst->data.dpdk_if.pci_addr,
+ sizeof(inst->data.dpdk_if.pci_addr), edata.bus_info,
+ pci_len);
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRNCPY_S failed]ret=%d.", ret);
+ return -1;
+ }
+
+ if (!hal_is_script_valid(inst->data.dpdk_if.pci_addr))
+ {
+ NSHAL_LOGERR("pci_addr is invalid]pci_addr=%s",
+ inst->data.dpdk_if.pci_addr);
+ return -1;
+ }
+
+ if (dpdk_non_root_user && getuid())
+ {
+ ret = dpdk_set_pci_permission(inst->data.dpdk_if.pci_addr);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("dpdk_set_pci_permission fail");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_mlx_linkup
+ Description : linkup the port for mlx
+ In bonding mode, mlx4 NICs should be set up manually,
+ in order to make bond port up
+ Input : char* name
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_mlx_linkup(char *name)
+{
+ struct ifreq st_ifreq;
+ int sock;
+ int retVal;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ NSHAL_LOGERR("socket fail]errno=%d", errno);
+ return 2;
+ }
+
+ retVal = strcpy_s(st_ifreq.ifr_name, sizeof(st_ifreq.ifr_name), name);
+
+ if (EOK != retVal)
+ {
+ NSHAL_LOGERR("STRCPY_S fail]");
+ close(sock);
+ return 1;
+ }
+
+ if (ioctl(sock, (uint64_t) SIOCGIFFLAGS, &st_ifreq) < 0)
+ {
+ NSHAL_LOGERR("ioctl SIOCGIFFLAGS fail]errno=%d", errno);
+ close(sock);
+ return 3;
+ }
+
+ st_ifreq.ifr_flags |= IFF_UP;
+ st_ifreq.ifr_flags |= IFF_RUNNING;
+
+ if (ioctl(sock, (uint64_t) SIOCSIFFLAGS, &st_ifreq) < 0)
+ {
+ NSHAL_LOGERR("ioctl SIOCSIFFLAGS fail]errno=%d", errno);
+ close(sock);
+ return 3;
+ }
+
+ close(sock);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_nonmlx_linkdown
+ Description : linkdown the port for nonmlx
+ Input : char* name
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_nonmlx_linkdown(char *name)
+{
+ int ret, ret_len;
+ char script_cmmd[HAL_SCRIPT_LENGTH];
+ char result_buf[HAL_SCRIPT_LENGTH];
+
+ ret =
+ hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "sudo ifconfig %s down", name);
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("spl_snprintf failed]");
+ return -1;
+ }
+
+ ret_len = hal_run_script(script_cmmd, result_buf, sizeof(result_buf));
+ NSHAL_LOGINF("ifconfig]script_cmmd=%s,ret_len=%d", script_cmmd, ret_len);
+ if (0 > ret_len)
+ {
+ NSHAL_LOGERR("cannot able to ifconfig %s down", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_uio_by_pci_addr
+ Description : get uio
+ Input : char *pci_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_get_uio_by_pci_addr(char *pci_addr)
+{
+ int i, ret, ret_len;
+ char script_cmmd[HAL_SCRIPT_LENGTH];
+ char result_buf[HAL_SCRIPT_LENGTH];
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+ {
+ ret = hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "readlink ls /sys/class/uio/uio%d/device | awk -F '/' '{print $4}'",
+ i);
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("hal_snprintf fail]pci=%s,i=%d", pci_addr, i);
+ return -1;
+ }
+
+ ret_len = hal_run_script(script_cmmd, result_buf, sizeof(result_buf));
+ if (0 > ret_len)
+ {
+ NSHAL_LOGERR("hal_run_script fail]pci=%s,i=%d", pci_addr, i);
+ return -1;
+ }
+ if (strcmp(result_buf, pci_addr) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_set_uio_permission
+ Description : set uio permission
+ Input : char *pci_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_set_uio_permission(char *pci_addr)
+{
+ int ret, uio_idx;
+ char file_path[HAL_SCRIPT_LENGTH / 2] = { 0 };
+
+ /* get /dev/uio by pci addr */
+ uio_idx = dpdk_get_uio_by_pci_addr(pci_addr);
+ if (uio_idx < 0)
+ {
+ NSHAL_LOGERR("dpdk_get_uio_by_pci_addr fail]pci_addr=%s", pci_addr);
+ return -1;
+ }
+
+ NSHAL_LOGINF("uio_idx]pci=%s,uio%d", pci_addr, uio_idx);
+
+ /* change /dev/uio%u permission */
+ if (snprintf_s
+ (file_path, sizeof(file_path), sizeof(file_path) - 1, "/dev/uio%d",
+ uio_idx) < 0)
+ {
+ NSHAL_LOGERR("SNPRINTF_S failed]uio%d", uio_idx);
+ return -1;
+ }
+ sys_sleep_ns(0, 500000000);
+ ret =
+ chown(file_path, dpdk_non_root_user->pw_uid,
+ dpdk_non_root_user->pw_gid);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chown fail]file_path=%s,ret=%d,errno=%d", file_path,
+ ret, errno);
+ return -1;
+ }
+ NSHAL_LOGWAR("chown succ]file_path=%s,ret=%d", file_path, ret);
+
+ ret = chmod(file_path, 0640);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chmod fail]file_path=%s,ret=%d,errno=%d", file_path,
+ ret, errno);
+ return -1;
+ }
+ NSHAL_LOGWAR("chmod succ]file_path=%s,ret=%d", file_path, ret);
+
+ /* change /sys/class/uio/uio%u/device/config permission */
+ if (snprintf_s
+ (file_path, sizeof(file_path), sizeof(file_path) - 1,
+ "/sys/class/uio/uio%d/device/config", uio_idx) < 0)
+ {
+ NSHAL_LOGERR("SNPRINTF_S failed]uio%d", uio_idx);
+ return -1;
+ }
+
+ ret =
+ chown(file_path, dpdk_non_root_user->pw_uid,
+ dpdk_non_root_user->pw_gid);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chown fail]file_path=%s,ret=%d,errno=%d", file_path,
+ ret, errno);
+ return -1;
+ }
+ NSHAL_LOGWAR("chown succ]file_path=%s,ret=%d", file_path, ret);
+
+ ret = chmod(file_path, 0640);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("chmod fail]file_path=%s,ret=%d,errno=%d", file_path,
+ ret, errno);
+ return -1;
+ }
+ NSHAL_LOGWAR("chmod succ]file_path=%s,ret=%d", file_path, ret);
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_nic_list_file
+ Description : get dpdk bind nic list file
+ Input : void
+ Output : char*
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC char *dpdk_get_nic_list_file(void)
+{
+ int ret;
+ static char buffer[HAL_MAX_PATH_LEN]; /* static so auto-zeroed */
+ const char *directory = "/var/run";
+ const char *home_dir = getenv("HOME");
+
+ if (getuid() != 0 && home_dir != NULL)
+ directory = home_dir;
+
+ ret =
+ snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1,
+ DPDK_NIC_LIST_FILE, directory);
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("SNPRINTF_S failed]ret=%d", ret);
+ return NULL;
+ }
+
+ return buffer;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_bind_uio
+ Description : bind uio
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_bind_uio(netif_inst_t * inst)
+{
+ char script_cmmd[HAL_SCRIPT_LENGTH];
+ char result_buf[HAL_SCRIPT_LENGTH];
+ int ret, ret_len;
+
+ result_buf[0] = '\0';
+
+ if (strncmp("mlx4_co", inst->data.dpdk_if.driver_name, (size_t) 7) == 0)
+ {
+ /*For MLX4: NIC should be set link up before rte_eth_dev_start() is called. */
+ ret = dpdk_mlx_linkup(inst->data.dpdk_if.nic_name);
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("set mlx linkup fail]nic_name=%s,ret=%d",
+ inst->data.dpdk_if.nic_name, ret);
+
+ return -1;
+ }
+ }
+ else
+ {
+ /*For other drivers: NIC should be set link down before bind uio. */
+ ret = dpdk_nonmlx_linkdown(inst->data.dpdk_if.nic_name);
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("dpdk_nonmlx_linkdown fail]nic_name=%s",
+ inst->data.dpdk_if.nic_name);
+ return -1;
+ }
+
+ /* save binded VF list to file /var/run/ip_module/.nstack_dpdk_nic_list */
+ ret = hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "sudo %s"
+ "/dpdk-devbind.py -s | grep `ethtool -i %s| grep bus-info |awk '{print $2}'` >> %s 2>&1",
+ dpdk_tool_path, inst->data.dpdk_if.nic_name,
+ dpdk_get_nic_list_file());
+
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("hal_snprintf fail]nic_name=%s",
+ inst->data.dpdk_if.nic_name);
+ return -1;
+ }
+
+ ret_len =
+ hal_run_script(script_cmmd, result_buf, sizeof(result_buf) - 1);
+ NSHAL_LOGINF("bind]script_cmmd=%s,ret_len=%d", script_cmmd, ret_len);
+ if (0 > ret_len)
+ {
+ NSHAL_LOGERR("hal_run_script fail]script_cmmd=%s", script_cmmd);
+ return -1;
+ }
+
+ if (strncmp("virtio", inst->data.dpdk_if.driver_name, (size_t) 6) ==
+ 0)
+ {
+ /* For Virtio NIC, should call "./devbind.sh ethX" to bind the VF */
+ ret = hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "sudo %s"
+ "/dpdk-devbind.py --bind=igb_uio `ethtool -i %s| grep bus-info |awk '{print $2}'`",
+ dpdk_tool_path, inst->data.dpdk_if.nic_name);
+ //"sudo %s" "/devbind.sh " "%s", dpdk_tool_path, inst->data.dpdk_if.nic_name);
+
+ }
+ else
+ {
+ ret = hal_snprintf(script_cmmd, sizeof(script_cmmd),
+ "sudo %s" "/dpdk-devbind.py --bind=igb_uio "
+ "%s", dpdk_tool_path,
+ inst->data.dpdk_if.nic_name);
+ }
+
+ if (-1 == ret)
+ {
+ NSHAL_LOGERR("hal_snprintf failed");
+ return -1;
+ }
+
+ ret_len =
+ hal_run_script(script_cmmd, result_buf, sizeof(result_buf) - 1);
+ NSHAL_LOGINF("bind]script_cmmd=%s,retlen=%d", script_cmmd, ret_len);
+ if (0 > ret_len)
+ {
+ NSHAL_LOGERR("hal_run_script fail]script_cmmd=%s", script_cmmd);
+ return -1;
+ }
+
+ if (dpdk_non_root_user && getuid())
+ {
+ ret = dpdk_set_uio_permission(inst->data.dpdk_if.pci_addr);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("set_uio_permission fail]nic_name=%s",
+ inst->data.dpdk_if.nic_name);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_probe_pci
+ Description : probe pci
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_probe_pci(netif_inst_t * inst)
+{
+ int ret;
+ uint16_t port_id;
+ struct rte_eth_dev *eth_dev;
+ char *pci_addr = inst->data.dpdk_if.pci_addr;
+
+ ret = rte_eal_iopl_init();
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("rte_eal_iopl_init fail]pci_addr=%s,ret=%d", pci_addr,
+ ret);
+ return -1;
+ }
+
+ ret = rte_eth_dev_attach(pci_addr, &port_id);
+ if (0 != ret)
+ {
+ NSHAL_LOGWAR
+ ("pci attach to DPDK fail, the pci may have attached, try to get port id]pci_addr=%s,ret=%d",
+ pci_addr, ret);
+
+ eth_dev = rte_eth_dev_allocated(inst->data.dpdk_if.nic_name);
+ if (NULL != eth_dev && NULL != eth_dev->data)
+ {
+ port_id = eth_dev->data->port_id;
+ ret = 0;
+ }
+ }
+
+ if (!ret)
+ {
+ ret = dpdk_set_port(inst, port_id);
+
+ if (0 == ret)
+ {
+ NSHAL_LOGINF("set port success]pci_addr=%s,port_id=%u", pci_addr,
+ port_id);
+ }
+ else
+ {
+ NSHAL_LOGERR("set port fail]pci_addr=%s,port_id=%u", pci_addr,
+ port_id);
+ return -1;
+ }
+ }
+ else
+ {
+ NSHAL_LOGERR("get port fail]pci_addr=%s,ret=%d", pci_addr, ret);
+ return -1;
+ }
+
+ /*[TA33635][2017-04-24][l00408818] Start: support bond mode */
+ ret = rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, pci_addr);
+ if (!ret)
+ {
+ NSHAL_LOGINF("pci attach to whitelist success]pci_addr=%s", pci_addr);
+ }
+ else
+ {
+ NSHAL_LOGERR("pci attach to whitelist fail]pci_addr=%s", pci_addr);
+ return -1;
+ }
+ /*[TA33635][2017-04-24][l00408818] End */
+
+ return 0;
+}
+
+/*nic_name->driver_name->pci_addr->get port*/
+/*****************************************************************************
+ Prototype : dpdk_open
+ Description : open the port
+ Input : netif_inst_t* inst
+ const char* name
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_open(netif_inst_t * inst, const char *name, const char *type)
+{
+ int ret;
+
+ if ((inst == NULL) || (name == NULL) || (type == NULL))
+ {
+ NSHAL_LOGERR
+ ("invaliad arguments]inst==NULL, nic_type==NULL or type==NULL");
+ return -1;
+ }
+
+ ret = dpdk_set_nic_type(inst, type);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_set_nic_type fail]nic_type=%s, ret=%d", type, ret);
+ return -1;
+ }
+
+ ret = dpdk_set_nic_name(inst, name);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_set_nic_name fail]nic_name=%s, ret=%d", name, ret);
+ return -1;
+ }
+
+ if (!strncmp(type, "vhost", strlen("vhost")))
+ {
+ /*for vhost-user device, the remaining steps is unnecessary, y0413485 */
+ NSHAL_LOGERR("initting vhost device]nic_name=%s type=%s", name, type);
+ return 0;
+ }
+
+ ret = dpdk_get_driver_name(inst);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_get_driver_name fail]nic_name=%s, ret=%d", name,
+ ret);
+ return -1;
+ }
+
+ ret = dpdk_get_pci_addr(inst);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_get_pci_addr fail]nic_name=%s, ret=%d", name, ret);
+ return -1;
+ }
+
+ ret = dpdk_bind_uio(inst);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_bind_uio fail]nic_name=%s, ret=%d", name, ret);
+ return -1;
+ }
+
+ ret = dpdk_probe_pci(inst);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_probe_pci fail]nic_name=%s, ret=%d", name, ret);
+ return -1;
+ }
+
+ NSHAL_LOGINF("open port succ]port_id=%u, nic_name=%s",
+ inst->data.dpdk_if.port_id, inst->data.dpdk_if.nic_name);
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_close
+ Description : close the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_close(netif_inst_t * inst)
+{
+ int i;
+
+ /* close slave NIC first */
+ for (i = 0; i < inst->data.dpdk_if.slave_num; i++)
+ {
+ rte_eth_dev_close(inst->data.dpdk_if.slave_port[i]);
+ NSHAL_LOGINF("close slave port succ]port_id=%u, nic_name=%s",
+ inst->data.dpdk_if.slave_port[i],
+ inst->data.dpdk_if.nic_name);
+ }
+
+ rte_eth_dev_close(inst->data.dpdk_if.port_id);
+ NSHAL_LOGINF("close port succ]port_id=%u, nic_name=%s",
+ inst->data.dpdk_if.port_id, inst->data.dpdk_if.nic_name);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_queue_conf
+ Description : get the port queue configure
+ Input : netif_inst_t* inst
+ struct rte_eth_rxconf** rx_conf
+ struct rte_eth_txconf** tx_conf
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_get_queue_conf(netif_inst_t * inst,
+ struct rte_eth_rxconf **rx_conf,
+ struct rte_eth_txconf **tx_conf)
+{
+ static struct rte_eth_dev_info slave_dev_info;
+
+ if (strncmp("igb", inst->data.dpdk_if.driver_name, (size_t) 3) == 0)
+ {
+ *rx_conf = (struct rte_eth_rxconf *) &rx_conf_default_igb;
+ *tx_conf = (struct rte_eth_txconf *) &tx_conf_default_igb;
+ NSHAL_LOGINF("igb config is enable]port_id=%u",
+ inst->data.dpdk_if.port_id);
+ }
+ else if (strncmp("ixgbe", inst->data.dpdk_if.driver_name, (size_t) 5) ==
+ 0)
+ {
+ *rx_conf = (struct rte_eth_rxconf *) &rx_conf_default_ixgbe;
+ *tx_conf = (struct rte_eth_txconf *) &tx_conf_default_ixgbe;
+ NSHAL_LOGINF("igxbe config is enable]port_id=%u",
+ inst->data.dpdk_if.port_id);
+ }
+ else if (strncmp("bond", inst->data.dpdk_if.driver_name, (size_t) 4) == 0)
+ {
+ *rx_conf = NULL;
+ rte_eth_dev_info_get(inst->data.dpdk_if.slave_port[0],
+ &slave_dev_info);
+ *tx_conf = &(slave_dev_info.default_txconf);
+ NSHAL_LOGINF("bond config is enable]port_id=%u",
+ inst->data.dpdk_if.port_id);
+ }
+ else
+ {
+ *rx_conf = NULL;
+ *tx_conf = NULL;
+ NSHAL_LOGINF("default config is enable]port_id=%u",
+ inst->data.dpdk_if.port_id);
+ }
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_port_conf
+ Description : get the port configure
+ Input : netif_inst_t* inst
+ struct rte_eth_conf** port_conf
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC void
+dpdk_get_port_conf(netif_inst_t * inst, struct rte_eth_conf **port_conf)
+{
+ if (strncmp("virtio", inst->data.dpdk_if.driver_name, (size_t) 6) == 0)
+ {
+ *port_conf = &port_conf_default_virtio;
+ }
+ else if (strncmp("bond", inst->data.dpdk_if.driver_name, (size_t) 4) == 0)
+ {
+ *port_conf = &port_conf_default_bond;
+ }
+ else if (strncmp("vhost", inst->data.dpdk_if.nic_type, (size_t) 5) == 0)
+ {
+ *port_conf = &port_conf_default_vhost;
+ return;
+ }
+ else
+ {
+ *port_conf = &port_conf_default_normal;
+ }
+
+ (*port_conf)->rxmode.hw_vlan_filter = inst->data.dpdk_if.hw_vlan_filter;
+ (*port_conf)->rxmode.hw_vlan_strip = inst->data.dpdk_if.hw_vlan_strip;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_setup_port
+ Description : setup the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_setup_port(netif_inst_t * inst)
+{
+ int ret;
+ uint32_t i;
+ struct rte_eth_conf *port_conf;
+ struct rte_eth_rxconf *rx_conf;
+ struct rte_eth_txconf *tx_conf;
+
+ uint8_t port_id = inst->data.dpdk_if.port_id;
+ struct rte_mempool **mp =
+ (struct rte_mempool **) inst->data.dpdk_if.rx_pool;
+ uint32_t *rx_ring_size = inst->data.dpdk_if.rx_ring_size;
+ uint32_t *tx_ring_size = inst->data.dpdk_if.tx_ring_size;
+ uint32_t rx_queue_num = inst->data.dpdk_if.rx_queue_num;
+ uint32_t tx_queue_num = inst->data.dpdk_if.tx_queue_num;
+
+ dpdk_get_port_conf(inst, &port_conf);
+
+ ret =
+ rte_eth_dev_configure(port_id, rx_queue_num, tx_queue_num, port_conf);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("rte_eth_dev_configure]port_id=%u,ret=%d", port_id, ret);
+ return ret;
+ }
+
+ if (dpdk_get_queue_conf(inst, &rx_conf, &tx_conf) < 0)
+ {
+ NSHAL_LOGERR("dpdk_get_queue_conf failed]inst=%p,rx_conf=%p", inst,
+ rx_conf);
+ return -1;
+ }
+ /* fix "FORTIFY.Out-of-Bounds_Read" type codedex issue CID 33436 */
+ if (rx_queue_num > HAL_ETH_MAX_QUEUE_NUM
+ || tx_queue_num > HAL_ETH_MAX_QUEUE_NUM)
+ {
+ NSHAL_LOGERR
+ ("queue num error]rx_queue_num=%u, tx_queue_num=%u, HAL_ETH_MAX_QUEUE_NUM=%d",
+ rx_queue_num, tx_queue_num, HAL_ETH_MAX_QUEUE_NUM);
+
+ return -1;
+ }
+
+ for (i = 0; i < rx_queue_num; i++)
+ {
+ ret =
+ rte_eth_rx_queue_setup(port_id, i, rx_ring_size[i], SOCKET_ID_ANY,
+ rx_conf, mp[i]);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("rx queue setup fail]index=%u,port_id=%u,ret=%d", i,
+ port_id, ret);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < tx_queue_num; i++)
+ {
+ ret =
+ rte_eth_tx_queue_setup(port_id, i, tx_ring_size[i], SOCKET_ID_ANY,
+ tx_conf);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("tx queue setup fail]q=%u,ret=%d", i, ret);
+ return ret;
+ }
+ }
+
+ rte_eth_promiscuous_enable(port_id);
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_start
+ Description : start the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_start(netif_inst_t * inst)
+{
+ int ret;
+ struct ether_addr eth_addr;
+
+ ret = dpdk_setup_port(inst);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("call dpdk_setup_port fail]ret=%d", ret);
+ return ret;
+ }
+
+ ret = rte_eth_dev_start(inst->data.dpdk_if.port_id);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("rte_eth_dev_start fail]ret=%d", ret);
+ return ret;
+ }
+
+ rte_eth_macaddr_get(inst->data.dpdk_if.port_id, &eth_addr);
+ NSHAL_LOGINF("port_id=%u,nic_name=%s,mac=%02X:%02X:%02X:%02X:%02X:%02X",
+ inst->data.dpdk_if.port_id,
+ inst->data.dpdk_if.nic_name,
+ eth_addr.addr_bytes[0],
+ eth_addr.addr_bytes[1],
+ eth_addr.addr_bytes[2],
+ eth_addr.addr_bytes[3],
+ eth_addr.addr_bytes[4], eth_addr.addr_bytes[5]);
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_stop
+ Description : stop the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_stop(netif_inst_t * inst)
+{
+ int i;
+
+ /* stop slave NIC first */
+ for (i = 0; i < inst->data.dpdk_if.slave_num; i++)
+ {
+ rte_eth_dev_stop(inst->data.dpdk_if.slave_port[i]);
+ NSHAL_LOGINF("stop slave port succ]port_id=%u, nic_name=%s",
+ inst->data.dpdk_if.slave_port[i],
+ inst->data.dpdk_if.nic_name);
+ }
+ rte_eth_dev_stop(inst->data.dpdk_if.port_id);
+
+ NSHAL_LOGINF("stop port succ]port_id=%u, nic_name=%s",
+ inst->data.dpdk_if.port_id, inst->data.dpdk_if.nic_name);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_mtu
+ Description : get the port mtu
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC uint32_t dpdk_get_mtu(netif_inst_t * inst)
+{
+ uint32_t mtu;
+
+ if (rte_eth_dev_get_mtu(inst->data.dpdk_if.port_id, (uint16_t *) & mtu))
+ {
+ return 0;
+ }
+
+ return mtu;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_macaddr
+ Description : get the port mac addr
+ Input : netif_inst_t* inst
+ void* mac_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_get_macaddr(netif_inst_t * inst, void *mac_addr)
+{
+ /*bond port */
+ int primary_port = rte_eth_bond_primary_get(inst->data.dpdk_if.port_id);
+ if (0 <= primary_port)
+ {
+ rte_eth_macaddr_get((uint8_t) primary_port,
+ (struct ether_addr *) mac_addr);
+
+ NSHAL_LOGDBG
+ ("primary_port_id=%u,nic_name=%s,mac=%02X:%02X:%02X:%02X:%02X:%02X",
+ primary_port, inst->data.dpdk_if.nic_name,
+ ((struct ether_addr *) mac_addr)->addr_bytes[0],
+ ((struct ether_addr *) mac_addr)->addr_bytes[1],
+ ((struct ether_addr *) mac_addr)->addr_bytes[2],
+ ((struct ether_addr *) mac_addr)->addr_bytes[3],
+ ((struct ether_addr *) mac_addr)->addr_bytes[4],
+ ((struct ether_addr *) mac_addr)->addr_bytes[5]);
+ }
+ /*normal port */
+ else
+ {
+ rte_eth_macaddr_get(inst->data.dpdk_if.port_id,
+ (struct ether_addr *) mac_addr);
+
+ NSHAL_LOGDBG
+ ("normal_port_id=%u,nic_name=%s,mac=%02X:%02X:%02X:%02X:%02X:%02X",
+ inst->data.dpdk_if.port_id, inst->data.dpdk_if.nic_name,
+ ((struct ether_addr *) mac_addr)->addr_bytes[0],
+ ((struct ether_addr *) mac_addr)->addr_bytes[1],
+ ((struct ether_addr *) mac_addr)->addr_bytes[2],
+ ((struct ether_addr *) mac_addr)->addr_bytes[3],
+ ((struct ether_addr *) mac_addr)->addr_bytes[4],
+ ((struct ether_addr *) mac_addr)->addr_bytes[5]);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_capa_convert
+ Description : convert format from dpdk to hal
+ Input : const struct rte_eth_dev_info* dev_info
+ hal_netif_capa_t* capa
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC inline void
+dpdk_capa_convert(const struct rte_eth_dev_info *dev_info,
+ struct hal_netif_hw_feature *capa)
+{
+ int retVal = memset_s(capa, sizeof(struct hal_netif_hw_feature), 0,
+ sizeof(struct hal_netif_hw_feature));
+ if (EOK != retVal)
+ {
+ NSHAL_LOGERR("MEMSET_S fail]retVal=%d", retVal);
+ }
+
+ /* Set Rx checksum checking */
+ if (dev_info->rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
+ {
+ NSHAL_LOGINF("RX IP checksum offload supported.");
+ capa->rx_csum_ip = 1;
+ }
+ if ((dev_info->rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM) &&
+ (dev_info->rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM))
+ {
+ NSHAL_LOGINF("RX L4 checksum offload supported.");
+ capa->rx_csum_l4 = 1;
+ }
+ if (dev_info->rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO)
+ {
+ NSHAL_LOGINF("RX LRO supported.");
+ capa->rx_lro = 1;
+ }
+ if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)
+ {
+ NSHAL_LOGINF("TX IP checksum offload supported.");
+ capa->tx_csum_ip = 1;
+ }
+ if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM)
+ {
+ NSHAL_LOGINF("TX UDP checksum offload supported.");
+ capa->tx_csum_udp = 1;
+ }
+ if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)
+ {
+ NSHAL_LOGINF("TX TCP checksum offload supported.");
+ capa->tx_csum_tcp = 1;
+ }
+ if (dev_info->tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO)
+ {
+ NSHAL_LOGINF("TSO is supported.");
+ capa->tx_tso = 1;
+ }
+ else
+ {
+ NSHAL_LOGINF("TSO is disabled.");
+ capa->tx_tso = 0;
+ }
+}
+
+/*****************************************************************************
+ Prototype : dpdk_get_capability
+ Description : get the port capability
+ Input : netif_inst_t* inst
+ hal_netif_capa_t* capa
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_get_capability(netif_inst_t * inst, struct hal_netif_hw_feature *capa)
+{
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(inst->data.dpdk_if.port_id, &dev_info);
+ dpdk_capa_convert(&dev_info, capa);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_recv
+ Description : recv packet from the port
+ Input : netif_inst_t* inst
+ uint16_t queue_id
+ struct common_mem_mbuf** rx_pkts
+ uint16_t nb_pkts
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC uint16_t
+dpdk_recv(netif_inst_t * inst, uint16_t queue_id,
+ void **rx_pkts, uint16_t nb_pkts)
+{
+ return hal_rte_eth_rx_burst(inst->data.dpdk_if.port_id, queue_id,
+ (struct rte_mbuf **) rx_pkts, nb_pkts);
+}
+
+/*****************************************************************************
+ Prototype : dpdk_send
+ Description : send packet to the port
+ Input : netif_inst_t* inst
+ uint16_t queue_id
+ struct common_mem_mbuf** tx_pkts
+ uint16_t nb_pkts
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC uint16_t
+dpdk_send(netif_inst_t * inst, uint16_t queue_id,
+ void **tx_pkts, uint16_t nb_pkts)
+{
+ return hal_rte_eth_tx_burst(inst->data.dpdk_if.port_id, queue_id,
+ (struct rte_mbuf **) tx_pkts, nb_pkts);
+}
+
+/*****************************************************************************
+ Prototype : dpdk_link_status
+ Description : get link status form the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC uint32_t dpdk_link_status(netif_inst_t * inst)
+{
+ struct rte_eth_link eth_link;
+
+ /* add log output when failed */
+ int retVal = memset_s(&eth_link, sizeof(struct rte_eth_link), 0,
+ sizeof(struct rte_eth_link));
+ if (EOK != retVal)
+ {
+ NSHAL_LOGERR("MEMSET_S fail]retVal=%d", retVal);
+ }
+
+ rte_eth_link_get(inst->data.dpdk_if.port_id, &eth_link);
+
+ return eth_link.link_status;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_stats_convert
+ Description : convert format from dpdk to hal
+ Input : const struct rte_eth_stats* rte_stats
+ hal_netif_stats_t* stats
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC inline void
+dpdk_stats_convert(const struct rte_eth_stats *rte_stats,
+ hal_netif_stats_t * stats)
+{
+ int i;
+
+ /* give fail error number when failed */
+ int retVal = memset_s(stats, sizeof(hal_netif_stats_t), 0,
+ sizeof(hal_netif_stats_t));
+ if (EOK != retVal)
+ {
+ NSHAL_LOGERR("MEMSET_S fail]retVal=%d", retVal);
+ }
+
+ stats->ipackets = rte_stats->ipackets;
+ stats->opackets = rte_stats->opackets;
+ stats->ibytes = rte_stats->ibytes;
+ stats->obytes = rte_stats->obytes;
+ stats->imissed = rte_stats->imissed;
+ stats->ierrors = rte_stats->ierrors;
+ stats->oerrors = rte_stats->oerrors;
+ stats->rx_nombuf = rte_stats->rx_nombuf;
+
+ for (i = 0; i < HAL_ETH_QUEUE_STAT_CNTRS; i++)
+ {
+ stats->q_ipackets[i] = rte_stats->q_ipackets[i];
+ stats->q_opackets[i] = rte_stats->q_opackets[i];
+ stats->q_ibytes[i] = rte_stats->q_ibytes[i];
+ stats->q_obytes[i] = rte_stats->q_obytes[i];
+ stats->q_errors[i] = rte_stats->q_errors[i];
+ }
+}
+
+/*****************************************************************************
+ Prototype : dpdk_stats
+ Description : get stats form the port
+ Input : netif_inst_t* inst
+ hal_netif_stats_t* stats
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_stats(netif_inst_t * inst, hal_netif_stats_t * stats)
+{
+ int ret;
+ struct rte_eth_stats rte_stats;
+
+ ret = rte_eth_stats_get(inst->data.dpdk_if.port_id, &rte_stats);
+ if (ret == 0)
+ {
+ dpdk_stats_convert(&rte_stats, stats);
+ return 0;
+ }
+
+ return -1;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_stats_reset
+ Description : reset stats to the port
+ Input : netif_inst_t* inst
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_stats_reset(netif_inst_t * inst)
+{
+ rte_eth_stats_reset(inst->data.dpdk_if.port_id);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_config
+ Description : config the port queue and ring
+ Input : netif_inst_t* inst
+ hal_netif_config_t* conf
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_config(netif_inst_t * inst, hal_netif_config_t * conf)
+{
+ uint32_t i;
+
+ inst->data.dpdk_if.hw_vlan_filter = conf->bit.hw_vlan_filter;
+ inst->data.dpdk_if.hw_vlan_strip = conf->bit.hw_vlan_strip;
+
+ inst->data.dpdk_if.rx_queue_num = conf->rx.queue_num;
+ /* fix Buffer Overflow type code-dex issue */
+ if (inst->data.dpdk_if.rx_queue_num > HAL_ETH_MAX_QUEUE_NUM)
+ {
+ NSHAL_LOGERR
+ ("rx queue num error]rx_queue_num=%u, HAL_ETH_MAX_QUEUE_NUM=%d",
+ inst->data.dpdk_if.rx_queue_num, HAL_ETH_MAX_QUEUE_NUM);
+
+ return -1;
+ }
+
+ for (i = 0; i < inst->data.dpdk_if.rx_queue_num; i++)
+ {
+ inst->data.dpdk_if.rx_ring_size[i] = conf->rx.ring_size[i];
+ inst->data.dpdk_if.rx_pool[i] =
+ (struct rte_mempool *) conf->rx.ring_pool[i];
+ }
+
+ inst->data.dpdk_if.tx_queue_num = conf->tx.queue_num;
+ /* fix "FORTIFY.Out-of-Bounds_Read--Off-by-One" type codedex issue */
+ if (inst->data.dpdk_if.tx_queue_num > HAL_ETH_MAX_QUEUE_NUM)
+ {
+ NSHAL_LOGERR
+ ("tx queue num error]rx_queue_num=%u, HAL_ETH_MAX_QUEUE_NUM=%d",
+ inst->data.dpdk_if.tx_queue_num, HAL_ETH_MAX_QUEUE_NUM);
+
+ return -1;
+ }
+ for (i = 0; i < inst->data.dpdk_if.tx_queue_num; i++)
+ {
+ inst->data.dpdk_if.tx_ring_size[i] = conf->tx.ring_size[i];
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_bond_config
+ Description : config the port for bond mode
+ Input : netif_inst_t* inst
+ uint8_t slave_num
+ netif_inst_t* slave_inst[]
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_bond_config(netif_inst_t * inst, uint8_t slave_num,
+ netif_inst_t * slave_inst[])
+{
+ int ret;
+ uint32_t i, queue;
+
+ inst->data.dpdk_if.slave_num = slave_num;
+
+ for (i = 0; i < slave_num; i++)
+ {
+ inst->data.dpdk_if.slave_port[i] =
+ slave_inst[i]->data.dpdk_if.port_id;
+
+ if (0 == i)
+ {
+ inst->data.dpdk_if.hw_vlan_filter =
+ slave_inst[i]->data.dpdk_if.hw_vlan_filter;
+ inst->data.dpdk_if.hw_vlan_strip =
+ slave_inst[i]->data.dpdk_if.hw_vlan_strip;
+ inst->data.dpdk_if.rx_queue_num =
+ slave_inst[i]->data.dpdk_if.rx_queue_num;
+ inst->data.dpdk_if.tx_queue_num =
+ slave_inst[i]->data.dpdk_if.tx_queue_num;
+
+ /*will be used in function dpdk_get_queue_conf and dpdk_get_port_conf */
+ ret =
+ strcpy_s(inst->data.dpdk_if.driver_name,
+ sizeof(inst->data.dpdk_if.driver_name), "bond");
+
+ if (EOK != ret)
+ {
+ NSHAL_LOGERR("STRCPY_S failed]ret=%d.", ret);
+ return -1;
+ }
+
+ for (queue = 0; queue < HAL_ETH_MAX_QUEUE_NUM; queue++)
+ {
+ inst->data.dpdk_if.rx_pool[queue] =
+ slave_inst[i]->data.dpdk_if.rx_pool[queue];
+ inst->data.dpdk_if.rx_ring_size[queue] =
+ slave_inst[i]->data.dpdk_if.rx_ring_size[queue];
+ inst->data.dpdk_if.tx_ring_size[queue] =
+ slave_inst[i]->data.dpdk_if.tx_ring_size[queue];
+ }
+ }
+ }
+
+ return 0;
+
+}
+
+/*****************************************************************************
+ Prototype : dpdk_bond
+ Description : bond port
+ Input : netif_inst_t* inst
+ const char* bond_name
+ uint8_t slave_num
+ netif_inst_t* slave_inst[]
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_bond(netif_inst_t * inst, const char *bond_name, uint8_t slave_num,
+ netif_inst_t * slave_inst[])
+{
+ int i, ret;
+ int port;
+ struct ether_addr eth_addr;
+
+ /* check if all the slaves' drivers are same, not support different drivers */
+ for (i = 1; i < slave_num; i++)
+ {
+ if (strncmp
+ (slave_inst[0]->data.dpdk_if.driver_name,
+ slave_inst[i]->data.dpdk_if.driver_name,
+ strlen(slave_inst[0]->data.dpdk_if.driver_name)))
+ {
+ NSHAL_LOGERR
+ ("dpdk does not support different types of network card]slave[0]=%s, slave[%i]=%s",
+ slave_inst[0]->data.dpdk_if.driver_name, i,
+ slave_inst[i]->data.dpdk_if.driver_name);
+ return -1;
+ }
+ }
+
+ ret = dpdk_set_nic_name(inst, bond_name);
+
+ if (0 != ret)
+ {
+ NSHAL_LOGERR("dpdk_set_nic_name fail]ret=%d", ret);
+ return -1;
+ }
+
+ port =
+ rte_eth_bond_create(bond_name, BONDING_MODE_ACTIVE_BACKUP,
+ SOCKET_ID_0);
+ if (port < 0)
+ {
+ NSHAL_LOGERR("rte_eth_bond_create fail]ret=%i", ret);
+ return -1;
+ }
+
+ ret = dpdk_set_port(inst, (uint8_t) port);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("dpdk_set_port fail]ret=%i", ret);
+ return ret;
+ }
+
+ ret = dpdk_bond_config(inst, slave_num, slave_inst);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("dpdk_bond_config fail]ret=%i", ret);
+ return ret;
+ }
+
+ ret = dpdk_setup_port(inst);
+
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("dpdk_setup_port fail]ret=%i", ret);
+ return ret;
+ }
+
+ for (i = 0; i < slave_num; i++)
+ {
+ NSHAL_LOGINF("add slave port_id=%u, nic_name=%s",
+ slave_inst[i]->data.dpdk_if.port_id,
+ slave_inst[i]->data.dpdk_if.nic_name);
+
+ if (rte_eth_bond_slave_add
+ ((uint8_t) port, slave_inst[i]->data.dpdk_if.port_id) == -1)
+ {
+ NSHAL_LOGERR("adding slave (%u) to bond (%u) failed]",
+ slave_inst[i]->data.dpdk_if.port_id, port);
+ return -1;
+ }
+ }
+
+ rte_eth_macaddr_get(slave_inst[0]->data.dpdk_if.port_id, &eth_addr);
+
+ ret = rte_eth_bond_mac_address_set((uint8_t) port, &eth_addr);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("rte_eth_bond_mac_address_set fail]ret=%i", ret);
+ return ret;
+ }
+
+ ret = rte_eth_dev_start(inst->data.dpdk_if.port_id);
+ if (ret < 0)
+ {
+ NSHAL_LOGERR("rte_eth_dev_start fail]ret=%i, port_id=%d", ret,
+ inst->data.dpdk_if.port_id);
+ return ret;
+ }
+
+ NSHAL_LOGINF("port_id=%d,nic_name=%s,mac=%02X:%02X:%02X:%02X:%02X:%02X",
+ port,
+ inst->data.dpdk_if.nic_name,
+ eth_addr.addr_bytes[0],
+ eth_addr.addr_bytes[1],
+ eth_addr.addr_bytes[2],
+ eth_addr.addr_bytes[3],
+ eth_addr.addr_bytes[4], eth_addr.addr_bytes[5]);
+ return 0;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_add_mcastaddr
+ Description : add mcastaddr to the port
+ Input : netif_inst_t* inst
+ void* mc_addr_set
+ void* mc_addr
+ uint32_t nb_mc_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int
+dpdk_set_mcastaddr(netif_inst_t * inst, void *mc_addr_set,
+ void *mc_addr, uint32_t nb_mc_addr)
+{
+ uint8_t port = inst->data.dpdk_if.port_id;
+ int iRetVal;
+
+ NSHAL_LOGINF("mc_addr_set number=%u", nb_mc_addr);
+ iRetVal = rte_eth_dev_set_mc_addr_list(port, mc_addr_set, nb_mc_addr);
+ if (iRetVal != 0)
+ {
+ NSHAL_LOGWAR("fail to set_mc_addr_list]port=%u,ret=%d", port,
+ iRetVal);
+ }
+
+ return iRetVal;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_add_mac_addr
+ Description : add mcastaddr to the port
+ Input : netif_inst_t* inst
+ void* mc_addr
+ Output : None
+ Return Value : NSTACK_STATIC int
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_add_mac_addr(netif_inst_t * inst, void *mc_addr)
+{
+ uint8_t port = inst->data.dpdk_if.port_id;
+ int iRetVal;
+
+ /* for MLX: set_mc_addr_list() is not callback, so call mac_addr_add() instead */
+ iRetVal = rte_eth_dev_mac_addr_add(port, mc_addr, 0);
+ if (0 != iRetVal)
+ {
+ NSHAL_LOGWAR("fail to add_mac_addr]port=%u,ret=%d", port, iRetVal);
+ }
+
+ return iRetVal;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_rmv_mac_addr
+ Description : remove mcastaddr to the port
+ Input : netif_inst_t* inst
+ void* mc_addr
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_rmv_mac_addr(netif_inst_t * inst, void *mc_addr)
+{
+ uint8_t port = inst->data.dpdk_if.port_id;
+ int iRetVal;
+
+ /* for MLX: set_mc_addr_list() is not callback, so call mac_addr_remove() instead */
+ iRetVal = rte_eth_dev_mac_addr_remove(port, mc_addr);
+ if (0 != iRetVal)
+ {
+ NSHAL_LOGWAR("fail to rmv_mac_addr]port=%u,ret=%d", port, iRetVal);
+ }
+
+ return iRetVal;
+}
+
+/*****************************************************************************
+ Prototype : dpdk_allmcast
+ Description : set allmcast mode to the port
+ Input : netif_inst_t* inst
+ uint8_t enable
+ Output : None
+ Return Value : NSTACK_STATIC
+ Calls :
+ Called By :
+
+*****************************************************************************/
+NSTACK_STATIC int dpdk_allmcast(netif_inst_t * inst, uint8_t enable)
+{
+ if (enable)
+ {
+ rte_eth_allmulticast_enable(inst->data.dpdk_if.port_id);
+ }
+ else
+ {
+ rte_eth_allmulticast_disable(inst->data.dpdk_if.port_id);
+ }
+
+ return 0;
+}
+
+const netif_ops_t dpdk_netif_ops = {
+ .name = "dpdk",
+ .init_global = dpdk_init_global,
+ .init_local = dpdk_init_local,
+ .open = dpdk_open,
+ .close = dpdk_close,
+ .start = dpdk_start,
+ .stop = dpdk_stop,
+ .bond = dpdk_bond,
+ .mtu = dpdk_get_mtu,
+ .macaddr = dpdk_get_macaddr,
+ .capability = dpdk_get_capability,
+ .recv = dpdk_recv,
+ .send = dpdk_send,
+ .link_status = dpdk_link_status,
+ .stats = dpdk_stats,
+ .stats_reset = dpdk_stats_reset,
+ .config = dpdk_config,
+ .mcastaddr = dpdk_set_mcastaddr,
+ .add_mac = dpdk_add_mac_addr,
+ .rmv_mac = dpdk_rmv_mac_addr,
+ .allmcast = dpdk_allmcast
+};
+
+HAL_IO_REGISTER(dpdk, &dpdk_netif_ops);
diff --git a/stacks/lwip_stack/src/mem/CMakeLists.txt b/stacks/lwip_stack/src/mem/CMakeLists.txt
new file mode 100644
index 0000000..eb4e0b5
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/CMakeLists.txt
@@ -0,0 +1,36 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+if(WITH_HAL_LIB)
+else()
+ SET(PAL_H_DIRECTORIES "/usr/include/dpdk/")
+endif()
+
+
+FILE(GLOB_RECURSE MEM *.c)
+ADD_LIBRARY(nsfw_mem STATIC ${MEM})
+ADD_DEPENDENCIES(nsfw_mem GLOG)
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../include
+ ${PAL_H_DIRECTORIES}
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include
+ nsfw_shmem/
+ include/
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+ ${CMAKE_CURRENT_LIST_DIR}/nsfw_nshmem/
+)
diff --git a/stacks/lwip_stack/src/mem/include/common_mem_memzone.h b/stacks/lwip_stack/src/mem/include/common_mem_memzone.h
new file mode 100644
index 0000000..20e18c2
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/include/common_mem_memzone.h
@@ -0,0 +1,25 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_MEM_MEMZONE_H_
+#define _COMMON_MEM_MEMZONE_H_
+
+#ifdef HAL_LIB
+#else
+#include "rte_memzone.h"
+#endif
+
+#endif /* _COMMON_MEM_MEMZONE_H_ */
diff --git a/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h b/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h
new file mode 100644
index 0000000..086460c
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/include/common_pal_bitwide_adjust.h
@@ -0,0 +1,204 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _COMMON_PAL_BITWIDE_ADJUST_H_
+#define _COMMON_PAL_BITWIDE_ADJUST_H_
+
+#ifdef HAL_LIB
+#include "pal_bitwide_adjust.h"
+#else
+#define MODULE(name) (1)
+
+#include "common_mem_common.h"
+
+#include "common_func.h"
+
+#define ALIGN_SIZET(size) ((uint64_t)(size))
+#define ALIGN_PTR(PTR) ((uint64_t)(PTR))
+
+extern struct common_mem_memseg *g_PMemSegArry;
+extern void **g_LMegAddrArry;
+
+/*get Local Seg addr by segIdx*/
+#define HMEM_SEG_LVADDR(segid) (g_LMegAddrArry[segid])
+/*get SegIDX by PrimSegAddr, just get the array Idx of g_PMemSegArry*/
+#define HMEM_SEGID(segaddr) ((struct common_mem_memseg*)segaddr - &(g_PMemSegArry[0]))
+
+/*****************************************************************
+Parameters : LMegAddrArry[] Local common_mem_memseg addr Array
+ SegNum common_mem_memseg Num.
+Return :
+Description : init g_PrimAddr2LocalMap g_LocalAddr2PrimMap while the process start
+*****************************************************************/
+void *pal_shddr_to_laddr(uint64_t shaddr);
+uint64_t pal_laddr_to_shddr(void *laddr);
+int dmm_pal_addr_align();
+void *shmem_shddr_to_laddr(void *addr);
+uint64_t shmem_laddr_to_shddr(void *addr);
+
+extern int g_PrimSameFlg;
+
+/* if __NSTACK_MAIN__ is defined, no need do addr trans*/
+#ifndef __NSTACK_MAIN__
+/* g_PrimSameFlg check should be done before calling cast functions */
+
+/*share memory address to local virtual address*/
+#define ADDR_SHTOL(addr) (g_PrimSameFlg ? ((void*) (addr)) : pal_shddr_to_laddr((uint64_t)(addr)))
+
+/*local virtual address to share memory address according to memseg*/
+#define ADDR_LTOSH(addr) (g_PrimSameFlg ? ((uint64_t)(addr)) : pal_laddr_to_shddr((void*)(addr)))
+
+#define PTR_SHTOL(type, addr) ((type)ADDR_SHTOL(addr))
+
+/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/
+#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr)
+#else
+/*share memory address to local virtual address*/
+#define ADDR_SHTOL(addr) ((void*)(addr))
+
+/*local virtual address to share memory address according to memseg*/
+#define ADDR_LTOSH(addr) ((uint64_t)(addr))
+
+#define PTR_SHTOL(type, addr) ((type)(addr))
+
+/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/
+#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr)
+#endif
+
+#if MODULE("list")
+#define COMMON_LIST_INSERT_HEAD(lhead, lelm, field) do { \
+ if (((lelm)->field.le_next_align = (lhead)->lh_first_align) != ((typeof((lhead)->lh_first_align))(long)NULL)) \
+ ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align))->field.le_prev_align = \
+ ADDR_LTOSH(&(lelm)->field.le_next); \
+ (lhead)->lh_first_align = ADDR_LTOSH(lelm); \
+ (lelm)->field.le_prev_align = ADDR_LTOSH(&(lhead)->lh_first); \
+} while (/*CONSTCOND*/0)
+
+#define COMMON_LIST_REMOVE(lelm, field) do { \
+ if ((lelm)->field.le_next_align != ((typeof((lelm)->field.le_next_align))ALIGN_PTR(NULL))) \
+ ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align))->field.le_prev_align = \
+ (lelm)->field.le_prev_align; \
+ if (EOK != (MEMCPY_S((typeof((lelm)->field.le_prev))ADDR_SHTOL((lelm)->field.le_prev_align), \
+ sizeof((lelm)->field.le_next_align), \
+ &((lelm)->field.le_next_align), \
+ sizeof((lelm)->field.le_next_align)))) \
+ {\
+ NSCOMM_LOGERR("MEMCPY_S failed.");\
+ return;\
+ }\
+} while (/*CONSTCOND*/0)
+
+#define COMMON_LIST_EMPTY(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align) == NULL)
+#define COMMON_LIST_FIRST(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align))
+#define COMMON_LIST_NEXT(lelm, field) ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align))
+
+#endif
+
+#if MODULE("tailq")
+
+#define COMMON_TAILQ_INSERT_TAIL(lhead, lelm, field) do { \
+ (lelm)->field.tqe_next_align = (typeof((lelm)->field.tqe_next_align))NULL; \
+ (lelm)->field.tqe_prev_align = (lhead)->tqh_last_align; \
+ typeof((lhead)->tqh_last_align) tempelm = ADDR_LTOSH(lelm);\
+ if (EOK != (MEMCPY_S(ADDR_SHTOL((lhead)->tqh_last_align), sizeof(tempelm), &tempelm, sizeof(tempelm)))) \
+ {\
+ NSCOMM_LOGERR("MEMCPY_S failed.");\
+ }\
+ (lhead)->tqh_last_align = ADDR_LTOSH(&(lelm)->field.tqe_next); \
+} while (/*CONSTCOND*/0)
+
+#define COMMON_TAILQ_FOREACH(lvar, lhead, field) \
+ for ((lvar) = (typeof(lvar))ADDR_SHTOL((lhead)->tqh_first_align); \
+ (lvar); \
+ (lvar) = (typeof(lvar))ADDR_SHTOL((lvar)->field.tqe_next_align))
+
+#define COMMON_TAILQ_REMOVE(lhead, lelm, field) do { \
+ if (((lelm)->field.tqe_next_align) != (typeof((lelm)->field.tqe_next_align))NULL) \
+ ((typeof((lelm)->field.tqe_next))ADDR_SHTOL((lelm)->field.tqe_next_align))->field.tqe_prev_align = \
+ (lelm)->field.tqe_prev_align; \
+ else \
+ (lhead)->tqh_last_align = (lelm)->field.tqe_prev_align; \
+ if (EOK != (MEMCPY_S(ADDR_SHTOL((lelm)->field.tqe_prev_align), \
+ sizeof((lelm)->field.tqe_next_align), \
+ &((lelm)->field.tqe_next_align), \
+ sizeof((lelm)->field.tqe_next_align)))) \
+ {\
+ NSCOMM_LOGERR("MEMCPY_S failed.");\
+ }\
+ } while (/*CONSTCOND*/0)
+
+/*
+ * Tail queue functions.
+ */
+#define COMMON_TAILQ_INIT(head) do { \
+ (head)->tqh_first_align = (typeof((head)->tqh_first_align))NULL; \
+ (head)->tqh_last_align = ADDR_LTOSH(&(head)->tqh_first); \
+ } while (/*CONSTCOND*/0)
+
+/*
+ * Tail queue access methods.
+ */
+#define COMMON_TAILQ_EMPTY(head) ((head)->tqh_first_align == (typeof((head)->tqh_first_align))NULL)
+#define COMMON_TAILQ_FIRST(head) ((typeof((head)->tqh_first))ADDR_SHTOL((head)->tqh_first_align))
+#define COMMON_TAILQ_NEXT(elm, field) ((typeof((elm)->field.tqe_next))ADDR_SHTOL((elm)->field.tqe_next_align))
+
+#endif
+
+#if MODULE("stailq")
+/*
+* Singly-linked Tail queue functions.
+*/
+#define COMMON_STAILQ_INIT(head) do { \
+ (head)->stqh_first_align = ALIGN_PTR(NULL); \
+ (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \
+} while (/*CONSTCOND*/0)
+
+#define COMMON_STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next_align = ALIGN_PTR(NULL); \
+ typeof((head)->stqh_last_align) telm = ADDR_LTOSH(elm);\
+ if (EOK != (MEMCPY_S(ADDR_SHTOL((head)->stqh_last_align), sizeof(telm), &telm, sizeof(telm))))\
+ {\
+ NSCOMM_LOGERR("MEMCPY_S failed.");\
+ }\
+ (head)->stqh_last_align = ADDR_LTOSH(&(elm)->field.stqe_next); \
+} while (/*CONSTCOND*/0)
+
+#define COMMON_STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first_align = \
+ ((typeof((head)->stqh_first))ADDR_SHTOL((head)->stqh_first_align))->field.stqe_next_align) == \
+ (PTR_ALIGN_TYPE)NULL) \
+ (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \
+} while (/*CONSTCOND*/0)
+
+#define COMMON_STAILQ_FOREACH(var, head, field) \
+ for ((var) = ADDR_SHTOL((head)->stqh_first_align); \
+ (var); \
+ (var) = ADDR_SHTOL((var)->field.stqe_next_align))
+
+/*
+* Singly-linked Tail queue access methods.
+*/
+
+#define COMMON_STAILQ_EMPTY(head) ((head)->stqh_first_align == (PTR_ALIGN_TYPE)NULL)
+
+#define COMMON_STAILQ_FIRST(head) (ADDR_SHTOL((head)->stqh_first_align))
+
+#define COMMON_STAILQ_NEXT(elm, field) (ADDR_SHTOL((elm)->field.stqe_next_align))
+#endif
+
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/include/common_sys_config.h b/stacks/lwip_stack/src/mem/include/common_sys_config.h
new file mode 100644
index 0000000..736c47b
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/include/common_sys_config.h
@@ -0,0 +1,46 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __COMMON_SYS_CONFIG_H_
+#define __COMMON_SYS_CONFIG_H_
+
+/* Below compile macro is used only in UT makefile */
+#if (HAL_LIB)
+#else
+#undef RTE_CACHE_LINE_SIZE
+#define RTE_CACHE_LINE_SIZE 64 /* RTE_CACHE_LINE_SIZE */
+#undef RTE_MAX_LCORE
+#define RTE_MAX_LCORE 128 /* RTE_MAX_LCORE */
+#undef RTE_MAX_NUMA_NODES
+#define RTE_MAX_NUMA_NODES 8 /* RTE_MAX_NUMA_NODES */
+#undef RTE_MAX_MEMSEG
+#define RTE_MAX_MEMSEG 256 /* RTE_MAX_MEMSEG */
+#undef RTE_MAX_MEMZONE
+#define RTE_MAX_MEMZONE 2560 /* RTE_MAX_MEMZONE */
+#undef RTE_MAX_TAILQ
+#define RTE_MAX_TAILQ 32 /* RTE_MAX_TAILQ */
+#undef RTE_ARCH_X86
+#define RTE_ARCH_X86 1 /* RTE_ARCH_64 */
+#undef RTE_ARCH_64
+#define RTE_ARCH_64 1 /* RTE_ARCH_64 */
+#undef RTE_PKTMBUF_HEADROOM
+#define RTE_PKTMBUF_HEADROOM 128 /* RTE_PKTMBUF_HEADROOM */
+#undef RTE_MEMPOOL_CACHE_MAX_SIZE
+#define RTE_MEMPOOL_CACHE_MAX_SIZE 512 /* RTE_MEMPOOL_CACHE_MAX_SIZE */
+
+#endif
+
+#endif // __COMMON_SYS_CONFIG_H_
diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c
new file mode 100644
index 0000000..453f33f
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_api.c
@@ -0,0 +1,163 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include "common_mem_api.h"
+#include "nstack_log.h"
+#include "nstack_securec.h"
+#include "common_func.h"
+#include "pid_common.h"
+
+void sys_sem_init_v2(sys_sem_t_v2 sem)
+{
+ sem->locked = 1;
+}
+
+/** Returns the current time in milliseconds,
+ * may be the same as sys_jiffies or at least based on it. */
+u32_t sys_now(void)
+{
+ struct timespec now;
+
+ if (unlikely(0 != clock_gettime(CLOCK_MONOTONIC, &now)))
+ {
+ NSRTP_LOGERR("Failed to get time, errno = %d", errno);
+ }
+
+ return 1000 * now.tv_sec + now.tv_nsec / 1000000;
+}
+
+long sys_jiffies(void)
+{
+ return sys_now();
+}
+
+err_t sys_sem_new_v2(sys_sem_t_v2 * sem, u8_t isUnLockd)
+{
+ int retVal;
+ if (!sem)
+ {
+ return -1;
+ }
+ *sem = malloc(sizeof(common_mem_spinlock_t));
+
+ if (NULL == *sem)
+ {
+ return -1;
+ }
+ else
+ {
+ retVal =
+ memset_s(*sem, sizeof(common_mem_spinlock_t), 0,
+ sizeof(common_mem_spinlock_t));
+ if (EOK != retVal)
+ {
+ NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal);
+ free(*sem);
+ *sem = NULL;
+ return -1;
+ }
+ common_mem_spinlock_init(*sem);
+ }
+
+ if (!isUnLockd)
+ {
+ common_mem_spinlock_lock(*sem);
+ }
+
+ return 0;
+}
+
+void sys_sem_free_v2(sys_sem_t_v2 * sem)
+{
+ if ((sem != NULL) && (*sem != NULL))
+ {
+ free(*sem);
+ *sem = NULL;
+ }
+ else
+ {
+ }
+}
+
+void sys_sem_signal_v2(sys_sem_t_v2 * sem)
+{
+ common_mem_spinlock_unlock(*sem);
+}
+
+void sys_sem_signal_s_v2(sys_sem_t_v2 sem)
+{
+ common_mem_spinlock_unlock(sem);
+}
+
+u32_t sys_arch_sem_trywait_v2(sys_sem_t_v2 * sem)
+{
+ return (u32_t) common_mem_spinlock_trylock(*sem);
+}
+
+u32_t sys_arch_sem_wait_v2(sys_sem_t_v2 * pstsem)
+{
+ common_mem_spinlock_lock(*pstsem);
+ return 0;
+}
+
+u32_t sys_arch_sem_wait_s_v2(sys_sem_t_v2 sem)
+{
+ common_mem_spinlock_lock(sem);
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : get_pid_namespace
+* Description : Get namespace of pid
+* Input : uint32_t pid
+* Output : None
+* Return Value : uint64_t
+* Calls :
+* Called By :
+*****************************************************************************/
+uint64_t get_pid_namespace(pid_t pid)
+{
+ char buf[BUF_SIZE_FILEPATH] = { 0 };
+ char path[BUF_SIZE_FILEPATH] = { 0 };
+ const char *pstart;
+ int ret = 0;
+ if (!pid)
+ {
+ NSSOC_LOGERR("Pid is zero!");
+ return 0;
+ }
+
+ ret =
+ snprintf_s(path, sizeof(path), sizeof(path) - 1, "/proc/%d/ns/pid",
+ pid);
+ if (-1 == ret)
+ {
+ NSSOC_LOGERR("SNPRINTF_S failed]ret=%d", ret);
+ return 0;
+ }
+
+ ret = readlink(path, buf, sizeof(buf) - 1);
+ if (ret <= (int) sizeof(STR_PID))
+ {
+ NSSOC_LOGERR("readlink pid ns file error]ret=%d", ret);
+ return 0;
+ }
+
+ buf[ret - 1] = 0;
+ pstart = &(buf[sizeof(STR_PID)]);
+ return strtoull(pstart, NULL, 10);
+}
diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c
new file mode 100644
index 0000000..98983d5
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_buf.c
@@ -0,0 +1,299 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/queue.h>
+
+#include "common_mem_base_type.h"
+
+#include "common_mem_common.h"
+
+#include "common_mem_memzone.h"
+
+#include "common_mem_mempool.h"
+#include "common_mem_buf.h"
+
+#include "nstack_log.h"
+#include "nstack_securec.h"
+
+#include "common_func.h"
+#include "common_pal_bitwide_adjust.h"
+
+#define LOG_ERR 0
+#define LOG_WARN 1
+#define LOG_INFO 2
+#define LOG_DEBUG 3
+#define LOG_MAX 4
+
+#define COMMON_LOG_PRINT(level, fmt, args...) \
+ if (level <= log_level) NSRTP_LOGERR("===>[COMMON]"fmt, ##args); \
+
+#define COMMON_PANIC(fmt) \
+ NSRTP_LOGERR("==>[COMMON_PANIC]"fmt); \
+ common_dump_stack(); \
+
+#define PARA1_SET(argv, tempargv, Index, para1) do {\
+ retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para1);\
+ if (retVal != EOK)\
+ {\
+ NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\
+ return DMM_MBUF_RET_ERR;\
+ }\
+ argv[Index] = tempargv[Index]; \
+ Index ++; } while (0)
+
+#define PARA2_SET(argv, tempargv, Index, para1, para2) do {\
+ retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para1); \
+ if (retVal != EOK)\
+ {\
+ NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\
+ return DMM_MBUF_RET_ERR;\
+ }\
+ argv[Index] = tempargv[Index]; \
+ Index++; \
+ retVal = strcpy_s(tempargv[Index], PATA_STRLENT, para2); \
+ if (retVal != EOK)\
+ {\
+ NSRTP_LOGERR("STRCPY_S failed]ret=%d", retVal);\
+ return DMM_MBUF_RET_ERR;\
+ }\
+ argv[Index] = tempargv[Index]; \
+ Index ++; } while (0)
+
+#define PATA_STRLENT 64
+#define PATA_NUM_MAX 12
+
+int log_level = LOG_INFO;
+
+int
+nscomm_pal_module_init(nsfw_mem_para * para,
+ common_mem_pal_module_info * pinfo, u8 app_mode)
+{
+ char tempargv[PATA_NUM_MAX][PATA_STRLENT];
+ char *argv[PATA_NUM_MAX];
+ char tempbuf[PATA_STRLENT];
+ unsigned int Index = 0;
+ int ioffset = 0;
+ int agindex = 0;
+ int intmask = 0;
+ int retVal;
+ char name[10] = { '\0' };
+
+ if (para == NULL)
+ {
+ NSRTP_LOGERR("para is null");
+ return DMM_MBUF_RET_ERR;
+ }
+
+ retVal = memset_s(tempargv, sizeof(tempargv), '\0', sizeof(tempargv));
+ if (EOK != retVal)
+ {
+ NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ retVal = memset_s(argv, sizeof(argv), 0, sizeof(argv));
+ if (EOK != retVal)
+ {
+ NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ if (NSFW_PROC_MAIN == para->enflag)
+ {
+ if (para->iargsnum != 0)
+ {
+ if (common_mem_pal_init(para->iargsnum, para->pargs) < 0)
+ {
+ COMMON_LOG_PRINT(LOG_ERR, "Cannot init pal\r\n");
+ return DMM_MBUF_RET_ERR;
+ }
+ else
+ {
+ return DMM_MBUF_RET_OK;
+ }
+ }
+
+ PARA1_SET(argv, tempargv, agindex, "nStackMain");
+ PARA2_SET(argv, tempargv, agindex, "-c", "0x1");
+ PARA2_SET(argv, tempargv, agindex, "-n", "4");
+ PARA1_SET(argv, tempargv, agindex, "--huge-dir=/mnt/nstackhuge");
+ PARA1_SET(argv, tempargv, agindex, "--proc-type=primary");
+
+ if (app_mode == 1)
+ {
+ sprintf(name, "dmm_app_%ld", (long) getpid());
+ PARA2_SET(argv, tempargv, agindex, "--file-prefix", name);
+ PARA1_SET(argv, tempargv, agindex, "--no-pci");
+
+ // TODO: the size of the memory should not be fixed
+ PARA2_SET(argv, tempargv, agindex, "-m", "32");
+ }
+ else
+ {
+ // TODO: replay the name 'nStackMain'
+ /* snprintf(name, 10, "dmm_main_%ld", (long) getpid()); */
+ PARA2_SET(argv, tempargv, agindex, "--file-prefix", "nStackMain");
+ PARA2_SET(argv, tempargv, agindex, "-m", "2048");
+ }
+
+ }
+ else
+ {
+ PARA1_SET(argv, tempargv, agindex, "nStackMain");
+ PARA2_SET(argv, tempargv, agindex, "--file-prefix", "nStackMain");
+
+ retVal = sprintf_s(tempbuf, PATA_STRLENT, "0x");
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", ioffset);
+ return DMM_MBUF_RET_ERR;
+ }
+ ioffset = retVal;
+ for (Index = 0; Index < LCORE_MASK_MAX; Index++)
+ {
+ if (ioffset >= PATA_STRLENT)
+ {
+ NSRTP_LOGERR("SPRINTF_S tempbuf overflow]ioffset=%d",
+ ioffset);
+ return DMM_MBUF_RET_ERR;
+ }
+ retVal =
+ sprintf_s(&(tempbuf[ioffset]), PATA_STRLENT - ioffset, "%8u",
+ pinfo->ilcoremask[Index]);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", ioffset);
+ return DMM_MBUF_RET_ERR;
+ }
+ ioffset = ioffset + retVal;
+ intmask |= pinfo->ilcoremask[Index];
+ }
+ if (0 == intmask)
+ {
+ PARA2_SET(argv, tempargv, agindex, "-c", "0x1");
+ }
+ else
+ {
+ PARA2_SET(argv, tempargv, agindex, "-c", tempbuf);
+ }
+ if (pinfo->ishare_mem_size > 0)
+ {
+ retVal = memset_s(tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX);
+ if (EOK != retVal)
+ {
+ NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ retVal =
+ sprintf_s(tempbuf, PATA_STRLENT, "%d",
+ pinfo->ishare_mem_size);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ PARA2_SET(argv, tempargv, agindex, "-m", tempbuf);
+ }
+
+ retVal = memset_s(tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX);
+ if (EOK != retVal)
+ {
+ NSRTP_LOGERR("MEMSET_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+
+ switch (pinfo->ucproctype)
+ {
+ case DMM_PROC_T_PRIMARY:
+ retVal =
+ sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=primary");
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ break;
+ case DMM_PROC_T_SECONDARY:
+ retVal =
+ sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=secondary");
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ break;
+ case DMM_PROC_T_AUTO:
+ default:
+ retVal = sprintf_s(tempbuf, PATA_STRLENT, "--proc-type=auto");
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ return DMM_MBUF_RET_ERR;
+ }
+ break;
+ }
+ PARA1_SET(argv, tempargv, agindex, tempbuf);
+
+ if (DMM_HUGTBL_DISABLE == pinfo->uchugeflag)
+ {
+ PARA1_SET(argv, tempargv, agindex, "--no-huge");
+ }
+ }
+ if (common_mem_pal_init(agindex, argv) < 0)
+ {
+ COMMON_LOG_PRINT(LOG_ERR, "Cannot init pal\r\n");
+ return DMM_MBUF_RET_ERR;
+ }
+ return DMM_MBUF_RET_OK;
+}
+
+void *nscomm_memzone_data_reserve_name(const char *name, size_t len,
+ int socket_id)
+{
+ const struct common_mem_memzone *mz = NULL;
+ /*
+ rte_memzone_reserve must Call first, cause rte_memzone_reserve has a globe lock.
+ while proc race happen, who(calls A) got lock first will create memzone success.
+ others create same memzone proc will got lock after A, and rte_memzone_reserve return NULL;
+ so while rte_memzone_reserve return NULL we need do rte_memzone_lookup;
+ */
+ mz = common_mem_memzone_reserve(name, len, socket_id, 0);
+ if (mz == NULL)
+ {
+ mz = common_mem_memzone_lookup(name);
+ }
+
+ return mz ? (void *) ADDR_SHTOL(mz->addr_64) : NULL;
+}
+
+void *nscomm_memzone_data_lookup_name(const char *name)
+{
+ void *addr = NULL;
+ const struct common_mem_memzone *mz = NULL;
+ mz = common_mem_memzone_lookup(name);
+ if (mz == NULL)
+ {
+ return NULL;
+ }
+ addr = (void *) ADDR_SHTOL(mz->addr_64);
+ return addr;
+}
diff --git a/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c b/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c
new file mode 100644
index 0000000..6dd3d13
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/lib_common_mem/common_func.c
@@ -0,0 +1,211 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "common_mem_pal_memconfig.h"
+#include "common_mem_mbuf.h"
+#include "common_mem_common.h"
+#include "nstack_log.h"
+#include "common_pal_bitwide_adjust.h"
+
+#include "common_func.h"
+
+#include "nstack_securec.h"
+
+#define COMMON_PROCESS_MAPS "/proc/self/maps"
+
+int g_PrimSameFlg = 1;
+
+NSTACK_STATIC void **g_PrimAddr2LocalMap = NULL;
+NSTACK_STATIC void *g_LocalBaseAddr = NULL;
+NSTACK_STATIC void *g_LocalMaxAddr = NULL;
+NSTACK_STATIC void *g_LocalCfgAddrBase = NULL;
+
+NSTACK_STATIC uint64_t *g_LocalAddr2PrimMap = NULL;
+NSTACK_STATIC uint64_t g_PrimBaseAddr = 0;
+NSTACK_STATIC uint64_t g_PrimMaxAddr = 0;
+NSTACK_STATIC uint64_t g_PrimCfgAddrBase = 0;
+
+NSTACK_STATIC uint64_t g_LBitMask = 0;
+NSTACK_STATIC int g_LBitMaskLen = 0;
+
+uint64_t pal_laddr_to_shddr(void *LAddr)
+{
+ size_t l2pIdx;
+
+ if (g_PrimSameFlg || LAddr == NULL)
+ {
+ return (uint64_t) LAddr;
+ }
+
+ /*calculate the IDX */
+ l2pIdx = (ALIGN_PTR(LAddr) - ALIGN_PTR(g_LocalBaseAddr)) >> g_LBitMaskLen;
+
+ /*check the Hugepage Addr Rang */
+ if (LAddr <= g_LocalMaxAddr && LAddr >= g_LocalBaseAddr
+ && g_LocalAddr2PrimMap[l2pIdx])
+ {
+ return g_LocalAddr2PrimMap[l2pIdx] + (ALIGN_PTR(LAddr) & g_LBitMask);
+ }
+
+ /*check the Cfg Mapping Addr Rang */
+ if (LAddr >= g_LocalCfgAddrBase
+ && LAddr <=
+ (void *) ((char *) g_LocalCfgAddrBase +
+ sizeof(struct common_mem_mem_config)))
+ {
+ return g_PrimCfgAddrBase + ((char *) LAddr -
+ (char *) g_LocalCfgAddrBase);
+ }
+
+ NSRTP_LOGWAR
+ ("WARNING!!! Input invalid LAddr]LAddr=%p, g_LocalBaseAddr=%p, g_LocalMaxAddr=%p, g_LocalCfgAddrBase=%p, g_LocalCfgAddrMax=%p.",
+ LAddr, g_LocalBaseAddr, g_LocalMaxAddr, g_LocalCfgAddrBase,
+ (char *) g_LocalCfgAddrBase + sizeof(struct common_mem_mem_config));
+
+ return (uint64_t) LAddr;
+}
+
+void *pal_shddr_to_laddr(uint64_t PAddr)
+{
+ size_t p2lIdx;
+
+ if (g_PrimSameFlg || PAddr == ALIGN_PTR(NULL))
+ {
+ return (void *) PAddr;
+ }
+
+ p2lIdx = (PAddr - g_PrimBaseAddr) >> g_LBitMaskLen;
+ /*check the Hugepage Addr Rang */
+ if (PAddr <= g_PrimMaxAddr && PAddr >= g_PrimBaseAddr
+ && g_PrimAddr2LocalMap[p2lIdx])
+ {
+ return (void *) ((uint64_t) g_PrimAddr2LocalMap[p2lIdx] +
+ (PAddr & g_LBitMask));
+ }
+
+ /*check the Cfg Mapping Addr Rang */
+ if (PAddr >= g_PrimCfgAddrBase
+ && PAddr <= g_PrimCfgAddrBase + sizeof(struct common_mem_mem_config))
+ {
+ return (void *) ((uint64_t) g_LocalCfgAddrBase + PAddr -
+ g_PrimCfgAddrBase);
+ }
+
+ NSRTP_LOGWAR
+ ("WARNING!!! Input invalid PAddr]PAddr=%lx, g_PrimBaseAddr=%lx, g_PrimMaxAddr=%lx, g_PrimCfgAddrBase=%lx, g_PrimCfgAddrMax=%lx.",
+ PAddr, g_PrimBaseAddr, g_PrimMaxAddr, g_PrimCfgAddrBase,
+ g_PrimCfgAddrBase + sizeof(struct common_mem_mem_config));
+
+ return (void *) PAddr;
+}
+
+/*lint +e539 */
+
+int dmm_pal_addr_align()
+{
+ return g_PrimSameFlg;
+}
+
+int32_t
+dmm_pktmbuf_pool_iterator(struct common_mem_mempool * mp, uint32_t start,
+ uint32_t end, dmm_mbuf_item_fun fun, void *argv)
+{
+ if (NULL == mp || fun == NULL)
+ {
+ return 0;
+ }
+
+ if (start >= mp->size || end <= start)
+ {
+ return 0;
+ }
+
+ int32_t elm_size = mp->elt_size + mp->header_size + mp->trailer_size;
+ struct common_mem_mbuf *elm_mbuf = (struct common_mem_mbuf *) (STAILQ_FIRST(&mp->mem_list)->addr + start * elm_size + mp->header_size); /*lint !e647 */
+
+ uint32_t i;
+ uint32_t mbuf_end = COMMON_MEM_MIN(end, mp->size) - start;
+ for (i = 0; i < mbuf_end; i++)
+ {
+ (void) fun(elm_mbuf, argv);
+ elm_mbuf = (struct common_mem_mbuf *) ((char *) elm_mbuf + elm_size);
+ }
+
+ return mbuf_end;
+}
+
+void dmm_addr_print(void)
+{
+ const struct common_mem_mem_config *mcfg =
+ common_mem_pal_get_configuration()->mem_config;
+ int s;
+ FILE *fd;
+ char *ptembuf = NULL;
+ if (!mcfg)
+ {
+ NSRTP_LOGERR("mcfg is null");
+ return;
+ }
+ /*printf base address */
+ NSRTP_LOGINF("********master baseaddr begin***************");
+ for (s = 0; s < COMMON_MEM_MAX_MEMSEG; ++s)
+ {
+ if ((mcfg->memseg[s].len > 0) && (mcfg->memseg[s].addr != 0))
+ {
+ NSRTP_LOGINF("addr:%p, len:%u", mcfg->memseg[s].addr,
+ mcfg->memseg[s].len);
+ }
+ }
+ NSRTP_LOGINF("********master baseaddr end***************");
+
+ fd = fopen(COMMON_PROCESS_MAPS, "r");
+ if (!fd)
+ {
+ NSRTP_LOGERR("/proc/self/maps open fail, erro:%d", errno);
+ return;
+ }
+
+ ptembuf = (char *) malloc(BUFSIZ);
+ if (!ptembuf)
+ {
+ NSRTP_LOGERR("malloc buff failed]buff_len=%d", BUFSIZ);
+ fclose(fd);
+ return;
+ }
+ if (EOK != memset_s(ptembuf, BUFSIZ, 0, BUFSIZ))
+ {
+ NSRTP_LOGERR("MEMSET_S failed] buff=%p", ptembuf);
+ }
+ NSRTP_LOGINF("********self process addr space begin***************");
+ while (fgets(ptembuf, BUFSIZ, fd) != NULL)
+ {
+ NSRTP_LOGERR("%s", ptembuf);
+ }
+ NSRTP_LOGINF("********self process addr space end*****************");
+ fclose(fd);
+ free(ptembuf);
+ return;
+}
+
+void *shmem_shddr_to_laddr(void *addr)
+{
+ return ADDR_SHTOL(addr);
+}
+
+uint64_t shmem_laddr_to_shddr(void *addr)
+{
+ return ADDR_LTOSH(addr);
+}
diff --git a/stacks/lwip_stack/src/mem/lwip_mem_api.c b/stacks/lwip_stack/src/mem/lwip_mem_api.c
new file mode 100644
index 0000000..72dd9e5
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/lwip_mem_api.c
@@ -0,0 +1,86 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include "nsfw_mem_api.h"
+#include "nstack_securec.h"
+#include "nsfw_ring_data.h"
+#include "nsfw_init_api.h"
+#include "nsfw_shmem_mng.h"
+
+#define NSFW_MEM_MBUF_CHECK_RET_ERR(mhandle, entype, desc) {\
+ if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \
+ { \
+ NSRTP_LOGERR("input para error]desc=%s,mhandle=%p,mtype=%d", desc, mhandle, entype); \
+ return NSFW_MEM_ERR; \
+ } \
+ }
+
+#define NSFW_MEM_MBUF_CHECK_RET_NULL(mhandle, entype, desc) {\
+ if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \
+ { \
+ NSRTP_LOGERR("input para error]desc=%s,mhandle=%p,mtype=%d", desc, mhandle, entype); \
+ return NULL; \
+ } \
+ }
+
+/*****************************************************************************
+* Prototype : nsfw_mem_mbf_alloc
+* Description : alloc a mbuf from mbuf pool
+* Input : mpool_handle mhandle
+* nsfw_mem_type entype
+* Output : None
+* Return Value : mbuf_handle
+* Calls :
+* Called By :
+*****************************************************************************/
+mbuf_handle nsfw_mem_mbf_alloc(mpool_handle mhandle, nsfw_mem_type entype)
+{
+ if (entype == NSFW_SHMEM)
+ {
+ return nsfw_shmem_mbfalloc(mhandle);
+ }
+
+ NSPOL_LOGINF(NS_LOG_STACKPOOL_ON, "mbf alloc fail] handle=%p, type=%d",
+ mhandle, entype);
+ return NULL;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_mem_mbf_free
+* Description : put a mbuf backintp mbuf pool
+* Input : mbuf_handle mhandle
+* nsfw_mem_type entype
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+i32 nsfw_mem_mbf_free(mbuf_handle mhandle, nsfw_mem_type entype)
+{
+ if (entype == NSFW_SHMEM)
+ {
+ return nsfw_shmem_mbffree(mhandle);
+ }
+
+ NSPOL_LOGINF(NS_LOG_STACKPOOL_ON, "mbf free fail] handle=%p, type=%d",
+ mhandle, entype);
+ return NSFW_MEM_ERR;
+
+}
diff --git a/stacks/lwip_stack/src/mem/lwip_mem_desc.c b/stacks/lwip_stack/src/mem/lwip_mem_desc.c
new file mode 100644
index 0000000..217649a
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/lwip_mem_desc.c
@@ -0,0 +1,80 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include "nsfw_mem_api.h"
+#include "nsfw_shmem_ring.h"
+#include "nsfw_nshmem_ring.h"
+
+/* *INDENT-OFF* */
+nsfw_ring_ops g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX] = {
+ {
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_singlethread_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_singlethread_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_singlethread_dequeuev
+ }
+ },
+ {
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev
+ },
+ {
+ (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_singlethread_enqueue, \
+ (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_singlethread_dequeue, \
+ (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_singlethread_dequeuev
+ }
+ }
+};
+/* *INDENT-ON* */
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c
new file mode 100644
index 0000000..1be5f82
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.c
@@ -0,0 +1,44 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "nsfw_mem_api.h"
+#include "nsfw_nshmem_mng.h"
+#include "nsfw_nshmem_mdesc.h"
+
+/*no share memory access inferface*/
+nsfw_mem_ops g_nshmem_ops = {
+ nsfw_nshmem_init,
+ nsfw_nshmem_destory,
+ nsfw_nshmem_create,
+ NULL,
+ nsfw_nshmem_lookup,
+ nsfw_nshmem_release,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ nsfw_nshmem_spcreate,
+ NULL,
+ NULL,
+ nsfw_nshmem_sprelease,
+ nsfw_nshmem_sp_lookup,
+ nsfw_nshmem_ringcreate,
+ NULL,
+ nsfw_nshmem_ringrelease,
+ nsfw_nshmem_static,
+ NULL, /*mem_ops_sp_iterator */
+ NULL, /*mem_ops_mbuf_iterator */
+};
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h
new file mode 100644
index 0000000..1b63520
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mdesc.h
@@ -0,0 +1,22 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_NSHMEM_MDESC_H
+#define _NSFW_NSHMEM_MDESC_H
+
+extern nsfw_mem_ops g_nshmem_ops;
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c
new file mode 100644
index 0000000..a3c7f60
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c
@@ -0,0 +1,529 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdlib.h>
+#include "nstack_log.h"
+#include "nstack_securec.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_ring_fun.h"
+#include "nsfw_nshmem_ring.h"
+#include "nsfw_nshmem_mng.h"
+
+#include "common_func.h"
+
+#define nsfw_get_glb_lock() (&g_nshmem_internal_cfg->mlock)
+
+#define NSFW_NSHMEM_INIT_CHK_RET_NULL() \
+ if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \
+ { \
+ NSRTP_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \
+ return NULL; \
+ }
+
+#define NSFW_NSHMEM_INIT_CHK_RET() \
+ if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \
+ { \
+ NSRTP_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \
+ return NSFW_MEM_ERR; \
+ }
+
+nsfw_mem_localdata *g_nshmem_localdata = NULL;
+nsfw_nshmem_cfg *g_nshmem_internal_cfg = NULL;
+
+/*look up a mem zone*/
+NSTACK_STATIC inline nsfw_nshmem_mzone *nsfw_nshmem_get_free_zone(void)
+{
+ int icnt = 0;
+
+ /*g_nshmem_internal_cfg must not be null if come here */
+ for (icnt = 0; icnt < COMMON_MEM_MAX_MEMZONE; icnt++)
+ {
+ if (g_nshmem_internal_cfg->amemzone[icnt].addr == NULL)
+ {
+ return &g_nshmem_internal_cfg->amemzone[icnt];
+ }
+ }
+
+ return NULL;
+}
+
+NSTACK_STATIC inline void nsfw_nshmem_free_zone(nsfw_nshmem_mzone * pzone)
+{
+ nsfw_nshmem_mzone *pzonebase = &g_nshmem_internal_cfg->amemzone[0];
+ nsfw_nshmem_mzone *pzoneend =
+ &g_nshmem_internal_cfg->amemzone[NSFW_NSHMEM_ZONE_MAX - 1];
+
+ if ((((int) ((char *) pzone - (char *) pzonebase) < 0)
+ || ((int) ((char *) pzone - (char *) pzoneend) > 0))
+ && ((unsigned int) ((char *) pzone - (char *) pzonebase) %
+ sizeof(nsfw_nshmem_mzone) != 0))
+ {
+ NSRTP_LOGERR("nshmem free fail] mem=%p", pzone);
+ return;
+ }
+ if (pzone->addr)
+ {
+ free(pzone->addr);
+ }
+ pzone->addr = NULL;
+
+ int ret = memset_s((void *) pzone, sizeof(nsfw_nshmem_mzone), 0,
+ sizeof(nsfw_nshmem_mzone));
+ if (EOK != ret)
+ {
+ NSRTP_LOGERR("MEMSET_S failed] mem=%p, ret=%d", pzone, ret);
+ }
+ return;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_init
+* Description : nsh module init
+* Input : nsfw_mem_para* para
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*****************************************************************************/
+i32 nsfw_nshmem_init(nsfw_mem_para * para)
+{
+ i32 iret = NSFW_MEM_OK;
+ NSRTP_LOGINF("nsfw nshmem init begin");
+ g_nshmem_localdata =
+ (nsfw_mem_localdata *) malloc(sizeof(nsfw_mem_localdata));
+
+ if (NULL == g_nshmem_localdata)
+ {
+ NSRTP_LOGERR("nshmem init g_nshmem_localdata malloc fail");
+ return NSFW_MEM_ERR;
+ }
+
+ iret =
+ memset_s(g_nshmem_localdata, sizeof(nsfw_mem_localdata), 0,
+ sizeof(nsfw_mem_localdata));
+
+ if (EOK != iret)
+ {
+ NSRTP_LOGERR("nshmem init g_nshmem_localdata MEMSET_S fail");
+ goto ERROR;
+ }
+
+ g_nshmem_internal_cfg =
+ (nsfw_nshmem_cfg *) malloc(sizeof(nsfw_nshmem_cfg));
+
+ if (NULL == g_nshmem_internal_cfg)
+ {
+ NSRTP_LOGERR("nshmem init g_nshmem_internal_cfg malloc fail");
+ goto ERROR;
+ }
+
+ iret =
+ memset_s(g_nshmem_internal_cfg, sizeof(nsfw_nshmem_cfg), 0,
+ sizeof(nsfw_nshmem_cfg));
+
+ if (EOK != iret)
+ {
+ NSRTP_LOGERR("nshmem init g_nshmem_internal_cfg MEMSET_S fail");
+ goto ERROR;
+ }
+
+ g_nshmem_localdata->enflag = para->enflag;
+ NSRTP_LOGINF("nsfw nshmem init end");
+ goto OK;
+
+ ERROR:
+ iret = NSFW_MEM_ERR;
+ nsfw_nshmem_destory();
+ return iret;
+ OK:
+ iret = NSFW_MEM_OK;
+ return iret;
+}
+
+/*
+ * memory destory
+ */
+void nsfw_nshmem_destory(void)
+{
+ if (g_nshmem_localdata)
+ {
+ free(g_nshmem_localdata);
+ g_nshmem_localdata = NULL;
+ }
+
+ if (g_nshmem_internal_cfg)
+ {
+ free(g_nshmem_internal_cfg);
+ g_nshmem_internal_cfg = NULL;
+ }
+
+ return;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_reserv_safe
+* Description : malloc a memory and save to memzone
+* Input : const char* name
+* size_t length
+* Output : None
+* Return Value : mzone_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mzone_handle nsfw_nshmem_reserv_safe(const char *name, size_t length)
+{
+ void *addr = NULL;
+ i32 iret = NSFW_MEM_OK;
+ nsfw_nshmem_mzone *pmemzone = NULL;
+
+ if (length <= 0)
+ {
+ return NULL;
+ }
+
+ nsfw_write_lock(nsfw_get_glb_lock());
+
+ addr = malloc(length);
+ if (!addr)
+ {
+ NSRTP_LOGERR("nshmem malloc addr fail] addr=%p", addr);
+ nsfw_write_unlock(nsfw_get_glb_lock());
+ return NULL;
+ }
+
+ iret = memset_s(addr, length, 0, length);
+ if (EOK != iret)
+ {
+ NSRTP_LOGERR("nshmem malloc addr MEMSET_S fail] addr=%p", addr);
+ free(addr);
+ nsfw_write_unlock(nsfw_get_glb_lock());
+ return NULL;
+ }
+
+ pmemzone = nsfw_nshmem_get_free_zone();
+
+ if (!pmemzone)
+ {
+ NSRTP_LOGERR("nshmem get free zone fail");
+ free(addr);
+ nsfw_write_unlock(nsfw_get_glb_lock());
+ return NULL;
+ }
+
+ pmemzone->addr = addr;
+ pmemzone->length = length;
+ /*name must be less than NSFW_MEM_APPNAME_LENGTH */
+ if (EOK !=
+ strcpy_s((char *) pmemzone->aname, sizeof(pmemzone->aname), name))
+ {
+ NSRTP_LOGERR("STRCPY_S failed]name=%s", name);
+ free(addr);
+ nsfw_write_unlock(nsfw_get_glb_lock());
+ return NULL;
+ }
+
+ nsfw_write_unlock(nsfw_get_glb_lock());
+ return addr;
+}
+
+/*
+ * create no shared memory
+ * nsfw_mem_zone::stname no shared memory name
+ * nsfw_mem_zone::isize memory size
+ */
+mzone_handle nsfw_nshmem_create(nsfw_mem_zone * pinfo)
+{
+
+ NSFW_NAME_LENCHECK_RET_NULL(pinfo->stname.aname, "nshmem create");
+ NSFW_NSHMEM_INIT_CHK_RET_NULL();
+ return nsfw_nshmem_reserv_safe(pinfo->stname.aname, pinfo->lenth);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_lookup
+* Description : find a block memory by name
+* Input : nsfw_mem_name* pname
+* Output : None
+* Return Value : mzone_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mzone_handle nsfw_nshmem_lookup(nsfw_mem_name * pname)
+{
+ int icnt = 0;
+ nsfw_nshmem_mzone *mz = NULL;
+
+ NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "nshmem lookup");
+ NSFW_NSHMEM_INIT_CHK_RET_NULL();
+ nsfw_read_lock(nsfw_get_glb_lock());
+
+ for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++)
+ {
+ mz = &g_nshmem_internal_cfg->amemzone[icnt];
+
+ if (mz->addr != NULL
+ && !strncmp(pname->aname, mz->aname, NSFW_MEM_NAME_LENTH))
+ {
+ nsfw_read_unlock(nsfw_get_glb_lock());
+ return mz->addr;
+ }
+ }
+
+ nsfw_read_unlock(nsfw_get_glb_lock());
+ return NULL;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_release
+* Description : free a block memory
+* Input : nsfw_mem_name* pname
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+i32 nsfw_nshmem_release(nsfw_mem_name * pname)
+{
+ int icnt = 0;
+ nsfw_nshmem_mzone *mz = NULL;
+
+ NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem release");
+ NSFW_NSHMEM_INIT_CHK_RET();
+ nsfw_read_lock(nsfw_get_glb_lock());
+
+ for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++)
+ {
+ mz = &g_nshmem_internal_cfg->amemzone[icnt];
+
+ if (mz->addr != NULL
+ && !strncmp(pname->aname, mz->aname, NSFW_MEM_NAME_LENTH))
+ {
+ nsfw_nshmem_free_zone(mz);
+ nsfw_read_unlock(nsfw_get_glb_lock());
+ return NSFW_MEM_OK;
+ }
+ }
+
+ nsfw_read_unlock(nsfw_get_glb_lock());
+ return NSFW_MEM_OK;
+
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_spcreate
+* Description : create a memory pool by ring
+* Input : nsfw_mem_sppool* pmpinfo
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*****************************************************************************/
+mring_handle nsfw_nshmem_spcreate(nsfw_mem_sppool * pmpinfo)
+{
+ size_t len = 0;
+ unsigned int usnum = common_mem_align32pow2(pmpinfo->usnum + 1);
+ unsigned int uselt_size = pmpinfo->useltsize;
+ struct nsfw_mem_ring *pringhead = NULL;
+ unsigned int uscnt = 0;
+ char *pmz = NULL;
+ NSFW_NAME_LENCHECK_RET_NULL(pmpinfo->stname.aname, "nshmem sp create");
+ NSFW_NSHMEM_INIT_CHK_RET_NULL();
+
+ len =
+ sizeof(struct nsfw_mem_ring) +
+ (size_t) usnum *sizeof(union RingData_U) + (size_t) usnum *uselt_size;
+ pringhead =
+ (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe(pmpinfo->
+ stname.aname, len);
+
+ if (!pringhead)
+ {
+ NSRTP_LOGERR("nshmem sp create mzone reserv fail");
+ return NULL;
+ }
+
+ nsfw_mem_ring_init(pringhead, usnum, pringhead, NSFW_NSHMEM,
+ pmpinfo->enmptype);
+ pmz =
+ ((char *) pringhead + sizeof(struct nsfw_mem_ring) +
+ usnum * sizeof(union RingData_U));
+
+ for (uscnt = 0; uscnt < usnum; uscnt++)
+ {
+ if (0 ==
+ g_ring_ops_arry[pringhead->memtype][pringhead->
+ ringflag].ring_ops_enqueue
+ (pringhead, (void *) pmz))
+ {
+ NSRTP_LOGERR("nsfw_nshmem_ringenqueue enqueue fail] uscnt=%u",
+ uscnt);
+ }
+
+ pmz = pmz + uselt_size;
+ }
+
+ return pringhead;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_sp_lookup
+* Description : look up a sppool memory
+* Input : nsfw_mem_name* pname
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*****************************************************************************/
+mring_handle nsfw_nshmem_sp_lookup(nsfw_mem_name * pname)
+{
+ return nsfw_nshmem_lookup(pname);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_sprelease
+* Description : release a sp pool
+* Input : nsfw_mem_name* pname
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+i32 nsfw_nshmem_sprelease(nsfw_mem_name * pname)
+{
+ NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem sp mempool release");
+ NSFW_NSHMEM_INIT_CHK_RET();
+ return nsfw_nshmem_release(pname);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_ringcreate
+* Description : create a ring
+* Input : nsfw_mem_mring* pringinfo
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle nsfw_nshmem_ringcreate(nsfw_mem_mring * pringinfo)
+{
+ size_t len = 0;
+ unsigned int usnum = common_mem_align32pow2(pringinfo->usnum + 1);
+ struct nsfw_mem_ring *pringhead = NULL;
+ NSFW_NAME_LENCHECK_RET_NULL(pringinfo->stname.aname,
+ "nshmem ring create");
+ NSFW_NSHMEM_INIT_CHK_RET_NULL();
+
+ len = sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U);
+ pringhead =
+ (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe(pringinfo->
+ stname.aname, len);
+
+ if (!pringhead)
+ {
+ NSRTP_LOGERR("nshmem ring create mzone reserv fail");
+ return NULL;
+ }
+
+ nsfw_mem_ring_init(pringhead, usnum, (void *) pringhead, NSFW_NSHMEM,
+ pringinfo->enmptype);
+ return pringhead;
+
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_ringrelease
+* Description : release a nsh ring memory
+* Input : nsfw_mem_name* pname
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+i32 nsfw_nshmem_ringrelease(nsfw_mem_name * pname)
+{
+ NSFW_NAME_LENCHECK_RET(pname->aname, "nshmem ring mempool release");
+ NSFW_NSHMEM_INIT_CHK_RET();
+ return nsfw_nshmem_release(pname);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_sppool_statics
+* Description : static the memory size of sppool
+* Input : mring_handle sppool
+* Output : None
+* Return Value : ssize_t
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+ssize_t nsfw_nshmem_sppool_statics(mring_handle sppool)
+{
+ struct nsfw_mem_ring *phead = (struct nsfw_mem_ring *) sppool;
+
+ return sizeof(struct nsfw_mem_ring) +
+ (ssize_t) phead->size * sizeof(union RingData_U) +
+ (ssize_t) phead->size * phead->eltsize;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_ring_statics
+* Description : static the memory size of ring
+* Input : mring_handle handle
+* Output : None
+* Return Value : ssize_t
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+ssize_t nsfw_nshmem_ring_statics(mring_handle handle)
+{
+ struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle;
+ return ring->size * sizeof(union RingData_U) +
+ sizeof(struct nsfw_mem_ring);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_nshmem_static
+* Description : static the memory size according to mem type
+* Input : void* handle
+* nsfw_mem_struct_type type
+* Output : None
+* Return Value : ssize_t
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+ssize_t nsfw_nshmem_static(void *handle, nsfw_mem_struct_type type)
+{
+ switch (type)
+ {
+ case NSFW_MEM_MBUF:
+ return -1;
+ case NSFW_MEM_SPOOL:
+ return nsfw_nshmem_sppool_statics(handle);
+ case NSFW_MEM_RING:
+ return nsfw_nshmem_ring_statics(handle);
+ default:
+ break;
+ }
+ return -1;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h
new file mode 100644
index 0000000..fa5bc6b
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.h
@@ -0,0 +1,70 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_NSHMEM_MNG_H_
+#define _NSFW_NSHMEM_MNG_H_
+
+#include "common_mem_rwlock.h"
+
+#include "common_func.h"
+
+#define NSFW_NSHMEM_ZONE_MAX 2560
+
+typedef struct
+{
+ i8 aname[NSFW_MEM_NAME_LENTH];
+ void *addr;
+ int length;
+} nsfw_nshmem_mzone;
+
+typedef struct
+{
+ nsfw_nshmem_mzone amemzone[NSFW_NSHMEM_ZONE_MAX];
+ common_mem_rwlock_t mlock;
+} nsfw_nshmem_cfg;
+
+/*
+ * no share memory module init
+ */
+i32 nsfw_nshmem_init(nsfw_mem_para * para);
+
+/*
+ * no share memory module destory
+ */
+void nsfw_nshmem_destory(void);
+
+/*
+ * create a no shared memory
+ */
+mzone_handle nsfw_nshmem_create(nsfw_mem_zone * pinfo);
+
+mzone_handle nsfw_nshmem_lookup(nsfw_mem_name * pname);
+
+i32 nsfw_nshmem_release(nsfw_mem_name * pname);
+
+mring_handle nsfw_nshmem_spcreate(nsfw_mem_sppool * pmpinfo);
+
+i32 nsfw_nshmem_sprelease(nsfw_mem_name * pname);
+
+mring_handle nsfw_nshmem_sp_lookup(nsfw_mem_name * pname);
+
+mring_handle nsfw_nshmem_ringcreate(nsfw_mem_mring * pringinfo);
+
+i32 nsfw_nshmem_ringrelease(nsfw_mem_name * pname);
+
+ssize_t nsfw_nshmem_static(void *handle, nsfw_mem_struct_type type);
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c
new file mode 100644
index 0000000..51f1fa4
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.c
@@ -0,0 +1,434 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include <sched.h>
+#include "nstack_securec.h"
+
+#include "nsfw_mem_api.h"
+#include "nsfw_nshmem_ring.h"
+#include "nsfw_ring_fun.h"
+#include "common_func.h"
+
+/*copy the data to obj*/
+NSTACK_STATIC inline void
+nsfw_nshmem_ring_obj_copy(struct nsfw_mem_ring *r, uint32_t cons_head,
+ void **obj_table, unsigned n)
+{
+ uint32_t idx = cons_head & r->mask;
+ unsigned i = 0;
+ const uint32_t size = r->size;
+
+ if (likely(idx + n < size))
+ {
+ for (i = 0; i < (n & (~(unsigned) 0x3)); i += 4, idx += 4)
+ {
+ obj_table[i] = (void *) r->ring[idx].data_l;
+ obj_table[i + 1] = (void *) r->ring[idx + 1].data_l;
+ obj_table[i + 2] = (void *) r->ring[idx + 2].data_l;
+ obj_table[i + 3] = (void *) r->ring[idx + 3].data_l;
+ }
+ switch (n & 0x3)
+ {
+ case 3:
+ obj_table[i++] = (void *) r->ring[idx++].data_l;
+
+ case 2:
+ obj_table[i++] = (void *) r->ring[idx++].data_l;
+
+ case 1:
+ obj_table[i++] = (void *) r->ring[idx++].data_l;
+ }
+ }
+ else
+ {
+ for (i = 0; idx < size; i++, idx++)
+ {
+ obj_table[i] = (void *) r->ring[idx].data_l;
+ }
+
+ for (idx = 0; i < n; i++, idx++)
+ {
+ obj_table[i] = (void *) r->ring[idx].data_l;
+ }
+ }
+}
+
+/*fork recover*/
+NSTACK_STATIC inline void
+nsfw_nshmem_enqueue_fork_recov(struct nsfw_mem_ring *r)
+{
+ u32_t pidflag = 0;
+ u32_t curpid = get_sys_pid();
+ int success = 0;
+ /*if pid is not the same, maybe mult thread fork happen */
+ pidflag = r->prodhflag;
+
+ if (unlikely(pidflag != curpid))
+ {
+ success = common_mem_atomic32_cmpset(&r->prodhflag, pidflag, curpid);
+
+ if (unlikely(success != 0))
+ {
+ /*recover it */
+ if (r->prod.tail != r->prod.head)
+ {
+ r->prod.head = r->prod.tail;
+ }
+
+ r->prodtflag = curpid;
+ }
+ }
+
+ return;
+}
+
+NSTACK_STATIC inline void
+nsfw_nshmem_dequeue_fork_recov(struct nsfw_mem_ring *r)
+{
+ u32_t pidflag = 0;
+ u32_t curpid = get_sys_pid();
+ int success = 0;
+ /*if pid is not the same, maybe mult thread fork happen */
+ pidflag = r->conshflag;
+
+ if (unlikely(pidflag != curpid))
+ {
+ success = common_mem_atomic32_cmpset(&r->conshflag, pidflag, curpid);
+
+ if (unlikely(success != 0))
+ {
+ /*recover it */
+ if (r->cons.tail != r->cons.head)
+ {
+ r->cons.head = r->cons.tail;
+ }
+
+ r->constflag = curpid;
+ }
+ }
+
+ return;
+}
+
+/*
+this is a multi thread/process enqueue function, please pay attention to the bellow point
+1. while Enqueue corrupt, we may lose one element; because no one to add the Head
+*/
+int
+nsfw_nshmem_ring_mp_enqueue(struct nsfw_mem_ring *mem_ring, void *obj_table)
+{
+ uint32_t producer_head, producer_next;
+ uint32_t consumer_tail, free_entries;
+ int success;
+ unsigned rep = 0;
+ uint32_t mask = mem_ring->mask;
+ uint32_t size = mem_ring->size;
+ uint32_t n = 1;
+
+ /* move prod.head atomically */
+ do
+ {
+
+ producer_head = mem_ring->prod.head;
+ consumer_tail = mem_ring->cons.tail;
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * producer_head > consumer_tail). So 'free_entries' is always between 0
+ * and size(ring)-1. */
+ free_entries = (size + consumer_tail - producer_head);
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > free_entries))
+ {
+ return 0;
+ /* Below code is commented currenlty as its a dead code. */
+ }
+
+ /*if pid is not the same, maybe mult thread fork happen */
+ nsfw_nshmem_enqueue_fork_recov(mem_ring);
+
+ while (unlikely
+ ((mem_ring->prod.tail != mem_ring->prod.head)
+ || (mem_ring->prodtflag != mem_ring->prodhflag)))
+ {
+ common_mem_pause();
+ }
+
+ producer_next = producer_head + n;
+ success =
+ common_mem_atomic32_cmpset(&mem_ring->prod.head, producer_head,
+ producer_next);
+ }
+ while (unlikely(success == 0));
+
+ mem_ring->ring[producer_head & mask].data_l = (u64) obj_table;
+
+ /*
+ * If there are other enqueues in progress that preceded us,
+ * we need to wait for them to complete
+ */
+ while (unlikely(mem_ring->prod.tail != producer_head))
+ {
+ common_mem_pause();
+
+ /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting
+ * for other thread finish. It gives pre-emptied thread a chance
+ * to proceed and finish with ring dequeue operation. */
+ /* check the queue can be operate */
+ if (++rep == 5)
+ {
+ rep = 0;
+ (void) sched_yield();
+ }
+ }
+
+ mem_ring->prod.tail = producer_next;
+ return (int) n;
+}
+
+/*
+ this is a single thread/process enqueue function
+ */
+int nsfw_nshmem_ring_sp_enqueue(struct nsfw_mem_ring *r, void *obj_table)
+{
+ uint32_t producer_head, consumer_tail;
+ uint32_t producer_next, free_entries;
+ uint32_t mask = r->mask;
+ uint32_t n = 1;
+ uint32_t size = r->size;
+
+ producer_head = r->prod.head;
+ consumer_tail = r->cons.tail;
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * producer_head > consumer_tail). So 'free_entries' is always between 0
+ * and size(ring)-1. */
+ free_entries = size + consumer_tail - producer_head;
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > free_entries))
+ {
+ return 0;
+ }
+
+ nsfw_nshmem_enqueue_fork_recov(r);
+
+ producer_next = producer_head + n;
+ r->prod.head = producer_next;
+
+ r->ring[producer_head & mask].data_l = (u64) obj_table;
+
+ r->prod.tail = producer_next;
+ return (int) n;
+}
+
+/*
+ this is enhanced mc_ring_dequeue, support dequeue multi element one time.
+*/
+int
+nsfw_nshmem_ring_mc_dequeuev(struct nsfw_mem_ring *r, void **obj_table,
+ unsigned int n)
+{
+ uint32_t consumer_head, producer_tail;
+ uint32_t consumer_next, entries;
+ int success;
+ unsigned rep = 0;
+ uint32_t num = n;
+
+ /* Avoid the unnecessary cmpset operation below, which is also
+ * potentially harmful when n equals 0. */
+ if (unlikely(num == 0))
+ {
+ return 0;
+ }
+
+ nsfw_nshmem_dequeue_fork_recov(r);
+
+ /* move cons.head atomically */
+ do
+ {
+ num = n;
+ consumer_head = r->cons.head;
+ producer_tail = r->prod.tail;
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1. */
+ entries = (producer_tail - consumer_head);
+
+ /* Set the actual entries for dequeue */
+ if (unlikely(num > entries))
+ {
+ if (likely(entries > 0))
+ {
+ num = entries;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /* check the queue can be operate */
+ while (unlikely
+ ((r->cons.tail != r->cons.head)
+ || (r->conshflag != r->constflag)))
+ {
+ common_mem_pause();
+ }
+
+ consumer_next = consumer_head + num;
+
+ success =
+ common_mem_atomic32_cmpset(&r->cons.head, consumer_head,
+ consumer_next);
+ }
+ while (unlikely(success == 0));
+
+ nsfw_nshmem_ring_obj_copy(r, consumer_head, obj_table, num);
+
+ /*
+ * If there are other dequeues in progress that preceded us,
+ * we need to wait for them to complete
+ */
+ while (unlikely(r->cons.tail != consumer_head))
+ {
+ common_mem_pause();
+
+ /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting
+ * for other thread finish. It gives pre-emptied thread a chance
+ * to proceed and finish with ring dequeue operation. */
+ /* check the queue can be operate */
+ if (++rep == 5)
+ {
+ rep = 0;
+ (void) sched_yield();
+ }
+ }
+
+ r->cons.tail = consumer_next;
+
+ return (int) num;
+}
+
+/*this is a multi thread/process dequeue function, please pay attention to the bellow point
+1. while dequeue corrupt, the tail no one added, may multi the try times.
+*/
+int nsfw_nshmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ return nsfw_nshmem_ring_mc_dequeuev(ring, box, 1);
+}
+
+/*
+ this is a single thread/process dequeue function
+*/
+int
+nsfw_nshmem_ring_sc_dequeuev(struct nsfw_mem_ring *r, void **obj_table,
+ unsigned int n)
+{
+ uint32_t consumer_head, producer_tail;
+ uint32_t consumer_next, entries;
+ uint32_t inum = n;
+ consumer_head = r->cons.head;
+ producer_tail = r->prod.tail;
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1. */
+ entries = producer_tail - consumer_head;
+
+ if (unlikely(inum > entries))
+ {
+ if (likely(entries > 0))
+ {
+ inum = entries;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ nsfw_nshmem_dequeue_fork_recov(r);
+
+ consumer_next = consumer_head + inum;
+ r->cons.head = consumer_next;
+
+ nsfw_nshmem_ring_obj_copy(r, consumer_head, obj_table, inum);
+
+ r->cons.tail = consumer_next;
+ return (int) inum;
+}
+
+/*
+ this is enhanced mc_ring_dequeue, support dequeue multi element one time.
+*/
+int nsfw_nshmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ return nsfw_nshmem_ring_sc_dequeuev(ring, box, 1);
+}
+
+/*stack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_nshmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, void *box)
+{
+ u32 head = 0;
+
+ /*if queue is full, just return 0 */
+ if (unlikely(ring->prod.head >= (ring->size + ring->cons.tail)))
+ {
+ return 0;
+ }
+
+ head = ring->prod.head;
+ ring->ring[head & ring->mask].data_l = (u64) box;
+ ring->prod.head++;
+ return 1;
+}
+
+/*stack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_nshmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ return nsfw_nshmem_ring_singlethread_dequeuev(ring, box, 1);
+}
+
+/*stack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_nshmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring,
+ void **box, unsigned int n)
+{
+ u32 tail = 0;
+ u32 num = 0;
+
+ while (num < n)
+ {
+ tail = ring->cons.tail;
+
+ /* if all entries are dequeued return 0 */
+ if (unlikely(ring->prod.head == ring->cons.tail))
+ {
+ return num;
+ }
+
+ box[num] = (void *) ring->ring[tail & ring->mask].data_l;
+ ring->cons.tail++;
+ num++;
+ }
+
+ return num;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h
new file mode 100644
index 0000000..f7f7732
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_ring.h
@@ -0,0 +1,38 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_NSHMEM_RING_H_
+#define _NSFW_NSHMEM_RING_H_
+
+#include <stdint.h>
+#include "nsfw_ring_data.h"
+
+int nsfw_nshmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box);
+int nsfw_nshmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box);
+int nsfw_nshmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box);
+int nsfw_nshmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n);
+int nsfw_nshmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box);
+int nsfw_nshmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n);
+int nsfw_nshmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring,
+ void *box);
+int nsfw_nshmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring,
+ void **box);
+int nsfw_nshmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring,
+ void **box, unsigned int n);
+
+#endif /*_NSFW_NSHMEM_RING_H_*/
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c
new file mode 100644
index 0000000..9016282
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c
@@ -0,0 +1,989 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdint.h>
+#include "nstack_securec.h"
+#include "nstack_log.h"
+#include "nsfw_ring_fun.h"
+#include "nsfw_shmem_ring.h"
+#include "nsfw_shmem_mng.h"
+#include "common_mem_buf.h"
+#include "common_mem_common.h"
+
+#include "common_func.h"
+#include "common_pal_bitwide_adjust.h"
+
+/*get the base address of msg data */
+#define NSFW_SHMEM_GET_DATA(pmsg, type) (type *)&((pmsg)->aidata[0])
+
+/*if input point is nun, just return null*/
+#define NSFW_POINT_CHK_RET_NULL(p, desc) \
+ if (NULL == (p)) \
+ { \
+ NSRTP_LOGERR("point check fail] desc_para=%s", desc); \
+ return NULL; \
+ }
+
+/*if input point is nun, just return err num*/
+#define NSFW_POINT_CHK_RET_ERR(p, desc) \
+ if (NULL == (p)) \
+ { \
+ NSRTP_LOGDBG("point check fail] desc_para=%s", desc); \
+ return NSFW_MEM_ERR; \
+ }
+
+/*if input point is nun, goto flag*/
+#define NSFW_POINT_CHK_RET_GOTO(p, gotoflag, desc) \
+ if (NULL == (p)) \
+ { \
+ NSRTP_LOGERR("point check fail] desc_para=%s", desc); \
+ goto gotoflag; \
+ }
+
+/*init the msg head*/
+#define NSFW_SHMEM_MSG_HEAD_INIT(pmsg, type, length) { \
+ (pmsg)->usmsg_type = (type); \
+ (pmsg)->uslenth = (length); \
+ }
+
+/*rsp msg head check, and if err goto*/
+#define NSFW_SHMEM_MSGHEAD_CHK_GOTO(pmsg, type, length, gotoflag) { \
+ if (((type) != pmsg->usmsg_type) && ((length) != pmsg->uslenth)) \
+ { \
+ NSRTP_LOGERR("check fail] msgtype=%d, type_para=%d, len=%d", (pmsg->usmsg_type), (type), (length)); \
+ goto gotoflag; \
+ } \
+ }
+
+/*rsp check the state*/
+#define NSFW_SHMEM_ACKSTATE_CHK_GOTO(expret, ret, expseg, seg, gotoflag) { \
+ if (((ret) != (expret)) || ((expseg) != (seg))) \
+ { \
+ NSRTP_LOGERR("ackstate check fail]msgack exp=%d, real=%d,eseg=%d, rseg=%d", (expret), (ret), (expseg), (seg)); \
+ goto gotoflag; \
+ } \
+ }
+
+/*mzone msg init*/
+#define NSFW_SHMEM_MZONE_DATA_INIT(pdata, slength, seg, socketid) { \
+ (pdata)->isocket_id = (socketid); \
+ (pdata)->lenth = (slength); \
+ (pdata)->usseq = (seg); \
+ (pdata)->ireserv = 0; \
+ }
+
+/*mbuf msg init*/
+#define NSFW_SHMEM_MBUF_DATA_INIT(pdata, seg, num, cashsize, priv_size, data_room, flag, socketid) { \
+ (pdata)->usseq = (seg); \
+ (pdata)->usnum = (num); \
+ (pdata)->uscash_size = (cashsize); \
+ (pdata)->uspriv_size = (priv_size); \
+ (pdata)->usdata_room = (data_room); \
+ (pdata)->enmptype = (flag); \
+ (pdata)->isocket_id = (socketid); \
+ (pdata)->ireserv = 0; \
+ }
+
+/*mpool msg init*/
+#define NSFW_SHMEM_MPOOL_DATA_INIT(pdata, seg, num, eltsize, flag, socketid) { \
+ (pdata)->usseq = (seg); \
+ (pdata)->usnum = (num); \
+ (pdata)->useltsize = (eltsize); \
+ (pdata)->enmptype = (flag); \
+ (pdata)->isocket_id = (socketid); \
+ (pdata)->ireserv = 0; \
+ }
+
+/*mring msg init*/
+#define NSFW_SHMEM_MRING_DATA_INIT(pdata, seg, num, flag, socketid) { \
+ (pdata)->usseq = (seg); \
+ (pdata)->usnum = (num); \
+ (pdata)->enmptype = (flag); \
+ (pdata)->isocket_id = (socketid); \
+ (pdata)->ireserv = 0; \
+ }
+
+#define NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg) {\
+ if (pmsg) \
+ { \
+ nsfw_mgr_msg_free(pmsg); \
+ } \
+ if (prsp_msg) \
+ { \
+ nsfw_mgr_msg_free(prsp_msg); \
+ } \
+}
+
+/*
+ * create a block memory by send a msg
+ *
+ */
+mzone_handle
+nsfw_memzone_remote_reserv(const i8 * name, size_t mlen, i32 socket_id)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+
+ /*msg head point define */
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ /*msg data point define */
+ nsfw_shmem_reserv_req *pdata = NULL;
+ nsfw_shmem_msg_head *pack_head = NULL;
+
+ /*ack msg define */
+ nsfw_shmem_ack *pack_data = NULL;
+
+ mzone_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+
+ //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER);
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_NULL(pmsg, "remote reserv pmsg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, "remote reserv rspmsg alloc");
+
+ /*msg head init */
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RESERV_REQ_MSG,
+ sizeof(nsfw_shmem_reserv_req));
+
+ /*msg data init */
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_reserv_req);
+ iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name);
+ if (EOK != iretval)
+ {
+ NSRTP_LOGERR("reserv mem copy name fail] ret=%d", iretval);
+ goto release;
+ }
+
+ /*fill msg data */
+ NSFW_SHMEM_MZONE_DATA_INIT(pdata, mlen, (u16) 0, socket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("reserv mem req rsp fail] ret=%u", ucret);
+ goto release;
+ }
+
+ /*interrupt msg head */
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RESERV_ACK_MSG,
+ sizeof(nsfw_shmem_ack), release);
+
+ pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0,
+ pack_data->usseq, release);
+
+ hhandle = (mzone_handle) ADDR_SHTOL(pack_data->pbase_addr);
+ NSRTP_LOGDBG("mem reserve] name=%s, handle=%p, seg=%u", name, hhandle,
+ pack_data->usseq);
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return hhandle;
+}
+
+/*
+ *create some memories by send a msg
+ */
+i32
+nsfw_memzone_remote_reserv_v(nsfw_mem_zone * pmeminfo,
+ mzone_handle * paddr_array, i32 inum, pid_t pid)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+ nsfw_shmem_msg_head *pdata_head = NULL;
+ nsfw_shmem_reserv_req *pdata = NULL;
+ nsfw_shmem_reserv_req *ptempdata = NULL;
+ nsfw_shmem_msg_head *pack_head = NULL;
+
+ nsfw_shmem_ack *pack_data = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+ i32 icount = 0;
+ i32 itindex = 0;
+ i32 iindex = 0;
+ u16 ussegbase = 0;
+ u16 ustempv = 0;
+ i32 ieltnum = 0;
+ i32 ieltnum_max =
+ (NSFW_MGR_MSG_BODY_LEN -
+ sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_reserv_req);
+
+ //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER);
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_GOTO(pmsg, err, "remote reserv_v msg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, err, "remote reserv_v rspmsg alloc");
+
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+
+ ptempdata = pdata =
+ NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_reserv_req);
+
+ do
+ {
+ icount++;
+ ieltnum++;
+
+ if (((icount % ieltnum_max) == 0) || (icount >= inum))
+ {
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RESERV_REQ_MSG,
+ ieltnum * sizeof(nsfw_shmem_reserv_req));
+
+ itindex = icount - 1;
+ int retVal =
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmeminfo[itindex].stname.aname, pid);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ }
+ NSFW_SHMEM_MZONE_DATA_INIT(ptempdata, pmeminfo[itindex].lenth,
+ (u16) itindex,
+ pmeminfo[itindex].isocket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("reserv v mem req rsp fail] ret=%u", ucret);
+ goto err;
+ }
+
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RESERV_ACK_MSG,
+ ieltnum * sizeof(nsfw_shmem_ack),
+ err);
+
+ pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+
+ for (iindex = 0; iindex < ieltnum; iindex++)
+ {
+ ustempv = ussegbase + iindex;
+
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC,
+ pack_data->cstate, ustempv,
+ (u16) pack_data->usseq, err);
+
+ paddr_array[ustempv] = ADDR_SHTOL(pack_data->pbase_addr);
+ NSRTP_LOGDBG("remote reserve]index=%u, seg=%u, handle=%p",
+ ustempv, pack_data->usseq, paddr_array[ustempv]);
+ pack_data++;
+ }
+
+ ussegbase = icount;
+ ieltnum = 0;
+ ptempdata = pdata;
+ }
+ else
+ {
+ itindex = icount - 1;
+ int retVal =
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmeminfo[itindex].stname.aname, pid);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ }
+ NSFW_SHMEM_MZONE_DATA_INIT(ptempdata, pmeminfo[itindex].lenth,
+ (u16) itindex,
+ pmeminfo[itindex].isocket_id);
+ ptempdata++;
+ }
+ }
+ while (icount < inum);
+
+ iretval = NSFW_MEM_OK;
+ goto free;
+
+ err:
+ iretval = NSFW_MEM_ERR;
+ free:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return iretval;
+}
+
+/*
+ *release a block memory with name by send msg
+ */
+i32 nsfw_remote_free(const i8 * name, nsfw_mem_struct_type entype)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ nsfw_shmem_free_req *pdata = NULL;
+
+ nsfw_shmem_msg_head *pack_head = NULL;
+ nsfw_shmem_ack *pack_data = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_ERR(pmsg, "remote free msg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, terr, "remote free rspmsg alloc");
+
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RELEASE_REQ_MSG,
+ sizeof(nsfw_shmem_free_req));
+
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_free_req);
+ if (EOK != strcpy_s(pdata->aname, sizeof(pdata->aname), name))
+ {
+ NSRTP_LOGERR("STRCPY_S failed]name=%s", name);
+ }
+ pdata->usseq = 0;
+ pdata->ustype = entype;
+ pdata->ireserv = 0;
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("free mem req rsp fail] ret=%u", ucret);
+ goto release;
+ }
+
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RELEASE_ACK_MSG,
+ sizeof(nsfw_shmem_ack), terr);
+
+ pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0,
+ pack_data->usseq, terr);
+
+ iretval = NSFW_MEM_OK;
+ goto release;
+ terr:
+ iretval = NSFW_MEM_ERR;
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return iretval;
+}
+
+/*
+ *create a mbuf pool by send a msg
+ */
+mpool_handle
+nsfw_remote_shmem_mbf_create(const i8 * name, unsigned n,
+ unsigned cache_size, unsigned priv_size,
+ unsigned data_room_size, i32 socket_id,
+ nsfw_mpool_type entype)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+ nsfw_shmem_msg_head *pdata_head = NULL;
+ nsfw_shmem_mbuf_req *pdata = NULL;
+ nsfw_shmem_msg_head *tpack_head = NULL;
+ nsfw_shmem_ack *tpack_data = NULL;
+ mpool_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_NULL(pmsg, "remote mbf create pmsg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, release, "remote mbf create msg alloc");
+
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MBUF_REQ_MSG,
+ sizeof(nsfw_shmem_mbuf_req));
+
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_mbuf_req);
+ iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name);
+ if (EOK != iretval)
+ {
+ NSRTP_LOGERR("mbf create name cpy fail] ret=%d", iretval);
+ goto release;
+ }
+
+ NSFW_SHMEM_MBUF_DATA_INIT(pdata, 0, n, cache_size, priv_size,
+ data_room_size, (u16) entype, socket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("mbf create mem req rsp fail] ret=%u", ucret);
+ goto release;
+ }
+
+ tpack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(tpack_head, NSFW_MBUF_ACK_MSG,
+ sizeof(nsfw_shmem_ack), release);
+
+ tpack_data = NSFW_SHMEM_GET_DATA(tpack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, tpack_data->cstate, 0,
+ tpack_data->usseq, release);
+
+ hhandle = ADDR_SHTOL(tpack_data->pbase_addr);
+ NSRTP_LOGDBG("mbf create] name=%s, handle=%p, seg=%u", name, hhandle,
+ tpack_data->usseq);
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return hhandle;
+}
+
+/*
+ *create some mbuf pools
+ */
+i32
+nsfw_remote_shmem_mbf_createv(nsfw_mem_mbfpool * pmbfname,
+ mpool_handle * phandle_array, i32 inum,
+ pid_t pid)
+{
+ /*msg point define */
+ nsfw_mgr_msg *mbpmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ nsfw_shmem_mbuf_req *pdata = NULL;
+ nsfw_shmem_mbuf_req *ptempdata = NULL;
+
+ nsfw_shmem_msg_head *pack_head = NULL;
+
+ nsfw_shmem_ack *pack_data = NULL;
+ mpool_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+ i32 icount = 0;
+ i32 itindex = 0;
+ i32 iindex = 0;
+ i32 isegbase = 0;
+ i32 ieltnum = 0;
+ i32 ieltnum_max =
+ (NSFW_MGR_MSG_BODY_LEN -
+ sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_mbuf_req);
+
+ mbpmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_GOTO(mbpmsg, lerr, "remote mbf createv msg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, lerr,
+ "remote mbf createv rspmsg alloc");
+
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, mbpmsg);
+
+ ptempdata = pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_mbuf_req);
+
+ do
+ {
+ icount++;
+ ieltnum++;
+
+ if (((icount % ieltnum_max) == 0) || (icount >= inum))
+ {
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MBUF_REQ_MSG,
+ ieltnum * sizeof(nsfw_shmem_mbuf_req));
+
+ /*fill msg data */
+ itindex = icount - 1;
+ if (-1 ==
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmbfname[itindex].stname.aname, pid))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ goto lerr;
+ }
+ NSFW_SHMEM_MBUF_DATA_INIT(ptempdata, (u16) itindex,
+ pmbfname[itindex].usnum,
+ pmbfname[itindex].uscash_size,
+ pmbfname[itindex].uspriv_size,
+ pmbfname[itindex].usdata_room,
+ pmbfname[itindex].enmptype,
+ pmbfname[itindex].isocket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(mbpmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("mbf createv mem req rsp fail] ret=%d", ucret);
+ goto lerr;
+ }
+
+ /*interrupt msg head */
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_MBUF_ACK_MSG,
+ ieltnum * sizeof(nsfw_shmem_ack),
+ lerr);
+
+ pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+
+ for (iindex = 0; iindex < ieltnum; iindex++)
+ {
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC,
+ pack_data->cstate,
+ (isegbase + iindex),
+ (u16) pack_data->usseq, lerr);
+ phandle_array[isegbase + iindex] =
+ ADDR_SHTOL(pack_data->pbase_addr);
+ NSRTP_LOGDBG("mbf createv] seg=%d, handle=%p",
+ pack_data->usseq, hhandle);
+ pack_data++;
+ }
+
+ isegbase = icount;
+ ieltnum = 0;
+ ptempdata = pdata;
+ }
+ else
+ {
+ itindex = icount - 1;
+ if (-1 ==
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmbfname[itindex].stname.aname, pid))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ goto lerr;
+ }
+ NSFW_SHMEM_MBUF_DATA_INIT(ptempdata, (u16) itindex,
+ pmbfname[itindex].usnum,
+ pmbfname[itindex].uscash_size,
+ pmbfname[itindex].uspriv_size,
+ pmbfname[itindex].usdata_room,
+ pmbfname[itindex].enmptype,
+ pmbfname[itindex].isocket_id);
+ ptempdata++;
+ }
+ }
+ while (icount < inum);
+
+ /*release memory */
+ iretval = NSFW_MEM_OK;
+ goto release;
+
+ lerr:
+ iretval = NSFW_MEM_ERR;
+ release:
+ NSFW_SHMEM_MSG_FREE(mbpmsg, prsp_msg);
+ return iretval;
+}
+
+/*
+ *create a simpile pool
+ */
+mring_handle
+nsfw_remote_shmem_mpcreate(const char *name, unsigned int n,
+ unsigned int elt_size, i32 socket_id,
+ nsfw_mpool_type entype)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+ nsfw_shmem_msg_head *pdata_head = NULL;
+ nsfw_shmem_sppool_req *pdata = NULL;
+ nsfw_shmem_msg_head *mppack_head = NULL;
+ nsfw_shmem_ack *mppack_data = NULL;
+ mring_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_NULL(pmsg, "remote mbf mpcreate pmsg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, release,
+ "remote mpcreate rspmsg alloc");
+
+ /*init msg head */
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_SPPOOL_REQ_MSG,
+ sizeof(nsfw_shmem_sppool_req));
+
+ /*fill msg data */
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_sppool_req);
+ iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name);
+ if (EOK != iretval)
+ {
+ NSRTP_LOGERR("mp create copy name fail] ret=%d", iretval);
+ goto release;
+ }
+
+ /*fill msg data */
+ NSFW_SHMEM_MPOOL_DATA_INIT(pdata, 0, n, elt_size, entype, socket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("mp create rsp fail] ret=%d", ucret);
+ goto release;
+ }
+
+ /*get msg head */
+ mppack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(mppack_head, NSFW_SPPOOL_ACK_MSG,
+ sizeof(nsfw_shmem_ack), release);
+
+ mppack_data = NSFW_SHMEM_GET_DATA(mppack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, mppack_data->cstate, 0,
+ mppack_data->usseq, release);
+
+ hhandle = ADDR_SHTOL(mppack_data->pbase_addr);
+ NSRTP_LOGDBG("mpcreate] name=%s, handle=%p, seg=%d", name, hhandle,
+ mppack_data->usseq);
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return hhandle;
+}
+
+/*
+ *create some simpile pools by send a msg
+ */
+i32
+nsfw_remote_shmem_mpcreatev(nsfw_mem_sppool * pmpinfo,
+ mring_handle * pringhandle_array, i32 inum,
+ pid_t pid)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+
+ /*msg head define */
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ /*msg data define */
+ nsfw_shmem_sppool_req *pdata = NULL;
+ nsfw_shmem_sppool_req *ptempdata = NULL;
+
+ /*ack msg define */
+ nsfw_shmem_msg_head *pack_head = NULL;
+
+ nsfw_shmem_ack *pack_data = NULL;
+ mring_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+ i32 icount = 0;
+ i32 itindex = 0;
+ i32 iindex = 0;
+ i32 isegbase = 0;
+ i32 ieltnum = 0;
+ /*the max members that a msg can take */
+ i32 ieltnum_max =
+ (NSFW_MGR_MSG_BODY_LEN -
+ sizeof(nsfw_shmem_msg_head)) / sizeof(nsfw_shmem_sppool_req);
+
+ /*alloc a msg */
+ //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER);
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_GOTO(pmsg, mperr, "remote mpcreatev pmsg alloc");
+
+ /*alloc rsp msg */
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, mperr, "remote mpcreatev rspmsg alloc");
+
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+
+ ptempdata = pdata =
+ NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_sppool_req);
+
+ do
+ {
+ icount++;
+ ieltnum++;
+
+ /*if the element num reach the bigest, or already send all, just deal */
+ if (((icount % ieltnum_max) == 0) || (icount >= inum))
+ {
+ /*init msg header */
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_SPPOOL_REQ_MSG,
+ ieltnum * sizeof(nsfw_shmem_sppool_req));
+
+ /*fill the msg data */
+ itindex = icount - 1;
+
+ int retVal =
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmpinfo[itindex].stname.aname, pid);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S fail]ret=%d", retVal);
+ goto mperr;
+ }
+ NSFW_SHMEM_MPOOL_DATA_INIT(ptempdata, itindex,
+ pmpinfo[itindex].usnum,
+ pmpinfo[itindex].useltsize,
+ pmpinfo[itindex].enmptype,
+ pmpinfo[itindex].isocket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("mpcreatev create fail] ret=%u", ucret);
+ goto mperr;
+ }
+
+ /*interrupt mgs head */
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_SPPOOL_ACK_MSG,
+ ieltnum * sizeof(nsfw_shmem_ack),
+ mperr);
+
+ pack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+
+ for (iindex = 0; iindex < ieltnum; iindex++)
+ {
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC,
+ pack_data->cstate,
+ (isegbase + iindex),
+ (u16) pack_data->usseq, mperr);
+ pringhandle_array[isegbase + iindex] =
+ ADDR_SHTOL(pack_data->pbase_addr);
+ NSRTP_LOGDBG("mpcreatev] seg=%u, handle=%p", pack_data->usseq,
+ hhandle);
+ pack_data++;
+ }
+
+ isegbase = icount;
+ ieltnum = 0;
+ ptempdata = pdata;
+ }
+ else
+ {
+ itindex = icount - 1;
+ int retVal =
+ sprintf_s(ptempdata->aname, sizeof(ptempdata->aname), "%s_%x",
+ pmpinfo[itindex].stname.aname, pid);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S fail]ret=%d", retVal);
+ goto mperr;
+ }
+ NSFW_SHMEM_MPOOL_DATA_INIT(ptempdata, itindex,
+ pmpinfo[itindex].usnum,
+ pmpinfo[itindex].useltsize,
+ pmpinfo[itindex].enmptype,
+ pmpinfo[itindex].isocket_id);
+
+ ptempdata++;
+ }
+ }
+ while (icount < inum);
+
+ /*release the memory */
+ iretval = NSFW_MEM_OK;
+ goto release;
+
+ mperr:
+ iretval = NSFW_MEM_ERR;
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return iretval;
+}
+
+/*
+ *create a ring
+ */
+mring_handle
+nsfw_remote_shmem_ringcreate(const char *name, unsigned int n, i32 socket_id,
+ nsfw_mpool_type entype)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+
+ /*msg head define */
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ /*msg data define */
+ nsfw_shmem_ring_req *pdata = NULL;
+ /*ack msg define */
+ nsfw_shmem_msg_head *pack_head = NULL;
+ nsfw_shmem_ack *ppack_data = NULL;
+ mring_handle hhandle = NULL;
+ u8 ucret = TRUE;
+ i32 iretval = NSFW_MEM_OK;
+
+ //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER);
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_NULL(pmsg, "remote ringcreate pmsg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, release,
+ "remote ringcreate rspmsg alloc");
+
+ /*fill msg head */
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_RING_REQ_MSG,
+ sizeof(nsfw_shmem_ring_req));
+
+ /*fill msg data */
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_ring_req);
+ iretval = strcpy_s(pdata->aname, sizeof(pdata->aname), name);
+ if (EOK != iretval)
+ {
+ NSRTP_LOGERR("ring create cpy name fail] ret=%d", iretval);
+ goto release;
+ }
+
+ /*fill msg data */
+ NSFW_SHMEM_MRING_DATA_INIT(pdata, 0, n, entype, socket_id);
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("ring create rsp fail] ret=%d", ucret);
+ goto release;
+ }
+
+ /*interrupt mgs head */
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_RING_ACK_MSG,
+ sizeof(nsfw_shmem_ack), release);
+
+ ppack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, ppack_data->cstate, 0,
+ ppack_data->usseq, release);
+
+ hhandle = ADDR_SHTOL(ppack_data->pbase_addr);
+ NSRTP_LOGDBG("ring create] name=%s, handle=%p, seg=%u", name, hhandle,
+ ppack_data->usseq);
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return hhandle;
+}
+
+/*
+ *create a mem pool that the members are rings by send a msg
+ *ieltnum:the num of ring member
+ *iringnum:the num of ring in simple mem pool
+ *entype:the default the of ring
+ */
+i32
+nsfw_remote_shmem_ringcreatev(const char *name, i32 ieltnum,
+ mring_handle * pringhandle_array, i32 iringnum,
+ i32 socket_id, nsfw_mpool_type entype)
+{
+ unsigned int useltsize = 0;
+ mring_handle nhandle = NULL;
+ i32 icount = 0;
+ i32 n = 0;
+ uint64_t baseaddr = 0;
+ uint64_t endaddr = 0;
+ /*the num of ring member must be power of 2 */
+ unsigned int usnum = common_mem_align32pow2(ieltnum + 1);
+
+ useltsize =
+ sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U);
+ nhandle =
+ nsfw_remote_shmem_mpcreate(name, iringnum, useltsize, socket_id,
+ NSFW_MRING_SPSC);
+ NSFW_POINT_CHK_RET_ERR(nhandle, "remote ringcreatev msg alloc");
+
+ n = nsfw_shmem_ring_sc_dequeuev(nhandle, (void **) pringhandle_array,
+ iringnum);
+
+ if (n != iringnum)
+ {
+ NSRTP_LOGERR("ring dequeue fail] ringnum=%d, retnum=%d", iringnum, n);
+ return NSFW_MEM_ERR;
+ }
+
+ nsfw_shmem_ring_baseaddr_query(&baseaddr, &endaddr);
+
+ for (icount = 0; icount < iringnum; icount++)
+ {
+ nsfw_mem_ring_init(pringhandle_array[icount], usnum,
+ (void *) baseaddr, NSFW_SHMEM, entype);
+ }
+
+ return NSFW_MEM_OK;
+}
+
+/*
+ *look up a msg by send a msg
+ */
+void *nsfw_remote_shmem_lookup(const i8 * name, nsfw_mem_struct_type entype)
+{
+ /*msg point define */
+ nsfw_mgr_msg *pmsg = NULL;
+ nsfw_mgr_msg *prsp_msg = NULL;
+ void *addr = NULL;
+ /*msg head data define */
+ nsfw_shmem_msg_head *pdata_head = NULL;
+
+ /*msg data define */
+ nsfw_shmem_lookup_req *pdata = NULL;
+
+ /*ack msg define */
+ nsfw_shmem_msg_head *pack_head = NULL;
+ nsfw_shmem_ack *lpack_data = NULL;
+ u8 ucret = TRUE;
+
+ pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN);
+ NSFW_POINT_CHK_RET_NULL(pmsg, "remote lookup pmsg alloc");
+
+ prsp_msg = nsfw_mgr_null_rspmsg_alloc();
+ NSFW_POINT_CHK_RET_GOTO(prsp_msg, perr, "remote lookup rspmsg alloc");
+
+ /*msg head init */
+ pdata_head = GET_USER_MSG(nsfw_shmem_msg_head, pmsg);
+ NSFW_SHMEM_MSG_HEAD_INIT(pdata_head, NSFW_MEM_LOOKUP_REQ_MSG,
+ sizeof(nsfw_shmem_lookup_req));
+
+ pdata = NSFW_SHMEM_GET_DATA(pdata_head, nsfw_shmem_lookup_req);
+ if (EOK != strcpy_s(pdata->aname, sizeof(pdata->aname), name))
+ {
+ NSRTP_LOGERR("STRCPY_S failed]name=%s", name);
+ }
+ pdata->usseq = 0;
+ pdata->ustype = entype;
+ pdata->ireserv = 0;
+
+ ucret = nsfw_mgr_send_req_wait_rsp(pmsg, prsp_msg);
+
+ if (FALSE == ucret)
+ {
+ NSRTP_LOGERR("mem lookup fail] ret=%u", ucret);
+ goto release;
+ }
+
+ /*interrupt mgs head */
+ pack_head = GET_USER_MSG(nsfw_shmem_msg_head, prsp_msg);
+ NSFW_SHMEM_MSGHEAD_CHK_GOTO(pack_head, NSFW_MEM_LOOKUP_ACK_MSG,
+ sizeof(nsfw_shmem_ack), perr);
+
+ lpack_data = NSFW_SHMEM_GET_DATA(pack_head, nsfw_shmem_ack);
+ NSFW_SHMEM_ACKSTATE_CHK_GOTO(NSFW_MEM_ALLOC_SUCC, lpack_data->cstate, 0,
+ lpack_data->usseq, perr);
+
+ addr = ADDR_SHTOL(lpack_data->pbase_addr);
+ NSRTP_LOGDBG("shmem lookup] name=%s, handle=%p, seg=%u", name, addr,
+ lpack_data->usseq);
+ goto release;
+ perr:
+ addr = NULL;
+
+ release:
+ NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg);
+ return addr;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h
new file mode 100644
index 0000000..0ae5cd5
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h
@@ -0,0 +1,51 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_RSHMEM_MNG_H
+#define _NSFW_RSHMEM_MNG_H
+
+mzone_handle nsfw_memzone_remote_reserv(const i8 * name, size_t mlen,
+ i32 socket_id);
+i32 nsfw_memzone_remote_reserv_v(nsfw_mem_zone * pmeminfo,
+ mzone_handle * paddr_array, i32 inum,
+ pid_t pid);
+i32 nsfw_remote_free(const i8 * name, nsfw_mem_struct_type entype);
+mpool_handle nsfw_remote_shmem_mbf_create(const i8 * name, unsigned int n,
+ unsigned cache_size,
+ unsigned priv_size,
+ unsigned data_room_size,
+ i32 socket_id,
+ nsfw_mpool_type entype);
+i32 nsfw_remote_shmem_mbf_createv(nsfw_mem_mbfpool * pmbfname,
+ mpool_handle * phandle_array, i32 inum,
+ pid_t pid);
+mring_handle nsfw_remote_shmem_mpcreate(const char *name, unsigned int n,
+ unsigned int elt_size, i32 socket_id,
+ nsfw_mpool_type entype);
+i32 nsfw_remote_shmem_mpcreatev(nsfw_mem_sppool * pmpinfo,
+ mring_handle * pringhandle_array, i32 inum,
+ pid_t pid);
+mring_handle nsfw_remote_shmem_ringcreate(const char *name, unsigned int n,
+ i32 socket_id,
+ nsfw_mpool_type entype);
+i32 nsfw_remote_shmem_ringcreatev(const char *name, i32 ieltnum,
+ mring_handle * pringhandle_array,
+ i32 iringnum, i32 socket_id,
+ nsfw_mpool_type entype);
+
+void *nsfw_remote_shmem_lookup(const i8 * name, nsfw_mem_struct_type entype);
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c
new file mode 100644
index 0000000..3d4dd42
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c
@@ -0,0 +1,48 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "nsfw_mem_api.h"
+#include "nsfw_shmem_mng.h"
+#include "nsfw_shmem_mdesc.h"
+#include "common_pal_bitwide_adjust.h"
+/*the inferaces accessing memory*/
+nsfw_mem_ops g_shmem_ops = {
+ nsfw_shmem_init,
+ nsfw_shmem_destroy,
+ nsfw_shmem_create,
+ nsfw_shmem_createv,
+ nsfw_shmem_lookup,
+ nsfw_shmem_release,
+ nsfw_shmem_mbfmpcreate,
+ nsfw_shmem_mbfmpcreatev,
+ nsfw_shmem_mbfmplookup,
+ nsfw_shmem_mbfmprelease,
+ nsfw_shmem_spcreate,
+ nsfw_shmem_spcreatev,
+ nswf_shmem_sp_ringcreate,
+ nsfw_shmem_sprelease,
+ nsfw_shmem_sp_lookup,
+ nsfw_shmem_ringcreate,
+ nsfw_shmem_ring_lookup,
+ nsfw_shmem_ringrelease,
+ nsfw_shmem_static,
+ nsfw_shmem_sp_iterator,
+ nsfw_shmem_mbuf_iterator,
+ NULL,
+ shmem_shddr_to_laddr,
+ shmem_laddr_to_shddr,
+ nsfw_attach_core_id
+};
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h
new file mode 100644
index 0000000..afd9e29
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h
@@ -0,0 +1,22 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_SHMEM_MDESC_H_
+#define _NSFW_SHMEM_MDESC_H_
+
+extern nsfw_mem_ops g_shmem_ops;
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c
new file mode 100644
index 0000000..1066b9a
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c
@@ -0,0 +1,800 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "nstack_securec.h"
+#include "nstack_log.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_ring_fun.h"
+#include "nsfw_shmem_ring.h"
+#include "nsfw_shmem_mng.h"
+#include "common_mem_mempool.h"
+#include "common_mem_memzone.h"
+#include "common_mem_buf.h"
+#include "common_mem_mbuf.h"
+#include "nsfw_rshmem_mng.h"
+#include "common_mem_api.h"
+#include "common_sys_config.h"
+#include "nsfw_maintain_api.h"
+#include "common_pal_bitwide_adjust.h"
+
+#include "common_func.h"
+
+#define NSFW_SHMEM_PID (get_sys_pid())
+#define NSFW_SHMEM_FLAG (g_shmem_localdata->enflag)
+
+/* app_mode 1: simple stack with APP*/
+extern u8 app_mode;
+u8 app_mode = 0;
+
+nsfw_mem_localdata *g_shmem_localdata = NULL;
+
+/*check g_mem_localdata*/
+#define NSFW_INIT_CHK_RET() \
+ if (!g_shmem_localdata) \
+ { \
+ return NSFW_MEM_ERR; \
+ }
+
+#define NSFW_INIT_CHK_RET_NULL() \
+ if (!g_shmem_localdata) \
+ { \
+ return NULL; \
+ }
+
+/*
+ *share memory mng module init
+ *
+ */
+i32 nsfw_shmem_init(nsfw_mem_para * para)
+{
+ common_mem_pal_module_info rteinfo = { 0 };
+ i32 iret = NSFW_MEM_ERR;
+ int flag = 0;
+ if (!para)
+ {
+ return NSFW_MEM_ERR;
+ }
+
+ NSRTP_LOGINF("nsfw shmem init begin");
+
+ LCORE_MASK_SET(rteinfo.ilcoremask, 1);
+ rteinfo.ucproctype = DMM_PROC_T_SECONDARY;
+ iret = common_pal_module_init(para, &rteinfo, app_mode);
+
+ if (DMM_MBUF_RET_OK != iret)
+ {
+ NSRTP_LOGERR("rte init fail] ret=0x%x", iret);
+ return NSFW_MEM_ERR;
+ }
+
+ flag = dmm_pal_addr_align();
+ if ((0 == flag) && (NSFW_PROC_MAIN == para->enflag))
+ {
+ dmm_addr_print();
+ NSRTP_LOGERR
+ ("rte init addr is not the same with primary] nstackmain flag=%d",
+ flag);
+ return NSFW_MEM_ERR;
+ }
+
+ g_shmem_localdata =
+ (nsfw_mem_localdata *) malloc(sizeof(nsfw_mem_localdata));
+
+ if (NULL == g_shmem_localdata)
+ {
+ NSRTP_LOGERR("g_shmem_localdata malloc fail");
+ return NSFW_MEM_ERR;
+ }
+
+ iret =
+ memset_s(g_shmem_localdata, sizeof(nsfw_mem_localdata), 0,
+ sizeof(nsfw_mem_localdata));
+ if (EOK != iret)
+ {
+ NSRTP_LOGERR("memset fail] g_shmem_localdata=%p ", g_shmem_localdata);
+ free(g_shmem_localdata);
+ g_shmem_localdata = NULL;
+ return NSFW_MEM_ERR;
+ }
+
+ g_shmem_localdata->enflag = para->enflag;
+
+ NSRTP_LOGINF("nsfw shmem init end] enflag=%d", para->enflag);
+ return NSFW_MEM_OK;
+
+}
+
+/*
+ *module destroy
+ */
+void nsfw_shmem_destroy(void)
+{
+ if (g_shmem_localdata)
+ {
+ free(g_shmem_localdata);
+ g_shmem_localdata = NULL;
+ }
+
+ return;
+}
+
+/*
+ * create a shared memory
+ * nsfw_mem_zone::stname memory name
+ * nsfw_mem_zone::isize
+ */
+mzone_handle nsfw_shmem_create(nsfw_mem_zone * pinfo)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET_NULL()if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return common_memzone_data_reserve_name(pinfo->stname.aname,
+ pinfo->lenth,
+ pinfo->isocket_id);
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ NSFW_NAME_LENCHECK_RET_NULL(pinfo->stname.aname, "shmem create")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pinfo->stname.aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ return NULL;
+ }
+ }
+
+ return nsfw_memzone_remote_reserv((char *) &aname[0], pinfo->lenth,
+ SOCKET_ID_ANY);
+}
+
+/*
+ *create some memory
+ *inum must be equal iarray_num
+ */
+i32
+nsfw_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum,
+ mzone_handle * paddr_array, i32 iarray_num)
+{
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_memzone_remote_reserv_v(pmeminfo, paddr_array, iarray_num,
+ 0);
+ }
+ else
+ {
+ return nsfw_memzone_remote_reserv_v(pmeminfo, paddr_array, iarray_num,
+ NSFW_SHMEM_PID);
+ }
+ return NSFW_MEM_ERR;
+}
+
+mzone_handle nsfw_shmem_lookup(nsfw_mem_name * pname)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return common_memzone_data_lookup_name(pname->aname);
+ }
+
+ if ((NSFW_PROC_NULL == pname->enowner)
+ || (NSFW_PROC_MAIN == pname->enowner))
+ {
+ int retVal =
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ return NULL;
+ }
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "shmem lookup")
+ int retVal =
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pname->aname,
+ NSFW_SHMEM_PID);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ return NULL;
+ }
+ }
+
+ return nsfw_remote_shmem_lookup(aname, NSFW_MEM_MZONE);
+}
+
+i32 nsfw_shmem_release(nsfw_mem_name * pname)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+ const struct common_mem_memzone *pmzone = NULL;
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ pmzone = common_mem_memzone_lookup(pname->aname);
+
+ if (pmzone)
+ {
+ common_mem_memzone_free(pmzone);
+ }
+ return NSFW_MEM_OK;
+ }
+ else
+ {
+ NSFW_NAME_LENCHECK_RET(pname->aname, "shmem free")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pname->aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ return NSFW_MEM_ERR;
+ }
+ }
+
+ return nsfw_remote_free(aname, NSFW_MEM_MZONE);
+}
+
+mpool_handle nsfw_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return common_mem_pktmbuf_pool_create(pbufinfo->stname.aname,
+ pbufinfo->usnum,
+ pbufinfo->uscash_size,
+ pbufinfo->uspriv_size,
+ pbufinfo->usdata_room,
+ pbufinfo->isocket_id);
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ NSFW_NAME_LENCHECK_RET_NULL(pbufinfo->stname.aname, "mbufpool create")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pbufinfo->stname.aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_mbf_create(aname, pbufinfo->usnum,
+ pbufinfo->uscash_size,
+ pbufinfo->uspriv_size,
+ pbufinfo->usdata_room, SOCKET_ID_ANY,
+ pbufinfo->enmptype);
+}
+
+/*
+ *create some mbuf pools
+ */
+i32
+nsfw_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum,
+ mpool_handle * phandle_array, i32 iarray_num)
+{
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_remote_shmem_mbf_createv(pmbfname, phandle_array,
+ iarray_num, 0);
+ }
+ else
+ {
+ return nsfw_remote_shmem_mbf_createv(pmbfname, phandle_array,
+ iarray_num, NSFW_SHMEM_PID);
+ }
+
+ return NSFW_MEM_ERR;
+}
+
+mbuf_handle nsfw_shmem_mbfalloc(mpool_handle mhandle)
+{
+ return (mbuf_handle)
+ common_mem_pktmbuf_alloc((struct common_mem_mempool *) mhandle);
+}
+
+i32 nsfw_shmem_mbffree(mbuf_handle mhandle)
+{
+ common_mem_pktmbuf_free((struct common_mem_mbuf *) mhandle);
+ return NSFW_MEM_OK;
+}
+
+i32 nsfw_shmem_mbfmprelease(nsfw_mem_name * pname)
+{
+ return NSFW_MEM_OK;
+}
+
+mpool_handle nsfw_shmem_mbfmplookup(nsfw_mem_name * pmbfname)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return common_mem_mempool_lookup(pmbfname->aname);
+ }
+
+ if ((NSFW_PROC_NULL == pmbfname->enowner)
+ || (NSFW_PROC_MAIN == pmbfname->enowner))
+ {
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s",
+ pmbfname->aname))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ NSFW_NAME_LENCHECK_RET_NULL(pmbfname->aname, "shmem lookup")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pmbfname->aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_lookup(aname, NSFW_MEM_MBUF);
+}
+
+mring_handle nsfw_shmem_spcreate(nsfw_mem_sppool * pmpinfo)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_shmem_pool_create(pmpinfo->stname.aname, pmpinfo->usnum,
+ pmpinfo->useltsize, pmpinfo->isocket_id,
+ pmpinfo->enmptype);
+ }
+ else
+ {
+ NSFW_NAME_LENCHECK_RET_NULL(pmpinfo->stname.aname, "mpool create")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pmpinfo->stname.aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_mpcreate(aname, pmpinfo->usnum,
+ pmpinfo->useltsize, SOCKET_ID_ANY,
+ pmpinfo->enmptype);
+}
+
+i32
+nsfw_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum,
+ mring_handle * pringhandle_array, i32 iarray_num)
+{
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_remote_shmem_mpcreatev(pmpinfo, pringhandle_array, inum,
+ 0);
+ }
+ else
+ {
+ return nsfw_remote_shmem_mpcreatev(pmpinfo, pringhandle_array, inum,
+ NSFW_SHMEM_PID);
+ }
+ return NSFW_MEM_ERR;
+}
+
+i32
+nsfw_lshmem_ringcreatev(const char *name, i32 ieltnum,
+ mring_handle * pringhandle_array, i32 iringnum,
+ i32 socket_id, nsfw_mpool_type entype)
+{
+ i32 useltsize = 0;
+ mring_handle nhandle = NULL;
+ i32 icount = 0;
+ i32 n = 0;
+ uint64_t baseaddr = 0;
+ uint64_t endaddr = 0;
+ i32 usnum = common_mem_align32pow2(ieltnum + 1);
+
+ useltsize =
+ sizeof(struct nsfw_mem_ring) + usnum * sizeof(union RingData_U);
+ nhandle =
+ nsfw_shmem_pool_create(name, iringnum, useltsize, socket_id,
+ NSFW_MRING_SPSC);
+ if (NULL == (nhandle))
+ {
+ return NSFW_MEM_ERR;
+ }
+
+ n = nsfw_shmem_ring_sc_dequeuev(nhandle, (void **) pringhandle_array,
+ iringnum);
+
+ if (n != iringnum)
+ {
+ NSRTP_LOGERR
+ ("ring dequeuev failed] ring=%p, dequeue num=%d, expect num=%d",
+ nhandle, n, iringnum);
+ return NSFW_MEM_ERR;
+ }
+
+ nsfw_shmem_ring_baseaddr_query(&baseaddr, &endaddr);
+
+ for (icount = 0; icount < iringnum; icount++)
+ {
+ nsfw_mem_ring_init(pringhandle_array[icount], usnum,
+ (void *) baseaddr, NSFW_SHMEM, entype);
+ }
+
+ return NSFW_MEM_OK;
+}
+
+i32
+nswf_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo,
+ mring_handle * pringhandle_array, i32 iringnum)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_lshmem_ringcreatev(prpoolinfo->stname.aname,
+ prpoolinfo->usnum, pringhandle_array,
+ iringnum, SOCKET_ID_ANY,
+ prpoolinfo->enmptype);
+ }
+ else
+ {
+ NSFW_NAME_LENCHECK_RET(prpoolinfo->stname.aname, "ring pool")
+ int retVal =
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ prpoolinfo->stname.aname, NSFW_SHMEM_PID);
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_ringcreatev(aname, prpoolinfo->usnum,
+ pringhandle_array, iringnum,
+ SOCKET_ID_ANY, prpoolinfo->enmptype);
+}
+
+i32 nsfw_shmem_sprelease(nsfw_mem_name * pname)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+ void *mz_mem = NULL;
+ struct nsfw_mem_ring *ring_ptr = NULL;
+ NSFW_INIT_CHK_RET();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ mz_mem = common_memzone_data_lookup_name(pname->aname);
+
+ if (mz_mem)
+ {
+ ring_ptr =
+ (struct nsfw_mem_ring *) ((char *) mz_mem +
+ sizeof(struct
+ nsfw_shmem_ring_head));
+ nsfw_shmem_pool_free(ring_ptr);
+ }
+ return NSFW_MEM_OK;
+ }
+ else
+ {
+ NSFW_NAME_LENCHECK_RET(pname->aname, "shmem free")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pname->aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_free(aname, NSFW_MEM_SPOOL);
+}
+
+mring_handle nsfw_shmem_sp_lookup(nsfw_mem_name * pname)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+ void *mz_mem = NULL;
+ struct nsfw_mem_ring *ring_ptr = NULL;
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ mz_mem = common_memzone_data_lookup_name(pname->aname);
+
+ if (mz_mem)
+ {
+ ring_ptr =
+ (struct nsfw_mem_ring *) ((char *) mz_mem +
+ sizeof(struct
+ nsfw_shmem_ring_head));
+ return ring_ptr;
+ }
+ return mz_mem;
+ }
+
+ if ((NSFW_PROC_NULL == pname->enowner)
+ || (NSFW_PROC_MAIN == pname->enowner))
+ {
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname))
+ {
+ NSRTP_LOGERR("SPRINTF_S fails]");
+ }
+ }
+ else
+ {
+ /*app's name can not over NSFW_MEM_APPNAME_LENGTH */
+ NSFW_NAME_LENCHECK_RET_NULL(pname->aname, "shmem lookup")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pname->aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_lookup(aname, NSFW_MEM_SPOOL);
+}
+
+mring_handle nsfw_shmem_ringcreate(nsfw_mem_mring * pringinfo)
+{
+ i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 };
+
+ NSFW_INIT_CHK_RET_NULL();
+
+ if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG)
+ {
+ return nsfw_shmem_ring_create(pringinfo->stname.aname,
+ pringinfo->usnum, pringinfo->isocket_id,
+ pringinfo->enmptype);
+ }
+ else
+ {
+ NSFW_NAME_LENCHECK_RET_NULL(pringinfo->stname.aname, "ring create")
+ if (-1 ==
+ sprintf_s(aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x",
+ pringinfo->stname.aname, NSFW_SHMEM_PID))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ return nsfw_remote_shmem_ringcreate(aname, pringinfo->usnum,
+ SOCKET_ID_ANY, pringinfo->enmptype);
+}
+
+mring_handle nsfw_shmem_ring_lookup(nsfw_mem_name * pname)
+{
+ return nsfw_shmem_lookup(pname);
+}
+
+i32 nsfw_shmem_ringrelease(nsfw_mem_name * pname)
+{
+ return nsfw_shmem_release(pname);
+}
+
+size_t nsfw_shmem_mbufpool_statics(mpool_handle mbufpool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) mbufpool;
+ return (size_t) mp->size * (mp->header_size + mp->elt_size +
+ mp->trailer_size) +
+ (size_t) mp->private_data_size +
+ (size_t)
+ common_mem_ring_get_memsize(common_mem_align32pow2(mp->size + 1));
+}
+
+size_t nsfw_shmem_sppool_statics(mring_handle sppool)
+{
+ struct nsfw_shmem_ring_head *temp = NULL;
+ size_t lent = 0;
+ temp =
+ (struct nsfw_shmem_ring_head *) ((char *) sppool -
+ sizeof(struct nsfw_shmem_ring_head));
+
+ while (temp)
+ {
+ lent += temp->mem_zone->len;
+ temp = temp->next;
+ }
+
+ return lent;
+}
+
+size_t nsfw_shmem_ring_statics(mring_handle handle)
+{
+ struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle;
+ return ring->size * sizeof(union RingData_U) +
+ sizeof(struct nsfw_mem_ring);
+}
+
+ssize_t nsfw_shmem_static(void *handle, nsfw_mem_struct_type type)
+{
+ switch (type)
+ {
+ case NSFW_MEM_MBUF:
+ return nsfw_shmem_mbufpool_statics(handle);
+ case NSFW_MEM_SPOOL:
+ return nsfw_shmem_sppool_statics(handle);
+ case NSFW_MEM_RING:
+ return nsfw_shmem_ring_statics(handle);
+ default:
+ break;
+ }
+ return -1;
+}
+
+i32 nsfw_shmem_mbuf_recycle(mpool_handle handle)
+{
+ return NSFW_MEM_OK;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_shmem_sp_iterator
+* Description : sp pool iterator
+* Input : mpool_handle handle
+* u32 start
+* u32 end
+* nsfw_mem_item_fun fun
+* void *argv
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*****************************************************************************/
+i32
+nsfw_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end,
+ nsfw_mem_item_fun fun, void *argv)
+{
+ struct nsfw_mem_ring *perfring_ptr = (struct nsfw_mem_ring *) handle;
+ if (NULL == perfring_ptr || NULL == fun)
+ {
+ return 0;
+ }
+
+ if (0 == perfring_ptr->eltsize)
+ {
+ return 0;
+ }
+
+ int num = perfring_ptr->size;
+ if (start >= (u32) num || end <= start)
+ {
+ return 0;
+ }
+
+ struct nsfw_shmem_ring_head *ring_head =
+ (struct nsfw_shmem_ring_head *) ((char *) handle -
+ sizeof(struct nsfw_shmem_ring_head));
+ void *mz =
+ (void *) ((char *) perfring_ptr + sizeof(struct nsfw_mem_ring) +
+ num * sizeof(union RingData_U));
+
+ if (ring_head->mem_zone->len <
+ sizeof(struct nsfw_shmem_ring_head) + sizeof(struct nsfw_mem_ring) +
+ num * sizeof(union RingData_U))
+ {
+ return 0;
+ }
+
+ u32 mz_len =
+ ring_head->mem_zone->len - sizeof(struct nsfw_shmem_ring_head) -
+ sizeof(struct nsfw_mem_ring) - num * sizeof(union RingData_U);
+
+ u32 start_idx = 0;
+ u32 elm_num = 0;
+ elm_num = mz_len / perfring_ptr->eltsize;
+ while (start > start_idx + elm_num)
+ {
+ if (NULL == ring_head->next || NULL == ring_head->next->mem_zone
+ || 0 == elm_num)
+ {
+ return 0;
+ }
+
+ ring_head =
+ (struct nsfw_shmem_ring_head *) ring_head->next->
+ mem_zone->addr_64;
+ mz_len =
+ ring_head->mem_zone->len - sizeof(struct nsfw_shmem_ring_head);
+
+ elm_num = mz_len / perfring_ptr->eltsize;
+ mz = (void *) ((char *) ring_head +
+ sizeof(struct nsfw_shmem_ring_head));
+ start_idx += elm_num;
+ }
+
+ u32 cur_idx = start - start_idx;
+ char *cur_elm = NULL;
+ int proc_count = 0;
+ while (cur_idx + start_idx < end && cur_idx + start_idx < (u32) num)
+ {
+ if (cur_idx >= elm_num)
+ {
+ if (NULL == ring_head->next || NULL == ring_head->next->mem_zone
+ || 0 == elm_num)
+ {
+ break;
+ }
+
+ ring_head =
+ (struct nsfw_shmem_ring_head *) ring_head->next->
+ mem_zone->addr_64;
+ mz_len =
+ ring_head->mem_zone->len -
+ sizeof(struct nsfw_shmem_ring_head);
+
+ elm_num = mz_len / perfring_ptr->eltsize;
+ mz = (void *) ((char *) ring_head +
+ sizeof(struct nsfw_shmem_ring_head));
+ start_idx += elm_num;
+
+ cur_idx = 0;
+ cur_elm = NULL;
+ continue;
+ }
+
+ if (NULL == cur_elm)
+ {
+ cur_elm = ((char *) mz + cur_idx * perfring_ptr->eltsize);
+ }
+ else
+ {
+ cur_elm += perfring_ptr->eltsize;
+ }
+
+ cur_idx++;
+ proc_count++;
+ (void) fun(cur_elm, argv);
+ }
+
+ return proc_count;
+}
+
+i32
+nsfw_shmem_mbuf_iterator(mpool_handle handle, u32 start, u32 end,
+ nsfw_mem_item_fun fun, void *argv)
+{
+ return dmm_pktmbuf_pool_iterator((struct common_mem_mempool *) handle,
+ start, end, (dmm_mbuf_item_fun) fun,
+ argv);
+}
+
+int nsfw_attach_core_id(nsfw_mem_name * name)
+{
+ return 0;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h
new file mode 100644
index 0000000..6fbff59
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h
@@ -0,0 +1,135 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_SHMEM_MNG_H
+#define _NSFW_SHMEM_MNG_H
+
+/*
+ * mem mgr module init
+ * para:point to nstack_fwmem_para
+ */
+i32 nsfw_shmem_init(nsfw_mem_para * para);
+
+/*
+ * mem mgr module destory
+ *
+ */
+void nsfw_shmem_destroy(void);
+
+/*
+ * create a block memory with name
+ * fw_mem_zone::stname name of memory
+ * fw_mem_zone::isize memory size
+ */
+mzone_handle nsfw_shmem_create(nsfw_mem_zone * pinfo);
+
+/*
+ *create some blocks memory
+ */
+i32 nsfw_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum,
+ mzone_handle * paddr_array, i32 iarray_num);
+
+/*
+ *lookup a memory
+ */
+mzone_handle nsfw_shmem_lookup(nsfw_mem_name * pname);
+
+/*release the memory*/
+i32 nsfw_shmem_release(nsfw_mem_name * pname);
+
+/*
+ *create mbuf pool
+ */
+mpool_handle nsfw_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo);
+
+/*
+ *create some mbuf pool
+ */
+i32 nsfw_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum,
+ mpool_handle * phandle_array, i32 iarray_num);
+
+/*
+ *alloc a mbuf from mbuf pool
+ */
+mbuf_handle nsfw_shmem_mbfalloc(mpool_handle mhandle);
+
+/*
+ *release a mbuf pool
+ */
+i32 nsfw_shmem_mbffree(mbuf_handle mhandle);
+
+/*
+ *put mbuf back to mbuf pool
+ */
+i32 nsfw_shmem_mbfmprelease(nsfw_mem_name * pname);
+
+/*look up mbuf mpool*/
+mpool_handle nsfw_shmem_mbfmplookup(nsfw_mem_name * pmbfname);
+
+/*
+ *create simple pool
+ */
+mring_handle nsfw_shmem_spcreate(nsfw_mem_sppool * pmpinfo);
+
+/*
+ *create some simple pools
+ */
+i32 nsfw_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum,
+ mring_handle * pringhandle_array, i32 iarray_num);
+
+/*
+ *create a simple pool that members are rings
+ */
+i32 nswf_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo,
+ mring_handle * pringhandle_array, i32 iringnum);
+
+/*
+ *release a simple pool
+ */
+i32 nsfw_shmem_sprelease(nsfw_mem_name * pname);
+
+/*
+ *look up a simple pool
+ */
+mring_handle nsfw_shmem_sp_lookup(nsfw_mem_name * pname);
+
+/*
+ *create a ring with name
+ */
+mring_handle nsfw_shmem_ringcreate(nsfw_mem_mring * pringinfo);
+
+/*
+ *look up a ring with name
+ */
+mring_handle nsfw_shmem_ring_lookup(nsfw_mem_name * pname);
+
+/*
+ *release ring
+ */
+i32 nsfw_shmem_ringrelease(nsfw_mem_name * pname);
+
+ssize_t nsfw_shmem_static(void *handle, nsfw_mem_struct_type type);
+
+i32 nsfw_shmem_mbuf_recycle(mpool_handle handle);
+
+i32 nsfw_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end,
+ nsfw_mem_item_fun fun, void *argv);
+i32 nsfw_shmem_mbuf_iterator(mpool_handle handle, u32 start, u32 end,
+ nsfw_mem_item_fun fun, void *argv);
+
+int nsfw_attach_core_id(nsfw_mem_name * name);
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c
new file mode 100644
index 0000000..f580640
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c
@@ -0,0 +1,843 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include <common_sys_config.h>
+
+#include "common_mem_pal_memconfig.h"
+#include "nstack_securec.h"
+#include "nsfw_shmem_ring.h"
+#include "nsfw_ring_fun.h"
+#include "common_mem_buf.h"
+#include "common_func.h"
+#include "common_pal_bitwide_adjust.h"
+
+void
+nsfw_shmem_ring_baseaddr_query(uint64_t * rte_lowest_addr,
+ uint64_t * rte_highest_addr)
+{
+ struct common_mem_mem_config *pMemCfg =
+ common_mem_pal_get_configuration()->mem_config;
+ struct common_mem_memseg *PMemSegArry = pMemCfg->memseg;
+
+ *rte_lowest_addr = PMemSegArry[0].addr_64;
+ *rte_highest_addr = PMemSegArry[0].addr_64 + PMemSegArry[0].len;
+
+ int s = 1;
+
+ while (s < COMMON_MEM_MAX_MEMSEG && PMemSegArry[s].len > 0)
+ {
+ if (*rte_lowest_addr > PMemSegArry[s].addr_64)
+ {
+ *rte_lowest_addr = PMemSegArry[s].addr_64;
+ }
+
+ if (*rte_highest_addr < PMemSegArry[s].addr_64 + PMemSegArry[s].len)
+ {
+ *rte_highest_addr = PMemSegArry[s].addr_64 + PMemSegArry[s].len;
+ }
+
+ s++;
+ }
+
+}
+
+static unsigned
+nsfw_shmem_pool_node_alloc(struct nsfw_mem_ring *perfring_ptr,
+ unsigned alloc_index, unsigned max_index,
+ void *mz, size_t mz_len, unsigned elt_size)
+{
+ size_t alloc_size = 0;
+ unsigned offset_idx = 0;
+ NSTCP_LOGINF("mz(%p), mz_len = 0x%x", mz, mz_len);
+
+ while (alloc_size + elt_size <= mz_len)
+ {
+ perfring_ptr->ring[alloc_index + offset_idx].data_s.ver =
+ alloc_index + offset_idx;
+ perfring_ptr->ring[alloc_index + offset_idx].data_s.val =
+ ADDR_LTOSH_EXT(mz) - ((uint64_t) perfring_ptr->Addrbase);
+ mz = (char *) mz + elt_size;
+ alloc_size += elt_size;
+ offset_idx++;
+
+ if (alloc_index + offset_idx == max_index)
+ {
+ break;
+ }
+ }
+
+ return offset_idx;
+}
+
+void nsfw_shmem_pool_free(struct nsfw_mem_ring *perfring_ptr)
+{
+ struct nsfw_shmem_ring_head *ptemp;
+
+ if (NULL == perfring_ptr)
+ {
+ return;
+ }
+
+ struct nsfw_shmem_ring_head *pnode =
+ (struct nsfw_shmem_ring_head *) ((char *) perfring_ptr -
+ sizeof(struct nsfw_shmem_ring_head));
+
+ while (pnode)
+ {
+ // phead is involved in phead->mem_zone
+ ptemp = pnode->next;
+ common_mem_memzone_free(pnode->mem_zone);
+ pnode = ptemp;
+ }
+}
+
+struct nsfw_mem_ring *nsfw_shmem_pool_create(const char *name, unsigned int n,
+ unsigned int elt_size,
+ int socket_id,
+ unsigned char flag)
+{
+ struct nsfw_mem_ring *perfring_ptr = NULL;
+ struct common_mem_memzone *mz_mem;
+ void *mz = NULL;
+
+ /*get pool size, pool size must pow of 2 */
+ unsigned int num = common_mem_align32pow2(n + 1);
+
+ struct nsfw_shmem_ring_head *pcur = NULL;
+ /*calculate the empty rte_perf_ring Size */
+ size_t len =
+ sizeof(struct nsfw_shmem_ring_head) + sizeof(struct nsfw_mem_ring) +
+ (size_t) num * sizeof(union RingData_U) + (size_t) num * elt_size;
+ size_t alloc_len = len;
+ unsigned int alloc_num = 0;
+ unsigned int alloc_index = 0;
+
+ size_t mz_len = 0;
+
+ unsigned int mz_index = 1;
+ char mz_name[128] = { 0 };
+ int retVal;
+ /*we'd better use `strlen(src)` or `sizeof(dst)` to explain copying length of src string.
+ it's meaningless using `sizeof(dst) - 1` to reserve 1 byte for '\0'.
+ if copying length equals to or bigger than dst length, just let STRNCPY_S() returns failure. */
+ retVal = strncpy_s(mz_name, sizeof(mz_name), name, sizeof(mz_name));
+
+ if (EOK != retVal)
+ {
+ NSTCP_LOGERR("STRNCPY_S failed]ret=%d", retVal);
+ return NULL;
+ }
+
+ mz_mem = common_memzone_data_lookup_name(name);
+ NSTCP_LOGINF("memzone data look up] n=%u,num=%u,len=%zu", n, num, len);
+
+ if (mz_mem)
+ {
+ perfring_ptr =
+ (struct nsfw_mem_ring *) ((char *) mz_mem +
+ sizeof(struct nsfw_shmem_ring_head));
+ return perfring_ptr;
+ }
+
+ while (alloc_len > 0)
+ {
+ if (NULL != perfring_ptr)
+ {
+ retVal =
+ sprintf_s(mz_name, sizeof(mz_name), "%s_%03d", name,
+ mz_index);
+
+ if (-1 == retVal)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]ret=%d", retVal);
+ nsfw_shmem_pool_free(perfring_ptr);
+ return NULL;
+ }
+ }
+
+ mz_mem =
+ (struct common_mem_memzone *) common_mem_memzone_reserve(mz_name,
+ alloc_len,
+ socket_id,
+ 0);
+
+ if (mz_mem == NULL)
+ {
+ mz_mem =
+ (struct common_mem_memzone *)
+ common_mem_memzone_reserve(mz_name, 0, socket_id, 0);
+ }
+
+ if (mz_mem == NULL)
+ {
+ nsfw_shmem_pool_free(perfring_ptr);
+ return NULL;
+ }
+
+ if (NULL == perfring_ptr
+ && (mz_mem->len <
+ sizeof(struct nsfw_shmem_ring_head) +
+ sizeof(struct nsfw_mem_ring) +
+ num * sizeof(union RingData_U)))
+ {
+ common_mem_memzone_free(mz_mem);
+ return NULL;
+ }
+
+ if (NULL == perfring_ptr)
+ {
+ pcur =
+ (struct nsfw_shmem_ring_head *) ADDR_SHTOL(mz_mem->addr_64);
+ pcur->mem_zone = mz_mem;
+ pcur->next = NULL;
+
+ perfring_ptr =
+ (struct nsfw_mem_ring *) ((char *) pcur +
+ sizeof(struct
+ nsfw_shmem_ring_head));
+
+ mz = (void *) ((char *) perfring_ptr +
+ sizeof(struct nsfw_mem_ring) +
+ num * sizeof(union RingData_U));
+ mz_len =
+ mz_mem->len - sizeof(struct nsfw_shmem_ring_head) -
+ sizeof(struct nsfw_mem_ring) - num * sizeof(union RingData_U);
+
+ uint64_t rte_base_addr;
+ uint64_t rte_highest_addr;
+ nsfw_shmem_ring_baseaddr_query(&rte_base_addr, &rte_highest_addr);
+ nsfw_mem_pool_head_init(perfring_ptr, num, elt_size,
+ (void *) rte_base_addr, NSFW_SHMEM,
+ (nsfw_mpool_type) flag);
+ }
+ else
+ {
+ if (pcur)
+ {
+ pcur->next =
+ (struct nsfw_shmem_ring_head *)
+ ADDR_SHTOL(mz_mem->addr_64);
+ pcur = pcur->next;
+ pcur->mem_zone = mz_mem;
+ pcur->next = NULL;
+
+ if (mz_mem->len < sizeof(struct nsfw_shmem_ring_head))
+ {
+ NSRTP_LOGERR("mz_len error %d", mz_mem->len);
+ nsfw_shmem_pool_free(perfring_ptr);
+ return NULL;
+ }
+
+ mz = (void *) ((char *) pcur +
+ sizeof(struct nsfw_shmem_ring_head));
+ mz_len = mz_mem->len - sizeof(struct nsfw_shmem_ring_head);
+ }
+ }
+
+ alloc_num =
+ nsfw_shmem_pool_node_alloc(perfring_ptr, alloc_index, num, mz,
+ mz_len, elt_size);
+ alloc_index += alloc_num;
+
+ if (alloc_index >= num)
+ {
+ break;
+ }
+
+ // second time allocate should not contained all ring head
+ alloc_len =
+ (size_t) (num - alloc_index) * elt_size +
+ sizeof(struct nsfw_shmem_ring_head);
+ mz_index++;
+ }
+
+ return perfring_ptr;
+}
+
+/*ring create*/
+struct nsfw_mem_ring *nsfw_shmem_ring_create(const char *name, unsigned int n,
+ int socket_id,
+ unsigned char flag)
+{
+ struct nsfw_mem_ring *perfring_ptr;
+ struct common_mem_memzone *mz;
+ uint64_t rte_base_addr;
+ uint64_t rte_highest_addr;
+
+ unsigned int num = common_mem_align32pow2(n);
+
+ mz = (struct common_mem_memzone *) common_mem_memzone_reserve(name,
+ sizeof
+ (struct
+ nsfw_mem_ring)
+ +
+ num *
+ sizeof(union
+ RingData_U),
+ socket_id,
+ 0);
+
+ if (mz == NULL)
+ {
+ return NULL;
+ }
+
+ perfring_ptr = mz->addr;
+
+ nsfw_shmem_ring_baseaddr_query(&rte_base_addr, &rte_highest_addr);
+ nsfw_mem_ring_init(perfring_ptr, num, (void *) rte_base_addr, NSFW_SHMEM,
+ flag);
+
+ return perfring_ptr;
+}
+
+/*
+this is a multi thread/process enqueue function, please pay attention to the bellow point
+1. while Enqueue corrupt, we may lose one element; because no one to add the Head
+*/
+int nsfw_shmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box)
+{
+ union RingData_U expectPostVal;
+ union RingData_U curVal;
+ unsigned int tmpHead;
+ unsigned int tmpTail;
+ unsigned int CurHead = ring->prod.head;
+ unsigned int mask = ring->mask;
+ unsigned int size = ring->size;
+ void *prmBox = NULL;
+
+ prmBox = (void *) ADDR_LTOSH_EXT(box);
+
+ /*do box range check */
+ if ((char *) prmBox <= (char *) ring->Addrbase
+ || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE)
+ {
+ /*invalid addr of box, can't put in rte_perf_ring, maybe should set a errno here */
+ return -1;
+ }
+
+ do
+ {
+ /*
+ if the ring is Full return directly; this not a exact check, cause we made tail++ after dequeue success.
+ the thing we could make sure is ring[ring->Tail&mask] already dequeue
+ */
+ tmpTail = ring->cons.tail;
+
+ if (tmpTail + size - CurHead == 0)
+ {
+ /*
+ here we give enqueue a chance to recorrect the Tail, if tail not has Data let tail++
+ */
+ if (ring->ring[tmpTail & mask].data_s.val == 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail,
+ tmpTail + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /*
+ the old version of ring->ring[CurHead&mask] must CurHead - size, which enqueue set to this pos lasttime
+ & the val must already dequeue. otherwise this pos can't enqueue;
+ */
+ expectPostVal.data_l =
+ (((unsigned long long) (CurHead - size)) << VALUE_LEN);
+
+ /*
+ the new version of ring->ring[CurHead&mask] must CurHead, which enqueue set to this pos this time.
+ */
+ curVal.data_l =
+ ((((unsigned long long) CurHead) << VALUE_LEN) |
+ ((char *) prmBox - (char *) ring->Addrbase));
+ if (ring->ring[CurHead & mask].data_s.ver == expectPostVal.data_s.ver
+ && __sync_bool_compare_and_swap(&ring->
+ ring[CurHead & mask].data_l,
+ expectPostVal.data_l,
+ curVal.data_l))
+ {
+ /*
+ enqueue success, add Head Value now
+ here we using CAS set instead __sync_fetch_and_add(&ring->Head, 1) to assume that, if one process enqueue success && been killed before
+ add Head, other process can recorrect the Head Value;
+ one more thing the direction of Tail must been add-direction, so we using the condition (ring->Head - CurHead >0x80000000);
+ while many thread do enqueue at same time, Head may not correct,exp:
+ thread A get old head 10, thread A want set head to 11
+ thread B get old head 10, thread B want set head to 12
+ thread A do CAS && thread B do CAS at same time, thread A do CAS success;
+ the result of head is 11, but the correct Value should be 12;
+
+ then thread C get old head 11, thread C will set head to 13[cause pos 12 already has value, thread C will skill 12],
+ the head will be recorrect by thread C.
+ if no thread C, thread A& B are the last enqueue thread; the head must recorrect by the deque function.
+ */
+ tmpHead = ring->prod.head;
+
+ if (0 == (CurHead & 0x03) && tmpHead - CurHead > 0x80000000)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead,
+ CurHead + 1);
+ }
+
+ break;
+ }
+
+ /*
+ CurHead++ here;
+ may be cpu slice is end here; while re-sched CurHead < ring->Tail < ring->Head; to avoid multi try
+ we using a cmp & CurHead++ instead CurHead++ directly.
+ if using CurHead++ will amplify the probability of ABA problem
+ */
+ /*CurHead++; */
+ tmpHead = ring->prod.head;
+ CurHead = CurHead - tmpHead < mask - 1 ? CurHead + 1 : tmpHead;
+ }
+ while (1);
+
+ return 1;
+}
+
+/*
+ this is a single thread/process enqueue function
+ */
+int nsfw_shmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box)
+{
+ union RingData_U texpectPostVal;
+ union RingData_U curVal;
+ unsigned int tmpTail;
+ unsigned int CurHead = ring->prod.head;
+ unsigned int mask = ring->mask;
+ unsigned int uisize = ring->size;
+ void *prmBox = NULL;
+
+ prmBox = (void *) ADDR_LTOSH_EXT(box);
+
+ if ((char *) prmBox <= (char *) ring->Addrbase
+ || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE)
+ {
+ return -1;
+ }
+
+ do
+ {
+ tmpTail = ring->cons.tail;
+ if (tmpTail + uisize - CurHead == 0)
+ {
+ /*
+ *here we give enqueue a chance to recorrect the Tail, if tail not has Data let tail++
+ */
+ if (ring->ring[tmpTail & mask].data_s.val == 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail,
+ tmpTail + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ texpectPostVal.data_l =
+ (((unsigned long long) (CurHead - uisize)) << VALUE_LEN);
+
+ curVal.data_l =
+ ((((unsigned long long) CurHead) << VALUE_LEN) |
+ ((char *) prmBox - (char *) ring->Addrbase));
+
+ if (ring->ring[CurHead & mask].data_l == texpectPostVal.data_l)
+ {
+ ring->ring[CurHead & mask].data_l = curVal.data_l;
+ ring->prod.head = CurHead + 1;
+ break;
+ }
+
+ CurHead++;
+ }
+ while (1);
+ return 1;
+}
+
+/*this is a multi thread/process dequeue function, please pay attention to the bellow point
+*/
+int nsfw_shmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ unsigned int CurTail;
+ unsigned int tmpTail;
+ unsigned int tmpHead;
+ unsigned int mask = ring->mask;
+ union RingData_U curNullVal;
+ union RingData_U ExcpRingVal;
+
+ CurTail = ring->cons.tail;
+ do
+ {
+ /*if ring is empty return directly */
+ tmpHead = ring->prod.head;
+
+ if (CurTail == tmpHead)
+ {
+ /*
+ here we give deque a chance to recorrect the Head, if head has Data let Head++
+ */
+ if (ring->ring[tmpHead & mask].data_s.val != 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead,
+ tmpHead + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN);
+ ExcpRingVal = ring->ring[CurTail & mask];
+ /*
+ *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF
+ */
+ if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver)
+ && (ExcpRingVal.data_s.val)
+ && __sync_bool_compare_and_swap(&ring->
+ ring[CurTail & mask].data_l,
+ ExcpRingVal.data_l,
+ curNullVal.data_l))
+ {
+
+ *box =
+ ADDR_SHTOL(((char *) ring->Addrbase +
+ ExcpRingVal.data_s.val));
+
+ /*
+ enqueue success, add Tail Value now
+ here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue success && been killed before
+ add Tail, other process can recorrect the Tail Value;
+ one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000);
+ while multi CAS done the result value of CurTail may not correct, but we don't care, it will be recorrect while next deque done.
+
+ avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime]
+ here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS.
+ */
+ tmpTail = ring->cons.tail;
+
+ if (0 == (CurTail & 0x03) && tmpTail - CurTail > 0x80000000)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail,
+ CurTail + 1);
+ }
+ break;
+ }
+
+ /*
+ CurTail++ here;
+ may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try
+ we using a cmp & CurTail++ instead CurTail++ directly.
+ if using CurTail++ will amplify the probability of ABA problem
+ */
+ /*CurTail++; */
+ tmpTail = ring->cons.tail;
+ CurTail = CurTail - tmpTail < mask - 1 ? CurTail + 1 : tmpTail;
+ }
+ while (1);
+
+ return 1;
+}
+
+/*
+ this is enhanced mc_ring_dequeue, support dequeue multi element one time.
+*/
+int
+nsfw_shmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n)
+{
+ unsigned int uiCurTail;
+ unsigned int tmpTail;
+ unsigned int tmpHead;
+ unsigned int uimask = ring->mask;
+ union RingData_U curNullVal;
+ union RingData_U ExcpRingVal;
+ unsigned int deqNum = 0;
+ uiCurTail = ring->cons.tail;
+ do
+ {
+ /*if ring is empty return directly */
+ tmpHead = ring->prod.head;
+ if (uiCurTail == tmpHead)
+ {
+ /*
+ here we give deque a chance to recorrect the Head, if head has Data let Head++;
+ here must done to avoid some msg can't deque.
+ */
+ if (deqNum == 0 && ring->ring[tmpHead & uimask].data_s.val != 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead,
+ tmpHead + 1);
+ }
+ else
+ {
+ return deqNum;
+ }
+ }
+
+ curNullVal.data_l = (((unsigned long long) uiCurTail) << VALUE_LEN);
+ ExcpRingVal = ring->ring[uiCurTail & uimask];
+
+ /*
+ *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF
+ */
+ if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver)
+ && (ExcpRingVal.data_s.val)
+ && __sync_bool_compare_and_swap(&ring->
+ ring[uiCurTail & uimask].data_l,
+ ExcpRingVal.data_l,
+ curNullVal.data_l))
+ {
+
+ box[deqNum] =
+ ADDR_SHTOL(((char *) ring->Addrbase +
+ ExcpRingVal.data_s.val));
+
+ /*
+ enqueue success, add Tail Value now
+ here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue success && been killed before
+ add Tail, other process can recorrect the Tail Value;
+ one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000);
+
+ avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime]
+ here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS.
+ */
+ tmpTail = ring->cons.tail;
+
+ if (0 == (uiCurTail & 0x03) && tmpTail - uiCurTail > 0x80000000)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->cons.tail, tmpTail,
+ uiCurTail + 1);
+ }
+
+ deqNum++;
+ }
+
+ /*
+ CurTail++ here;
+ may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try
+ we using a cmp & CurTail++ instead CurTail++ directly.
+ if using CurTail++ will amplify the probability of ABA problem
+ */
+ /*CurTail++; */
+ tmpTail = ring->cons.tail;
+ uiCurTail =
+ uiCurTail - tmpTail < uimask - 1 ? uiCurTail + 1 : tmpTail;
+
+ }
+ while (n > deqNum);
+
+ return deqNum;
+}
+
+/*
+ this is enhanced mc_ring_dequeue, support dequeue multi element one time.
+*/
+int nsfw_shmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ unsigned int CurTail;
+ unsigned int mask = ring->mask;
+ union RingData_U curNullVal;
+ union RingData_U ExcpRingVal;
+ unsigned int uitmpHead;
+
+ CurTail = ring->cons.tail;
+
+ do
+ {
+ /*if ring is empty return directly */
+ uitmpHead = ring->prod.head;
+ if (CurTail == uitmpHead)
+ {
+ /*
+ here we give deque a chance to recorrect the Head, if head has Data let Head++
+ */
+ if (ring->ring[uitmpHead & mask].data_s.val != 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->prod.head,
+ uitmpHead, uitmpHead + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN);
+ ExcpRingVal = ring->ring[CurTail & mask];
+
+ if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver)
+ && (ExcpRingVal.data_s.val))
+ {
+ ring->ring[CurTail & mask].data_l = curNullVal.data_l;
+
+ *box =
+ ADDR_SHTOL(((char *) ring->Addrbase +
+ ExcpRingVal.data_s.val));
+
+ ring->cons.tail = CurTail + 1;
+ break;
+ }
+
+ CurTail++;
+ }
+ while (1);
+
+ return 1;
+}
+
+/*
+ this is a single thread/process dequeue function
+*/
+int
+nsfw_shmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n)
+{
+ unsigned int CurTail;
+ unsigned int tmpHead;
+ unsigned int mask = ring->mask;
+ union RingData_U curNullVal;
+ union RingData_U ExcpRingVal;
+ unsigned int usdeqNum = 0;
+
+ CurTail = ring->cons.tail;
+
+ do
+ {
+ /*if ring is empty return directly */
+ tmpHead = ring->prod.head;
+ if (CurTail == tmpHead)
+ {
+ /*
+ here we give deque a chance to recorrect the Head, if head has Data let Head++;
+ here must done to avoid some msg can't deque.
+ */
+ if (usdeqNum == 0 && ring->ring[tmpHead & mask].data_s.val != 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->prod.head, tmpHead,
+ tmpHead + 1);
+ }
+ else
+ {
+ return usdeqNum;
+ }
+ }
+ curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN);
+ ExcpRingVal = ring->ring[CurTail & mask];
+
+ /*
+ the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF
+ */
+ if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver)
+ && (ExcpRingVal.data_s.val))
+ {
+ ring->ring[CurTail & mask].data_l = curNullVal.data_l;
+
+ box[usdeqNum] =
+ ADDR_SHTOL(((char *) ring->Addrbase +
+ ExcpRingVal.data_s.val));
+
+ ring->cons.tail = CurTail + 1;
+ usdeqNum++;
+ }
+
+ CurTail++;
+ }
+ while (n > usdeqNum);
+
+ return usdeqNum;
+}
+
+/* nstack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_shmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring, void *box)
+{
+ u32 head = 0;
+ void *prmBox = NULL;
+
+ /*if queue is full, just return 0 */
+ if (ring->prod.head >= (ring->size + ring->cons.tail))
+ {
+ return 0;
+ }
+
+ prmBox = (void *) ADDR_LTOSH_EXT(box);
+
+ head = ring->prod.head;
+ ring->prod.head = head + 1;
+ ring->ring[head & ring->mask].data_s.ver = head;
+ ring->ring[head & ring->mask].data_s.val =
+ (char *) prmBox - (char *) ring->Addrbase;
+ return 1;
+}
+
+/* nstack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_shmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring, void **box)
+{
+ u32 tail = 0;
+
+ /* if all entries are dequeued return 0 */
+ if (unlikely(ring->prod.head == ring->cons.tail))
+ {
+ return 0;
+ }
+
+ tail = ring->cons.tail;
+ *box =
+ ADDR_SHTOL((char *) ring->Addrbase +
+ ring->ring[tail & ring->mask].data_s.val);
+ ring->ring[tail & ring->mask].data_s.val = 0;
+ ring->ring[tail & ring->mask].data_s.ver = tail;
+ ring->cons.tail++;
+ return 1;
+}
+
+/* nstack just using one thread, for performance using que not support multi thread*/
+int
+nsfw_shmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n)
+{
+ u32 tail = 0;
+ u32 num = 0;
+
+ while (num < n)
+ {
+ tail = ring->cons.tail;
+
+ /* if all entries are dequeued return 0 */
+ if (unlikely(ring->prod.head == ring->cons.tail))
+ {
+ return num;
+ }
+
+ ring->cons.tail = tail + 1;
+
+ box[num] =
+ ADDR_SHTOL((char *) ring->Addrbase +
+ ring->ring[tail & ring->mask].data_s.val);
+
+ ring->ring[tail & ring->mask].data_s.val = 0;
+ ring->ring[tail & ring->mask].data_s.ver = tail;
+ num++;
+ }
+
+ return num;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h
new file mode 100644
index 0000000..af7c30c
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h
@@ -0,0 +1,60 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _NSFW_SHMEM_RING_H_
+#define _NSFW_SHMEM_RING_H_
+
+#include <stdint.h>
+
+#include "common_func.h"
+
+struct nsfw_shmem_ring_head
+{
+ struct common_mem_memzone *mem_zone;
+ struct nsfw_shmem_ring_head *next;
+ unsigned int uireserv[4];
+};
+
+void nsfw_shmem_ring_baseaddr_query(uint64_t * rte_lowest_addr,
+ uint64_t * rte_highest_addr);
+struct nsfw_mem_ring *nsfw_shmem_pool_create(const char *name,
+ unsigned int n,
+ unsigned int elt_size,
+ int socket_id,
+ unsigned char flag);
+struct nsfw_mem_ring *nsfw_shmem_ring_create(const char *name,
+ unsigned int n, int socket_id,
+ unsigned char flag);
+
+void nsfw_shmem_pool_free(struct nsfw_mem_ring *perfring_ptr);
+
+void nsfw_shmem_ring_reset(struct nsfw_mem_ring *ring, unsigned char flag);
+int nsfw_shmem_ring_mp_enqueue(struct nsfw_mem_ring *ring, void *box);
+int nsfw_shmem_ring_sp_enqueue(struct nsfw_mem_ring *ring, void *box);
+int nsfw_shmem_ring_mc_dequeue(struct nsfw_mem_ring *ring, void **box);
+int nsfw_shmem_ring_mc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n);
+int nsfw_shmem_ring_sc_dequeue(struct nsfw_mem_ring *ring, void **box);
+int nsfw_shmem_ring_sc_dequeuev(struct nsfw_mem_ring *ring, void **box,
+ unsigned int n);
+int nsfw_shmem_ring_singlethread_enqueue(struct nsfw_mem_ring *ring,
+ void *box);
+int nsfw_shmem_ring_singlethread_dequeue(struct nsfw_mem_ring *ring,
+ void **box);
+int nsfw_shmem_ring_singlethread_dequeuev(struct nsfw_mem_ring *ring,
+ void **box, unsigned int n);
+
+#endif /*_NSFW_SHMEM_RING_H_*/
diff --git a/stacks/lwip_stack/src/nStackMain/CMakeLists.txt b/stacks/lwip_stack/src/nStackMain/CMakeLists.txt
new file mode 100644
index 0000000..22bf8b8
--- /dev/null
+++ b/stacks/lwip_stack/src/nStackMain/CMakeLists.txt
@@ -0,0 +1,66 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+FILE(GLOB_RECURSE MAIN *.c)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -pie")
+
+ADD_DEFINITIONS(-rdynamic -D__NSTACK_MAIN__)
+ADD_EXECUTABLE(nStackMain ${MAIN})
+TARGET_LINK_LIBRARIES(
+ nStackMain
+ -Wl,--whole-archive
+ ${LIB_PATH_STATIC}/libjson-c.a
+ ${LIB_PATH_STATIC}/libglog.a
+ nStackFw
+ stacklwip
+ nStackHal
+ nStackAlarm
+ nTcpdump
+ nsfw_mem
+ -Wl,--no-whole-archive,-lstdc++ -ldl
+ -Wl,--no-as-needed
+ rte_eal
+ rte_ethdev
+ rte_mempool
+ rte_ring
+ rte_mbuf
+ rte_pmd_ixgbe
+ rte_pmd_virtio
+ rte_pmd_e1000
+ rte_pmd_vmxnet3_uio
+ rte_pmd_bond
+ rte_kvargs
+ rte_cmdline
+)
+
+if(WITH_SECUREC_LIB)
+ADD_DEPENDENCIES(nStackMain nStackAlarm stacklwip SECUREC)
+else()
+ADD_DEPENDENCIES(nStackMain nStackAlarm stacklwip)
+endif()
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../alarm/
+ ${CMAKE_CURRENT_LIST_DIR}/../maintain/
+ ${CMAKE_CURRENT_LIST_DIR}/../include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_shmem/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_nshmem/
+)
diff --git a/stacks/lwip_stack/src/nStackMain/main.c b/stacks/lwip_stack/src/nStackMain/main.c
new file mode 100644
index 0000000..6f58823
--- /dev/null
+++ b/stacks/lwip_stack/src/nStackMain/main.c
@@ -0,0 +1,457 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <signal.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include "nstack_securec.h"
+#include "nstack_log.h"
+#include "types.h"
+#include "nsfw_init_api.h"
+#include "alarm_api.h"
+
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_ps_mem_api.h"
+#include "nsfw_ps_api.h"
+#include "nsfw_recycle_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nsfw_maintain_api.h"
+#include "nstack_dmm_adpt.h"
+
+#include "nsfw_mem_api.h"
+#include "nsfw_mt_config.h"
+#include "nsfw_shmem_mdesc.h"
+#include "nsfw_nshmem_mdesc.h"
+
+#define GLOBAL_Stack_ARG "stack"
+#define GlOBAL_HELP "--help"
+#define GLOBAL_Dpdk_ARG "dpdk"
+#define GLOBAL_STACK_PORT "-port"
+#define NSTACK_MAIN_MAX_PARA 32
+#define NSTACK_MAIN_MIN_PARA 1
+
+#define MAX_MASTER_OPEN_FD 1024
+
+extern int uStackArgIndex;
+extern void spl_tcpip_thread(void *arg);
+extern int globalArgc;
+extern char **gArgv;
+extern int g_dpdk_argc;
+extern char **g_dpdk_argv;
+extern void print_call_stack();
+extern int adjust_mem_arg(int argc, char *argv[]);
+extern struct cfg_item_info g_cfg_item_info[CFG_SEG_MAX][MAX_CFG_ITEM];
+extern int get_network_json_data();
+extern int get_ip_json_data();
+extern nsfw_ring_ops
+ g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX];
+
+#ifdef SYS_MEM_RES_STAT
+extern void get_resource_stat();
+#endif
+
+extern alarm_result ms_alarm_check_func(void *para);
+int g_tcpip_thread_stat = 0; //this variable will be used at health check feature
+
+#if (DPDK_MODULE)
+extern void pal_common_usage(void);
+#endif
+
+typedef void (*pSignalFunc) (int);
+int app_init(void);
+
+void helpInfo()
+{
+ NSPOL_LOGERR
+ ("-----------------------------------------------------------------"
+ "\nThe format of arg"
+ "\nbash:./nStackMain RTE-ARGS stack STACK-ARGS"
+ "\n RTE-ARGS=-c COREMASK -n NUM [-b <domain:bus:devid.func>] [--socket-mem=MB,...] [-m MB] [-r NUM] [-v] [--file-prefix] [--proc-type <primary|secondary|auto>] [-- xen-dom0]"
+ "\n STACK-ARGS=-port PORTMASK [-c COREMASK] [-thread NUM]"
+ "\nUser examples:"
+ "\nTo make the DPDK run on core mask:0xf,Number of memory channels per processor socket in DPDK is 3 "
+ "\nTo make the stack run on eth coremask:f"
+ "\nbash: ./nStackMain -c 0xf -n 3 stack -port f"
+ "\nTo get more help info for stack:" "\n ./nStackMain --help stack"
+ "\nTo get more help info for dpdk:" "\n ./nStackMain --help dpdk"
+ "\n-----------------------------------------------------------------");
+
+#ifndef FOR_NSTACK_UT
+ exit(0);
+#endif
+
+}
+
+#define SIG_PTRACE __SIGRTMIN + 5
+
+void signal_handler(int s)
+{
+ NSPOL_LOGERR("Received signal exiting.]s=%d", s);
+ if (s == SIGSEGV) /* add for gdb attach work */
+ {
+ print_call_stack();
+ }
+
+ nstack_segment_error(s);
+ if ((SIG_PTRACE != s) && (SIG_PTRACE + 2 != s))
+ {
+#ifndef FOR_NSTACK_UT
+ exit(0);
+#endif
+ }
+
+ int i;
+ for (i = 0; i < MAX_THREAD; i++)
+ {
+ if (g_all_thread[i] != pthread_self() && 0 != g_all_thread[i])
+ {
+ NSFW_LOGERR("send sig thread %d", g_all_thread[i]);
+ if (0 == pthread_kill(g_all_thread[i], SIG_PTRACE + 2))
+ {
+ return;
+ }
+ }
+ g_all_thread[i] = 0;
+ }
+
+ for (i = 0; i < MAX_THREAD; i++)
+ {
+ if (0 != g_all_thread[i])
+ {
+ return;
+ }
+ }
+
+#ifndef FOR_NSTACK_UT
+ exit(0);
+#endif
+
+ //dpdk_signal_handler();
+}
+
+void register_signal_handler()
+{
+/* donot catch SIGHUP SIGTERM */
+ static const int s_need_handle_signals[] = {
+ SIGABRT,
+ SIGBUS,
+ SIGFPE,
+ SIGILL,
+ SIGIOT,
+ SIGQUIT,
+ SIGSEGV,
+ //SIGTRAP,
+ SIGXCPU,
+ SIGXFSZ,
+ //SIGALRM,
+ //SIGHUP,
+ SIGINT,
+ //SIGKILL,
+ SIGPIPE,
+ SIGPROF,
+ SIGSYS,
+ //SIGTERM,
+ SIGUSR1,
+ SIGUSR2,
+ //SIGVTALRM,
+ //SIGSTOP,
+ //SIGTSTP,
+ //SIGTTIN,
+ //SIGTTOU
+ };
+
+ /* here mask signal that will use in sigwait() */
+ sigset_t waitset, oset;
+
+ if (0 != sigemptyset(&waitset))
+ {
+ NSPOL_LOGERR("sigemptyset failed.");
+ }
+ sigaddset(&waitset, SIGRTMIN); /* for timer */
+ sigaddset(&waitset, SIGRTMIN + 2);
+ pthread_sigmask(SIG_BLOCK, &waitset, &oset);
+ unsigned int i = 0;
+
+ struct sigaction s;
+ s.sa_handler = signal_handler;
+ if (0 != sigemptyset(&s.sa_mask))
+ {
+ NSPOL_LOGERR("sigemptyset failed.");
+ }
+
+ s.sa_flags = (int) SA_RESETHAND;
+
+ /* register sig handler for more signals */
+ for (i = 0; i < sizeof(s_need_handle_signals) / sizeof(int); i++)
+ {
+ if (sigaction(s_need_handle_signals[i], &s, NULL) != 0)
+ {
+ NSPOL_LOGERR("Could not register %d signal handler.",
+ s_need_handle_signals[i]);
+ }
+
+ }
+
+}
+
+void checkArgs(int argc, char **argv)
+{
+ int uStackArg = 0; //mark the status whether need helpinfo and return
+ int i;
+ const unsigned int global_para_length = 5; //GLOBAL_Stack_ARG "stack" and GLOBAL_STACK_PORT "-port" string length, both are 5
+ const unsigned int global_help_length = 6; //GlOBAL_HELP "--help" string length is 6
+ const unsigned int global_dpdk_length = 4; //GLOBAL_Dpdk_ARG "dpdk" string length is 4
+
+ for (i = 0; i < argc; i++)
+ {
+ if (argc > 1)
+ {
+ if (strncmp(argv[i], GLOBAL_Stack_ARG, global_para_length) == 0)
+ {
+ if (i < 5)
+ {
+ NSPOL_LOGERR("Too less args");
+ helpInfo();
+ return;
+ }
+
+ uStackArg = 1;
+ uStackArgIndex = i;
+ continue;
+ }
+
+ if (strncmp(argv[i], GLOBAL_STACK_PORT, global_para_length) == 0)
+ {
+ continue;
+ }
+
+ if (strncmp(argv[i], GlOBAL_HELP, global_help_length) == 0)
+ {
+ if (i == (argc - 1))
+ {
+ helpInfo();
+ return;
+ }
+ else if ((++i < argc)
+ &&
+ (strncmp
+ (argv[i], GLOBAL_Dpdk_ARG,
+ global_dpdk_length) == 0))
+ {
+#if (DPDK_MODULE != 1)
+ //eal_common_usage();
+#else
+ pal_common_usage();
+#endif
+ return;
+ }
+ else
+ {
+ helpInfo();
+ return;
+ }
+ }
+ }
+ else
+ {
+ NSPOL_LOGERR("Too less args");
+ helpInfo();
+ return;
+ }
+ }
+
+ if (!uStackArg)
+ {
+ helpInfo();
+ return;
+ }
+}
+
+extern u64 timer_get_threadid();
+
+#ifdef FOR_NSTACK_UT
+int nstack_main(void)
+{
+ int argc;
+
+ char *argv[NSTACK_MAIN_MAX_PARA];
+ argv[0] = "nStackMain";
+ argv[1] = "-c";;
+ argv[2] = "0xffffffff";
+ argv[3] = "-n";
+ argv[4] = "3";
+ argv[5] = "stack";
+ argv[6] = "-port";
+ argv[7] = "288";
+ argv[8] = "-c";
+ argv[9] = "2";
+ argc = 10;
+
+#else
+int main(int argc, char *argv[])
+{
+#endif
+ fw_poc_type proc_type = NSFW_PROC_MAIN;
+
+ /* although nStackMaster has set close on exec, here can't be removed.
+ * in upgrade senario, if Master is old which has not set close on exec, here,
+ * if new version Main not close, problem will reappear. Add Begin*/
+ int i;
+ for (i = 4; i < MAX_MASTER_OPEN_FD; i++)
+ {
+ close(i);
+ }
+
+ cfg_module_param config_para;
+ config_para.proc_type = proc_type;
+ config_para.argc = argc;
+ config_para.argv = (unsigned char **) argv;
+ config_module_init(&config_para);
+
+ set_log_proc_type(LOG_PRO_NSTACK);
+ (void) nstack_log_init();
+
+// nstack_tracing_enable();
+ if (0 != nsfw_proc_start_with_lock(NSFW_PROC_MAIN))
+ {
+ NSFW_LOGERR("another process is running!!");
+ return 0;
+ }
+
+ if (1 != mallopt(M_ARENA_MAX, 1))
+ {
+ NSPOL_LOGERR("Error: mallopt fail, continue init");
+ }
+
+ /* Set different mem args to PAL and EAL */
+ INITPOL_LOGINF("main_thread", "adjust_mem_arg init", NULL_STRING,
+ LOG_INVALID_VALUE, MODULE_INIT_START);
+ if (adjust_mem_arg(argc, argv))
+ {
+ INITPOL_LOGERR("main_thread", "adjust_mem_arg init", NULL_STRING,
+ LOG_INVALID_VALUE, MODULE_INIT_FAIL);
+ return -1;
+ }
+ INITPOL_LOGINF("main_thread", "adjust_mem_arg init", NULL_STRING,
+ LOG_INVALID_VALUE, MODULE_INIT_SUCCESS);
+
+ checkArgs(globalArgc, gArgv);
+ register_signal_handler();
+
+ (void) signal(SIG_PTRACE, signal_handler);
+ (void) signal(SIG_PTRACE + 2, signal_handler);
+
+ if (nsfw_mgr_comm_fd_init(NSFW_PROC_MAIN) < 0)
+ {
+ NSFW_LOGERR("nsfw_mgr_comm_fd_init failed");
+ }
+
+ (void) nsfw_reg_trace_thread(pthread_self());
+
+ nsfw_mem_para stinfo = { 0 };
+ stinfo.iargsnum = uStackArgIndex;
+ stinfo.pargs = gArgv;
+ stinfo.enflag = proc_type;
+ (void) nstack_framework_set_module_param(NSFW_MEM_MGR_MODULE, &stinfo);
+ (void) nstack_framework_set_module_param(NSFW_MGR_COM_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_TIMER_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_RECYCLE_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_LOG_CFG_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_VER_MGR_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(SPL_RES_MGR_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_SOFT_PARAM_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_ALARM_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(TCPDUMP_MODULE,
+ (void *) ((u64) proc_type));
+ proc_type = NSFW_PROC_MASTER;
+ (void) nstack_framework_set_module_param(NSFW_PS_MODULE,
+ (void *) ((u64) proc_type));
+ (void) nstack_framework_set_module_param(NSFW_PS_MEM_MODULE,
+ (void *) ((u64) proc_type));
+
+ g_nsfw_mem_ops[NSFW_SHMEM].stmemop = &g_shmem_ops;
+ g_nsfw_mem_ops[NSFW_NSHMEM].stmemop = &g_nshmem_ops;
+ nsfw_ring_ops *ring_ops = (nsfw_ring_ops *) g_ring_ops_arry;
+ nsfw_ring_ops *temp_ring_ops = (nsfw_ring_ops *) g_ring_ops_arry_lwip;
+ for (i = 0; i < NSFW_MEM_TYPEMAX * NSFW_MPOOL_TYPEMAX; i++)
+ {
+ ring_ops[i] = *temp_ring_ops;
+ temp_ring_ops++;
+ }
+
+ int init_ret = nstack_framework_init();
+ if (init_ret < 0)
+ {
+ NSFW_LOGERR
+ ("######################init failed!!!!######################");
+ return -1;
+ }
+
+ ns_send_init_alarm(ALARM_EVENT_NSTACK_MAIN_ABNORMAL);
+
+ while (!timer_get_threadid())
+ {
+ (void) nsfw_thread_chk();
+ sys_sleep_ns(0, 500000000);
+ }
+ (void) nsfw_thread_chk_unreg();
+ NSFW_LOGINF("tcpip thread start!");
+ (void) sleep(2);
+
+ NSFW_LOGINF("read configuration!");
+ if (0 != get_network_json_data())
+ {
+ NSFW_LOGINF("get_network_json_data error");
+ return -1;
+ }
+
+ if (0 != get_ip_json_data())
+ {
+ NSFW_LOGINF("get_ip_json_data error");
+ return -1;
+ }
+
+ int ep_thread = 0;
+ while (1)
+ {
+#ifdef SYS_MEM_RES_STAT
+ get_resource_stat();
+#endif
+ (void) sleep(3);
+ ep_thread = nsfw_mgr_com_chk_hbt(1);
+ if (ep_thread > 0)
+ {
+ NSFW_LOGINF("force release lock");
+ (void) nsfw_recycle_rechk_lock();
+ }
+#ifdef FOR_NSTACK_UT
+ return 0;
+#endif
+
+ }
+}
diff --git a/stacks/lwip_stack/src/sbr/CMakeLists.txt b/stacks/lwip_stack/src/sbr/CMakeLists.txt
new file mode 100644
index 0000000..8bd5007
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/CMakeLists.txt
@@ -0,0 +1,37 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+if(WITH_HAL_LIB)
+else()
+ SET(PAL_H_DIRECTORIES "/usr/include/dpdk/")
+endif()
+
+
+FILE(GLOB SBR *.c)
+ADD_LIBRARY(lwip_dpdk SHARED ${SBR})
+TARGET_LINK_LIBRARIES(lwip_dpdk -Wl,--whole-archive socket nsfw_mem -Wl,--no-whole-archive rte_eal rte_mempool rte_ring rte_mbuf)
+ADD_DEPENDENCIES(lwip_dpdk socket DPDK)
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../include
+ ${PAL_H_DIRECTORIES}
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../stacks/lwip_stack/src/mem/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_shmem/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_nshmem/
+)
diff --git a/stacks/lwip_stack/src/sbr/sbr_err.h b/stacks/lwip_stack/src/sbr/sbr_err.h
new file mode 100644
index 0000000..96b5399
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_err.h
@@ -0,0 +1,190 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SBR_ERR_H
+#define SBR_ERR_H
+#include <errno.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifdef SBR_PROVIDE_ERRNO
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No stored locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+
+#define EDEADLOCK EDEADLK
+
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale NFS file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+
+#define ENSROK 0
+#define ENSRNODATA 160
+#define ENSRFORMERR 161
+#define ENSRSERVFAIL 162
+#define ENSRNOTFOUND 163
+#define ENSRNOTIMP 164
+#define ENSRREFUSED 165
+#define ENSRBADQUERY 166
+#define ENSRBADNAME 167
+#define ENSRBADFAMILY 168
+#define ENSRBADRESP 169
+#define ENSRCONNREFUSED 170
+#define ENSRTIMEOUT 171
+#define ENSROF 172
+#define ENSRFILE 173
+#define ENSRNOMEM 174
+#define ENSRDESTRUCTION 175
+#define ENSRQUERYDOMAINTOOLONG 176
+#define ENSRCNAMELOOP 177
+#define OPTION_DEG 200
+
+#endif
+
+static inline void sbr_set_errno(int err)
+{
+ errno = err;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_index_ring.c b/stacks/lwip_stack/src/sbr/sbr_index_ring.c
new file mode 100644
index 0000000..b684918
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_index_ring.c
@@ -0,0 +1,212 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include "sbr_index_ring.h"
+#include "nstack_securec.h"
+#include "common_mem_common.h"
+#include "common_func.h"
+
+/*****************************************************************************
+* Prototype : sbr_init_index_ring
+* Description : init index ring
+* Input : sbr_index_ring* ring
+* u32 num
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_init_index_ring(sbr_index_ring * ring, u32 num)
+{
+ u32 loop;
+
+ ring->head = 0;
+ ring->tail = 0;
+ ring->num = num;
+ ring->mask = num - 1;
+
+ for (loop = 0; loop < num; loop++)
+ {
+ ring->nodes[loop].ver = (loop - num);
+ ring->nodes[loop].val = 0;
+ }
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_index_ring
+* Description : create index ring
+* Input : u32 num
+* Output : None
+* Return Value : sbr_index_ring*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+sbr_index_ring *sbr_create_index_ring(u32 num)
+{
+ num = common_mem_align32pow2(num + 1);
+ sbr_index_ring *ring =
+ (sbr_index_ring *) malloc(sizeof(sbr_index_ring) +
+ num * sizeof(sbr_index_node));
+ if (!ring)
+ {
+ return NULL;
+ }
+
+ sbr_init_index_ring(ring, num);
+ return ring;
+}
+
+/*****************************************************************************
+* Prototype : sbr_index_ring_enqueue
+* Description : enqueue data,val != 0
+* Input : sbr_index_ring* ring
+* i32 val
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_index_ring_enqueue(sbr_index_ring * ring, i32 val)
+{
+ if (0 == val)
+ {
+ return -1;
+ }
+
+ sbr_index_node expect_node;
+ sbr_index_node cur_node;
+ u32 tmp_head;
+ u32 tmp_tail;
+ u32 cur_head = ring->head;
+ u32 mask = ring->mask;
+ u32 size = ring->num;
+
+ do
+ {
+ tmp_tail = ring->tail;
+ if (tmp_tail + size - cur_head == 0)
+ {
+ if (ring->nodes[tmp_tail & mask].val == 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->tail, tmp_tail,
+ tmp_tail + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ expect_node.ver = cur_head - size;
+ expect_node.val = 0;
+
+ cur_node.ver = cur_head;
+ cur_node.val = val;
+
+ if ((ring->nodes[cur_head & mask].ver == expect_node.ver)
+ && __sync_bool_compare_and_swap(&ring->
+ nodes[cur_head & mask].data,
+ expect_node.data, cur_node.data))
+ {
+ tmp_head = ring->head;
+ if ((tmp_head - cur_head > 0x80000000)
+ && (0 == (cur_head & 0x11)))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->head, tmp_head,
+ cur_head);
+ }
+
+ break;
+ }
+
+ tmp_head = ring->head;
+ cur_head = cur_head - tmp_head < mask - 1 ? cur_head + 1 : tmp_head;
+ }
+ while (1);
+
+ return 1;
+}
+
+/*****************************************************************************
+* Prototype : sbr_index_ring_dequeue
+* Description : dequeue
+* Input : sbr_index_ring* ring
+* i32* val
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_index_ring_dequeue(sbr_index_ring * ring, i32 * val)
+{
+ u32 cur_tail;
+ u32 tmp_tail;
+ u32 tmp_head;
+ u32 mask = ring->mask;
+ sbr_index_node null_node;
+ sbr_index_node expect_node;
+
+ cur_tail = ring->tail;
+ do
+ {
+ tmp_head = ring->head;
+ if (cur_tail == tmp_head)
+ {
+ if (0 != (ring->nodes[tmp_head & mask].val))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->head, tmp_head,
+ tmp_head + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ null_node.ver = cur_tail;
+ null_node.val = 0;
+ expect_node = ring->nodes[cur_tail & mask];
+
+ if ((null_node.ver == expect_node.ver) && (expect_node.val)
+ && __sync_bool_compare_and_swap(&ring->
+ nodes[cur_tail & mask].data,
+ expect_node.data, null_node.data))
+
+ {
+ *val = expect_node.val;
+ tmp_tail = ring->tail;
+ if ((tmp_tail - cur_tail > 0x80000000)
+ && (0 == (cur_tail & 0x11)))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->tail, tmp_tail,
+ cur_tail);
+ }
+
+ break;
+ }
+
+ tmp_tail = ring->tail;
+ cur_tail = cur_tail - tmp_tail < mask - 1 ? cur_tail + 1 : tmp_tail;
+ }
+ while (1);
+
+ return 1;
+}
diff --git a/stacks/lwip_stack/src/sbr/sbr_index_ring.h b/stacks/lwip_stack/src/sbr/sbr_index_ring.h
new file mode 100644
index 0000000..7a1e396
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_index_ring.h
@@ -0,0 +1,61 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _SBR_INDEX_RING_H_
+#define _SBR_INDEX_RING_H_
+
+#include "types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ volatile u32 ver;
+ volatile u32 val;
+ };
+ u64 data;
+ };
+} sbr_index_node;
+
+typedef struct
+{
+ volatile u32 head;
+ i8 cache_space[124];
+ volatile u32 tail;
+ u32 num;
+ u32 mask;
+ sbr_index_node nodes[0];
+} sbr_index_ring;
+
+sbr_index_ring *sbr_create_index_ring(u32 num);
+int sbr_index_ring_enqueue(sbr_index_ring * ring, i32 val);
+int sbr_index_ring_dequeue(sbr_index_ring * ring, i32 * val);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_protocol_api.h b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
new file mode 100644
index 0000000..16608bc
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
@@ -0,0 +1,102 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SBR_PROTOCOL_API_H
+#define SBR_PROTOCOL_API_H
+#include <sys/uio.h>
+#include <sys/epoll.h>
+#include <netinet/in.h>
+#include "sbr_err.h"
+#include "nsfw_msg_api.h"
+#include "nsfw_mt_config.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifndef SBR_MAX_INTEGER
+#define SBR_MAX_INTEGER 0x7FFFFFFF
+#endif
+
+#ifndef socklen_t
+#define socklen_t u32
+#endif
+
+#define SBR_MAX_FD_NUM MAX_SOCKET_NUM
+
+typedef struct sbr_socket_s sbr_socket_t;
+typedef struct
+{
+ int (*socket) (sbr_socket_t *, int, int, int);
+ int (*bind) (sbr_socket_t *, const struct sockaddr *, socklen_t);
+ int (*listen) (sbr_socket_t *, int);
+ int (*accept) (sbr_socket_t *, sbr_socket_t *, struct sockaddr *,
+ socklen_t *);
+ int (*accept4) (sbr_socket_t *, sbr_socket_t *, struct sockaddr *,
+ socklen_t *, int);
+ int (*connect) (sbr_socket_t *, const struct sockaddr *, socklen_t);
+ int (*shutdown) (sbr_socket_t *, int);
+ int (*getsockname) (sbr_socket_t *, struct sockaddr *, socklen_t *);
+ int (*getpeername) (sbr_socket_t *, struct sockaddr *, socklen_t *);
+ int (*getsockopt) (sbr_socket_t *, int, int, void *, socklen_t *);
+ int (*setsockopt) (sbr_socket_t *, int, int, const void *, socklen_t);
+ int (*recvfrom) (sbr_socket_t *, void *, size_t, int, struct sockaddr *,
+ socklen_t *);
+ int (*readv) (sbr_socket_t *, const struct iovec *, int);
+ int (*recvmsg) (sbr_socket_t *, struct msghdr *, int);
+ int (*send) (sbr_socket_t *, const void *, size_t, int);
+ int (*sendto) (sbr_socket_t *, const void *, size_t, int,
+ const struct sockaddr *, socklen_t);
+ int (*sendmsg) (sbr_socket_t *, const struct msghdr *, int);
+ int (*writev) (sbr_socket_t *, const struct iovec *, int);
+ int (*fcntl) (sbr_socket_t *, int, long);
+ int (*ioctl) (sbr_socket_t *, unsigned long, void *);
+ int (*close) (sbr_socket_t *);
+ int (*peak) (sbr_socket_t *);
+ void (*lock_common) (sbr_socket_t *);
+ void (*unlock_common) (sbr_socket_t *);
+ void (*fork_parent) (sbr_socket_t *, pid_t);
+ void (*fork_child) (sbr_socket_t *, pid_t, pid_t);
+ void (*(*ep_triggle) (sbr_socket_t *, int triggle_ops, void *, void *));
+ int (*ep_getevt) (sbr_socket_t *);
+ void (*set_app_info) (sbr_socket_t *, void *appinfo);
+ void (*set_close_stat) (sbr_socket_t *, int flag);
+} sbr_fdopt;
+
+struct sbr_socket_s
+{
+ int fd;
+ sbr_fdopt *fdopt;
+ void *stack_obj;
+ void *sk_obj;
+};
+
+int sbr_init_protocol();
+int sbr_fork_protocol();
+sbr_fdopt *sbr_get_fdopt(int domain, int type, int protocol);
+void sbr_app_touch_in(void); /*app send its version info to nStackMain */
+int lwip_try_select(int fdsize, fd_set * fdread, fd_set * fdwrite,
+ fd_set * fderr, struct timeval *timeout);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_res_mgr.c b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c
new file mode 100644
index 0000000..3758084
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c
@@ -0,0 +1,87 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "nstack_securec.h"
+#include "sbr_res_mgr.h"
+
+sbr_res_group g_res_group = { };
+
+/*****************************************************************************
+* Prototype : sbr_init_sk
+* Description : init sock pool
+* Input : None
+* Output : None
+* Return Value : static int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+NSTACK_STATIC int sbr_init_sk()
+{
+ sbr_index_ring *ring = sbr_create_index_ring(SBR_MAX_FD_NUM - 1);
+
+ if (!ring)
+ {
+ NSSBR_LOGERR("init ring failed");
+ return -1;
+ }
+
+ int i;
+ /*the queue can't accept value=0, so i begin with 1 */
+ for (i = 1; i <= SBR_MAX_FD_NUM; ++i)
+ {
+ g_res_group.sk[i].fd = i;
+ if (sbr_index_ring_enqueue(ring, i) != 1)
+ {
+ NSSBR_LOGERR
+ ("sbr_index_ring_enqueue failed, this can not happen");
+ free(ring);
+ return -1;
+ }
+ }
+
+ g_res_group.sk_ring = ring;
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : sbr_init_res
+* Description : init sbr res
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_init_res()
+{
+ if (sbr_init_sk() != 0)
+ {
+ return -1;
+ }
+
+ NSSBR_LOGDBG("init socket ok");
+
+ if (sbr_init_protocol() != 0)
+ {
+ return -1;
+ }
+
+ NSSBR_LOGDBG("init protocol ok");
+
+ return 0;
+}
diff --git a/stacks/lwip_stack/src/sbr/sbr_res_mgr.h b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
new file mode 100644
index 0000000..d597ef7
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
@@ -0,0 +1,155 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SBR_RES_MGR_H
+#define SBR_RES_MGR_H
+#include "sbr_protocol_api.h"
+#include "sbr_index_ring.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct
+{
+ sbr_index_ring *sk_ring;
+ sbr_socket_t sk[SBR_MAX_FD_NUM + 1]; /* unuse index 0 */
+} sbr_res_group;
+
+extern sbr_res_group g_res_group;
+
+/*****************************************************************************
+* Prototype : sbr_malloc_sk
+* Description : malloc sock
+* Input : None
+* Output : None
+* Return Value : static inline sbr_socket_t *
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline sbr_socket_t *sbr_malloc_sk()
+{
+ int fd;
+
+ if (sbr_index_ring_dequeue(g_res_group.sk_ring, &fd) != 1)
+ {
+ NSSBR_LOGERR("malloc sk failed]");
+ sbr_set_errno(EMFILE);
+ return NULL;
+ }
+
+ NSSBR_LOGDBG("malloc sk ok]fd=%d", fd);
+ return &g_res_group.sk[fd];
+}
+
+/*****************************************************************************
+* Prototype : sbr_free_sk
+* Description : free sock
+* Input : sbr_socket_t * sk
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_free_sk(sbr_socket_t * sk)
+{
+ sk->fdopt = NULL;
+ sk->sk_obj = NULL;
+ sk->stack_obj = NULL;
+
+ if (sbr_index_ring_enqueue(g_res_group.sk_ring, sk->fd) != 1)
+ {
+ NSSBR_LOGERR("sbr_index_ring_enqueue failed, this can not happen");
+ }
+
+ NSSBR_LOGDBG("free sk ok]fd=%d", sk->fd);
+}
+
+/*****************************************************************************
+* Prototype : sbr_lookup_sk
+* Description : lookup socket
+* Input : int fd
+* Output : None
+* Return Value : static inline sbr_socket_t *
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline sbr_socket_t *sbr_lookup_sk(int fd)
+{
+ if ((fd < 1) || (fd > SBR_MAX_FD_NUM))
+ {
+ NSSBR_LOGERR("fd is not ok]fd=%d", fd);
+ sbr_set_errno(EBADF);
+ return NULL;
+ }
+
+ sbr_socket_t *sk = &g_res_group.sk[fd];
+ if (!sk->sk_obj || !sk->stack_obj)
+ {
+ NSSBR_LOGERR
+ ("data in sk is error, this can not happen]fd=%d,sk_obj=%p,stack_obj=%p",
+ fd, sk->sk_obj, sk->stack_obj);
+ sbr_set_errno(EBADF);
+ return NULL;
+ }
+
+ return sk;
+}
+
+/*****************************************************************************
+* Prototype : sbr_free_sk
+* Description : free sock
+* Input : sbr_socket_t * sk
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_free_fd(int fd)
+{
+ if ((fd < 1) || (fd > SBR_MAX_FD_NUM))
+ {
+ NSSBR_LOGERR("fd is not ok]fd=%d", fd);
+ sbr_set_errno(EBADF);
+ return;
+ }
+
+ sbr_socket_t *sk = &g_res_group.sk[fd];
+ if (!sk->fdopt && !sk->sk_obj && !sk->stack_obj)
+ {
+ NSSBR_LOGERR
+ ("can't free empty fd] fd=%d, fdopt=%p, sk_obj=%p, stack_obj=%p",
+ fd, sk->fdopt, sk->sk_obj, sk->stack_obj);
+ return;
+ }
+ sbr_free_sk(sk);
+}
+
+int sbr_init_res();
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_socket.c b/stacks/lwip_stack/src/sbr/sbr_socket.c
new file mode 100644
index 0000000..27f3ad1
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_socket.c
@@ -0,0 +1,1324 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <dlfcn.h>
+#include "sbr_protocol_api.h"
+#include "sbr_res_mgr.h"
+#include "nstack_log.h"
+#include "nsfw_shmem_mdesc.h"
+#include "nsfw_nshmem_mdesc.h"
+#include "nstack_callback_ops.h"
+#include "nstack_rd_data.h"
+
+#define SBR_INTERCEPT(ret, name, args) ret sbr_ ## name args
+#define CALL_SBR_INTERCEPT(name, args) sbr_ ## name args
+#define GET_SBR_INTERCEPT(name) sbr_ ## name
+
+void *lwip_rd_table = NULL;
+extern nsfw_ring_ops
+ g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX];
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : create socket
+* Input : int
+* socket
+* (int domain
+* int type
+* int protocol)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, socket, (int domain, int type, int protocol))
+{
+ NSSBR_LOGDBG("socket]domain=%d,type=%d,protocol=%d", domain, type,
+ protocol);
+ sbr_fdopt *fdopt = sbr_get_fdopt(domain, type, protocol);
+
+ if (!fdopt)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_malloc_sk();
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt = fdopt;
+
+ int ret = sk->fdopt->socket(sk, domain, type, protocol);
+
+ if (ret != 0)
+ {
+ sbr_free_sk(sk);
+ return ret;
+ }
+
+ return sk->fd;
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_addr
+* Description : check addr
+* Input : int s
+* struct sockaddr * addr
+* socklen_t * addrlen
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int
+sbr_check_addr(int s, struct sockaddr *addr, socklen_t * addrlen)
+{
+ if (addr)
+ {
+ if (!addrlen)
+ {
+ NSSBR_LOGERR("addrlen is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (0 > (int) (*addrlen))
+ {
+ NSSBR_LOGERR("addrlen is negative]fd=%d,addrlen=%d", s, *addrlen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : accept4
+* Input : int
+* accept4
+* (int s
+* struct sockaddr * addr
+* socklen_t * addrlen
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, accept4,
+ (int s, struct sockaddr * addr, socklen_t * addrlen, int flags))
+{
+ NSSBR_LOGDBG("accept4]fd=%d,addr=%p,addrlen=%p,flags=%d", s, addr,
+ addrlen, flags);
+ int ret = sbr_check_addr(s, addr, addrlen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *new_sk = sbr_malloc_sk();
+ if (!new_sk)
+ {
+ return -1;
+ }
+
+ new_sk->fdopt = sk->fdopt;
+
+ ret = sk->fdopt->accept4(sk, new_sk, addr, addrlen, flags);
+ if (-1 == ret)
+ {
+ sbr_free_sk(new_sk);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : accept
+* Input : int
+* accept
+* (int s
+* struct sockaddr * addr
+* socklen_t * addrlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, accept,
+ (int s, struct sockaddr * addr, socklen_t * addrlen))
+{
+ NSSBR_LOGDBG("accept]fd=%d,addr=%p,addrlen=%p", s, addr, addrlen);
+ int ret = sbr_check_addr(s, addr, addrlen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *new_sk = sbr_malloc_sk();
+ if (!new_sk)
+ {
+ return -1;
+ }
+
+ new_sk->fdopt = sk->fdopt;
+
+ ret = sk->fdopt->accept(sk, new_sk, addr, addrlen);
+ if (-1 == ret)
+ {
+ sbr_free_sk(new_sk);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : bind
+* Input : int
+* bind
+* (int s
+* const struct sockaddr * name
+* socklen_t namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, bind,
+ (int s, const struct sockaddr * name, socklen_t namelen))
+{
+ NSSBR_LOGDBG("bind]fd=%d,name=%p,namelen=%d", s, name, namelen);
+ if (!name)
+ {
+ NSSBR_LOGERR("name is not ok]fd=%d,name=%p", s, name);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if ((name->sa_family) != AF_INET)
+ {
+ NSSBR_LOGERR("domain is not AF_INET]fd=%d,name->sa_family=%u", s,
+ name->sa_family);
+ sbr_set_errno(EAFNOSUPPORT);
+ return -1;
+ }
+
+ if (namelen != sizeof(struct sockaddr_in))
+ {
+ NSSBR_LOGERR("namelen is invalid]fd=%d,namelen=%d", s, namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->bind(sk, name, namelen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : listen
+* Input : int
+* listen
+* (int s
+* int backlog)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, listen, (int s, int backlog))
+{
+ NSSBR_LOGDBG("listen]fd=%d,backlog=%d", s, backlog);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ /* limit the "backlog" parameter to fit in an u8_t */
+ if (backlog < 0)
+ {
+ backlog = 0;
+ }
+
+ if (backlog > 0xff)
+ {
+ backlog = 0xff;
+ }
+
+ return sk->fdopt->listen(sk, backlog);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : connect
+* Input : int
+* connect
+* (int s
+* const struct sockaddr * name
+* socklen_t namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, connect,
+ (int s, const struct sockaddr * name, socklen_t namelen))
+{
+ NSSBR_LOGDBG("connect]fd=%d,name=%p,namelen=%d", s, name, namelen);
+ if (!name)
+ {
+ NSSBR_LOGERR("name is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (!
+ (namelen == sizeof(struct sockaddr_in)
+ && (name->sa_family == AF_INET)))
+ {
+ NSSBR_LOGERR("parameter invalid]fd=%d,domain=%u,namelen=%d", s,
+ name->sa_family, namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ NSSBR_LOGERR("get socket failed]fd=%d", s);
+ return -1;
+ }
+
+ return sk->fdopt->connect(sk, name, namelen);
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_sock_name
+* Description : check name
+* Input : int s
+* struct sockaddr * name
+* socklen_t * namelen
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int
+sbr_check_sock_name(int s, struct sockaddr *name, socklen_t * namelen)
+{
+ if (!name || !namelen)
+ {
+ NSSBR_LOGERR("name or namelen is null]fd=%d", s);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ if (*namelen & 0x80000000)
+ {
+ NSSBR_LOGERR("namelen is not ok]fd=%d,namelen=%d", s, *namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getpeername
+* Input : int
+* getpeername
+* (int s
+* struct sockaddr * name
+* socklen_t * namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getpeername,
+ (int s, struct sockaddr * name, socklen_t * namelen))
+{
+ NSSBR_LOGDBG("getpeername]fd=%d", s);
+ int ret = sbr_check_sock_name(s, name, namelen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ ret = sk->fdopt->getpeername(sk, name, namelen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getsockname
+* Input : int
+* getsockname
+* (int s
+* struct sockaddr * name
+* socklen_t * namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getsockname,
+ (int s, struct sockaddr * name, socklen_t * namelen))
+{
+ NSSBR_LOGDBG("getsockname]fd=%d", s);
+ int ret = sbr_check_sock_name(s, name, namelen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ ret = sk->fdopt->getsockname(sk, name, namelen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : setsockopt
+* Input : int
+* setsockopt
+* (int s
+* int level
+* int optname
+* const void * optval
+* socklen_t optlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, setsockopt,
+ (int s, int level, int optname, const void *optval,
+ socklen_t optlen))
+{
+ NSSBR_LOGDBG("setsockopt]fd=%d,level=%d,optname=%d,optval=%p,optlen=%d",
+ s, level, optname, optval, optlen);
+ if (!optval)
+ {
+ NSSBR_LOGERR("optval is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->setsockopt(sk, level, optname, optval, optlen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getsockopt
+* Input : int
+* getsockopt
+* (int s
+* int level
+* int optname
+* void * optval
+* socklen_t * optlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getsockopt,
+ (int s, int level, int optname, void *optval,
+ socklen_t * optlen))
+{
+ NSSBR_LOGDBG("getsockopt]fd=%d,level=%d,optname=%d,optval=%p,optlen=%p",
+ s, level, optname, optval, optlen);
+ if (!optval || !optlen)
+ {
+ NSSBR_LOGERR("optval or optlen is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->getsockopt(sk, level, optname, optval, optlen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : ioctl
+* Input : int
+* ioctl
+* (int s
+* unsigned long cmd
+* ...)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, ioctl, (int s, unsigned long cmd, ...))
+{
+ NSSBR_LOGDBG("ioctl]fd=%d,cmd=%lu", s, cmd);
+ va_list va;
+ va_start(va, cmd);
+ void *arg = va_arg(va, void *);
+ va_end(va);
+
+ if (!arg)
+ {
+ NSSBR_LOGERR("parameter is not ok]fd=%d", s);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->ioctl(sk, cmd, arg);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : fcntl
+* Input : int
+* fcntl
+* (int s
+* int cmd
+* ...)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, fcntl, (int s, int cmd, ...))
+{
+ NSSBR_LOGDBG("fcntl]fd=%d,cmd=%d", s, cmd);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ va_list va;
+ va_start(va, cmd);
+ long arg = va_arg(va, long);
+ va_end(va);
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->fcntl(sk, cmd, arg);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recvfrom
+* Input : int
+* recvfrom
+* (int s
+* void * mem
+* size_t len
+* int flags
+* struct sockaddr * from
+* socklen_t * fromlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recvfrom,
+ (int s, void *mem, size_t len, int flags,
+ struct sockaddr * from, socklen_t * fromlen))
+{
+ NSSBR_LOGDBG("recvfrom]fd=%d,mem=%p,len=%d,flags=%d,from=%p,fromlen=%p",
+ s, mem, len, flags, from, fromlen);
+
+ if (0 == len)
+ {
+ NSSBR_LOGDBG("len is zero]fd=%d,len=%u", s, (u32) len);
+ return 0; //return directly, don't change the last errno.
+ }
+
+ if (!mem)
+ {
+ NSSBR_LOGERR("mem is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (fromlen && (*((int *) fromlen) < 0))
+ {
+ NSSBR_LOGERR("fromlen is not ok]fd=%d,fromlen=%d", s, *fromlen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->recvfrom(sk, mem, len, flags, from, fromlen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : read
+* Input : int
+* read
+* (int s
+* void * mem
+* size_t len)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, read, (int s, void *mem, size_t len))
+{
+ NSSBR_LOGDBG("read]fd=%d,mem=%p,len=%d", s, mem, len);
+ return CALL_SBR_INTERCEPT(recvfrom, (s, mem, len, 0, NULL, NULL));
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_iov
+* Description : check iov
+* Input : int s
+* const struct iovec * iov
+* int iovcnt
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int sbr_check_iov(int s, const struct iovec *iov, int iovcnt)
+{
+ if ((!iov) || (iovcnt <= 0))
+ {
+ NSSBR_LOGERR("iov is NULL or iovcn <=0]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ int i;
+ for (i = 0; i < iovcnt; ++i)
+ {
+ if (!iov[i].iov_base && (iov[i].iov_len != 0))
+ {
+ NSSBR_LOGERR("iov is not ok]fd=%d,iov_base=%p,iov_len=%d", s,
+ iov[i].iov_base, iov[i].iov_len);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : readv
+* Input : int
+* readv
+* (int s
+* const struct iovec * iov
+* int iovcnt)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, readv, (int s, const struct iovec * iov, int iovcnt))
+{
+ NSSBR_LOGDBG("readv]fd=%d,iov=%p,iovcnt=%d", s, iov, iovcnt);
+
+ if (sbr_check_iov(s, iov, iovcnt) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->readv(sk, iov, iovcnt);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recv
+* Input : int
+* recv
+* (int s
+* void * mem
+* size_t len
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recv, (int s, void *mem, size_t len, int flags))
+{
+ NSSBR_LOGDBG("recv]fd=%d,mem=%p,len=%d,flags=%d", s, mem, len, flags);
+ return CALL_SBR_INTERCEPT(recvfrom, (s, mem, len, flags, NULL, NULL));
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_msg
+* Description : check msg
+* Input : int s
+* const struct msghdr * msg
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int sbr_check_msg(int s, const struct msghdr *msg)
+{
+ if (!msg)
+ {
+ NSSBR_LOGERR("msg is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (msg->msg_name && ((int) msg->msg_namelen < 0))
+ {
+ NSSBR_LOGERR("msg_namelen is not ok]fd=%d,msg_namelen=%d", s,
+ msg->msg_namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ return sbr_check_iov(s, msg->msg_iov, msg->msg_iovlen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recvmsg
+* Input : int
+* recvmsg
+* (int s
+* struct msghdr * msg
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recvmsg, (int s, struct msghdr * msg, int flags))
+{
+ NSSBR_LOGDBG("recvmsg]fd=%d,msg=%p,flags=%d", s, msg, flags);
+
+ if (sbr_check_msg(s, msg) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->recvmsg(sk, msg, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : send
+* Input : int
+* send
+* (int s
+* const void * data
+* size_t size
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, send,
+ (int s, const void *data, size_t size, int flags))
+{
+ NSSBR_LOGDBG("send]fd=%d,data=%p,size=%zu,flags=%d", s, data, size,
+ flags);
+ if (!data)
+ {
+ NSSBR_LOGERR("data is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->send(sk, data, size, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sendmsg
+* Input : int
+* sendmsg
+* (int s
+* const struct msghdr * msg
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, sendmsg, (int s, const struct msghdr * msg, int flags))
+{
+ NSSBR_LOGDBG("sendmsg]fd=%d,msg=%p,flags=%d", s, msg, flags);
+
+ if (sbr_check_msg(s, msg) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->sendmsg(sk, msg, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sendto
+* Input : int
+* sendto
+* (int s
+* const void * data
+* size_t size
+* int flags
+* const struct sockaddr * to
+* socklen_t tolen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, sendto,
+ (int s, const void *data, size_t size, int flags,
+ const struct sockaddr * to, socklen_t tolen))
+{
+ NSSBR_LOGDBG("sendto]fd=%d,data=%p,size=%zu,flags=%d,to=%p,tolen=%d", s,
+ data, size, flags, to, tolen);
+ if ((data == NULL) || (flags < 0))
+ {
+ NSSBR_LOGERR("parameter is not ok]fd=%d,data=%p,size=%zu,flags=%d", s,
+ data, size, flags);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->sendto(sk, data, size, flags, to, tolen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : write
+* Input : int
+* write
+* (int s
+* const void * data
+* size_t size)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, write, (int s, const void *data, size_t size))
+{
+ NSSBR_LOGDBG("write]fd=%d,data=%p,size=%zu", s, data, size);
+ return CALL_SBR_INTERCEPT(send, (s, data, size, 0));
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : writev
+* Input : int
+* writev
+* (int s
+* const struct iovec * iov
+* int iovcnt)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, writev, (int s, const struct iovec * iov, int iovcnt))
+{
+ NSSBR_LOGDBG("writev]fd=%d,iov=%p,iovcnt=%d", s, iov, iovcnt);
+
+ if (sbr_check_iov(s, iov, iovcnt) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->writev(sk, iov, iovcnt);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : shutdown
+* Input : int
+* shutdown
+* (int s
+* int how)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, shutdown, (int s, int how))
+{
+ NSSBR_LOGDBG("shutdown]fd=%d,how=%d", s, how);
+ if ((how != SHUT_RD) && (how != SHUT_WR) && (how != SHUT_RDWR))
+ {
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->shutdown(sk, how);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : close
+* Input : int
+* close
+* (int s)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, close, (int s))
+{
+ NSSBR_LOGDBG("close]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ int ret = sk->fdopt->close(sk);
+ sbr_free_sk(sk);
+ return ret;
+}
+
+SBR_INTERCEPT(int, select,
+ (int nfds, fd_set * readfd, fd_set * writefd,
+ fd_set * exceptfd, struct timeval * timeout))
+{
+ return lwip_try_select(nfds, readfd, writefd, exceptfd, timeout);
+}
+
+SBR_INTERCEPT(int, ep_getevt, (int profd))
+{
+ NSSBR_LOGDBG("proFD=%d", profd);
+ sbr_socket_t *sk = sbr_lookup_sk(profd);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->ep_getevt(sk);
+}
+
+SBR_INTERCEPT(void *, ep_triggle,
+ (int proFD, int triggle_ops, void *epinfo, void *epitem))
+{
+ NSSBR_LOGDBG("proFD=%d,triggle_ops=%d,epinfo=%p,epi=%p", proFD,
+ triggle_ops, epinfo, epitem);
+ sbr_socket_t *sk = sbr_lookup_sk(proFD);
+
+ if (!sk)
+ {
+ return NULL;
+ }
+
+ return sk->fdopt->ep_triggle(sk, triggle_ops, epinfo, epitem);
+}
+
+SBR_INTERCEPT(int, peak, (int s))
+{
+ NSSBR_LOGDBG("]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->peak(sk);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : set_app_info
+* Input : int
+* set_app_info
+* (int s
+* void* app_info)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, set_app_info, (int s, void *app_info))
+{
+ NSSBR_LOGDBG("set_app_info]fd=%d", s);
+
+ if (!app_info)
+ {
+ NSSBR_LOGERR("invalid param, app_info is NULL]");
+ return;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->set_app_info(sk, app_info);
+}
+
+/* app send its version info to nStackMain */
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sbr_app_touch
+* Input : int
+* sbr_app_touch
+* ()
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, app_touch, (void))
+{
+ NSSBR_LOGDBG("sbr_app_touch() is called]");
+
+ sbr_app_touch_in();
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : set_close_status
+* Input : void
+* set_close_stat
+* (int s
+* int flag)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, set_close_stat, (int s, int flag))
+{
+ NSSBR_LOGDBG("]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+ if (sk->fdopt->set_close_stat)
+ {
+ sk->fdopt->set_close_stat(sk, flag);
+ }
+
+}
+
+SBR_INTERCEPT(int, fd_alloc, ())
+{
+ return sbr_socket(AF_INET, SOCK_STREAM, 0);
+}
+
+SBR_INTERCEPT(int, fork_init_child, (pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG("fork_init_child() is called]");
+ return sbr_fork_protocol();
+}
+
+SBR_INTERCEPT(void, fork_parent_fd, (int s, pid_t p))
+{
+ NSSBR_LOGDBG("fork_parent_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_parent(sk, p);
+}
+
+SBR_INTERCEPT(void, fork_child_fd, (int s, pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG("fork_child_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_child(sk, p, c);
+
+}
+
+SBR_INTERCEPT(void, fork_free_fd, (int s))
+{
+ NSSBR_LOGDBG("fork_free_fd() is called]");
+ sbr_free_fd(s);
+}
+
+SBR_INTERCEPT(void *, get_ip_shmem, (void))
+{
+ lwip_rd_table = nstack_rd_malloc("lwip_rd_table");
+
+ if (!lwip_rd_table)
+ {
+ NSSOC_LOGERR("lwip rd table create failed!");
+ return NULL;
+ }
+
+ if (nstack_rd_parse("lwip", lwip_rd_table))
+ {
+ NSSOC_LOGWAR("lwip parse rd data failed, load default instead");
+ }
+
+ return lwip_rd_table;
+}
+
+SBR_INTERCEPT(int, module_init_pre,
+ (void *op1, void *op2, int memtype, int pooltype))
+{
+ int i;
+ nsfw_mem_attr *mem_ops = (nsfw_mem_attr *) op1;
+ nsfw_ring_ops *ring_ops = (nsfw_ring_ops *) op2;
+ nsfw_ring_ops *tmp_ring_ops;
+
+ if (!mem_ops || !ring_ops)
+ {
+ return -1;
+ }
+
+ mem_ops[NSFW_SHMEM].stmemop = &g_shmem_ops;
+ mem_ops[NSFW_NSHMEM].stmemop = &g_nshmem_ops;
+
+ tmp_ring_ops = (nsfw_ring_ops *) g_ring_ops_arry_lwip;
+ for (i = 0; i < memtype * pooltype; i++)
+ {
+ ring_ops[i] = tmp_ring_ops[i];
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nstack_stack_register
+* Description : reg api to nsocket
+* Input : nstack_socket_ops* ops
+* nstack_event_ops *val
+* nstack_proc_ops *deal
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+lwip_stack_register(nstack_socket_ops * ops, nstack_event_ops * val,
+ nstack_proc_ops * deal)
+{
+ if (!ops || !val || !val->handle)
+ {
+ return -1;
+ }
+
+#undef NSTACK_MK_DECL
+#define NSTACK_MK_DECL(ret, fn, args) \
+ ops->pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, "sbr_" # fn);
+#include "declare_syscalls.h.tmpl"
+
+ deal->module_init = sbr_init_res;
+ deal->fork_init_child = GET_SBR_INTERCEPT(fork_init_child);
+ deal->fork_fd = GET_SBR_INTERCEPT(fork_child_fd);
+ deal->fork_free_fd = GET_SBR_INTERCEPT(fork_free_fd);
+ deal->ep_getEvt = GET_SBR_INTERCEPT(ep_getevt);
+ deal->ep_triggle = GET_SBR_INTERCEPT(ep_triggle);
+ deal->peak = GET_SBR_INTERCEPT(peak);
+ //deal->stack_alloc_fd = GET_SBR_INTERCEPT (fd_alloc); /*alloc a fd id for epoll */
+ deal->fork_parent_fd = GET_SBR_INTERCEPT(fork_parent_fd);
+ deal->get_ip_shmem = GET_SBR_INTERCEPT(get_ip_shmem);
+ deal->module_init_pre = GET_SBR_INTERCEPT(module_init_pre);
+ return 0;
+}
diff --git a/stacks/lwip_stack/src/tools/CMakeLists.txt b/stacks/lwip_stack/src/tools/CMakeLists.txt
new file mode 100644
index 0000000..018b338
--- /dev/null
+++ b/stacks/lwip_stack/src/tools/CMakeLists.txt
@@ -0,0 +1,26 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+FILE(GLOB_RECURSE Tcpdump *.c)
+ADD_LIBRARY(nTcpdump STATIC ${Tcpdump})
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../include
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+)
+TARGET_LINK_LIBRARIES(nTcpdump nStackFw)
diff --git a/stacks/lwip_stack/src/tools/dump_tool.c b/stacks/lwip_stack/src/tools/dump_tool.c
new file mode 100644
index 0000000..7e6e67c
--- /dev/null
+++ b/stacks/lwip_stack/src/tools/dump_tool.c
@@ -0,0 +1,611 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <arpa/inet.h>
+
+#include "nsfw_init_api.h"
+#include "nsfw_maintain_api.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nstack_log.h"
+#include "nstack_securec.h"
+
+#include "dump_tool.h"
+#include "nstack_dmm_adpt.h"
+
+NSTACK_STATIC u32 g_dump_task_mask = 0;
+NSTACK_STATIC dump_task_info g_dump_task[MAX_DUMP_TASK];
+static dump_timer_info g_dump_timer;
+
+static nsfw_mem_name g_dump_mem_ring_info =
+ { NSFW_SHMEM, NSFW_PROC_MAIN, DUMP_SHMEM_RING_NAME };
+static nsfw_mem_name g_dump_mem_pool_info =
+ { NSFW_SHMEM, NSFW_PROC_MAIN, DUMP_SHMEM_POOL_NAME };
+
+NSTACK_STATIC inline void dump_task_init(dump_task_info * task)
+{
+ task->task_state = 0;
+ task->task_id = -1;
+ task->task_keep_time = 0;
+ task->task_pool = NULL;
+ task->task_queue = NULL;
+}
+
+NSTACK_STATIC inline void clear_dump_task()
+{
+ int i = 0;
+ for (; i < MAX_DUMP_TASK; i++)
+ {
+ dump_task_init(&g_dump_task[i]);
+ }
+}
+
+NSTACK_STATIC i16 get_dump_task(nsfw_tool_dump_msg * req)
+{
+ // base version just support 1 dump task
+ if (req->task_keep_time > MAX_DUMP_TIME
+ || req->task_keep_time < MIN_DUMP_TIME)
+ {
+ NSPOL_DUMP_LOGERR("task keep time invalid] time=%u.",
+ req->task_keep_time);
+ return -1;
+ }
+
+ if (1 == g_dump_task[0].task_state)
+ {
+ NSPOL_DUMP_LOGERR
+ ("start tcpdump task failed, task still in work state] task id=%d.",
+ 0);
+ return -1;
+ }
+
+ struct timespec cur_time;
+ GET_CUR_TIME(&cur_time); /*do not need return value */
+ g_dump_task[0].task_start_sec = cur_time.tv_sec;
+ g_dump_task[0].last_hbt_sec = cur_time.tv_sec;
+
+ g_dump_task[0].task_state = 1;
+ g_dump_task[0].task_id = 0;
+ g_dump_task[0].task_keep_time = req->task_keep_time;
+
+ g_dump_task_mask |= (1 << g_dump_task[0].task_id);
+ NSPOL_DUMP_LOGINF("start tcpdump task success] task id=%d.", 0);
+ return 0;
+}
+
+NSTACK_STATIC i16 close_dump_task(i16 task_id)
+{
+ if (task_id < 0 || task_id >= MAX_DUMP_TASK)
+ {
+ NSPOL_DUMP_LOGERR
+ ("receive invalid task id in close dump task req] task id=%d.",
+ task_id);
+ return -1;
+ }
+
+ g_dump_task[task_id].task_state = 0;
+
+ g_dump_task_mask &= ~(1 << task_id);
+
+ NSPOL_DUMP_LOGINF("stop tcpdump task success] task id=%d.", 0);
+
+ return task_id;
+}
+
+NSTACK_STATIC void stop_expired_task(int idx, u32 now_sec)
+{
+ dump_task_info *ptask = &g_dump_task[idx];
+ if (0 == ptask->task_state)
+ {
+ return;
+ }
+
+ if (now_sec - ptask->task_start_sec > ptask->task_keep_time)
+ {
+ NSPOL_DUMP_LOGERR
+ ("stop dump task because task time expired] task id=%d, now_sec=%u, task start time=%u, dump time=%u.",
+ ptask->task_id, now_sec, ptask->task_start_sec,
+ ptask->task_keep_time);
+ close_dump_task(ptask->task_id);
+ return;
+ }
+
+ if (now_sec - ptask->last_hbt_sec > DUMP_TASK_HBT_TIME_OUT)
+ {
+ NSPOL_DUMP_LOGERR
+ ("stop dump task because heart beat time out] task id=%d, now_sec=%u, last hbt time=%u, hbt timeout=%u.",
+ ptask->task_id, now_sec, ptask->last_hbt_sec,
+ DUMP_TASK_HBT_TIME_OUT);
+ close_dump_task(ptask->task_id);
+ }
+
+ return;
+}
+
+NSTACK_STATIC inline bool check_dump_alive(u32 timer_type, void *data)
+{
+ dump_timer_info *ptimer_info = (dump_timer_info *) data;
+
+ struct timespec cur_time;
+ GET_CUR_TIME(&cur_time); /*do not need return value */
+
+ int i = 0;
+ for (; i < MAX_DUMP_TASK; i++)
+ {
+ stop_expired_task(i, cur_time.tv_sec);
+ }
+
+ ptimer_info->ptimer =
+ nsfw_timer_reg_timer(1, ptimer_info, check_dump_alive,
+ *(struct timespec *) (ptimer_info->interval));
+
+ return true;
+}
+
+NSTACK_STATIC bool dump_init_timer(dump_timer_info * ptimer_info)
+{
+ struct timespec *trigger_time =
+ (struct timespec *) malloc(sizeof(struct timespec));
+ if (NULL == trigger_time)
+ {
+ NSPOL_DUMP_LOGERR("alloc memory for timer failed.");
+ return false;
+ }
+
+ trigger_time->tv_sec = DUMP_HBT_CHK_INTERVAL;
+ trigger_time->tv_nsec = 0;
+
+ ptimer_info->interval = trigger_time;
+ ptimer_info->ptimer =
+ nsfw_timer_reg_timer(1, ptimer_info, check_dump_alive, *trigger_time);
+ return true;
+}
+
+NSTACK_STATIC inline u32
+copy_limit_buf(char *dst_buf, int dst_buf_len, char *src_buf,
+ u32 src_buf_len, u32 limit_len)
+{
+ if (src_buf_len < limit_len)
+ {
+ NSPOL_DUMP_LOGERR("message too short] len=%d", src_buf_len);
+ return 0;
+ }
+
+ if (EOK != memcpy_s(dst_buf, dst_buf_len, src_buf, limit_len))
+ {
+ NSPOL_DUMP_LOGERR("MEMCPY_S failed");
+ return 0;
+ }
+
+ return limit_len;
+}
+
+NSTACK_STATIC inline u32
+get_packet_buf(char *dst_buf, int dst_buf_len, char *src_buf,
+ u32 src_buf_len, u32 eth_head_len)
+{
+#define TCP_BUF_LEN (eth_head_len + IP_HEAD_LEN + TCP_HEAD_LEN)
+#define UDP_BUF_LEN (eth_head_len + IP_HEAD_LEN + UDP_HEAD_LEN)
+#define ICMP_BUF_LEN (eth_head_len + IP_HEAD_LEN + ICMP_HEAD_LEN)
+
+ if (NULL == dst_buf || NULL == src_buf)
+ {
+ return 0;
+ }
+
+ struct ip_hdr *ip_head = (struct ip_hdr *) (src_buf + eth_head_len);
+ if (ip_head->_proto == IP_PROTO_TCP)
+ {
+ return copy_limit_buf(dst_buf, dst_buf_len, src_buf, src_buf_len,
+ TCP_BUF_LEN);
+ }
+
+ if (ip_head->_proto == IP_PROTO_UDP)
+ {
+ return copy_limit_buf(dst_buf, dst_buf_len, src_buf, src_buf_len,
+ UDP_BUF_LEN);
+ }
+
+ if (ip_head->_proto == IP_PROTO_ICMP)
+ {
+ return copy_limit_buf(dst_buf, dst_buf_len, src_buf, src_buf_len,
+ ICMP_BUF_LEN);
+ }
+
+ if (EOK != memcpy_s(dst_buf, dst_buf_len, src_buf, src_buf_len))
+ {
+ NSPOL_DUMP_LOGERR("MEMCPY_S failed");
+ return 0;
+ }
+
+ return src_buf_len;
+}
+
+NSTACK_STATIC int
+pack_msg_inout(void *dump_buf, char *msg_buf, u32 len, u16 direction,
+ void *para)
+{
+ (void) para;
+ dump_msg_info *pmsg = (dump_msg_info *) dump_buf;
+ if (!pmsg)
+ {
+ return 0;
+ }
+
+ pmsg->direction = direction;
+ struct timeval cur_time;
+ gettimeofday(&cur_time, NULL);
+ pmsg->dump_sec = cur_time.tv_sec;
+ pmsg->dump_usec = cur_time.tv_usec;
+
+ /* msg content can not be captured */
+ u32 real_len =
+ get_packet_buf(pmsg->buf, DUMP_MSG_SIZE, msg_buf, len, ETH_HEAD_LEN);
+ if (0 == real_len)
+ {
+ return 0;
+ }
+
+ pmsg->len = real_len;
+
+ return 1;
+}
+
+NSTACK_STATIC int
+pack_msg_loop(void *dump_buf, char *msg_buf, u32 len, u16 direction,
+ void *para)
+{
+ dump_msg_info *pmsg = (dump_msg_info *) dump_buf;
+ if (!pmsg)
+ {
+ return 0;
+ }
+ pmsg->direction = direction;
+ struct timeval cur_time;
+ gettimeofday(&cur_time, NULL);
+ pmsg->dump_sec = cur_time.tv_sec;
+ pmsg->dump_usec = cur_time.tv_usec;
+
+ eth_head pack_eth_head;
+ int retVal =
+ memcpy_s(pack_eth_head.dest_mac, MAC_ADDR_LEN, para, MAC_ADDR_LEN);
+ if (EOK != retVal)
+ {
+ NSPOL_DUMP_LOGERR("MEMCPY_S failed]retVal=%d", retVal);
+ return 0;
+ }
+ retVal =
+ memcpy_s(pack_eth_head.src_mac, MAC_ADDR_LEN, para, MAC_ADDR_LEN);
+ if (EOK != retVal)
+ {
+ NSPOL_DUMP_LOGERR("MEMCPY_S failed]retVal=%d", retVal);
+ return 0;
+ }
+ pack_eth_head.eth_type = htons(PROTOCOL_IP);
+
+ retVal =
+ memcpy_s(pmsg->buf, DUMP_MSG_SIZE, &pack_eth_head, sizeof(eth_head));
+ if (EOK != retVal)
+ {
+ NSPOL_DUMP_LOGERR("MEMCPY_S failed]retVal=%d", retVal);
+ return 0;
+ }
+
+ u32 buf_len = DUMP_MSG_SIZE - ETH_HEAD_LEN;
+
+ /* msg content can not be captured- Begin */
+ u32 real_len =
+ get_packet_buf(pmsg->buf + ETH_HEAD_LEN, buf_len, msg_buf, len, 0);
+ if (0 == real_len)
+ {
+ return 0;
+ }
+
+ pmsg->len = real_len + ETH_HEAD_LEN;
+
+ return 1;
+}
+
+NSTACK_STATIC void
+dump_enqueue(int task_idx, void *buf, u32 len, u16 direction,
+ pack_msg_fun pack_msg, void *para)
+{
+ mring_handle queue = (mring_handle *) g_dump_task[task_idx].task_queue;
+ mring_handle pool = (mring_handle *) g_dump_task[task_idx].task_pool;
+
+ void *msg = NULL;
+
+ if (nsfw_mem_ring_dequeue(pool, &msg) <= 0)
+ {
+ // such log may be too much if queue is empty
+ NSPOL_DUMP_LOGDBG("get msg node from mem pool failed] pool=%p.",
+ pool);
+ return;
+ }
+
+ if (NULL == msg)
+ {
+ NSPOL_DUMP_LOGWAR("get NULL msg node from mem pool] pool=%p.", pool);
+ return;
+ }
+
+ if (!pack_msg(msg, buf, len, direction, para))
+ {
+ NSPOL_DUMP_LOGWAR("get dump msg failed");
+ return;
+ }
+
+ if (nsfw_mem_ring_enqueue(queue, msg) < 0)
+ {
+ NSPOL_DUMP_LOGWAR("dump mem ring enqueue failed] ring=%p.", queue);
+ }
+
+ return;
+}
+
+NSTACK_STATIC inline bool dump_enabled()
+{
+ return (0 != g_dump_task_mask);
+}
+
+void ntcpdump(void *buf, u32 buf_len, u16 direction)
+{
+ u32 i;
+ if (!dump_enabled())
+ {
+ return;
+ }
+
+ /* fix Dead-code type Codedex issue here */
+ for (i = 0; i < MAX_DUMP_TASK; i++)
+ {
+ if (g_dump_task[i].task_state)
+ {
+ dump_enqueue(i, buf, buf_len, direction, pack_msg_inout, NULL);
+ }
+ }
+}
+
+void ntcpdump_loop(void *buf, u32 buf_len, u16 direction, void *eth_addr)
+{
+ u32 i;
+
+ if (!dump_enabled())
+ {
+ return;
+ }
+
+ /* fix Dead-code type Codedex issue here */
+ for (i = 0; i < MAX_DUMP_TASK; i++)
+ {
+ if (g_dump_task[i].task_state)
+ {
+ dump_enqueue(i, buf, buf_len, direction, pack_msg_loop, eth_addr);
+ }
+ }
+}
+
+// called by nStackMain
+bool dump_create_pool()
+{
+ nsfw_mem_sppool pool_info;
+ if (EOK !=
+ memcpy_s(&pool_info.stname, sizeof(nsfw_mem_name),
+ &g_dump_mem_pool_info, sizeof(nsfw_mem_name)))
+ {
+ NSPOL_DUMP_LOGERR("create dump mem pool failed, MEMCPY_S failed.");
+ return false;
+ }
+
+ pool_info.usnum = MAX_DUMP_MSG_NUM;
+ pool_info.useltsize = DUMP_MSG_SIZE + sizeof(dump_msg_info);
+ pool_info.isocket_id = NSFW_SOCKET_ANY;
+ pool_info.enmptype = NSFW_MRING_MPSC;
+
+ mring_handle pool = nsfw_mem_sp_create(&pool_info);
+ if (NULL == pool)
+ {
+ NSPOL_DUMP_LOGERR("create dump mem pool failed, pool create failed.");
+ return false;
+ }
+
+ g_dump_task[0].task_pool = pool;
+
+ NSPOL_DUMP_LOGINF("dump pool create success] pool=%p.", pool);
+
+ return true;
+}
+
+bool dump_create_ring()
+{
+ nsfw_mem_mring ring_info;
+ if (EOK !=
+ memcpy_s(&ring_info.stname, sizeof(nsfw_mem_name),
+ &g_dump_mem_ring_info, sizeof(nsfw_mem_name)))
+ {
+ NSPOL_DUMP_LOGERR("create dump mem ring failed, MEMCPY_S failed.");
+ return false;
+ }
+
+ ring_info.usnum = MAX_DUMP_MSG_NUM;
+ ring_info.isocket_id = NSFW_SOCKET_ANY;
+ ring_info.enmptype = NSFW_MRING_MPSC;
+
+ mring_handle ring = nsfw_mem_ring_create(&ring_info);
+ if (NULL == ring)
+ {
+ NSPOL_DUMP_LOGERR("create dump mem ring failed, ring create failed.");
+ return false;
+ }
+
+ g_dump_task[0].task_queue = ring;
+
+ NSPOL_DUMP_LOGINF("dump ring create success] ring=%p.", ring);
+
+ return true;
+}
+
+NSTACK_STATIC int on_dump_tool_req(nsfw_mgr_msg * req)
+{
+ i16 task_id = 0;
+ if (!req)
+ {
+ return -1;
+ }
+ if (req->src_proc_type != NSFW_PROC_TOOLS)
+ {
+ NSPOL_DUMP_LOGDBG
+ ("dump module receive invaild message] module type=%u.",
+ req->src_proc_type);
+ return -1;
+ }
+
+ if (req->msg_type != MGR_MSG_TOOL_TCPDUMP_REQ)
+ {
+ NSPOL_DUMP_LOGDBG("dump module receive invaild message] msg type=%u.",
+ req->msg_type);
+ return -1;
+ }
+
+ nsfw_tool_dump_msg *dump_msg_req = GET_USER_MSG(nsfw_tool_dump_msg, req);
+
+ switch (dump_msg_req->op_type)
+ {
+ case START_DUMP_REQ:
+ task_id = get_dump_task(dump_msg_req);
+ break;
+
+ case STOP_DUMP_REQ:
+ task_id = close_dump_task(dump_msg_req->task_id);
+ break;
+
+ default:
+ task_id = -1;
+ }
+
+ nsfw_mgr_msg *rsp = nsfw_mgr_rsp_msg_alloc(req);
+ if (NULL == rsp)
+ {
+ NSPOL_DUMP_LOGDBG("alloc response for dump request failed.");
+ return -1;
+ }
+
+ nsfw_tool_dump_msg *dump_msg_rsp = GET_USER_MSG(nsfw_tool_dump_msg, rsp);
+ dump_msg_rsp->op_type = dump_msg_req->op_type + DUMP_MSG_TYPE_RSP;
+ dump_msg_rsp->task_id = task_id;
+
+ nsfw_mgr_send_msg(rsp);
+ nsfw_mgr_msg_free(rsp);
+ return 0;
+
+}
+
+NSTACK_STATIC int on_dump_hbt_req(nsfw_mgr_msg * req)
+{
+ if (!req)
+ {
+ return -1;
+ }
+ if (req->src_proc_type != NSFW_PROC_TOOLS)
+ {
+ NSPOL_DUMP_LOGDBG
+ ("dump module receive invaild message] module type=%u.",
+ req->src_proc_type);
+ return -1;
+ }
+
+ if (req->msg_type != MGR_MSG_TOOL_HEART_BEAT)
+ {
+ NSPOL_DUMP_LOGDBG("dump module receive invaild message] msg type=%u.",
+ req->msg_type);
+ return -1;
+ }
+
+ nsfw_tool_hbt *dump_hbt_req = GET_USER_MSG(nsfw_tool_hbt, req);
+
+ i16 task_id = dump_hbt_req->task_id;
+ if (task_id < 0 || task_id >= MAX_DUMP_TASK)
+ {
+ NSPOL_DUMP_LOGERR("dump heart beat with invalid task id] task id=%d.",
+ task_id);
+ return -1;
+ }
+
+ if (0 == g_dump_task[task_id].task_state)
+ {
+ NSPOL_DUMP_LOGDBG
+ ("dump module receive heart beat but task not enabled] task id=%d.",
+ task_id);
+ return 0;
+ }
+
+ struct timespec cur_time;
+ GET_CUR_TIME(&cur_time); /*no need return value */
+
+ // update task alive time
+ g_dump_task[task_id].last_hbt_seq = dump_hbt_req->seq;
+ g_dump_task[task_id].last_hbt_sec = cur_time.tv_sec;
+
+ return 0;
+}
+
+NSTACK_STATIC int dump_tool_init(void *param);
+NSTACK_STATIC int dump_tool_init(void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ NSPOL_DUMP_LOGINF("dump module init] proc type=%d", proc_type);
+
+ switch (proc_type)
+ {
+ case NSFW_PROC_MAIN:
+ nsfw_mgr_reg_msg_fun(MGR_MSG_TOOL_TCPDUMP_REQ, on_dump_tool_req);
+ nsfw_mgr_reg_msg_fun(MGR_MSG_TOOL_HEART_BEAT, on_dump_hbt_req);
+ break;
+ default:
+ NSPOL_DUMP_LOGERR("dump init with unknow module] proc type=%d",
+ proc_type);
+ return -1;
+ }
+
+ clear_dump_task();
+
+ if (!dump_create_ring())
+ {
+ return -1;
+ }
+
+ if (!dump_create_pool())
+ {
+ return -1;
+ }
+
+ if (!dump_init_timer(&g_dump_timer))
+ {
+ return -1;
+ }
+
+ NSPOL_DUMP_LOGINF("dump module init success.");
+ return 0;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (TCPDUMP_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS(NSFW_MEM_MGR_MODULE)
+NSFW_MODULE_DEPENDS(NSFW_MGR_COM_MODULE)
+NSFW_MODULE_DEPENDS(NSFW_TIMER_MODULE)
+NSFW_MODULE_INIT (dump_tool_init)
+/* *INDENT-ON* */
diff --git a/stacks/lwip_stack/src/tools/dump_tool.h b/stacks/lwip_stack/src/tools/dump_tool.h
new file mode 100644
index 0000000..7727bc1
--- /dev/null
+++ b/stacks/lwip_stack/src/tools/dump_tool.h
@@ -0,0 +1,81 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _DUMP_TOOL_H_
+#define _DUMP_TOOL_H_
+
+#define IP_PROTO_ICMP 1
+#define IP_PROTO_IGMP 2
+#define IP_PROTO_UDP 17
+#define IP_PROTO_UDPLITE 136
+#define IP_PROTO_TCP 6
+
+#ifndef MAC_ADDR_LEN
+#define MAC_ADDR_LEN 6
+#endif
+
+#ifndef IP_HEAD_LEN
+#define IP_HEAD_LEN 20
+#endif
+#ifndef TCP_HEAD_LEN
+#define TCP_HEAD_LEN 20
+#endif
+#ifndef UDP_HEAD_LEN
+#define UDP_HEAD_LEN 8
+#endif
+
+#ifndef ICMP_HEAD_LEN
+#define ICMP_HEAD_LEN 8
+#endif
+
+typedef struct _dump_task_info
+{
+ u16 task_state; // 0:off, 1:on
+ i16 task_id;
+ u32 task_keep_time;
+ u32 task_start_sec;
+ u32 last_hbt_seq;
+ u32 last_hbt_sec;
+ void *task_queue;
+ void *task_pool;
+} dump_task_info;
+
+typedef struct _dump_eth_head
+{
+ u8 dest_mac[MAC_ADDR_LEN];
+ u8 src_mac[MAC_ADDR_LEN];
+ u16 eth_type;
+} eth_head;
+
+#define ETH_HEAD_LEN sizeof(eth_head)
+
+struct ip_hdr
+{
+ u16 _v_hl_tos;
+ u16 _len;
+ u16 _id;
+ u16 _offset;
+ u8 _ttl;
+ u8 _proto;
+ u16 _chksum;
+ u32 src;
+ u32 dest;
+};
+
+typedef int (*pack_msg_fun) (void *dump_buf, char *msg_buf, u32 len,
+ u16 direction, void *para);
+
+#endif