diff options
300 files changed, 52932 insertions, 26156 deletions
@@ -1,7 +1,9 @@ #ignoring the changes in sub folders of release folder /release/bin/ /release/lib64/ +/release/include/ /release/include/common/ +/release/include/generic/ /release/include/*.h !/release/include/declare_syscalls.h !/release/include/nsocket_dmm_api.h @@ -20,6 +22,23 @@ /build/Makefile /build/post_compile.sh /build/src/ - +/build/stacks/ +/build/thirdparty/ +/build/libnStackMaintain.a +/build/libsocket.a +/stacks/lwip_stack/lwip_src/lwip-2.0.3.zip +/stacks/lwip_stack/lwip_src/lwip/ +/stacks/lwip_stack/build/ +/stacks/lwip_stack/release/ +/scripts/checkstyle.sh +/stacks/lwip_stack/release/bin/ +/stacks/lwip_stack/release/script/ +/stacks/lwip_stack/src/include/ +!/stacks/lwip_stack/src/include/nsfw_msg_api.h +!/stacks/lwip_stack/src/include/nsfw_msg.h +!/stacks/lwip_stack/src/include/nsfw_mt_config.h +!/stacks/lwip_stack/src/include/nsfw_rti.h #ignoring the changes in sub folders of thirdparty folder /thirdparty/ +/thirdparty/glog/glog-0.3.4/compile/ +/thirdparty/glog/glog-0.3.4/m4/ diff --git a/CMakeLists.txt b/CMakeLists.txt index eed1625..2f5e9f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,11 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) PROJECT(nStack) + +option(RMWS "automatically remove trailing whitespace using git pre-commit hook" OFF) +option(WITH_SECUREC_LIB "Option description" OFF) +option(WITH_HAL_LIB "Option description" OFF) + SET(CMAKE_C_COMPILER "gcc") SET(EXECUTABLE_PATH ${CMAKE_CURRENT_LIST_DIR}/release/bin) SET(LIB_PATH_STATIC ${PROJECT_BINARY_DIR}) @@ -25,10 +30,15 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH_STATIC}) SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_PATH}) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_PATH_SHARED}) SET(DMM_DPDK_INSTALL_DIR "" CACHE STRING "to get the dpdk install path by cmd") +SET(DMM_REL_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/release/include) +SET(DMM_ARCH x86) SET(GENERATE_RPM_PATH ${CMAKE_CURRENT_LIST_DIR}/release/rpm) file(MAKE_DIRECTORY ${GENERATE_RPM_PATH}) +SET(GENERATE_DEB_PATH ${CMAKE_CURRENT_LIST_DIR}/release/deb) +file(MAKE_DIRECTORY ${GENERATE_DEB_PATH}) + MESSAGE(STATUS "Top dir is: " ${CMAKE_CURRENT_LIST_DIR}) MESSAGE(STATUS "Static library dir: " ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) MESSAGE(STATUS "Executable binary dir: " ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) @@ -36,11 +46,55 @@ MESSAGE(STATUS "Shared library dir: " ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) add_custom_target(clean-cmake-files - COMMAND ${CMAKE_COMMAND} -P clean-all.cmake + COMMAND ${CMAKE_COMMAND} -P clean-all.cmake ) -option(WITH_SECUREC_LIB "Option description" OFF) -option(WITH_HAL_LIB "Option description" OFF) +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + message(STATUS "Setting git commit template...") + execute_process(COMMAND git config --local commit.template ${CMAKE_SOURCE_DIR}/scripts/git/commit-msg-template + RESULT_VARIABLE git_config_ret) + if(git_config_ret EQUAL 0) + message(STATUS "Setting git commit template...done") + else() + message(WARNING "Setting git commit template...failed") + endif() + + find_program(GIT_REVIEW git-review) + if(NOT GIT_REVIEW) + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg") + message(STATUS "git-review not found") + message(STATUS "Setting git commit hook...") + execute_process(COMMAND ln -s ${CMAKE_SOURCE_DIR}/scripts/git/commit-msg-hook.py ${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg + RESULT_VARIABLE ln_ret) + if(ln_ret EQUAL 0) + message(STATUS "Setting git commit hook...done") + else() + message(WARNING "Setting git commit hook...failed") + endif() + endif() + else() + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg") + message(AUTHOR_WARNING "Found git-review but this repo does not seem to have been initialized by git-review. Please manually execute 'git review -s' before cmake.") + else() + file(READ ${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg contents) + string(FIND "${contents}" "commit-msg-hook.py" match_ret) + if(${match_ret} EQUAL -1) + file(APPEND ${CMAKE_SOURCE_DIR}/.git/hooks/commit-msg "${CMAKE_SOURCE_DIR}/scripts/git/commit-msg-hook.py $1") + endif() + endif() + endif() + + if(RMWS) + message(STATUS "Setting git pre-commit hook...") + execute_process(COMMAND ln -sf ${CMAKE_SOURCE_DIR}/scripts/git/pre-commit ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit + RESULT_VARIABLE ln_sf_ret) + if(ln_sf_ret EQUAL 0) + message(STATUS "Setting git pre-commit hook...done") + else() + message(WARNING "Setting git pre-commit hook...failed") + endif() + endif() +endif() if(WITH_SECUREC_LIB) add_definitions(-DSECUREC_LIB) @@ -60,16 +114,17 @@ FILE(APPEND ${post_compile} cp -f ${CMAKE_CURRENT_LIST_DIR}/src/nSocket/include/nstack_dmm_api.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/adapt/nstack_dmm_adpt.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/adapt/nstack_share_res.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ -cp -f ${CMAKE_CURRENT_LIST_DIR}/src/adapt/nstack_rd_mng.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/nSocket/include/declare_syscalls.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/include/* ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/base/include/*.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/base/include/common/* ${CMAKE_CURRENT_LIST_DIR}/release/include/ -cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/* ${CMAKE_CURRENT_LIST_DIR}/release/include/ +cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/*.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ +cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/generic ${CMAKE_CURRENT_LIST_DIR}/release/include/ +cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/arch/${DMM_ARCH}/* ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/ipc/mgr_com/mgr_com.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/hal/hal.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ -cp -f ${CMAKE_CURRENT_LIST_DIR}/build/libdmm_api.a ${CMAKE_CURRENT_LIST_DIR}/release/lib64/ +cp -f ${CMAKE_CURRENT_LIST_DIR}/src/nSocket/include/nstack_dmm_api.h ${CMAKE_CURRENT_LIST_DIR}/release/include/ echo post compile process success. " ) @@ -82,7 +137,7 @@ FILE(APPEND ${clean_compile} rm -rf ${CMAKE_CURRENT_LIST_DIR}/release/include/*.h rm -rf ${CMAKE_CURRENT_LIST_DIR}/release/include/generic -rm -rf ${CMAKE_CURRENT_LIST_DIR}/release/lib64/libdmm_api.a +rm -rf ${CMAKE_CURRENT_LIST_DIR}/release/lib64/libdmm_api.so echo post clean process success. " @@ -93,6 +148,16 @@ ADD_DEPENDENCIES(DPDK dmm_api) ADD_CUSTOM_TARGET(pkg-rpm COMMAND sh ../scripts/generate_dmm_rpm.sh) +ADD_CUSTOM_TARGET(pkg-deb COMMAND sh ../scripts/generate_dmm_deb.sh) + +ADD_CUSTOM_TARGET(vpp-stack COMMAND sh ../scripts/build_vpp.sh) +ADD_DEPENDENCIES(vpp-stack DPDK) + +ADD_CUSTOM_TARGET(checkstyle + COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/scripts/checkstyle.sh -c) +ADD_CUSTOM_TARGET(fixstyle + COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/scripts/checkstyle.sh -f) + ADD_CUSTOM_TARGET(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND sh clean_compile.sh) @@ -138,7 +203,7 @@ ExternalProject_Add( GLOG SOURCE_DIR ${GLOG_SRC} BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND autoreconf COMMAND sh configure CFLAGS=-fPIC CXXFLAGS=-fPIC + CONFIGURE_COMMAND autoreconf -ivf COMMAND sh configure CFLAGS=-fPIC CXXFLAGS=-fPIC BUILD_COMMAND COMMAND make -j 8 INSTALL_COMMAND cp -f ${GLOG_SRC}/.libs/libglog.a ${LIB_PATH_STATIC}/ ) @@ -146,5 +211,5 @@ ExternalProject_Add( ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(app_example) -#ADD_SUBDIRECTORY(thirdparty/rsrdma) +ADD_SUBDIRECTORY(stacks/rsocket) ADD_SUBDIRECTORY(thirdparty/apps) @@ -1,29 +1,28 @@ -# 1. Introduction: +# 1. Introduction -# ![nStack_Architecture](resources/nStack_Architecture.png "nStack_Architecture") +![nStack_Architecture](resources/nStack_Architecture.png "nStack_Architecture") DMM (Dual Mode, Multi-protocol, Multi-instance) is a framework between applications -and transport layer of networking stack. This framework can hosts different types of -networking stack instances operating on different domains (kernel/user-space) or even with +and transport layer of networking stack. This framework can host different types of +networking stack instances operating on different domains (kernel/user-space) with different protocol suites (TCP/IP, RDMA, or others). Application can use different type of protocol stack implementations based on functional/performance requirements. - -# 2. History: +# 2. History Emerging applications are bringing extremely high-performance requirements to the -network system. Eg. AR/VR, IOT etc. And Many of them coming with their unique demand -of QOS/SLA. Some application need low latency network, some need high reliability etc. +network system. Eg. AR/VR, IOT etc. And many of them come with their unique demand +of QOS/SLA. Some applications need low latency network, some need high reliability etc. Though such performance targets should be required for the complete communication system, -the transport layer protocols play a key role and encountered a relatively higher -challenge, because traditionally the TCP-based transport layer exploits the “best-effort” principle -and provides no performance guarantees in its nature. However, as Internet applications rapidly -grow and diversify, an all-powerful or one-fits-all protocol or algorithm becomes less feasible. +the transport layer protocols play a key role and there are relatively bigger challenges, +because traditionally the TCP-based transport layer exploits the “best-effort” principle +and provides no performance guarantees by its nature. However, as Internet applications rapidly +grow and diversify, all-powerful or one-fits-all protocol or algorithm become less feasible. Thus, the traditional single-instance TCP-based network stack bears great challenges when serving many applications with different QoS/SLA requirements simultaneously on the -same platform. Also Moving the networking stack out of the kernel is an obvious trend in both -the industry and literature. Technologies like DPDK, etc improving performance of network +same platform. Also moving the networking stack out of the kernel is an obvious trend in both +the industry and literature. Technologies, e.g. DPDK, improve performance of network stack, by bypassing the kernel, avoiding context-switching and data copies, as well as providing -a complete set of packet-processing acceleration libraries. Keeping above trends in mind the +a complete set of packet-processing acceleration libraries. Keeping above trends in mind,the DMM/nStack provides a framework where, system operators can plug in dedicated types of networking stack instances according to performance and/or functional requirements from the user space applications. Application doesn't have to worry about change their transport @@ -32,17 +31,19 @@ instances and the app/socket-to-stack-mappings, which are provided via the orche /management interface. So DMM provide a framework which can hide all the complexity of different transport layer protocol and also provide the flexibility to choose a protocol stack from manybased on functional/performance requirements. - - # 3. Quick Start Refer doc/Build_DMM.md - +# 4. Involved + * [Bi-Weekly DMM Metting.](https://wiki.fd.io/view/DMM/Meettng) + * [Join the DMM Mailing List.](https://lists.fd.io/g/dmm-dev) + * [Join fdio-dmm IRC channel.](https://wiki.fd.io/view/IRC) + * [Browse the code.](https://git.fd.io/dmm/tree/) + * [18.07 Release Plan](https://wiki.fd.io/view/Projects/dmm/Release_Plans/Release_Plan_18.07) + # 5. More Information - - https://wiki.fd.io/view/DMM - https://wiki.fd.io/view/Project_Proposals/DMM - Enabling “Protocol Routing”: Revisiting Transport Layer Protocol Design in Internet Communications(http://ieeexplore.ieee.org/document/8114687/) - diff --git a/app_example/CMakeLists.txt b/app_example/CMakeLists.txt index 0c88a4f..a82c752 100644 --- a/app_example/CMakeLists.txt +++ b/app_example/CMakeLists.txt @@ -15,4 +15,4 @@ ######################################################################### ADD_SUBDIRECTORY(perf-test) - +ADD_SUBDIRECTORY(func-test) diff --git a/app_example/func-test/CMakeLists.txt b/app_example/func-test/CMakeLists.txt new file mode 100644 index 0000000..e6357b8 --- /dev/null +++ b/app_example/func-test/CMakeLists.txt @@ -0,0 +1,18 @@ +######################################################################### +# +# 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. +######################################################################### + +ADD_SUBDIRECTORY(fork) + diff --git a/app_example/func-test/fork/CMakeLists.txt b/app_example/func-test/fork/CMakeLists.txt new file mode 100644 index 0000000..266dd9f --- /dev/null +++ b/app_example/func-test/fork/CMakeLists.txt @@ -0,0 +1,27 @@ +######################################################################### +# +# 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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC -m64 -mssse3 -std=gnu89") + +LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) + +ADD_EXECUTABLE(tcp_fork_server tcpserver.c) +ADD_DEPENDENCIES(tcp_fork_server nStackAPI) +TARGET_LINK_LIBRARIES(tcp_fork_server libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(tcp_client tcpclient.c) +ADD_DEPENDENCIES(tcp_client nStackAPI) +TARGET_LINK_LIBRARIES(tcp_client libnStackAPI.so -lpthread -lrt) + diff --git a/app_example/func-test/fork/tcpclient.c b/app_example/func-test/fork/tcpclient.c new file mode 100644 index 0000000..274dcbb --- /dev/null +++ b/app_example/func-test/fork/tcpclient.c @@ -0,0 +1,173 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#define DEBUG + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + printf(fmt, ##arg); \ +} while(0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +int srcPort = 0; +int destPort = 0; +int times = 0; + +void +random_str (char *str, const int len) +{ + static const char alphaNum[] = + "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; + int i = 0; + + for (i = 0; i < len; i++) + { + str[i] = alphaNum[rand () % (sizeof (alphaNum) - 1)]; + } + + str[len] = 0; +} + +static void +setArgsDefault () +{ + + memset (&g_dest, 0, sizeof (g_dest)); + g_dest.sin_family = AF_INET; + g_dest.sin_addr.s_addr = inet_addr ("127.0.0.1"); + g_dest.sin_port = htons (12345); + bzero (&(g_dest.sin_zero), 8); + + memset (&g_src, 0, sizeof (g_src)); + g_src.sin_family = AF_INET; + g_src.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_src.sin_port = htons (7895); + bzero (&(g_src.sin_zero), 8); + + times = 1; +} + +static int +process_arg (int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:t:"; + + if (argc < 5) + { + DBG + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n"); + return -1; + } + setArgsDefault (); + while ((opt = getopt (argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + g_dest.sin_port = htons (atoi (optarg)); + break; + case 'd': + g_dest.sin_addr.s_addr = inet_addr (optarg); + break; + case 's': + g_src.sin_addr.s_addr = inet_addr (optarg); + break; + case 'a': + g_src.sin_port = htons (atoi (optarg)); + break; + case 't': + times = atoi (optarg); + break; + } + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + + int clientSocket, ret, i; + char sndbuffer[1024]; + char rcvbuffer[1024]; + int result = 0; + + /* + * check command line arguments + */ + if (0 != process_arg (argc, argv)) + { + DBG ("Error in argument.%d\n", argc); + exit (1); + } + + clientSocket = socket (AF_INET, SOCK_STREAM, 0); + if (clientSocket < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("[INFO]Client Socket is created.\n"); + + ret = bind (clientSocket, (struct sockaddr *) &g_src, sizeof (g_src)); + if (ret < 0) + { + DBG ("Error in binding.\n"); + exit (1); + } + + DBG ("[INFO]Bind to client aaddress port 0\n"); + + ret = connect (clientSocket, (struct sockaddr *) &g_dest, sizeof (g_dest)); + if (ret < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("[INFO]Connected to Server.\n"); + + memset (sndbuffer, '\0', 1024 * sizeof (char)); + memset (rcvbuffer, '\0', 1024 * sizeof (char)); + + for (i = 1; i <= times; i++) + { + DBG ("Client: \t"); + random_str (sndbuffer, 50); + send (clientSocket, sndbuffer, strlen (sndbuffer), 0); + + if (recv (clientSocket, rcvbuffer, 1024, 0) < 0) + { + DBG ("Error in receiving data.\n"); + } + else + { + DBG ("Server: \t%s\n", rcvbuffer); + } + if (0 != strcmp (sndbuffer, rcvbuffer)) + { + result = -1; + break; + } + } + + /* Send exit message to server */ + strcpy (sndbuffer, "#exit"); + send (clientSocket, sndbuffer, strlen (sndbuffer), 0); + + DBG ("Result = %s\n", (result == 0) ? "Success" : "Fail"); + close (clientSocket); + DBG ("Disconnecting from server.\n"); + return 0; +} diff --git a/app_example/func-test/fork/tcpserver.c b/app_example/func-test/fork/tcpserver.c new file mode 100644 index 0000000..5474c35 --- /dev/null +++ b/app_example/func-test/fork/tcpserver.c @@ -0,0 +1,161 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/wait.h> + +static struct sockaddr_in g_src; +int srcPort = 0; +int destPort = 0; +int times = 0; + +#ifdef DEBUG +#define DBG(fmt, arg...) do { \ + DBG(fmt, ##arg); \ +} while(0) +#else +#define DBG(fmt, arg...) ((void)0) +#endif + +static void +setArgsDefault () +{ + memset (&g_src, 0, sizeof (g_src)); + g_src.sin_family = AF_INET; + g_src.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_src.sin_port = htons (7895); + bzero (&(g_src.sin_zero), 8); + + times = 1; +} + +static int +process_arg (int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "s:a:t:"; + + if (argc < 5) + { + DBG + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n"); + return -1; + } + setArgsDefault (); + while ((opt = getopt (argc, argv, optstring)) != -1) + { + switch (opt) + { + case 's': + g_src.sin_addr.s_addr = inet_addr (optarg); + break; + case 'a': + g_src.sin_port = htons (atoi (optarg)); + break; + case 't': + times = atoi (optarg); + break; + } + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + + int sockfd, ret; + int newSocket; + socklen_t addr_size; + static struct sockaddr_in accept_addr; + char buffer[1024]; + pid_t childpid; + + /* + * check command line arguments + */ + if (0 != process_arg (argc, argv)) + { + DBG ("Error in argument.%d\n", argc); + exit (1); + } + + sockfd = socket (AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + DBG ("Error in connection.\n"); + exit (1); + } + DBG ("Server Socket is created. %d\n", sockfd); + + ret = bind (sockfd, (struct sockaddr *) &g_src, sizeof (g_src)); + if (ret < 0) + { + DBG ("Error in binding.\n"); + exit (1); + } + + DBG ("Bind sucess port %d\n", g_src.sin_port); + + if (listen (sockfd, 10) == 0) + { + DBG ("Listening on %s....\n", inet_ntoa (g_src.sin_addr)); + } + else + { + DBG ("Error in binding.\n"); + } + + while (1) + { + newSocket = + accept (sockfd, (struct sockaddr *) &accept_addr, &addr_size); + if (newSocket < 0) + { + DBG ("Error: Exiting here pid %d", getpid ()); + exit (1); + } + + DBG ("Connection accepted from %s:%d fd %d\n", + inet_ntoa (accept_addr.sin_addr), + ntohs (accept_addr.sin_port), newSocket); + if ((childpid = fork ()) == 0) + { + DBG ("[ PID %d] Child process Created. Pid %d \r\n", getpid (), + getpid ()); + DBG ("[ PID %d] Closing fd %d\n", getpid (), sockfd); + close (sockfd); + + while (1) + { + memset (buffer, '\0', 1024 * sizeof (char)); + recv (newSocket, buffer, 1024, 0); + if (strcmp (buffer, "#exit") == 0) + { + DBG ("Disconnected from %s:%d\n", + inet_ntoa (newAddr.sin_addr), + ntohs (newAddr.sin_port)); + break; + } + else + { + DBG ("[PID %d]Client: %s\n", getpid (), buffer); + send (newSocket, buffer, strlen (buffer), 0); + bzero (buffer, sizeof (buffer)); + } + } + + DBG ("[PID %d]Closing socket %d\r\n", getpid (), newSocket); + close (newSocket); + } + + } + + DBG ("[PID %d]Process exiting... %d\r\n", getpid (), getpid ()); + return 0; +} diff --git a/app_example/perf-test/CMakeLists.txt b/app_example/perf-test/CMakeLists.txt index 686cf4f..7f05b84 100644 --- a/app_example/perf-test/CMakeLists.txt +++ b/app_example/perf-test/CMakeLists.txt @@ -37,3 +37,11 @@ TARGET_LINK_LIBRARIES(ks_epoll pthread) ADD_EXECUTABLE(ks_select multi_tcp_select_app_Ser.c) TARGET_LINK_LIBRARIES(ks_select pthread) + +ADD_EXECUTABLE(vs_common multi_tcp_common_Ser.c) +ADD_DEPENDENCIES(vs_common nStackAPI) +TARGET_LINK_LIBRARIES(vs_common libnStackAPI.so -lpthread -lrt) + +ADD_EXECUTABLE(ks_common multi_tcp_common_Ser.c) +TARGET_LINK_LIBRARIES(ks_common pthread) + diff --git a/app_example/perf-test/multi_tcp_common_Ser.c b/app_example/perf-test/multi_tcp_common_Ser.c new file mode 100644 index 0000000..984052b --- /dev/null +++ b/app_example/perf-test/multi_tcp_common_Ser.c @@ -0,0 +1,544 @@ +/* +* +* 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 <fcntl.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <time.h> +#include <linux/tcp.h> +#define __USE_GNU +#include <sched.h> +#include <pthread.h> +#include <arpa/inet.h> +#include <sys/epoll.h> +#include <errno.h> + +#define _BIND bind +#define _LISTEN listen +#define _SOCKET socket +#define _ACCEPT accept +#define _SEND send +#define _RECV recv +#define _CLOSE close +#define _CONNECT connect +#define _PROTOCOL IPPROTO_TCP + +#define MAX_TEST_TIME 1000 +#define MSG_LENGTH 256 +#define CORE_NUM 8 +#define START_CPU_ID 2 +#define MAX_CONN_LIMIT 256 +#define MAX_PORT_NUM 65535 +//1:A-B ;0:A-B-A +#define SEND_RECV_MODE 1 +#define MAX_EVENTS 1000 +#define Default_PortID 12345 +#define Default_SleepCnt 10000 +#define Default_SleepTime 1000000 +#define Flag_Print 1 +#define Fd_Number 1 + +static struct sockaddr_in g_dest; +static struct sockaddr_in g_src; +static struct sockaddr_in g_recv; + +int times = MAX_TEST_TIME; +int msg_length = MSG_LENGTH; +int coreNum = CORE_NUM; +int startCPUId = START_CPU_ID; +int connectNum = MAX_CONN_LIMIT; +int msgMode = SEND_RECV_MODE; +int sleepCnt = Default_SleepCnt; +int sleepTime = Default_SleepTime; //us +int fdNumber = Fd_Number; +int flagPrint = Flag_Print; +int unitPrint = 0; +int waitTime = 0; + +int srcPort = Default_PortID; +int destPort = 0; +int recvPort = 0; +char sendarr[256] = ""; +char recvarr[256] = ""; +char destarr[256] = ""; + +static void +setArgsDefault () +{ + + memset (&g_dest, 0, sizeof (g_dest)); + g_dest.sin_family = AF_INET; + g_dest.sin_addr.s_addr = inet_addr ("127.0.0.1"); + g_dest.sin_port = htons (12345); + bzero (&(g_dest.sin_zero), 8); + + memset (&g_src, 0, sizeof (g_src)); + g_src.sin_family = AF_INET; + g_src.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_src.sin_port = htons (7895); + bzero (&(g_src.sin_zero), 8); + + memset (&g_recv, 0, sizeof (g_recv)); + g_recv.sin_family = AF_INET; + g_recv.sin_addr.s_addr = inet_addr ("0.0.0.0"); + g_recv.sin_port = htons (7895); + bzero (&(g_recv.sin_zero), 8); + +} + +static int +process_arg (int argc, char *argv[]) +{ + int opt = 0; + int error = 0; + const char *optstring = "p:d:s:a:l:t:e:i:f:r:n:w:u:x:"; + int rw_mark = 0; + + if (argc < 4) + { + printf + ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -l msg_length; \n"); + printf + ("\t-t MAX_TEST_TIME; -i msg_interval ; -f client fd number ; -r receive port; -n connectNum(one server vs n client)\n"); + return 0; + } + while ((opt = getopt (argc, argv, optstring)) != -1) + { + switch (opt) + { + case 'p': + destPort = atoi (optarg); + g_dest.sin_port = htons (atoi (optarg)); + break; + case 'd': + stpcpy (destarr, optarg); + g_dest.sin_addr.s_addr = inet_addr (optarg); + break; + case 's': + stpcpy (sendarr, optarg); + g_src.sin_addr.s_addr = inet_addr (optarg); + g_recv.sin_addr.s_addr = inet_addr (optarg); + break; + case 'a': + //g_src.sin_port = htons(atoi(optarg)); + srcPort = atoi (optarg); + break; + case 'l': + msg_length = atoi (optarg); + break; + case 't': + times = atoi (optarg); + break; + case 'e': + sleepCnt = atoi (optarg); + break; + case 'i': + sleepTime = atoi (optarg); + break; + case 'f': + fdNumber = atoi (optarg); + break; + case 'r': + recvPort = atoi (optarg); + g_recv.sin_port = htons (atoi (optarg)); + break; + case 'n': + connectNum = atoi (optarg); + break; + case 'w': + waitTime = atoi (optarg); + break; + case 'u': + unitPrint = atoi (optarg); + break; + case 'x': + flagPrint = atoi (optarg); + break; + + } + } + return 1; +} + +void +process_client (void) +{ + int sendLen = 0; + int i = 0, t = 0, p = 0, optval = 0, ret = 0; + char send_buf[1000] = ""; + int c_socketfd[100] = { 0 }; + int errbind[1000] = { 0 }; + int errconn[1000] = { 0 }; + + int send_count[1000] = { 0 }; + int pps = 0; + long pps_time = 0; + + struct timespec startTime, endTime; + struct timespec countStart; + struct timespec countEnd; + + memset (&countStart, 0, sizeof (countStart)); + memset (&countEnd, 0, sizeof (countEnd)); + + for (i = 0; i < fdNumber; i++) + { + c_socketfd[i] = _SOCKET (PF_INET, SOCK_STREAM, _PROTOCOL); + if (0 > c_socketfd[i]) + { + printf ("client %d failed,err %d\n", i, errno); + } + else + { + printf ("client %d created success\n", i); + } + } + + for (i = 0; i < fdNumber; i++) + { + optval = 1; + ret = + setsockopt (c_socketfd[i], SOL_SOCKET, SO_REUSEADDR, (void *) &optval, + sizeof (optval)); + if (ret == -1) + { + printf ("Couldn't setsockopt(SO_REUSEADDR)\n"); + break; + } + } + + for (i = 0; i < fdNumber; i++) + { + g_src.sin_port = htons (srcPort + i); + errbind[i] = + _BIND (c_socketfd[i], (struct sockaddr *) &g_src, sizeof (g_src)); + if (errbind[i] < 0) + { + printf ("client %d bind Failed %d\n", i, errno); + _CLOSE (c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf ("client %d bind Success port:%d IP:%s\n", i, + ntohs (g_src.sin_port), + inet_ntoa (*((struct in_addr *) &(g_src.sin_addr.s_addr)))); + } + } + for (i = 0; i < fdNumber; i++) + { + if (errbind[i] >= 0) + { + errconn[i] = + _CONNECT (c_socketfd[i], (struct sockaddr *) &g_dest, + sizeof (g_dest)); + if (errconn[i] < 0) + { + printf ("client %d Connect Failed %d\n", i, errno); + _CLOSE (c_socketfd[i]); + c_socketfd[i] = -1; + continue; + } + else + { + printf ("client %d Connect Success port:%d, IP:%s\n", i, + ntohs (g_dest.sin_port), + inet_ntoa (* + ((struct in_addr *) + &(g_dest.sin_addr.s_addr)))); + } + } + } + + sleep (1); + + clock_gettime (CLOCK_MONOTONIC, &startTime); + clock_gettime (CLOCK_MONOTONIC, &countStart); + + for (t = 0; t < times; t++) + { + for (i = 0; i < fdNumber; i++) + { + if (c_socketfd[i] < 0) + { + continue; + } + do + { + sendLen = _SEND (c_socketfd[i], send_buf, msg_length, 0); + } + while (sendLen <= 0); + send_count[i]++; + } + + if (0 != sleepTime) + { + if ((t % sleepCnt) == 0) + { + usleep (sleepTime); + } + } + + if ((send_count[0] % unitPrint) == 0) + { + clock_gettime (CLOCK_MONOTONIC, &countEnd); + + pps_time = + (countEnd.tv_sec - countStart.tv_sec) * 1000000000 + + countEnd.tv_nsec - countStart.tv_nsec; + pps = ((float) 1000000000 / pps_time) * unitPrint * fdNumber; + if ((flagPrint != 0)) + { + printf (" sendcount %d, time: %ld ns\n", + send_count[0] * fdNumber, pps_time); + } + printf ("sendcount %d , pps=%d\n", send_count[0] * fdNumber, pps); + clock_gettime (CLOCK_MONOTONIC, &countStart); + } + } + + clock_gettime (CLOCK_MONOTONIC, &endTime); + + for (i = 0; i < fdNumber; i++) + { + printf ("client %d send %d , sendtime :%ld s %ld ns\n", i, + send_count[i], endTime.tv_sec - startTime.tv_sec, + endTime.tv_nsec - startTime.tv_nsec); + } + + for (i = 0; i < fdNumber; i++) + { + printf ("client %d close!\n", i); + if (c_socketfd[i] > 0) + _CLOSE (c_socketfd[i]); + } + + pthread_exit (NULL); +} + +/* + using this thread to do recv msg; +*/ +void * +process_server_msg_thread (void *pArgv) +{ + int recvLen = 0, recvLen2 = 0; + char send_buf[1000]; + char recv_buf[1000]; + int recv_count = 0; + long recv_ppstime = 0; + int recv_pps = 0; + int ret; + struct timespec recvStart; + struct timespec recvEnd; + memset (&recvStart, 0, sizeof (recvStart)); + memset (&recvEnd, 0, sizeof (recvEnd)); + + pthread_detach (pthread_self ()); + + int msgFd = *(int *) pArgv; + clock_gettime (CLOCK_MONOTONIC, &recvStart); + while (recv_count < times) + { + recvLen = 0; + recvLen2 = 0; + while (1) + { + recvLen2 = + recv (msgFd, recv_buf + recvLen, msg_length - recvLen, 0); + if (recvLen2 <= 0) + { + break; + } + else if (recvLen2 == msg_length - recvLen) + { + recvLen = 0; + recv_count++; + if (msg_length != send (msgFd, send_buf, msg_length, 0)) + { + printf ("send failed!====, need exit\n"); + } + + } + else if (recvLen2 < msg_length - recvLen) + { + recvLen += recvLen2; + } + if ((flagPrint != 0) && ((recv_count % unitPrint) == 0)) + { + clock_gettime (CLOCK_MONOTONIC, &recvEnd); + recv_ppstime = + (recvEnd.tv_sec - recvStart.tv_sec) * 1000000000 + + recvEnd.tv_nsec - recvStart.tv_nsec; + recv_pps = ((float) 1000000000 / recv_ppstime) * unitPrint; + printf ("receive count:%d, receive time: %ld ns\n", recv_count, + recv_ppstime); + printf ("receive pps = %d\n", recv_pps); + clock_gettime (CLOCK_MONOTONIC, &recvStart); + } + } + } + close (msgFd); +} + +/* + using this thread to do accept connect +*/ +void * +process_server_accept_thread (void *pArgv) +{ + int listenFd = 0; + int x, optval, ret, m = 0; + int acpt_socketfd[1000] = { 0 }; + + listenFd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (0 > listenFd) + { + printf ("ERROR:socket failed,errno [%d]\n", errno); + return; + } + else + { + printf ("INFO:Create listen socket Success, listenFd[%d]\n", listenFd); + } + + if (0 > fcntl (listenFd, F_SETFL, O_NONBLOCK)) + { + printf ("ERROR:fcntl failed. fd[%d], errno[%d]/n", listenFd, errno); + close (listenFd); + } + + optval = 1; + ret = + setsockopt (listenFd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, + sizeof (optval)); + if (ret == -1) + { + printf ("ERROR:setsockopt failed. fd[%d], errno[%d]\n", listenFd, + errno); + close (listenFd); + return; + } + + if (0 != + bind (listenFd, (struct sockaddr *) &g_recv, sizeof (struct sockaddr))) + { + printf ("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf ("INFO:Bind Failed, port %d IP:%s\n", ntohs (g_recv.sin_port), + inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + close (listenFd); + exit (-1); + } + else + { + printf ("Info Bind Success, port %d IP:%s\n", ntohs (g_recv.sin_port), + inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); + } + + if (0 != listen (listenFd, 100)) + { + printf ("server socket listen failed. err %d\n", errno); + close (listenFd); + return; + } + printf ("Listen Success\n"); + + int timeout = -1; + int accpedNum = 0; + while (accpedNum < connectNum) + { + while (1) + { + acpt_socketfd[accpedNum] = + accept4 (listenFd, NULL, NULL, SOCK_NONBLOCK); + if (acpt_socketfd[accpedNum] < 0) + { + break; + } + + fcntl (acpt_socketfd[accpedNum], F_SETFL, 0); + + /*add new accptFd to MsgEpFD */ + pthread_t ser_rcv_thread_id; + if (pthread_create + (&ser_rcv_thread_id, NULL, process_server_msg_thread, + (void *) &acpt_socketfd[accpedNum]) == -1) + { + printf ("create process_server_msg_thread fail\n"); + break; + } + + printf ("accept cnt [%d], cur accept fd [%d]\n", accpedNum, + acpt_socketfd[accpedNum]); + accpedNum++; + } + } + close (listenFd); + while (1) + { + sleep (10); + } + + pthread_exit (NULL); +} + +void +main (int argc, char *argv[]) +{ + socklen_t addrlen = sizeof (struct sockaddr); + int err = 0, result = 0, ret = 0; + int i = 0, j = 0, optval = 0, z = 0, x, listenfd; + cpu_set_t mask; + + setArgsDefault (); + ret = process_arg (argc, argv); + if (ret != 1) + { + printf ("The param error\n"); + return; + } + + pthread_t server_thread_id; + + if (pthread_create + (&server_thread_id, NULL, process_server_accept_thread, NULL) == -1) + { + printf ("create process_server_accept_thread fail\n"); + return; + } + + printf ("create process_server_accept_thread success\n"); + + if (server_thread_id != 0) + { + printf ("Server Thread join\n"); + pthread_join (server_thread_id, NULL); + } + + while (1) + { + sleep (10); + } + + return; +} diff --git a/app_example/perf-test/multi_tcp_common_app_Cli.c b/app_example/perf-test/multi_tcp_common_app_Cli.c index 5c1fada..e395848 100644 --- a/app_example/perf-test/multi_tcp_common_app_Cli.c +++ b/app_example/perf-test/multi_tcp_common_app_Cli.c @@ -255,7 +255,7 @@ process_client (void) sizeof (g_dest)); if (errconn[i] < 0) { - printf ("client %d Connect Failed %d\n", i, errno); + printf ("client %d Connect Failed %s\n", i, strerror(errno)); _CLOSE (c_socketfd[i]); c_socketfd[i] = -1; continue; diff --git a/app_example/perf-test/multi_tcp_epoll_app_Ser.c b/app_example/perf-test/multi_tcp_epoll_app_Ser.c index b853d68..270fbde 100644 --- a/app_example/perf-test/multi_tcp_epoll_app_Ser.c +++ b/app_example/perf-test/multi_tcp_epoll_app_Ser.c @@ -493,13 +493,15 @@ process_server_accept_thread (void *pArgv) bind (listenFd, (struct sockaddr *) &g_recv, sizeof (struct sockaddr))) { printf ("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf ("INFO:Bind Failed, port %d IP:%s\n", ntohs (g_recv.sin_port), + inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); close (listenFd); //return NULL; exit (-1); } else { - printf ("Info Bind Success, port %d IP:%s\n", ntohs (g_recv.sin_port), + printf ("INFO:Bind Success, port %d IP:%s\n", ntohs (g_recv.sin_port), inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); } diff --git a/app_example/perf-test/multi_tcp_select_app_Ser.c b/app_example/perf-test/multi_tcp_select_app_Ser.c index fb20be9..c1afe62 100644 --- a/app_example/perf-test/multi_tcp_select_app_Ser.c +++ b/app_example/perf-test/multi_tcp_select_app_Ser.c @@ -319,13 +319,15 @@ process_server_accept_thread (void *pArgv) bind (listenFd, (struct sockaddr *) &g_recv, sizeof (struct sockaddr))) { printf ("ERROR:bind failed. fd[%d] errno [%d]\n", listenFd, errno); + printf ("INFO:Bind Failed, port %d IP:%s\n", ntohs (g_recv.sin_port), + inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); close (listenFd); //return NULL; exit (-1); } else { - printf ("Info Bind Success, port %d IP:%s\n", ntohs (g_recv.sin_port), + printf ("INFO:Bind Success, port %d IP:%s\n", ntohs (g_recv.sin_port), inet_ntoa (*((struct in_addr *) &(g_recv.sin_addr.s_addr)))); } diff --git a/doc/Build_DMM.md b/doc/Build_DMM.md index 8eee84a..b74d5fb 100644 --- a/doc/Build_DMM.md +++ b/doc/Build_DMM.md @@ -1,83 +1,109 @@ -# 1. Introduction: +# 1. Introduction + The purpose of this document is to illustrate how to build DMM and run applications on it. Note: Users can easily build DMM by running DMM/scripts/build.sh, which contains following steps. -# 2. Build DPDK: - DPDK needs to be built first for DMM RTE memory dependency. +# 2. Build DPDK -- Steps : + DPDK needs to be built first for DMM RTE memory dependency. - Download dpdk-16.04.tar.xz from DPDK release, you can get it from [http://static.dpdk.org/rel](http://static.dpdk.org/rel) -``` - #wget http://static.dpdk.org/rel/dpdk-16.04.tar.xz - #tar xvf dpdk-16.04.tar.xz - #vi dpdk-16.04/config/common_base //make CONFIG_RTE_BUILD_SHARED_LIB=y, CONFIG_RTE_EXEC_ENV=y, CONFIG_RTE_LIBRTE_EAL=y - #cd dpdk-16.04 - #make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr -j 4 - #cd x86_64-native-linuxapp-gcc - #make //install the dpdk which will generate .so inside lib folder in the path. +- Steps: + + Download dpdk-18.02.tar.xz from DPDK release, you can get it from [http://static.dpdk.org/rel](http://static.dpdk.org/rel) + +```sh + wget http://static.dpdk.org/rel/dpdk-18.02.tar.xz + tar xvf dpdk-18.02.tar.xz + vi dpdk-18.02/config/common_base + //make CONFIG_RTE_BUILD_SHARED_LIB=y, CONFIG_RTE_EXEC_ENV=y, CONFIG_RTE_LIBRTE_EAL=y, CONFIG_RTE_EAL_PMD_PATH="/tmp/dpdk/drivers/" + cd dpdk-18.02 + make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr -j 4 + cd x86_64-native-linuxapp-gcc + make # install the dpdk which will generate .so inside lib folder in the path. + mkdir -p /tmp/dpdk/drivers/ + cp -f /usr/lib/librte_mempool_ring.so /tmp/dpdk/drivers/ ``` Note: - - Environment: - Linux ubuntu 14.04 or some distro which support dpdk-16.04 - -# 3. Build DMM: - -``` - #cd $(DMM_DIR)/thirdparty/glog/glog-0.3.4/ && autoreconf -ivf - #cd $(DMM_DIR)/build - #cmake .. + Under certain kernel versions (e.g. v3.10.0 adopted by CentOS 7.5), compiling DPDK with default + configuration will encounter errors like below. + `error: unknown field 'ndo_change_mtu' specified in initializer .no_change_mtu = kni_net_change_mtu` + This is caused by `kni` compiling, disable `kni` in dpdk config file will figure it out. + Actually, we have tested ubuntu 14.04 ~ 16.04, CentOS 7.2, and they worked well. + +# 3. Build DMM + +```sh + cd $(DMM_DIR)/thirdparty/glog/glog-0.3.4/ && autoreconf -ivf + cd $(DMM_DIR)/build + cmake .. ``` Note: $(DMM_DIR) is the directory where dmm has been cloned. After cmake all the makefiles and dependent .sh files will be copied under build directory. +```sh + make -j 8 ``` - #make -j 8 -``` + Then we can get libnStackAPI.so For centos we can use the command 'make pkg-rpm' to generate the rpm package in release/rpm. -# 4. Env Setting: - -- Hugepage setting: +# 4. Build rsocket +```sh + cd $(DMM_DIR)/build + make dmm_rsocket ``` - #sudo sysctl -w vm.nr_hugepages=1024 + +Note: + Make sure Mellanox OFED has been installed in your computer, or run the following command before compiling + +```sh + cd $DMM_DIR/stacks/rsocket + #Take ubuntu16.04 as an example, the tgz file has the format MLNX_OFED_LINUX-<ver>-<OS label><CPU arch>.tgz + wget http://www.mellanox.com/downloads/ofed/MLNX_OFED-4.4-1.0.0.0/MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64.tgz + tar -zxvf MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64.tgz + cd MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64 + ./mlnxofedinstall --force ``` -Check hugepage info +# 5. Env Setting +- Hugepage setting: +```sh + sudo sysctl -w vm.nr_hugepages=1024 ``` - #cat /proc/meminfo + +Check hugepage info + +```sh + cat /proc/meminfo ``` - Mount hugepages: -``` - #sudo mkdir -p /mnt/nstackhuge/ - #sudo mount -t hugetlbfs -o pagesize=2M none /mnt/nstackhuge/ - #sudo mkdir -p /var/run/ip_module +```sh + sudo mkdir -p /mnt/nstackhuge/ + sudo mount -t hugetlbfs -o pagesize=2M none /mnt/nstackhuge/ + sudo mkdir -p /var/run/ip_module ``` - -# 5. Build and Run the APP +# 6. Biuld and Run the APP - Link the app with the lib **libnStackAPI.so** first, you can refer to app_example/perf-test - Enable detail log of nstack by setting env var -``` - #export LD_LIBRARY_PATH=/dmm/release/lib64 - #export NSTACK_LOG_ON=DBG +```sh + export LD_LIBRARY_PATH=/dmm/release/lib64 + export NSTACK_LOG_ON=DBG ``` - Copy and update the module_config.json, rd_config.json into the same folder of app diff --git a/doc/DMM_DeveloperManual.md b/doc/DMM_DeveloperManual.md index 22fba2b..51e4be5 100644 --- a/doc/DMM_DeveloperManual.md +++ b/doc/DMM_DeveloperManual.md @@ -4,7 +4,7 @@ [**1. Introduction**](#1.-introduction)<br> [**2. DMM Overall Architecture**](#2.-dmm-overall-architecture)<br> -[**3. Core Components**](#3.-Core Components)<br> +[**3. Core Components**](#3.-Core-Components)<br> [**3.1 nSocket**](#3.1-nsocket)<br> [**3.2 Framework**](#3.2-framework)<br> [**3.3 Adapter**](#3.3-adapter)<br> @@ -15,7 +15,7 @@ [**4.2 Plug-in interface**](#4.2-plug-in-interface)<br> [**4.2.1 Interface of Stackx adapter APIs**](#4.2.1-interface-of-stackx-adapter-apis)<br> [**4.2.1.1 nstack\_stack\_register\_fn**](#4.2.1.1-nstack\_stack\_register\_fn)<br> -[**4.2.2 Interface of DMM-adapter APIs**](#4.2.2-interface-of dmm-adapter-apis)<br> +[**4.2.2 Interface of DMM-adapter APIs**](#4.2.2-interface-of-dmm-adapter-apis)<br> [**4.2.2.1 nstack\_adpt\_init**](#4.2.2.1-nstack\_adpt\_init)<br> [**4.2.5 Multithreading**](#4.2.5-multithreading)<br> [**4.2.6 Resource recovery**](#**4.2.6-resource-recovery)<br> @@ -25,7 +25,10 @@ [**5 Release file**](#5-release-file)<br> [**5.1 libs**](#5.1-libs)<br> [**5.2 Posix API of nSocket**](#5.2-posix-api-of-nsocket)<br> - [**6 Log & Debug**](#5.1-libs)<br> +[**6 Log & Debug**](#6-log-debug)<br> +[**7 How to use the incidental apps to test the protocol stack**](#7-how-to-use-the-incidental-apps-to-test-the-protocol-stack)<br> +[**7.1 App introduction**](#7.1-app-introduction)<br> +[**7.2 Test implementation**](#7.2-Test-implementation)<br> **1. Introduction**<br> ============================ @@ -1000,7 +1003,7 @@ stack itself. The standard socket APIs defined by DMM are as follows: **6. Log & Debug**<br> ============================ nStack uses GLOG framework to provide multi level logs. Supported log levels are debug, info, -warning, error and emergency. Logs will be stored at /product/gpaas/log/nStack. To enable log, +warning, error and emergency. Logs will be stored at /var/log/nStack/. To enable log, need to set the environment variables NSTACK\_LOG\_ON ``` export NSTACK_LOG_ON=DBG @@ -1039,7 +1042,7 @@ typedef enum _LOG_MODULE #define NSLOG_OFF 0x00 ``` -App logs stored in nStack_nSocket.log. Stackx logs will be stored in running.log. Other operational +App logs stored in app_$pname_$pid.log. Stackx logs will be stored in running.log. Other operational logs will be stored in operation.log. App logs will be stored in file if following is set to 1. ``` export NSTACK_LOG_FILE_FLAG=1 @@ -1049,3 +1052,68 @@ Also we can memntioned the file name for App log. ``` export NSTACK_APP_LOG_PATH=/path_to_log ``` +**7. How to use the incidental apps to test the protocol stack**<br> +============================ + +**7.1 App introduction** +------------------------- + +After building the DMM, test apps will be generated like below.The following table is the +introduction of the client and server apps. + + +| App name | client | server | use DMM |send/recv | s/r + epoll | s/r + select | +| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | +| vc_common |Y | N |Y | send | N | N | +| kc_common |Y | N | N | send |N | N | +| vs_common |N | Y | Y |recv |N | N | +| ks_common |N | Y | N |recv | N | N | +| vs_epoll |N | Y | Y | recv | Y | N | +| ks_epoll | N | Y | N | recv | Y | N | +| vs_select | N | Y | Y | recv |N | Y | +| ks_select | N | Y | N | recv |N | Y | +Here, the app's name whose first letter is k means that it will run through the kernel. +If the first letter is 'v', it will run through the dmm stack. If the second letter in the +app's name is 's', which means it is the server app. If the second letter is 'c', it means it +is the client app. The 'common' means that the app only implements the function of send or +receive,no select or epoll. The 'select' means the app uses the select() function to +implement the listening service.The 'epoll' means the app uses the epoll() function to +implement the listening service. + +**7.2 Test implementation** +------------------------- +Before testing, we need two servers, one for the client and one for the server.Then run the +following codes. The following takes ks_common and vc_common as examples. +**server** + + ``` +./ks_common -p 20000 -d <server ip> -a 10000 -s <client ip> -l 200 -t 5000000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 10000 -e 10 -x 1 + ``` + +**client** + + ``` +./vc_common -p 20000 -d <client ip> -a 10000 -s <server ip> -l 200 -t 5000000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 10000 -e 10 -x 1 +``` + +The following table is an introduction to some parameters in the code. + + parameter name | Functional description + ------------------- | --------------------- + -p | destination port number + -d | dest severIP + -a | src portid + -s | src clientIP + -l | msg length + -t | max test time + -i | msg interval + -f | client fd number + -r | receive port + -n | connect number(one server vs n client) + -w | wait time + -u | unit print + -e | sleep cut + -x | flag print + + + diff --git a/doc/TestAppUserGuide.md b/doc/TestAppUserGuide.md index 2f21023..ef118d2 100644 --- a/doc/TestAppUserGuide.md +++ b/doc/TestAppUserGuide.md @@ -98,12 +98,15 @@ We need to setup configuration as given below. Usage: -After building the DMM, inside the DMM/release directory below perf-test app will be generated. +After building the DMM, inside the DMM/release/bin directory below perf-test app will be generated. *kc_common, ks_epoll, ks_select, vc_common, vs_epoll, vs_select* The use of ks_epoll,ks_select,vs_epoll and vs_select are the same. +Before executing the app, we should disable ASLR (Address space layout randomization). + echo 0 > /proc/sys/kernel/randomize_va_space + Examples: **With Kernel stack(With direct kernel stack):** diff --git a/pkg/deb/control b/pkg/deb/control new file mode 100644 index 0000000..a373fef --- /dev/null +++ b/pkg/deb/control @@ -0,0 +1,13 @@ +Package: dmm +Version: 18.07 +Section: tuils +Priority: optional +Depends: libc6, libstdc++6, libgcc1 +Suggests: +Architecture: amd64 +Installed-Size: +Maintainer: jorth +Original-Maintainer: +Provides: +Description: DMM is a framework for protocol stack. +Homepage: https://gerrit.fd.io/r/dmm diff --git a/scripts/dmm.spec b/pkg/rpm/dmm.spec index 4869140..c9b8c75 100644 --- a/scripts/dmm.spec +++ b/pkg/rpm/dmm.spec @@ -1,5 +1,5 @@ Name: dmm -Version: 18.04 +Version: 18.07 Release: 1%{?dist} Summary: DMM Project @@ -7,6 +7,9 @@ License: GPL URL: https://gerrit.fd.io/r/dmm Source: %{name}-%{version}.tar.gz +BuildRequires: glibc, libstdc++, libgcc, numactl-libs +BuildRequires: dpdk >= 18.02, dpdk-devel >= 18.02 + %description The DMM framework provides posix socket APIs to the application. A protocol stack could be plugged into the DMM. DMM will choose the most suitable stack @@ -32,6 +35,8 @@ install -c ../BUILD/%{name}-%{version}/release/bin/vc_common %{name}-%{version}- install -c ../BUILD/%{name}-%{version}/release/bin/vs_epoll %{name}-%{version}-%{release}.x86_64/usr/bin install -c ../BUILD/%{name}-%{version}/release/bin/ks_select %{name}-%{version}-%{release}.x86_64/usr/bin install -c ../BUILD/%{name}-%{version}/release/bin/vs_select %{name}-%{version}-%{release}.x86_64/usr/bin +install -c ../BUILD/%{name}-%{version}/release/bin/ks_common %{name}-%{version}-%{release}.x86_64/usr/bin +install -c ../BUILD/%{name}-%{version}/release/bin/vs_common %{name}-%{version}-%{release}.x86_64/usr/bin install -c ../BUILD/%{name}-%{version}/release/lib64/libdmm_api.a %{name}-%{version}-%{release}.x86_64/usr/lib64 install -c ../BUILD/%{name}-%{version}/release/lib64/libnStackAPI.so %{name}-%{version}-%{release}.x86_64/usr/lib64 diff --git a/resources/extras/Vagrantfile b/resources/extras/Vagrantfile index c3107c9..969c91f 100644 --- a/resources/extras/Vagrantfile +++ b/resources/extras/Vagrantfile @@ -8,7 +8,8 @@ Vagrant.configure(2) do |config| if distro == 'centos7' config.vm.box = "puppetlabs/centos-7.2-64-nocm" else - config.vm.box = "fdio-csit/ubuntu-14.04.4_2016-05-25_1.0" + #config.vm.box = "fdio-csit/ubuntu-14.04.4_2016-05-25_1.0" + config.vm.box = "puppetlabs/ubuntu-16.04-64-nocm" end config.vm.box_check_update = false diff --git a/resources/extras/install_prereq.sh b/resources/extras/install_prereq.sh index 29e9cf2..f2413ea 100644 --- a/resources/extras/install_prereq.sh +++ b/resources/extras/install_prereq.sh @@ -1,5 +1,5 @@ #!/bin/bash -x -log_file="/dmm/resources/extras/install_log.txt-`date +'%Y-%m-%d_%H-%M-%S'`" +log_file="/tmp/install_log.txt-`date +'%Y-%m-%d_%H-%M-%S'`" exec 1> >(tee -a "$log_file") 2>&1 if [ "$(uname)" <> "Darwin" ]; then diff --git a/scripts/build.sh b/scripts/build.sh index a4b0278..eaa0f0e 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,3 +1,4 @@ +#!/bin/bash -x ######################################################################### # Copyright (c) 2018 Huawei Technologies Co.,Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,17 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. ######################################################################### -#!/bin/bash -x set -x TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) -log_file="/dmm/scripts/build_log.txt-$TIMESTAMP" +log_file="/tmp/build_log.txt-$TIMESTAMP" exec 1> >(tee -a "$log_file") 2>&1 # Get Command Line arguements if present DMM_DIR=$1 -if [ "x$1" != "x" ]; then +if [ "$1" == "all" ]; then + BUILD_ALL="YES" +fi + +if [ "x$1" != "x" ] && [ "$1" != "all" ]; then DMM_DIR=$1 else DMM_DIR=`dirname $(readlink -f $0)`/../ @@ -34,199 +38,29 @@ echo 2:$2 echo DMM_DIR: $DMM_DIR BUILD_DIR=${DMM_DIR}/build -LIB_PATH=${DMM_DIR}/release/lib64 - -OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') -OS_VERSION_ID=$(grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') -KERNEL_OS=`uname -o` -KERNEL_MACHINE=`uname -m` -KERNEL_RELEASE=`uname -r` -KERNEL_VERSION=`uname -v` - -echo KERNEL_OS: $KERNEL_OS -echo KERNEL_MACHINE: $KERNEL_MACHINE -echo KERNEL_RELEASE: $KERNEL_RELEASE -echo KERNEL_VERSION: $KERNEL_VERSION -echo OS_ID: $OS_ID -echo OS_VERSION_ID: $OS_ID -#DPDK download path -DPDK_DOWNLOAD_PATH=/tmp/dpdk +#print os information +bash -x $DMM_DIR/scripts/print_os_info.sh -#dpdk installation path -DPDK_INSTALL_PATH=/usr +# add inherited proxy for sudo user +LINE='Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"' +FILE=/etc/sudoers +grep -qF -- "$LINE" "$FILE" || sudo echo "$LINE" >> "$FILE" #set and check the environment for Linux -if [ "$OS_ID" == "ubuntu" ]; then - export DEBIAN_FRONTEND=noninteractive - export DEBCONF_NONINTERACTIVE_SEEN=true - - APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" - sudo apt-get update ${APT_OPTS} - sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim -elif [ "$OS_ID" == "debian" ]; then - export DEBIAN_FRONTEND=noninteractive - export DEBCONF_NONINTERACTIVE_SEEN=true - - APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" - sudo apt-get update ${APT_OPTS} - sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim -elif [ "$OS_ID" == "centos" ]; then - sudo yum install -y git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel -elif [ "$OS_ID" == "opensuse" ]; then - sudo yum install -y git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel -fi - - -#DPDK will be having dependancy on linux headers -if [ "$OS_ID" == "ubuntu" ]; then - sudo apt-get -y install git build-essential linux-headers-`uname -r` -elif [ "$OS_ID" == "debian" ]; then - sudo apt-get -y install git build-essential linux-headers-`uname -r` -elif [ "$OS_ID" == "centos" ]; then - sudo yum groupinstall -y "Development Tools" - sudo yum install -y kernel-headers -elif [ "$OS_ID" == "opensuse" ]; then - sudo yum groupinstall -y "Development Tools" - sudo yum install -y kernel-headers -fi - +bash -x $DMM_DIR/scripts/build_dmm_dep.sh || exit 1 #===========build DPDK================ - -if [ "$OS_ID" == "centos" ]; then - bash -x $DMM_DIR/scripts/build_dpdk.sh -else - - if [ ! -d /usr/include/dpdk ] || [ ! -d /usr/share/dpdk ] || [ ! -d /usr/lib/modules/4.4.0-31-generic/extra/dpdk ]; then - mkdir -p $DPDK_DOWNLOAD_PATH - - DPDK_FOLDER=$DPDK_DOWNLOAD_PATH/dpdk-16.04-$TIMESTAMP - cd $DPDK_DOWNLOAD_PATH - mkdir $DPDK_FOLDER - wget -N https://fast.dpdk.org/rel/dpdk-16.04.tar.xz --no-check-certificate - tar xvf dpdk-16.04.tar.xz -C $DPDK_FOLDER - cd $DPDK_FOLDER/dpdk-16.04 - - sed -i 's!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1' config/common_base - sed -i 's!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1' config/common_base - sed -i 's!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1' config/common_base - - sudo make install T=x86_64-native-linuxapp-gcc DESTDIR=${DPDK_INSTALL_PATH} -j 4 - - fi -fi +bash -x $DMM_DIR/scripts/build_dpdk.sh || exit 1 #===========build DMM================= -echo "DMM build started....." - -cd $DMM_DIR/thirdparty/glog/glog-0.3.4/ && autoreconf -ivf -cd $BUILD_DIR -rm -rf * -cmake .. -make -j 8 - -if [ $? -eq 0 ] -then - echo "DMM build is SUCCESS" -else - echo "DMM build has FAILED" - exit 1 -fi - -if [ "$OS_ID" == "centos" ]; then - make pkg-rpm -fi - -#===========check running env ================= -sudo sysctl -w vm.nr_hugepages=1024 -HUGEPAGES=`sysctl -n vm.nr_hugepages` -if [ $HUGEPAGES != 1024 ]; then - echo "ERROR: Unable to get 1024 hugepages, only got $HUGEPAGES. Cannot finish." - exit -fi -hugepageTotal=$(cat /proc/meminfo | grep -c "HugePages_Total: 0") -if [ $hugepageTotal -ne 0 ]; then - echo "HugePages_Total is zero" - exit -fi - -hugepageFree=$(cat /proc/meminfo | grep -c "HugePages_Free: 0") -if [ $hugepageFree -ne 0 ]; then - echo "HugePages_Free is zero" - exit -fi - -hugepageSize=$(cat /proc/meminfo | grep -c "Hugepagesize: 0 kB") -if [ $hugepageSize -ne 0 ]; then - echo "Hugepagesize is zero" - exit +bash -x $DMM_DIR/scripts/compile_dmm.sh || exit 1 + +if [ "${BUILD_ALL}" == "YES" ]; then + #===========build LWIP================ + bash -x $DMM_DIR/stacks/lwip_stack/vagrant/build.sh "from-base-build" || exit 1 + #============build rsocket============================ + bash -x $DMM_DIR/scripts/build_rsocket.sh || exit 1 + #=======other new stacks build can be called from here + echo "SUCCESSFULLY built all the stacks" fi - - -sudo mkdir /mnt/nstackhuge -p -sudo mount -t hugetlbfs -o pagesize=2M none /mnt/nstackhuge/ -sudo mkdir -p /var/run/ip_module/ - -export LD_LIBRARY_PATH=$LIB_PATH -export NSTACK_LOG_ON=DBG - -############### Preapre APP test directory -echo -e "\e[41m Preapring APP test directory.....\e[0m" - -mkdir -p $DMM_DIR/config/app_test -cd $DMM_DIR/config/app_test - -if [ "$OS_ID" == "ubuntu" ]; then - ifaddress1=$(ifconfig eth1 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}') - echo $ifaddress1 - ifaddress2=$(ifconfig eth2 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}') - echo $ifaddress2 -elif [ "$OS_ID" == "centos" ]; then - ifaddress1=$(ifconfig enp0s8 | grep 'inet' | cut -d: -f2 | awk '{print $2}') - echo $ifaddress1 - ifaddress2=$(ifconfig enp0s9 | grep 'inet' | cut -d: -f2 | awk '{print $2}') - echo $ifaddress2 -fi - -echo '{ - "default_stack_name": "kernel", - "module_list": [ - { - "stack_name": "kernel", - "function_name": "kernel_stack_register", - "libname": "./", - "loadtype": "static", - "deploytype": "1", - "maxfd": "1024", - "minfd": "0", - "priorty": "1", - "stackid": "0", - }, - ] -}' | tee module_config.json - -echo '{ - "ip_route": [ - { - "subnet": "'$ifaddress1'/24", - "type": "nstack-kernel", - }, - { - "subnet": "'$ifaddress2'/24", - "type": "nstack-kernel", - }, - ], - "prot_route": [ - { - "proto_type": "1", - "type": "nstack-kernel", - }, - { - "proto_type": "2", - "type": "nstack-kernel", - } - ], -}' | tee rd_config.json - -echo "DMM build finished....." diff --git a/scripts/build_dmm_dep.sh b/scripts/build_dmm_dep.sh new file mode 100755 index 0000000..ecbb686 --- /dev/null +++ b/scripts/build_dmm_dep.sh @@ -0,0 +1,35 @@ +#!/bin/bash -x + +set -x + +# add inherited proxy for sudo user +LINE='Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"' +FILE=/etc/sudoers +grep -qF -- "$LINE" "$FILE" || sudo echo "$LINE" >> "$FILE" + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') + +#set and check the environment for Linux +if [ "$OS_ID" == "ubuntu" ]; then + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + + APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" + sudo apt-get update ${APT_OPTS} + sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim pkg-config tcl libnl-route-3-200 flex graphviz tk debhelper dpatch gfortran ethtool libgfortran3 bison dkms quilt chrpath swig python-libxml2 unzip +elif [ "$OS_ID" == "debian" ]; then + echo "not tested for debian and exit" + exit 1 + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + + APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" + sudo apt-get update ${APT_OPTS} + sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim +elif [ "$OS_ID" == "centos" ]; then + sudo yum install -y deltarpm git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel libiverbs tk tcl tcsh redhat-lsb-core +elif [ "$OS_ID" == "opensuse" ]; then + echo "not tested for opensuse and exit" + exit 1 + sudo yum install -y git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel +fi diff --git a/scripts/build_dpdk.sh b/scripts/build_dpdk.sh index 80a78b6..f631b27 100755 --- a/scripts/build_dpdk.sh +++ b/scripts/build_dpdk.sh @@ -1,85 +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. -######################################################################### #!/bin/bash -x -echo "check whether dpdk installed" -cur_directory=${PWD} -check_dpdk=$(rpm -qa | grep dpdk) -if [ -z "$check_dpdk" ]; then - echo "system will install the dpdk" -else - echo "system has installed the dpdk" - echo "$check_dpdk" - exit 0 -fi - -cd ~ -mkdir -p rpmbuild/SOURCES - -cd ~/rpmbuild/SOURCES - -if [ ! -s dpdk-16.04.tar.gz ]; then -wget http://dpdk.org/browse/dpdk/snapshot/dpdk-16.04.tar.gz +set -x + +SCRIPT_DIR=`dirname $(readlink -f $0)` + +#DPDK download path +#if any change kindly update DPDK_DOWNLOAD_PATH in DMM/stacks/lwip_stack/vagrant/start_nStackMain.sh +DPDK_DOWNLOAD_PATH=/tmp/dpdk + +#dpdk installation path +DPDK_INSTALL_PATH=/usr + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +echo OS_ID: $OS_ID + +#DPDK will be having dependancy on linux headers +if [ "$OS_ID" == "ubuntu" ]; then + sudo apt-get -y install git build-essential linux-headers-`uname -r` + sudo apt-get -y install libnuma-dev +elif [ "$OS_ID" == "debian" ]; then + sudo apt-get -y install git build-essential linux-headers-`uname -r` +elif [ "$OS_ID" == "centos" ]; then + sudo yum groupinstall -y "Development Tools" + sudo yum install -y kernel-headers + sudo yum install -y numactl-devel +elif [ "$OS_ID" == "opensuse" ]; then + sudo yum groupinstall -y "Development Tools" + sudo yum install -y kernel-headers fi -tar xzvf dpdk-16.04.tar.gz -cp dpdk-16.04/pkg/dpdk.spec ~/rpmbuild/SOURCES/ - -echo "modify the spec" +#===========build DPDK================ -#get rid of the dependence of xen-devel -sed -i '48d' dpdk.spec -sed -i '47a BuildRequires: kernel-devel, kernel-headers, libpcap-devel' dpdk.spec - -#get rid of the dependence of texlive-collection -sed -i '/BuildRequires: texlive-collection/s/^/#&/' dpdk.spec - -#delete something about xen -sed -i '/LIBRTE_PMD_XENVIRT/s/^/#&/' dpdk.spec -sed -i '/LIBRTE_XEN_DOM0/s/^/#&/' dpdk.spec +if [ "$OS_ID" == "centos" ]; then + bash -x $SCRIPT_DIR/build_dpdk1802.sh || exit 1 +else -#delete something of generating doc -sed -i '/%{target} doc/s/^/#&/' dpdk.spec -sed -i '94d' dpdk.spec -sed -i '93a datadir=%{_datadir}/dpdk' dpdk.spec -sed -i '94a # datadir=%{_datadir}/dpdk docdir=%{_docdir}/dpdk' dpdk.spec -sed -i '/%files doc/s/^/#&/' dpdk.spec -sed -i '/%doc %{_docdir}/s/^/#&/' dpdk.spec + if [ ! -d /usr/include/dpdk ] || [ ! -d /usr/share/dpdk ] || [ ! -d /usr/lib/modules/4.4.0-31-generic/extra/dpdk ]; then + mkdir -p $DPDK_DOWNLOAD_PATH -sed -i '76a sed -i 's!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1' config/common_base' dpdk.spec -sed -i '77a sed -i 's!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1' config/common_base' dpdk.spec -sed -i '78a sed -i 's!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1' config/common_base' dpdk.spec + cd $DPDK_DOWNLOAD_PATH + wget -N https://fast.dpdk.org/rel/dpdk-18.02.tar.xz --no-check-certificate + tar xvf dpdk-18.02.tar.xz + cd dpdk-18.02 -echo "build the dependence" -#sudo yum-builddep -y dpdk.spec + sed -i 's!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1' config/common_base + sed -i 's!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1' config/common_base + sed -i 's!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1' config/common_base + sed -i 's!CONFIG_RTE_EAL_PMD_PATH=.*!CONFIG_RTE_EAL_PMD_PATH="/tmp/dpdk/drivers/"!1' config/common_base -sudo yum install -y libpcap-devel python-sphinx inkscape + sudo make install T=x86_64-native-linuxapp-gcc DESTDIR=${DPDK_INSTALL_PATH} -j 4 + if [ $? -eq 0 ]; then + echo "DPDK build is SUCCESS" + else + echo "DPDK build has FAILED" + exit 1 + fi -echo "generate the rpm package" -rpmbuild -ba dpdk.spec --define "_sourcedir ${PWD}" -if [ $? -eq 0 ]; then - echo "rpm build success" -else - echo "rpm build error" - exit + mkdir -p /tmp/dpdk/drivers/ + cp -f /usr/lib/librte_mempool_ring.so /tmp/dpdk/drivers/ + fi fi - -echo "install the rpm" -cd ../RPMS/x86_64/ -sudo rpm -ivh dpdk-16.04-1.x86_64.rpm -sudo rpm -ivh dpdk-devel-16.04-1.x86_64.rpm -cd ${cur_directory} diff --git a/scripts/build_dpdk1802.sh b/scripts/build_dpdk1802.sh new file mode 100755 index 0000000..74d4860 --- /dev/null +++ b/scripts/build_dpdk1802.sh @@ -0,0 +1,94 @@ +#!/bin/bash -x +######################################################################### +# +# 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. +######################################################################### + +echo "check whether dpdk installed" +cur_directory=${PWD} +check_dpdk=$(rpm -qa | grep dpdk-devel) +if [ -z "$check_dpdk" ]; then + echo "system will install the dpdk" +else + echo "system has installed the dpdk" + echo "$check_dpdk" + exit 0 +fi + +cd ~ +mkdir -p rpmbuild/SOURCES + +cd ~/rpmbuild/SOURCES + +if [ ! -s dpdk-18.02.tar.gz ]; then +wget http://dpdk.org/browse/dpdk/snapshot/dpdk-18.02.tar.gz +fi + +tar xzvf dpdk-18.02.tar.gz +cp dpdk-18.02/pkg/dpdk.spec ~/rpmbuild/SOURCES/ + +echo "modify the spec" + +#get rid of the dependence of texlive-collection +sed -i '/BuildRequires: texlive-collection/s/^/#&/' dpdk.spec + +#delete something of generating doc +sed -i '/%{target} doc/s/^/#&/' dpdk.spec +sed -i '98d' dpdk.spec +sed -i '97a datadir=%{_datadir}/dpdk' dpdk.spec +sed -i '98a # datadir=%{_datadir}/dpdk docdir=%{_docdir}/dpdk' dpdk.spec +sed -i '/%files doc/s/^/#&/' dpdk.spec +sed -i '/%doc %{_docdir}/s/^/#&/' dpdk.spec + +sed -i '82a sed -i '\''s!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1'\'' config/common_base' dpdk.spec +sed -i '83a sed -i '\''s!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1'\'' config/common_base' dpdk.spec +sed -i '84a sed -i '\''s!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1'\'' config/common_base' dpdk.spec +sed -i '85a sed -i '\''s!CONFIG_RTE_EAL_PMD_PATH=.*!CONFIG_RTE_EAL_PMD_PATH="/tmp/dpdk/drivers/"!1'\'' config/common_base' dpdk.spec + +#disable KNI mode by default +sed -i '93a sed -ri '\''s!CONFIG_RTE_LIBRARY_KNI=.*!CONFIG_RTE_LIBRARY_KNI=n!1'\'' %{target}/.config' dpdk.spec +sed -i '94a sed -ri '\''s!CONFIG_RTE_LIBRARY_PMD_KNI=.*!CONFIG_RTE_LIBRARY_PMD_KNI=n!1'\'' %{target}/.config' dpdk.spec +sed -i '95a sed -ri '\''s!CONFIG_RTE_KNI_KMOD=.*!CONFIG_RTE_KNI_KMOD=n!1'\'' %{target}/.config' dpdk.spec +sed -i '96a sed -ri '\''s!CONFIG_RTE_KNI_PREEMPT_DEFAULT=.*!CONFIG_RTE_KNI_PREEMPT_DEFAULT=n!1'\'' %{target}/.config' dpdk.spec + +#Add debug info +sed -i '98s!$! EXTRA_CFLAGS="-O0 -g" !' dpdk.spec + +#Not strip the debug info when generate the rpm +sed -i '43 i%global __os_install_post %{nil}\n%define debug_package %{nil}' dpdk.spec + +echo "build the dependence" +#sudo yum-builddep -y dpdk.spec +sudo yum install -y libpcap-devel python-sphinx inkscape kernel-devel-`uname -r` doxygen libnuma-devel kernel-`uname -r` + + +echo "generate the rpm package" +rpmbuild -ba dpdk.spec --define "_sourcedir ${PWD}" +if [ $? -eq 0 ]; then + echo "dpdk rpm build success" +else + echo "dpdk rpm build error" + exit 1 +fi + +echo "install the rpm" +cd ../RPMS/x86_64/ +sudo rpm -ivh dpdk-18.02-1.x86_64.rpm || exit 1 +sudo rpm -ivh dpdk-devel-18.02-1.x86_64.rpm || exit 1 + +mkdir -p /tmp/dpdk/drivers/ +cp -f /usr/lib64/librte_mempool_ring.so /tmp/dpdk/drivers/ +cp -f /usr/share/dpdk/usertools/dpdk-devbind.py /usr/sbin/ + +cd ${cur_directory} diff --git a/scripts/build_dpdk1805.sh b/scripts/build_dpdk1805.sh new file mode 100755 index 0000000..2727877 --- /dev/null +++ b/scripts/build_dpdk1805.sh @@ -0,0 +1,82 @@ +#!/bin/bash -x +######################################################################### +# +# 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. +######################################################################### + +echo "check whether dpdk installed" +cur_directory=${PWD} +check_dpdk=$(rpm -qa | grep dpdk) +if [ -z "$check_dpdk" ]; then + echo "system will install the dpdk" +else + echo "system has installed the dpdk" + echo "$check_dpdk" + exit 0 +fi + +cd ~ +mkdir -p rpmbuild/SOURCES + +cd ~/rpmbuild/SOURCES + +if [ ! -s dpdk-18.05.tar.gz ]; then +wget http://dpdk.org/browse/dpdk/snapshot/dpdk-18.05.tar.gz +fi + +tar xzvf dpdk-18.05.tar.gz +cp dpdk-18.05/pkg/dpdk.spec ~/rpmbuild/SOURCES/ + +echo "modify the spec" + +#get rid of the dependence of texlive-collection +sed -i '/BuildRequires: texlive-collection/s/^/#&/' dpdk.spec + +#delete something of generating doc +sed -i '/%{target} doc/s/^/#&/' dpdk.spec +sed -i '70d' dpdk.spec +sed -i '69a datadir=%{_datadir}/dpdk' dpdk.spec +sed -i '70a # datadir=%{_datadir}/dpdk docdir=%{_docdir}/dpdk' dpdk.spec +sed -i '/%files doc/s/^/#&/' dpdk.spec +sed -i '/%doc %{_docdir}/s/^/#&/' dpdk.spec + +sed -i '54a sed -i '\''s!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1'\'' config/common_base' dpdk.spec +sed -i '55a sed -i '\''s!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1'\'' config/common_base' dpdk.spec +sed -i '56a sed -i '\''s!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1'\'' config/common_base' dpdk.spec +sed -i '57a sed -i '\''s!CONFIG_RTE_EAL_PMD_PATH=.*!CONFIG_RTE_EAL_PMD_PATH="/tmp/dpdk/drivers/"!1'\'' config/common_base' dpdk.spec +sed -i '58a sed -i '\''s!CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=.*!CONFIG_RTE_LIBRTE_DPAA2_USE_PHYS_IOVA=n!1'\'' config/common_base' dpdk.spec + +echo "build the dependence" +#sudo yum-builddep -y dpdk.spec +sudo yum install -y libpcap-devel python-sphinx inkscape kernel-devel-`uname -r` doxygen libnuma-devel kernel-`uname -r` + + +echo "generate the rpm package" +rpmbuild -ba dpdk.spec --define "_sourcedir ${PWD}" +if [ $? -eq 0 ]; then + echo "dpdk rpm build success" +else + echo "dpdk rpm build error" + exit 1 +fi + +echo "install the rpm" +cd ../RPMS/x86_64/ +sudo rpm -ivh dpdk-18.05-1.x86_64.rpm || exit 1 +sudo rpm -ivh dpdk-devel-18.05-1.x86_64.rpm || exit 1 + +mkdir -p /tmp/dpdk/drivers/ +cp -f /usr/lib64/librte_mempool_ring.so /tmp/dpdk/drivers/ + +cd ${cur_directory} diff --git a/scripts/build_rsocket.sh b/scripts/build_rsocket.sh new file mode 100755 index 0000000..ef31c88 --- /dev/null +++ b/scripts/build_rsocket.sh @@ -0,0 +1,34 @@ +#!/bin/bash -x + +set -x + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') + +DMM_DIR=`dirname $(readlink -f $0)`/../ +BUILD_DIR=${DMM_DIR}/build + +############### build rsocket +echo "rsocket build start" +cd $DMM_DIR/stacks/rsocket +if [ "$OS_ID" == "ubuntu" ]; then + wget http://www.mellanox.com/downloads/ofed/MLNX_OFED-4.4-1.0.0.0/MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64.tgz + tar -zxvf MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64.tgz + cd MLNX_OFED_LINUX-4.4-1.0.0.0-ubuntu16.04-x86_64 +elif [ "$OS_ID" == "centos" ]; then + CENT_VERSION=`grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release` + wget http://www.mellanox.com/downloads/ofed/MLNX_OFED-4.4-1.0.0.0/MLNX_OFED_LINUX-4.4-1.0.0.0-rhel${CENT_VERSION}-x86_64.tgz + tar -zxvf MLNX_OFED_LINUX-4.4-1.0.0.0-rhel${CENT_VERSION}-x86_64.tgz + cd MLNX_OFED_LINUX-4.4-1.0.0.0-rhel${CENT_VERSION}-x86_64 +fi + +sudo ./mlnxofedinstall --force || exit 1 + +cd $BUILD_DIR +make dmm_rsocket +if [ $? -eq 0 ]; then + echo "rsocket build has SUCCESS" +else + echo "rsocket build has FAILED" + exit 1 +fi +echo "rsocket build finished"
\ No newline at end of file diff --git a/scripts/build_vpp.sh b/scripts/build_vpp.sh new file mode 100755 index 0000000..555aa9f --- /dev/null +++ b/scripts/build_vpp.sh @@ -0,0 +1,29 @@ +#!/bin/bash +######################################################################### +# +# 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 -x + +cd ../stacks/vpp + +git clone https://gerrit.fd.io/r/vpp + +cd vpp +git checkout origin/stable/1804 -b vpp_1804_br +cp ../adapt/* src/vcl/ +git am ../patch/* +make UNATTENDED=yes install-dep +make build diff --git a/scripts/check_hugepage.sh b/scripts/check_hugepage.sh new file mode 100755 index 0000000..bde11a9 --- /dev/null +++ b/scripts/check_hugepage.sh @@ -0,0 +1,41 @@ +#!/bin/bash -x + +set -x + +hugepagesize=$(cat /proc/meminfo | grep Hugepagesize | awk -F " " {'print$2'}) +if [ "$hugepagesize" == "2048" ]; then + pages=1536 +elif [ "$hugepagesize" == "1048576" ]; then + pages=3 +fi +sudo sysctl -w vm.nr_hugepages=$pages +HUGEPAGES=`sysctl -n vm.nr_hugepages` +if [ $HUGEPAGES != $pages ]; then + echo "ERROR: Unable to get $pages hugepages, only got $HUGEPAGES. Cannot finish." + exit 1 +fi + +hugepageTotal=$(cat /proc/meminfo | grep -c "HugePages_Total: 0") +if [ $hugepageTotal -ne 0 ]; then + echo "HugePages_Total is zero" + exit 1 +fi + +hugepageFree=$(cat /proc/meminfo | grep -c "HugePages_Free: 0") +if [ $hugepageFree -ne 0 ]; then + echo "HugePages_Free is zero" + exit 1 +fi + +hugepageSize=$(cat /proc/meminfo | grep -c "Hugepagesize: 0 kB") +if [ $hugepageSize -ne 0 ]; then + echo "Hugepagesize is zero" + exit 1 +fi + +sudo mkdir /mnt/nstackhuge -p +if [ "$hugepagesize" == "2048" ]; then + sudo mount -t hugetlbfs -o pagesize=2M none /mnt/nstackhuge/ +elif [ "$hugepagesize" == "1048576" ]; then + sudo mount -t hugetlbfs -o pagesize=1G none /mnt/nstackhuge/ +fi diff --git a/scripts/checkstyle.sh b/scripts/checkstyle.sh index 55f4f73..4f3c0a0 100644..100755 --- a/scripts/checkstyle.sh +++ b/scripts/checkstyle.sh @@ -17,13 +17,14 @@ #!/bin/bash CURR_DIR=`dirname $0` -DMM_DIR=${CURR_DIR}/.. +DMM_DIR=${CURR_DIR}/../ EXIT_CODE=0 FIX="0" FULL="0" CHECKSTYLED_FILES="" UNCHECKSTYLED_FILES="" UNCHECK_LIST="" +DOS2UNIX="0" SHOW_HELP="1" FIX="0" @@ -39,6 +40,7 @@ key="$1" case $key in -f|--fixstyle) FIX="1" + DOS2UNIX="1" SHOW_HELP="0" shift # past argument ;; @@ -106,9 +108,12 @@ HAVE_CLANG_FORMAT=0 #fi for i in ${FILELIST}; do - if [ -f ${i} ] && ( [ ${i: -2} == ".c" ] || [ ${i: -2} == ".h" ] ) && [[ ${i} != *"thirdparty"* ]] && [[ ${i} != *"testcode"* ]] ; then + if [ -f ${i} ] && ( [ ${i: -2} == ".c" ] || [ ${i: -2} == ".h" ] ) && [[ ${i} != *"glog"* ]] && [[ ${i} != *"lwip_src/lwip"* ]] && [[ ${i} != *"lwip_helper_files"* ]]; then #grep -q "fd.io coding-style-patch-verification: ON" ${i} if [ $? == 0 ]; then + if [ ${DOS2UNIX} == 1 ]; then + dos2unix ${i} + fi EXTENSION=`basename ${i} | sed 's/^\w\+.//'` case ${EXTENSION} in hpp|cpp|cc|hh) @@ -173,8 +178,8 @@ done if [ ${FULL} == "1" ] && [ ${FULL} == "1" ] ; then for i in ${FILELIST}; do - #egrep -qlr $'\r'\$ ${i} - if [ $? == 0 ] && [[ ${i} != *"thirdparty"* ]] && [[ ${i} != *"testcode"* ]] && [[ ${i} != *"resources"* ]] && [[ ${i} != *"build"* ]] && ( [ ${i: -2} == ".c" ] || [ ${i: -2} == ".h" ] || [ ${i: -3} == ".sh" ] ); then + egrep -qlr $'\r'\$ ${i} + if [ $? == 0 ] && [[ ${i} != *"glog"* ]] && [[ ${i} != *"lwip_src/lwip"* ]] && [[ ${i} != *"lwip_helper_files"* ]] && [[ ${i} != *"resources"* ]] && [[ ${i} != *"build"* ]] && ( [ ${i: -2} == ".c" ] || [ ${i: -2} == ".h" ] || [ ${i: -3} == ".sh" ] && [ ${i} != "checkstyle.sh" ]); then sed -e 's/\r//g' ${i} > ${i}.tmp echo "dos2unix conoversion happened for ${i}" mv ${i}.tmp ${i} diff --git a/scripts/compile_dmm.sh b/scripts/compile_dmm.sh new file mode 100755 index 0000000..b4bc455 --- /dev/null +++ b/scripts/compile_dmm.sh @@ -0,0 +1,29 @@ +#!/bin/bash -x + +set -x + +BUILD_DIR=`dirname $(readlink -f $0)`/../build + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') + +echo "DMM build started....." + +cd $BUILD_DIR +rm -rf * +cmake .. +make -j 8 + +if [ $? -eq 0 ]; then + echo "DMM build is SUCCESS" +else + echo "DMM build has FAILED" + exit 1 +fi + +if [ "$OS_ID" == "centos" ]; then + make pkg-rpm +elif [ "$OS_ID" == "ubuntu" ]; then + make pkg-deb +fi + +echo "DMM build has FINISHED" diff --git a/scripts/generate_dmm_deb.sh b/scripts/generate_dmm_deb.sh new file mode 100755 index 0000000..5168d07 --- /dev/null +++ b/scripts/generate_dmm_deb.sh @@ -0,0 +1,42 @@ +######################################################################### +# +# 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. +######################################################################### +#!/bin/sh + +cur_directory=${PWD} + +mkdir -p /tmp/mkdeb +mkdir -p /tmp/mkdeb/DEBIAN +mkdir -p /tmp/mkdeb/usr/bin +mkdir -p /tmp/mkdeb/usr/lib + +cd ../ +git archive --format=tar.gz -o /tmp/dmm.tar.gz --prefix=dmm/ HEAD + +cd /tmp/ +tar xzvf dmm.tar.gz +cd dmm/build +cmake .. +make -j 8 + +cd ../ +cp -f release/bin/* /tmp/mkdeb/usr/bin +cp -f release/lib64/* /tmp/mkdeb/usr/lib +cp -f pkg/deb/control /tmp/mkdeb/DEBIAN/ + +cd /tmp/ +dpkg-deb -b mkdeb/ ${cur_directory}/../release/deb/dmm.deb + +cd ${cur_directory} diff --git a/scripts/generate_dmm_rpm.sh b/scripts/generate_dmm_rpm.sh index bce4580..76d65a1 100755 --- a/scripts/generate_dmm_rpm.sh +++ b/scripts/generate_dmm_rpm.sh @@ -17,17 +17,17 @@ cur_directory=${PWD} name="dmm" -version="18.04" +version="18.07" mkdir -p ~/rpmbuild/SOURCES cd ../ -git archive --format=tar.gz -o ~/rpmbuild/SOURCES/${name}-${version}.tar.gz --prefix=${name}-${version}/ master +git archive --format=tar.gz -o ~/rpmbuild/SOURCES/${name}-${version}.tar.gz --prefix=${name}-${version}/ HEAD cd ~/rpmbuild/SOURCES tar xzvf ${name}-${version}.tar.gz -cp ${name}-${version}/scripts/dmm.spec ~/rpmbuild/SOURCES +cp ${name}-${version}/pkg/rpm/dmm.spec ~/rpmbuild/SOURCES echo "generate the rpm package" #QA_RPATHS=$[ 0x0002 ] is to shield the warning about rpath when generating the rpm package diff --git a/scripts/git/commit-msg-hook.py b/scripts/git/commit-msg-hook.py new file mode 100755 index 0000000..9c397ed --- /dev/null +++ b/scripts/git/commit-msg-hook.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys + + +# format: \033[type;fg;bgm +# +# fg bg color +# ------------------------------------------- +# 30 40 black +# 31 41 red +# 32 42 green +# 33 43 yellow +# 34 44 blue +# 35 45 purple +# 36 46 cyan +# 37 47 white +# +# type +# ------------------------- +# 0 normal +# 1 bold +# 4 underline +# 5 blink +# 7 invert +# 8 hide +# +# examples: +# \033[1;31;40m <!--1-bold 31-red fg 40-black bg--> +# \033[0m <!--back to normal--> + + +STYLE = { + 'fore': + { + 'black' : 30, + 'red' : 31, + 'green' : 32, + 'yellow' : 33, + 'blue' : 34, + 'purple' : 35, + 'cyan' : 36, + 'white' : 37, + }, + + 'back': + { + 'black' : 40, + 'red' : 41, + 'green' : 42, + 'yellow' : 43, + 'blue' : 44, + 'purple' : 45, + 'cyan' : 46, + 'white' : 47, + }, + + 'mode': + { + 'normal' : 0, + 'bold' : 1, + 'underline' : 4, + 'blink' : 5, + 'invert' : 7, + 'hide' : 8, + }, + + 'default': + { + 'end': 0, + }, +} + + +def style(string, mode='', fore='', back=''): + + mode = '%s' % STYLE['mode'][mode] if STYLE['mode'].has_key(mode) else '' + + fore = '%s' % STYLE['fore'][fore] if STYLE['fore'].has_key(fore) else '' + + back = '%s' % STYLE['back'][back] if STYLE['back'].has_key(back) else '' + + style = ';'.join([s for s in [mode, fore, back] if s]) + + style = '\033[%sm' % style if style else '' + + end = '\033[%sm' % STYLE['default']['end'] if style else '' + + return '%s%s%s' % (style, string, end) + + +def check_subject(subject_line): + types = ['Feat', 'Fix', 'Refactor', 'Style', 'Docs', 'Test', 'Chore'] + + if subject_line.startswith(' '): + print style('Error: Subject line starts with whitespace\n', fore='red') + return 1 + + if len(subject_line) > 50: + print style('Error: Subject line should be limited to 50 chars\n', fore='red') + return 1 + + ll = subject_line.split(':') + if len(ll) < 2: + print style('Error: Subject line should have a type\n', fore='red') + return 1 + + type = ll[0] + if type not in types: + print style('Error: Subject line starts with unknown type\n', fore='red') + return 1 + + return 0 + + +contents = [] +ret = 0 +subject = True + +with open(sys.argv[1], 'r') as commit_msg: + contents = commit_msg.readlines() + +for line in contents: + dup = line.lstrip() + if dup.startswith('#') or dup.startswith("Change-Id") or dup.startswith("Signed-of-by"): + continue + if subject is True: + ret = check_subject(line) + subject = False + else: + if len(line) > 72: + print style('Error: Body line should be limited to 72 chars\n', fore='red') + ret = 1 + +exit(ret) diff --git a/scripts/git/commit-msg-template b/scripts/git/commit-msg-template new file mode 100644 index 0000000..6d72af1 --- /dev/null +++ b/scripts/git/commit-msg-template @@ -0,0 +1,28 @@ +# <type>: (if applied, this commit will...) <subject> (Max 50 chars) +# |<---- Using a Maximum Of 50 Characters ---->| + + +# Explain why this change is being made +# |<---- Try To Limit Each Line to a Maximum Of 72 Characters ---->| + +# Provide links or keys to any relevant tickets, articles or other resources +# Example: Github issue #23 + +# --- COMMIT END --- +# Type can be +# Feat (new feature) +# Fix (bug fix) +# Refactor (refactoring production code) +# Style (formatting, missing semi colons, etc; no code change) +# Docs (changes to documentation) +# Test (adding or refactoring tests; no production code change) +# Chore (updating grunt tasks etc; no production code change) +# -------------------- +# Remember to +# Choose one of types above in subject line +# Use the imperative mood in the subject line +# Do not end the subject line with a period +# Separate subject from body with a blank line +# Use the body to explain what and why vs. how +# Can use multiple lines with "-" for bullet points in body +# -------------------- diff --git a/scripts/git/pre-commit b/scripts/git/pre-commit new file mode 100755 index 0000000..58cd14f --- /dev/null +++ b/scripts/git/pre-commit @@ -0,0 +1,14 @@ +#!/bin/bash + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +# autoremove trailing whitespace +for file in `git diff-index --check --cached $against -- | sed '/^[-+]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do + sed -i 's/[ \t]*$//g' $file +done diff --git a/scripts/install_prereq.sh b/scripts/install_prereq.sh new file mode 100755 index 0000000..ae8d442 --- /dev/null +++ b/scripts/install_prereq.sh @@ -0,0 +1,39 @@ +#!/bin/bash -x +log_file="/DMM/thirdpary/stackpool/vagrant/pre_install_log.txt-`date +'%Y-%m-%d_%H-%M-%S'`" +exec 1> >(tee -a "$log_file") 2>&1 + +if [ "$(uname)" <> "Darwin" ]; then + OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') + OS_VERSION_ID=$(grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +fi + +if [ "$OS_ID" == "ubuntu" ]; then + # Standard update + upgrade dance + cat << EOF >> /etc/apt/sources.list + deb http://in.archive.ubuntu.com/ubuntu/ trusty main restricted + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty main restricted + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates main restricted + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates main restricted + deb http://in.archive.ubuntu.com/ubuntu/ trusty universe + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty universe + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates universe + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates universe + deb http://in.archive.ubuntu.com/ubuntu/ trusty multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty multiverse + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates multiverse + deb http://in.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse + deb http://security.ubuntu.com/ubuntu trusty-security main restricted + deb-src http://security.ubuntu.com/ubuntu trusty-security main restricted + deb http://security.ubuntu.com/ubuntu trusty-security universe + deb-src http://security.ubuntu.com/ubuntu trusty-security universe + deb http://security.ubuntu.com/ubuntu trusty-security multiverse + deb-src http://security.ubuntu.com/ubuntu trusty-security multiverse + deb http://extras.ubuntu.com/ubuntu trusty main + deb-src http://extras.ubuntu.com/ubuntu trusty main +EOF +elif [ "$OS_ID" == "centos" ]; then + + echo centos +fi diff --git a/scripts/perf_test.sh b/scripts/perf_test.sh new file mode 100755 index 0000000..e3646bc --- /dev/null +++ b/scripts/perf_test.sh @@ -0,0 +1,24 @@ +#! /bin/bash + +exec=$1 +shift + +while getopts ":d:s:h" arg; do + case $arg in + d) # destination ip addr + dest=${OPTARG} + ;; + s) # source ip addr + src=${OPTARG} + ;; + h) # help + echo '-d destination ip address' + echo '-s source ip address' + exit 0 + ;; + esac +done + +dir=`dirname $0` + +${dir}/../release/bin/${exec} -p 20000 -d ${dest} -a 10000 -s ${src} -l 200 -t 5000000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 10000 -e 10 -x 1 diff --git a/scripts/prep_app_test.sh b/scripts/prep_app_test.sh new file mode 100755 index 0000000..23bfa8b --- /dev/null +++ b/scripts/prep_app_test.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +set -x +DMM_DIR=`dirname $(readlink -f $0)`/.. +LIB_PATH=$DMM_DIR/release/lib64/ + +mkdir -p $DMM_DIR/config/app_test +cd $DMM_DIR/config/app_test + +#===========check hugepages================= +source $DMM_DIR/scripts/check_hugepage.sh + +echo -e "\e[41m Preapring APP test directory.....\e[0m" + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +if [ "$OS_ID" == "ubuntu" ]; then + ifaddress1=$(ifconfig enp0s8 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}') + echo $ifaddress1 + ifaddress2=$(ifconfig enp0s9 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}') + echo $ifaddress2 +elif [ "$OS_ID" == "centos" ]; then + ifaddress1=$(ifconfig enp0s8 | grep 'inet' | cut -d: -f2 | awk '{print $2}') + echo $ifaddress1 + ifaddress2=$(ifconfig enp0s9 | grep 'inet' | cut -d: -f2 | awk '{print $2}') + echo $ifaddress2 +fi + +echo '{ + "default_stack_name": "kernel", + "module_list": [ + { + "stack_name": "kernel", + "function_name": "kernel_stack_register", + "libname": "./", + "loadtype": "static", + "deploytype": "1", + "maxfd": "1024", + "minfd": "0", + "priorty": "1", + "stackid": "0", + }, + ] +}' | tee module_config.json + +echo '{ + "ip_route": [ + { + "subnet": "'$ifaddress1'/24", + "type": "nstack-kernel", + }, + { + "subnet": "'$ifaddress2'/24", + "type": "nstack-kernel", + }, + ], + "prot_route": [ + { + "proto_type": "1", + "type": "nstack-kernel", + }, + { + "proto_type": "2", + "type": "nstack-kernel", + } + ], +}' | tee rd_config.json + +cp -r ${DMM_DIR}/release/lib64/* . +cp -r ${DMM_DIR}/release/configure/* . +cp -r ${DMM_DIR}/release/bin/* . +chmod 775 * + +#disable ASLR, othewise it may have some problems when mapping memory for secondary process +echo 0 > /proc/sys/kernel/randomize_va_space + +sudo mkdir -p /var/run/ip_module/ +sudo mkdir -p /var/log/nStack/ip_module/ + +export LD_LIBRARY_PATH=$LIB_PATH +export NSTACK_LOG_ON=DBG
\ No newline at end of file diff --git a/scripts/print_os_info.sh b/scripts/print_os_info.sh new file mode 100755 index 0000000..4d61c7b --- /dev/null +++ b/scripts/print_os_info.sh @@ -0,0 +1,17 @@ +#!/bin/bash -x + +set -x + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +OS_VERSION_ID=$(grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +KERNEL_OS=`uname -o` +KERNEL_MACHINE=`uname -m` +KERNEL_RELEASE=`uname -r` +KERNEL_VERSION=`uname -v` + +echo KERNEL_OS: $KERNEL_OS +echo KERNEL_MACHINE: $KERNEL_MACHINE +echo KERNEL_RELEASE: $KERNEL_RELEASE +echo KERNEL_VERSION: $KERNEL_VERSION +echo OS_ID: $OS_ID +echo OS_VERSION_ID: $OS_VERSION_ID diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d085679..1069e7f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,16 +22,18 @@ endif() INCLUDE_DIRECTORIES( framework/log/ + framework/mem framework/include/ framework/common/include/ + framework/common/include/arch/${DMM_ARCH} framework/common/base/include/ - framework/common/base/include/common/ - ${PRI_DIRECTORIES} + framework/common/base/include/common/ + ${PRI_DIRECTORIES} ../platform/SecureC/include/ ../thirdparty/glog/glog-0.3.4/src/ ) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC -m64 -mssse3 -std=gnu89") +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") @@ -40,7 +42,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack -mcmodel=medium") SET(COMPLE_CONFIG ${PROJECT_SOURCE_DIR}/src/framework/common/include/compile_config.h) ADD_DEFINITIONS(-include ${COMM_CONFIG}) ADD_DEFINITIONS(-include ${COMPLE_CONFIG}) -ADD_DEFINITIONS(-D_GNU_SOURCE -DNSTACK_GETVER_VERSION="18.04" -D_FORTIFY_SOURCE=2) +ADD_DEFINITIONS(-D_GNU_SOURCE -DNSTACK_GETVER_VERSION="18.07") #LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) if(WITH_SECUREC_LIB) diff --git a/src/adapt/nstack_dmm_adpt.c b/src/adapt/nstack_dmm_adpt.c index 8a79b03..d497b80 100644 --- a/src/adapt/nstack_dmm_adpt.c +++ b/src/adapt/nstack_dmm_adpt.c @@ -32,7 +32,6 @@ extern "C" { #include "nstack_eventpoll.h" #include "nstack_dmm_api.h" #include "nstack_dmm_adpt.h" -#include "nstack_rd_mng.h" #include "mgr_com.h" int g_same_process = 1; @@ -55,13 +54,6 @@ nstack_event_callback (void *pdata, int events) NSSOC_LOGWAR ("!!!!!!!err pdata=%p,get null epInfo", pdata); return -1; } -#if 0 - if (epInfo->rmidx >= 0 && epInfo->rmidx != modInx) - { - NSSOC_LOGDBG ("This fd should not issue events"); - return -1; - } -#endif NSSOC_LOGDBG ("Got one event]fd=%d,events=%u", epInfo->fd, events); @@ -106,7 +98,7 @@ nstack_event_callback (void *pdata, int events) ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); sem_post (&ep->waitSem); } - epi->revents |= events; + epi->revents |= (epi->event.events & events); out_unlock: sys_sem_s_signal (&ep->lock); } @@ -128,7 +120,8 @@ nstack_adpt_init (nstack_dmm_para * para) stinfo.iargsnum = para->argc; stinfo.pargs = para->argv; stinfo.enflag = para->proc_type; - if (para->deploy_type >= NSTACK_MODEL_TYPE1) + if (para->deploy_type != NSTACK_MODEL_TYPE1 + && para->deploy_type != NSTACK_MODEL_TYPE_SIMPLE_STACK) { g_same_process = 0; } @@ -179,12 +172,6 @@ nstack_adpt_init (nstack_dmm_para * para) NSFW_LOGERR ("nsep_create_memory failed"); return -1; } - - if (nstack_rd_mng_int (0) != 0) - { - NSFW_LOGERR ("nstack_rd_mng_int failed"); - return -1; - } } else { @@ -203,12 +190,6 @@ nstack_adpt_init (nstack_dmm_para * para) NSFW_LOGERR ("nsep_adpt_attach_memory failed"); return -1; } - - if (nstack_rd_mng_int (1) != 0) - { - NSFW_LOGERR ("nstack_rd_mng_int failed"); - return -1; - } } void *pret = diff --git a/src/adapt/nstack_dmm_adpt.h b/src/adapt/nstack_dmm_adpt.h index 25ac61f..1621475 100644 --- a/src/adapt/nstack_dmm_adpt.h +++ b/src/adapt/nstack_dmm_adpt.h @@ -30,6 +30,8 @@ typedef enum *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; diff --git a/src/adapt/nstack_rd_mng.c b/src/adapt/nstack_rd_mng.c deleted file mode 100644 index cb6a9b1..0000000 --- a/src/adapt/nstack_rd_mng.c +++ /dev/null @@ -1,317 +0,0 @@ -/* -* -* 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_rd_data.h" -#include "nsfw_mem_api.h" -#include "nstack_log.h" -#include "nstack_securec.h" - -#define RD_SHMEM_NAME "rd_table" - -#define RD_AGE_MAX_TIME 3 - -rd_route_table *g_rd_table_handle = NULL; - -#define RD_IP_ROUTE_CPY(pnode, name, data) { \ - if (EOK != STRCPY_S((pnode)->data.stack_name, RD_PLANE_NAMELEN, (name))) \ - { \ - NSSOC_LOGERR("STRCPY_S failed]copy_name=%s", name); \ - } \ - (pnode)->data.type = RD_DATA_TYPE_IP; \ - (pnode)->agetime = 0; \ - (pnode)->data.ipdata.addr = (data)->addr; \ - (pnode)->data.ipdata.masklen = (data)->masklen; \ - (pnode)->data.ipdata.resev[0] = 0; \ - (pnode)->data.ipdata.resev[1] = 0; \ -} - -/***************************************************************************** -* Prototype : nstack_rd_mng_int -* Description : rd mng module init, create a block memory -* Input : int flag -* Output : None -* Return Value : int -* Calls : -* Called By : nStackMain -*****************************************************************************/ -int -nstack_rd_mng_int (int flag) -{ - int ret; - nsfw_mem_zone zname = { - {NSFW_SHMEM, NSFW_PROC_MAIN, RD_SHMEM_NAME}, - sizeof (rd_route_table), - NSFW_SOCKET_ANY, - 0 - }; - NSSOC_LOGINF ("nstack rd mng init begin]flag=%d", flag); - /*nstack main create, app lookup */ - if (0 == flag) - { - g_rd_table_handle = (rd_route_table *) nsfw_mem_zone_create (&zname); - if (!g_rd_table_handle) - { - NSSOC_LOGERR ("mem create fail]mem name=%s", RD_SHMEM_NAME); - return -1; - } - ret = - MEMSET_S (&(g_rd_table_handle->node[0]), sizeof (rd_route_node), 0, - sizeof (rd_route_node)); - if (EOK != ret) - { - NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); - return -1; - } - g_rd_table_handle->size = NSTACK_RD_DATA_MAX; - g_rd_table_handle->icnt = 0; - } - else /* static data will not be erased in fault case */ - { - g_rd_table_handle = - (rd_route_table *) nsfw_mem_zone_lookup (&(zname.stname)); - if (!g_rd_table_handle) - { - NSSOC_LOGERR ("mem lookup fail]mem name=%s", RD_SHMEM_NAME); - return -1; - } - } - NSSOC_LOGINF ("nstack rd mng init end flag"); - return 0; -} - -/***************************************************************************** -* Prototype : nstack_rd_ip_node_insert -* Description : insert a rd_ip_data into list -* Input : char *name -* rd_ip_data *data -* Output : None -* Return Value : int -* Calls : -* Called By : nStackMain -*****************************************************************************/ -int -nstack_rd_ip_node_insert (char *name, rd_ip_data * data) -{ - if (!g_rd_table_handle) - { - NSSOC_LOGERR ("nstack rd mng not inited"); - return -1; - } - int iindex = 0; - rd_route_node *pnode = NULL; - int agetime = 0; - int ageindex = -1; - int freeindex = -1; - int repeatflag = 0; - - for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++) - { - pnode = &(g_rd_table_handle->node[iindex]); - /*record the index of first free element */ - if (RD_NODE_USELESS == pnode->flag) - { - if (-1 == freeindex) - { - freeindex = iindex; - NSSOC_LOGINF ("nstack rd ip free element index:%d was found", - iindex); - } - continue; - } - - /*if is using, and repeat just set flag */ - if (RD_NODE_USING == pnode->flag) - { - if (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) == - MASK_V (data->addr, data->masklen)) - { - NSSOC_LOGWAR - ("nstack:%s, old_addr:0x%x index:%d new_addr:0x%x, masklen:%u was repeat", - name, pnode->data.ipdata.addr, iindex, data->addr, - data->masklen); - repeatflag = 1; - } - continue; - } - - /*if flag is deleting, just update the age time, if agetime is on, just set flag to free */ - if (RD_NODE_DELETING == pnode->flag) - { - pnode->agetime++; - if (pnode->agetime >= RD_AGE_MAX_TIME) - { - pnode->flag = RD_NODE_USELESS; - NSSOC_LOGINF - ("nstack rd ip element index:%d addr:0x%x, masklen:%u was delete and set to free", - iindex, pnode->data.ipdata.addr, pnode->data.ipdata.masklen); - } - /*record delete time */ - if (agetime < pnode->agetime) - { - agetime = pnode->agetime; - ageindex = iindex; - } - continue; - } - } - - /*if repeat, just return */ - if (1 == repeatflag) - { - return 0; - } - if (-1 == freeindex) - { - if (-1 != ageindex) - { - freeindex = ageindex; - } - else - { - NSSOC_LOGERR - ("the rd table is full,nstack:%s, rd addr:0x%x, masklen:%u can't be inserted", - name, data->addr, data->masklen); - return -1; - } - } - pnode = &(g_rd_table_handle->node[freeindex]); - /*if no free found, just reuse the big agetime */ - RD_IP_ROUTE_CPY (pnode, name, data); - pnode->flag = RD_NODE_USING; /*last set */ - g_rd_table_handle->icnt++; - NSSOC_LOGINF ("nstack:%s, rd addr:0x%x, masklen:%u index was inserted", - name, data->addr, data->masklen); - return 0; -} - -/***************************************************************************** -* Prototype : nstack_rd_ip_node_delete -* Description : rd data delete -* Input : rd_ip_data *data -* Output : None -* Return Value : int -* Calls : -* Called By : nStackMain -* just set delete flag, because -*****************************************************************************/ -int -nstack_rd_ip_node_delete (rd_ip_data * data) -{ - int iindex = 0; - rd_route_node *pnode = NULL; - - if (!g_rd_table_handle) - { - NSSOC_LOGERR ("nstack rd mng not inited"); - return -1; - } - - for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++) - { - pnode = &(g_rd_table_handle->node[iindex]); - if ((RD_NODE_USING == pnode->flag) - && (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) == - MASK_V (data->addr, data->masklen))) - { - pnode->flag = RD_NODE_DELETING; /*just set deleting state */ - pnode->agetime = 0; - g_rd_table_handle->icnt--; - NSSOC_LOGINF - ("nstack rd delete:%s, addr:0x%x, masklen:%u index:%d was delete", - pnode->data.stack_name, data->addr, data->masklen, iindex); - return 0; - } - } - NSSOC_LOGINF ("nstack rd delete, addr:0x%x, masklen:%u index was not found", - data->addr, data->masklen); - return 0; -} - -/***************************************************************************** -* Prototype : nstack_rd_ip_get -* Description : get rd data from rd table -* Input : char *planename -* rd_route_data **data -* int *num -* Output : None -* Return Value : int -* Calls : -* Called By : -* Note : a block memory was alloc and return by data, -* this need free by caller if return 0, otherwise no need -*****************************************************************************/ -int -nstack_rd_ip_get (rd_route_data ** data, int *num) -{ - rd_route_data *pdata = NULL; - rd_route_node *pnode = NULL; - int size = 0; - int icnt = 0; - int idex = 0; - int ret; - - if (!g_rd_table_handle || !data || !num) - { - NSSOC_LOGERR ("nstack rd mng not inited or input err"); - return -1; - } - size = sizeof (rd_route_data) * g_rd_table_handle->size; - pdata = (rd_route_data *) malloc (size); - if (!pdata) - { - NSSOC_LOGERR ("rd route data malloc fail"); - return -1; - } - ret = MEMSET_S (pdata, size, 0, size); - if (EOK != ret) - { - NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); - free (pdata); - return -1; - } - for (icnt = 0; icnt < g_rd_table_handle->size; icnt++) - { - pnode = &(g_rd_table_handle->node[icnt]); - if (RD_NODE_USING == pnode->flag) - { - pdata[idex].type = pnode->data.type; - pdata[idex].ipdata.addr = pnode->data.ipdata.addr; - pdata[idex].ipdata.masklen = pnode->data.ipdata.masklen; - pdata[idex].ipdata.resev[0] = pnode->data.ipdata.resev[0]; - pdata[idex].ipdata.resev[1] = pnode->data.ipdata.resev[1]; - ret = - STRCPY_S (pdata[idex].stack_name, RD_PLANE_NAMELEN, - pnode->data.stack_name); - if (EOK != ret) - { - NSSOC_LOGERR ("STRCPY_S failed]ret=%d", ret); - free (pdata); - return -1; - } - idex++; - } - } - /*if no data fetched , just return fail */ - if (idex == 0) - { - free (pdata); - return -1; - } - *data = pdata; - *num = idex; - return 0; -} diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 83e9d81..6b22e51 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -29,10 +29,13 @@ FILE(GLOB STARTUP startup/*.c) FILE(GLOB MAINTAIN maintain/*.c) FILE(GLOB HAL hal/*.c) FILE(GLOB DMM_ADPT ../adapt/*.c) +FILE(GLOB MEM mem/*.c) +ADD_LIBRARY(dmm_api SHARED + ${COMMON} ${INIT} ${IPC} ${LOG} ${SNAPSHOT} + ${STARTUP} ${MAINTAIN} ${TRACEING} ${HAL} + ${DMM_ADPT} ${LIBCOMM} ${MEM}) - -ADD_LIBRARY(dmm_api STATIC ${COMMON} ${INIT} ${IPC} ${LOG} ${SNAPSHOT} ${STARTUP} ${MAINTAIN} ${TRACEING} ${HAL} ${DMM_ADPT} ${LIBCOMM}) if(WITH_SECUREC_LIB) ADD_DEPENDENCIES(dmm_api SECUREC JSON GLOG) else() diff --git a/src/framework/common/base/include/common/common_func.h b/src/framework/common/base/include/common/common_func.h index fdf2802..2b84b7a 100644 --- a/src/framework/common/base/include/common/common_func.h +++ b/src/framework/common/base/include/common/common_func.h @@ -93,6 +93,23 @@ #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 + #endif #endif // _RTE_COMM_FUNC_H_ diff --git a/src/framework/common/base/include/common/common_mem_api.h b/src/framework/common/base/include/common/common_mem_api.h index 9eb4344..d143732 100644 --- a/src/framework/common/base/include/common/common_mem_api.h +++ b/src/framework/common/base/include/common/common_mem_api.h @@ -75,6 +75,7 @@ typedef s8_t err_t; 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); @@ -90,7 +91,7 @@ get_sys_pid () } pid_t updata_sys_pid (); -long sys_now (void); +u32_t sys_now (void); #define sys_sem_t sys_sem_t_v2 #define sys_sem_st sys_sem_st_v2 @@ -126,9 +127,7 @@ sys_arch_lock_with_pid_v2 (sys_sem_t_v2 sem) #define NSTACK_SEM_MALLOC(sys_sem,count) \ { \ rte_spinlock_init(&(sys_sem)); \ - /*lint -e506*/\ if (!(count)) \ - /*lint +e506*/\ { \ rte_spinlock_lock(&(sys_sem)); \ } \ diff --git a/src/framework/common/base/include/common/common_mem_buf.h b/src/framework/common/base/include/common/common_mem_buf.h index 441da6a..f9f1593 100644 --- a/src/framework/common/base/include/common/common_mem_buf.h +++ b/src/framework/common/base/include/common/common_mem_buf.h @@ -21,6 +21,7 @@ #else #include "common_mem_base_type.h" +#include "types.h" typedef enum __DMM_PROC_TYPE { @@ -63,7 +64,7 @@ typedef struct __common_pal_module_info * @param name * The name of the buf pool. */ -int nscomm_pal_module_init (common_mem_pal_module_info * pinfo); +int nscomm_pal_module_init (common_mem_pal_module_info * pinfo, u8 app_mode); void *nscomm_memzone_data_reserve_name (const char *name, size_t len, int socket_id); diff --git a/src/framework/common/base/liblinuxapi/nsfw_getopt.c b/src/framework/common/base/liblinuxapi/nsfw_getopt.c deleted file mode 100644 index 4d6227b..0000000 --- a/src/framework/common/base/liblinuxapi/nsfw_getopt.c +++ /dev/null @@ -1,455 +0,0 @@ -/* -* -* 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 <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include "nsfw_getopt.h" -#include "nstack_log.h" - -char *nsfw_optarg = NULL; -int nsfw_optind = 1; -int nsfw_opterr = 1; -int nsfw_optopt = '?'; -NSTACK_STATIC char *nsfw_optnext = NULL; -NSTACK_STATIC int posixly_correct = -1; -NSTACK_STATIC int handle_nonopt_argv = 0; -NSTACK_STATIC int start = 0; -NSTACK_STATIC int end = 0; - -NSTACK_STATIC void check_gnu_extension (const char *optstring); -NSTACK_STATIC int nsfw_getopt_internal (int argc, char *const argv[], - const char *optstring, - const struct option *longopts, - int *longindex, int long_only); -NSTACK_STATIC int nsfw_getopt_shortopts (int argc, char *const argv[], - const char *optstring, - int long_only); -NSTACK_STATIC int nsfw_getopt_longopts (int argc, char *const argv[], - char *arg, const char *optstring, - const struct option *longopts, - int *longindex, int *long_only_flag); -NSTACK_STATIC inline int nsfw_getopt_internal_check_opts (const char - *optstring); -NSTACK_STATIC inline int nsfw_getopt_check_optind (); -NSTACK_STATIC inline int nsfw_getopt_internal_init (char *const argv[]); -NSTACK_STATIC inline int nsfw_getopt_longopts_check_longonly (int - *long_only_flag, - const char - *optstring, - char *const - argv[]); - -NSTACK_STATIC void -check_gnu_extension (const char *optstring) -{ - if (optstring[0] == '+' || getenv ("POSIXLY_CORRECT") != NULL) - { - posixly_correct = 1; /* assign 1 to posixly_correct */ - } - else - { - posixly_correct = 0; /* assign 0 to posixly_correct */ - } - if (optstring[0] == '-') - { - handle_nonopt_argv = 1; /* assign 1 to handle_nonopt_argv */ - } - else - { - handle_nonopt_argv = 0; /* assign 0 to handle_nonopt_argv */ - } -} - -int -nsfw_getopt_long (int argc, char *const argv[], const char *optstring, - const struct option *longopts, int *longindex) -{ - return nsfw_getopt_internal (argc, argv, optstring, longopts, longindex, 0); -} - -NSTACK_STATIC inline int -nsfw_getopt_internal_check_opts (const char *optstr) -{ - if (NULL == optstr) - { - return -1; /* return -1 */ - } - - if (nsfw_optopt == '?') - { - nsfw_optopt = 0; - } - - if (posixly_correct == -1) - { - check_gnu_extension (optstr); - } - - if (nsfw_optind == 0) - { - check_gnu_extension (optstr); - nsfw_optind = 1; - nsfw_optnext = NULL; - } - - switch (optstr[0]) - { - case '-': - case '+': - optstr++; - break; - default: - break; - } - return 0; -} - -NSTACK_STATIC inline int -nsfw_getopt_check_optind () -{ - if (nsfw_optind <= 0) - nsfw_optind = 1; - return 0; -} - -NSTACK_STATIC inline int -nsfw_getopt_internal_init (char *const argv[]) -{ - if (nsfw_optnext == NULL && start != 0) - { - int last_loc = nsfw_optind - 1; - - nsfw_optind -= end - start; - (void) nsfw_getopt_check_optind (); - - while (start < end--) - { - int j; - char *arg = argv[end]; - - for (j = end; j < last_loc; j++) - { - int k = j + 1; - ((char **) argv)[j] = argv[k]; - } - ((char const **) argv)[j] = arg; - last_loc--; - } - start = 0; /*make start as zero */ - } - return 0; -} - -NSTACK_STATIC int -nsfw_getopt_internal (int argc, char *const argv[], const char *optstring, - const struct option *longopts, int *longindex, - int long_only) -{ - - (void) nsfw_getopt_internal_check_opts (optstring); - - (void) nsfw_getopt_internal_init (argv); - - if (nsfw_optind >= argc) - { - nsfw_optarg = NULL; - return -1; /* return -1 */ - } - if (nsfw_optnext == NULL) - { - const char *arg = argv[nsfw_optind]; - if (*arg != '-') - { - if (handle_nonopt_argv) - { - nsfw_optarg = argv[nsfw_optind++]; - start = 0; - return 1; - } - else if (posixly_correct) - { - nsfw_optarg = NULL; - return -1; - } - else - { - int k; - - start = nsfw_optind; - for (k = nsfw_optind + 1; k < argc; k++) - { - if (argv[k][0] == '-') - { - end = k; - break; - } - } - if (k == argc) - { - nsfw_optarg = NULL; - return -1; - } - nsfw_optind = k; - arg = argv[nsfw_optind]; - } - } - if (strcmp (arg, "--") == 0) - { - nsfw_optind++; - return -1; - } - if (longopts != NULL && arg[1] == '-') - { - return nsfw_getopt_longopts (argc, argv, argv[nsfw_optind] + 2, - optstring, longopts, longindex, NULL); - } - } - - if (nsfw_optnext == NULL) - { - nsfw_optnext = argv[nsfw_optind] + 1; - } - if (long_only) - { - int long_only_flag = 0; - int rv = - nsfw_getopt_longopts (argc, argv, nsfw_optnext, optstring, longopts, - longindex, &long_only_flag); - if (!long_only_flag) - { - nsfw_optnext = NULL; - return rv; - } - } - - return nsfw_getopt_shortopts (argc, argv, optstring, long_only); -} - -NSTACK_STATIC int -nsfw_getopt_shortopts (int argc, char *const argv[], const char *optstring, - int long_only) -{ - int opt = *nsfw_optnext; - const char *os; - if (optstring != NULL) - { - os = strchr (optstring, opt); - } - else - { - /* here try to keep same with below behavior */ - return '?'; - } - - if (os == NULL) - { - nsfw_optarg = NULL; - if (long_only) - { - if (':' != optstring[0]) - { - NSFW_LOGERR ("unrecognized option] argv_0=%s, netopt=%s", - argv[0], nsfw_optnext); - } - nsfw_optind++; - nsfw_optnext = NULL; - } - else - { - nsfw_optopt = opt; - if (':' != optstring[0]) - { - NSFW_LOGERR ("invalid option] argv_0=%s, opt=%c", argv[0], opt); - } - if (*(++nsfw_optnext) == 0) - { - nsfw_optind++; - nsfw_optnext = NULL; - } - } - return '?'; - } - if (os[1] == ':') - { - if (nsfw_optnext[1] == 0) - { - nsfw_optind++; - if (os[2] == ':') - { - nsfw_optarg = NULL; - } - else - { - if (nsfw_optind == argc) - { - nsfw_optarg = NULL; - nsfw_optopt = opt; - if (':' != optstring[0]) - { - NSFW_LOGERR - ("option requires an argument] argv_0=%s, opt=%c", - argv[0], opt); - } - return optstring[0] == ':' ? ':' : '?'; - } - nsfw_optarg = argv[nsfw_optind]; - nsfw_optind++; - } - } - else - { - nsfw_optarg = nsfw_optnext + 1; - nsfw_optind++; - } - nsfw_optnext = NULL; - } - else - { - nsfw_optarg = NULL; - if (nsfw_optnext[1] == 0) - { - nsfw_optnext = NULL; - nsfw_optind++; - } - else - { - nsfw_optnext++; - } - } - return opt; -} - -NSTACK_STATIC inline int -nsfw_getopt_longopts_check_longonly (int *long_only_flag, - const char *optstring, - char *const argv[]) -{ - if (long_only_flag) - { - *long_only_flag = 1; - } - else - { - if (':' != optstring[0]) - { - NSFW_LOGERR ("unrecognized option] argv_0=%s, option=%s", argv[0], - argv[nsfw_optind]); - } - nsfw_optind++; - } - return 0; -} - -NSTACK_STATIC int -nsfw_getopt_longopts (int argc, char *const argv[], char *arg, - const char *optstring, const struct option *longopts, - int *longindex, int *long_only_flag) -{ - char *value = NULL; - const struct option *option; - size_t namelength; - int index; - - if ((longopts == NULL) || (arg == NULL)) - { - return -1; - } - - for (index = 0; longopts[index].name != NULL; index++) - { - option = &longopts[index]; - namelength = strlen (option->name); - - if (strncmp (arg, option->name, namelength) == 0) - { - switch (arg[namelength]) - { - case '\0': - switch (option->has_arg) - { - case nsfw_required_argument: - nsfw_optind++; - - if (nsfw_optind == argc) - { - nsfw_optarg = NULL; - nsfw_optopt = option->val; - if (':' != optstring[0]) - { - NSFW_LOGERR - ("requires an argument] argv_0=%s, opt name=%s", - argv[0], option->name); - } - return optstring[0] == ':' ? ':' : '?'; - } - - value = argv[nsfw_optind]; - break; - - default: - break; - } - - goto found; - - case '=': - if (option->has_arg == nsfw_no_argument) - { - const char *hyphens = - (argv[nsfw_optind][1] == '-') ? "--" : "-"; - nsfw_optind++; - nsfw_optarg = NULL; - nsfw_optopt = option->val; - if (':' != optstring[0]) - { - NSFW_LOGERR - ("doesn't allow an argument] argv_0=%s, hyphens=%s, opt name=%s", - argv[0], hyphens, option->name); - } - return '?'; - } - - value = arg + namelength + 1; - goto found; - - default: - break; - } - } - } - - (void) nsfw_getopt_longopts_check_longonly (long_only_flag, optstring, - argv); - return '?'; - -found: - nsfw_optarg = value; - nsfw_optind++; - - if (option->flag) - { - *option->flag = option->val; - } - - if (longindex) - { - *longindex = index; - } - - return option->flag ? 0 : option->val; -} diff --git a/src/framework/common/base/liblinuxapi/nsfw_lock_file.c b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c index 0ec196f..abfbfd1 100644 --- a/src/framework/common/base/liblinuxapi/nsfw_lock_file.c +++ b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c @@ -94,13 +94,6 @@ nsfw_proc_start_with_lock (u8 proc_type) return -1; } - ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_FOLDER); - if (EOK != ret) - { - NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); - return -1; - } - ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, module_name); if (EOK != ret) { diff --git a/src/framework/common/include/arch/x86/dmm_atomic.h b/src/framework/common/include/arch/x86/dmm_atomic.h new file mode 100644 index 0000000..fae99c2 --- /dev/null +++ b/src/framework/common/include/arch/x86/dmm_atomic.h @@ -0,0 +1,21 @@ +/* +* +* 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 _DMM_ATOMIC_H__ARCH_X86_ +#define _DMM_ATOMIC_H__ARCH_X86_ + +#include "generic/dmm_atomic.h" + +#endif /* #ifndef _DMM_ATOMIC_H__ARCH_X86_ */ diff --git a/src/framework/common/include/arch/x86/dmm_barrier.h b/src/framework/common/include/arch/x86/dmm_barrier.h new file mode 100644 index 0000000..bf53650 --- /dev/null +++ b/src/framework/common/include/arch/x86/dmm_barrier.h @@ -0,0 +1,21 @@ +/* +* +* 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 _DMM_BARRIER_H__ARCH_X86_ +#define _DMM_BARRIER_H__ARCH_X86_ + +#include "generic/dmm_barrier.h" + +#endif /* #ifndef _DMM_BARRIER_H__ARCH_X86_ */ diff --git a/src/framework/common/include/arch/x86/dmm_pause.h b/src/framework/common/include/arch/x86/dmm_pause.h new file mode 100644 index 0000000..56c60f0 --- /dev/null +++ b/src/framework/common/include/arch/x86/dmm_pause.h @@ -0,0 +1,30 @@ +/* +* +* 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 _DMM_PAUSE_H_ +#define _DMM_PAUSE_H_ + +#include <emmintrin.h> + +inline static void +dmm_pause (void) +{ + _mm_pause (); +} + +#define DMM_PAUSE_WHILE(cond) do { dmm_pause(); } while (!!(cond)) +#define DMM_WHILE_PAUSE(cond) do { while (!!(cond)) dmm_pause(); } while (0) + +#endif /* #ifndef _DMM_PAUSE_H_ */ diff --git a/src/framework/common/include/arch/x86/dmm_rwlock.h b/src/framework/common/include/arch/x86/dmm_rwlock.h new file mode 100644 index 0000000..0c31329 --- /dev/null +++ b/src/framework/common/include/arch/x86/dmm_rwlock.h @@ -0,0 +1,21 @@ +/* +* +* 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 _DMM_RWLOCK_H__ARCH_X86_ +#define _DMM_RWLOCK_H__ARCH_X86_ + +#include "generic/dmm_rwlock.h" + +#endif /* #ifndef _DMM_RWLOCK_H__ARCH_X86_ */ diff --git a/src/framework/common/include/arch/x86/dmm_spinlock.h b/src/framework/common/include/arch/x86/dmm_spinlock.h new file mode 100644 index 0000000..69ed9a6 --- /dev/null +++ b/src/framework/common/include/arch/x86/dmm_spinlock.h @@ -0,0 +1,21 @@ +/* +* +* 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 _DMM_SPINLOCK_H__ARCH_X86_ +#define _DMM_SPINLOCK_H__ARCH_X86_ + +#include "generic/dmm_spinlock.h" + +#endif /* #ifndef _DMM_SPINLOCK_H__ARCH_X86_ */ diff --git a/src/framework/common/include/dmm_fs.h b/src/framework/common/include/dmm_fs.h new file mode 100644 index 0000000..8fd9cd0 --- /dev/null +++ b/src/framework/common/include/dmm_fs.h @@ -0,0 +1,32 @@ +/* +* +* 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 _DMM_FS_H_ +#define _DMM_FS_H_ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +static size_t +dmm_file_size (int fd) +{ + struct stat st; + if (fstat (fd, &st) < 0) + return 0; + return st.st_size; +} + +#endif /* _DMM_FS_H_ */ diff --git a/src/framework/common/include/generic/dmm_atomic.h b/src/framework/common/include/generic/dmm_atomic.h new file mode 100644 index 0000000..637306b --- /dev/null +++ b/src/framework/common/include/generic/dmm_atomic.h @@ -0,0 +1,177 @@ +/* +* +* 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 _DMM_ATOMIC_H_ +#define _DMM_ATOMIC_H_ + +/* atomic 32 bit operation */ + +typedef struct +{ + volatile int cnt; +} dmm_atomic_t; + +inline static int +dmm_atomic_get (dmm_atomic_t * a) +{ + return a->cnt; +} + +inline static int +dmm_atomic_add (dmm_atomic_t * a, int n) +{ + return __sync_fetch_and_add (&a->cnt, n); +} + +inline static int +dmm_atomic_sub (dmm_atomic_t * a, int n) +{ + return __sync_fetch_and_sub (&a->cnt, n); +} + +inline static int +dmm_atomic_and (dmm_atomic_t * a, int n) +{ + return __sync_fetch_and_and (&a->cnt, n); +} + +inline static int +dmm_atomic_or (dmm_atomic_t * a, int n) +{ + return __sync_fetch_and_or (&a->cnt, n); +} + +inline static int +dmm_atomic_xor (dmm_atomic_t * a, int n) +{ + return __sync_fetch_and_xor (&a->cnt, n); +} + +inline static int +dmm_atomic_swap (dmm_atomic_t * a, int o, int n) +{ + return __sync_val_compare_and_swap (&a->cnt, o, n); +} + +inline static int +dmm_atomic_add_return (dmm_atomic_t * a, int n) +{ + return __sync_add_and_fetch (&a->cnt, n); +} + +inline static int +dmm_atomic_sub_return (dmm_atomic_t * a, int n) +{ + return __sync_sub_and_fetch (&a->cnt, n); +} + +inline static int +dmm_atomic_and_return (dmm_atomic_t * a, int n) +{ + return __sync_and_and_fetch (&a->cnt, n); +} + +inline static int +dmm_atomic_or_return (dmm_atomic_t * a, int n) +{ + return __sync_or_and_fetch (&a->cnt, n); +} + +inline static int +dmm_atomic_xor_return (dmm_atomic_t * a, int n) +{ + return __sync_xor_and_fetch (&a->cnt, n); +} + +/* atomit 64bit operation */ + +typedef struct +{ + volatile long long int cnt; +} dmm_atomic64_t; + +inline static long long int +dmm_atomic64_get (dmm_atomic64_t * a) +{ + return a->cnt; +} + +inline static long long int +dmm_atomic64_add (dmm_atomic64_t * a, int n) +{ + return __sync_fetch_and_add (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_sub (dmm_atomic64_t * a, int n) +{ + return __sync_fetch_and_sub (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_and (dmm_atomic64_t * a, int n) +{ + return __sync_fetch_and_and (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_or (dmm_atomic64_t * a, int n) +{ + return __sync_fetch_and_or (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_xor (dmm_atomic64_t * a, int n) +{ + return __sync_fetch_and_xor (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_swap (dmm_atomic_t * a, int o, int n) +{ + return __sync_val_compare_and_swap (&a->cnt, o, n); +} + +inline static long long int +dmm_atomic64_add_return (dmm_atomic64_t * a, int n) +{ + return __sync_add_and_fetch (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_sub_return (dmm_atomic64_t * a, int n) +{ + return __sync_sub_and_fetch (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_and_return (dmm_atomic64_t * a, int n) +{ + return __sync_and_and_fetch (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_or_return (dmm_atomic64_t * a, int n) +{ + return __sync_or_and_fetch (&a->cnt, n); +} + +inline static long long int +dmm_atomic64_xor_return (dmm_atomic64_t * a, int n) +{ + return __sync_xor_and_fetch (&a->cnt, n); +} + +#endif /* #ifndef _DMM_ATOMIC_H_ */ diff --git a/src/framework/common/include/generic/dmm_barrier.h b/src/framework/common/include/generic/dmm_barrier.h new file mode 100644 index 0000000..b70fe85 --- /dev/null +++ b/src/framework/common/include/generic/dmm_barrier.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 _DMM_BARRIER_H_ +#define _DMM_BARRIER_H_ + +inline static void +dmm_barrier (void) +{ + __sync_synchronize (); +} + +#endif /* #ifndef _DMM_BARRIER_H_ */ diff --git a/src/framework/common/include/generic/dmm_pause.h b/src/framework/common/include/generic/dmm_pause.h new file mode 100644 index 0000000..56c60f0 --- /dev/null +++ b/src/framework/common/include/generic/dmm_pause.h @@ -0,0 +1,30 @@ +/* +* +* 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 _DMM_PAUSE_H_ +#define _DMM_PAUSE_H_ + +#include <emmintrin.h> + +inline static void +dmm_pause (void) +{ + _mm_pause (); +} + +#define DMM_PAUSE_WHILE(cond) do { dmm_pause(); } while (!!(cond)) +#define DMM_WHILE_PAUSE(cond) do { while (!!(cond)) dmm_pause(); } while (0) + +#endif /* #ifndef _DMM_PAUSE_H_ */ diff --git a/src/framework/common/include/generic/dmm_rwlock.h b/src/framework/common/include/generic/dmm_rwlock.h new file mode 100644 index 0000000..93570f1 --- /dev/null +++ b/src/framework/common/include/generic/dmm_rwlock.h @@ -0,0 +1,76 @@ +/* +* +* 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 _DMM_RWLOCK_H_ +#define _DMM_RWLOCK_H_ + +#include "dmm_pause.h" + +typedef struct +{ + volatile int lock; +} dmm_rwlock_t; + +#define DMM_RWLOCK_INIT { 0 } + +inline static void +dmm_rwlock_init (dmm_rwlock_t * rwlock) +{ + rwlock->lock = 0; +} + +inline static void +dmm_read_lock (dmm_rwlock_t * rwlock) +{ + int val; + + do + { + if ((val = rwlock->lock) < 0) + { + dmm_pause (); + continue; + } + } + while (!__sync_bool_compare_and_swap (&rwlock->lock, val, val + 1)); +} + +inline static void +dmm_read_unlock (dmm_rwlock_t * rwlock) +{ + __sync_sub_and_fetch (&rwlock->lock, 1); +} + +inline static void +dmm_write_lock (dmm_rwlock_t * rwlock) +{ + do + { + if (rwlock->lock != 0) + { + dmm_pause (); + continue; + } + } + while (!__sync_bool_compare_and_swap (&rwlock->lock, 0, -1)); +} + +inline static void +dmm_write_unlock (dmm_rwlock_t * rwlock) +{ + rwlock->lock = 0; +} + +#endif /* #ifndef _DMM_RWLOCK_H_ */ diff --git a/src/framework/common/include/generic/dmm_spinlock.h b/src/framework/common/include/generic/dmm_spinlock.h new file mode 100644 index 0000000..be183a6 --- /dev/null +++ b/src/framework/common/include/generic/dmm_spinlock.h @@ -0,0 +1,53 @@ +/* +* +* 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 _DMM_SPINLOCK_H_ +#define _DMM_SPINLOCK_H_ + +#include "dmm_pause.h" + +typedef struct +{ + volatile int lock; +} dmm_spinlock_t; + +inline static void +dmm_spin_init (dmm_spinlock_t * spinlock) +{ + spinlock->lock = 0; +} + +inline static void +dmm_spin_lock (dmm_spinlock_t * spinlock) +{ + while (0 != __sync_lock_test_and_set (&spinlock->lock, 1)) + { + DMM_PAUSE_WHILE (spinlock->lock); + } +} + +inline static int +dmm_spin_trylock (dmm_spinlock_t * spinlock) +{ + return 0 == __sync_lock_test_and_set (&spinlock->lock, 1); +} + +inline static void +dmm_spin_unlock (dmm_spinlock_t * spinlock) +{ + spinlock->lock = 0; +} + +#endif /* #ifndef _DMM_SPINLOCK_H_ */ diff --git a/src/framework/common/include/types.h b/src/framework/common/include/types.h index c7d013c..bd4d80b 100644 --- a/src/framework/common/include/types.h +++ b/src/framework/common/include/types.h @@ -58,10 +58,6 @@ typedef unsigned long long u64; #define NULL ((void *)0) #endif -#define container_of(ptr, type, member) ( \ - (type *)((char *)(ptr) - offsetof(type,member)) \ - ) - #define PRIMARY_ADDR typedef struct _nsfw_res diff --git a/src/framework/common/mem_mgr/nsfw_res_mgr.c b/src/framework/common/mem_mgr/nsfw_res_mgr.c index 2f676c9..c4d8010 100644 --- a/src/framework/common/mem_mgr/nsfw_res_mgr.c +++ b/src/framework/common/mem_mgr/nsfw_res_mgr.c @@ -176,7 +176,7 @@ nsfw_res_flash_data (nsfw_res_mgr_item_cfg * res_scn_item) (struct common_mem_mempool *) scn_cfg->data; if (NULL == ring) { - ring = mp->ring; + ring = mp->pool_data; if (NULL == ring) return FALSE; } diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c index 270e0f8..08ad4cd 100644 --- a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c @@ -37,6 +37,10 @@ #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*/ @@ -75,13 +79,13 @@ nsfw_shmem_init (nsfw_mem_para * para) } else if (NSFW_PROC_MAIN == para->enflag) { - iret = common_pal_module_init (NULL); + iret = common_pal_module_init (NULL, app_mode); } else { LCORE_MASK_SET (rteinfo.ilcoremask, 1); rteinfo.ucproctype = DMM_PROC_T_SECONDARY; - iret = common_pal_module_init (&rteinfo); + iret = common_pal_module_init (&rteinfo, app_mode); } if (NSFW_MEM_OK != iret) @@ -699,53 +703,6 @@ nsfw_shmem_static (void *handle, nsfw_mem_struct_type type) i32 nsfw_shmem_mbuf_recycle (mpool_handle handle) { -#if 0 - const struct common_mem_mempool *mp = (struct common_mem_mempool *) handle; - struct common_mem_ring *rteRing = NULL; - struct common_mem_mbuf *m_buf = NULL; - uint32_t item; - u32_t *recycle_flg; - uint32_t size = mp->size; - uint32_t threadsize = (size >> 2) * 3; - rteRing = (struct common_mem_ring *) ADDR_SHTOL (mp->ring); - - if (rteRing->prod.tail - rteRing->cons.head < threadsize) - { - for (item = 0; item < size - 1; item++) - { - m_buf = (struct common_mem_mbuf *) ADDR_SHTOL (mp->elt_va_start + item * (mp->header_size + mp->elt_size + mp->trailer_size) + mp->header_size); /*lint !e647 */ - recycle_flg = - (uint32_t *) ((char *) (ADDR_SHTOL (m_buf->buf_addr_align)) + - RTE_PKTMBUF_HEADROOM - sizeof (uint32_t)); - - if (m_buf->refcnt > 0 && *recycle_flg == MBUF_HLD_BY_APP) - { - NSCOMM_LOGINF ("free mbuf hold by app]ring=%p, mbuf=%p", handle, - m_buf); - *recycle_flg = MBUF_UNUSED; - common_mem_pktmbuf_free (m_buf); - } - } - } - - NSCOMM_LOGINF ("To recycle app_tx_pool now]ring=%p,prod.head=%u," - "prod.tail=%u,cons.head=%u,cons.tail=%u.", handle, - rteRing->prod.head, rteRing->prod.tail, - rteRing->cons.head, rteRing->cons.tail); - - /*we Must check and recorrect the Queue if Queue is not correct - 1.if proc.head != proc.tail set proc.head to proc.tail [may lost some buf,but the queue still can use] - App May not putIn Data , just done head++, we can't set proc.tail to proc.head. - 2.if cons.head != cons.tail set cons.tail to cons.head [may lost some buf,but the queue still can use] - App May already finish deque,just not tail++, we can't set cons.head to cons.tail. - */ - if ((rteRing->prod.head != rteRing->prod.tail) - || (rteRing->cons.head != rteRing->cons.tail)) - { - rteRing->prod.head = rteRing->prod.tail; - rteRing->cons.tail = rteRing->cons.head; - } -#endif return NSFW_MEM_OK; } diff --git a/src/framework/hal/hal.c b/src/framework/hal/hal.c index 1adf274..545c759 100644 --- a/src/framework/hal/hal.c +++ b/src/framework/hal/hal.c @@ -31,8 +31,6 @@ static char* hal_invalid_str_script[] = {"&&", "||", ">>", "${", ";;", "/./", "/ static char* hal_invalid_str_script_begin[] = {"./", "../"}; -extern const netif_ops_t dpdk_netif_ops; - static hal_hdl_t hal_invaldi_hdl = {.id = -1}; static const netif_ops_t* netif_ops_table[HAL_DRV_MAX]; @@ -598,7 +596,7 @@ hal_get_capability (hal_hdl_t hdl, hal_netif_capa_t * info) *****************************************************************************/ uint16_t hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, - struct common_mem_mbuf **rx_pkts, uint16_t nb_pkts) + hal_mbuf_t ** rx_pkts, uint16_t nb_pkts) { netif_inst_t *inst; @@ -627,7 +625,7 @@ hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, *****************************************************************************/ uint16_t hal_send_packet (hal_hdl_t hdl, uint16_t queue_id, - struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts) + hal_mbuf_t ** tx_pkts, uint16_t nb_pkts) { netif_inst_t *inst; diff --git a/src/framework/hal/hal.h b/src/framework/hal/hal.h index 2f66914..36ad79d 100644 --- a/src/framework/hal/hal.h +++ b/src/framework/hal/hal.h @@ -59,7 +59,7 @@ typedef struct dpdk_if uint32_t rx_queue_num; uint32_t rx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; - struct rte_mempool *rx_pool[HAL_ETH_MAX_QUEUE_NUM]; + hal_mempool_t *rx_pool[HAL_ETH_MAX_QUEUE_NUM]; uint32_t tx_queue_num; uint32_t tx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; @@ -103,9 +103,9 @@ typedef struct netif_ops int (*macaddr) (netif_inst_t * inst, void *mac_addr); int (*capability) (netif_inst_t * inst, hal_netif_capa_t * info); uint16_t (*recv) (netif_inst_t * inst, uint16_t queue_id, - struct common_mem_mbuf ** rx_pkts, uint16_t nb_pkts); + hal_mbuf_t ** rx_pkts, uint16_t nb_pkts); uint16_t (*send) (netif_inst_t * inst, uint16_t queue_id, - struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts); + hal_mbuf_t ** tx_pkts, uint16_t nb_pkts); uint32_t (*link_status) (netif_inst_t * inst); int (*stats) (netif_inst_t * inst, hal_netif_stats_t * stats); int (*stats_reset) (netif_inst_t * inst); diff --git a/src/framework/include/dmm_config.h b/src/framework/include/dmm_config.h new file mode 100644 index 0000000..43a06ab --- /dev/null +++ b/src/framework/include/dmm_config.h @@ -0,0 +1,43 @@ +/* +* +* 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 _DMM_CONFIG_H_ +#define _DMM_CONFIG_H_ + +#ifndef DMM_VAR_DIR +#define DMM_VAR_DIR "/var/run" +#endif + +#ifndef DMM_MAIN_SHARE_TYPE +#define DMM_MAIN_SHARE_TYPE DMM_SHARE_FSHM /* 1 */ +#endif + +#ifndef DMM_MAIN_SHARE_SIZE +#define DMM_MAIN_SHARE_SIZE 1024 /* Megabyte */ +#endif + +#ifndef DMM_SHARE_TYPE +#define DMM_SHARE_TYPE DMM_SHARE_FSHM /* 1 */ +#endif + +#ifndef DMM_SHARE_SIZE +#define DMM_SHARE_SIZE 16 /* Megabyte */ +#endif + +#ifndef DMM_HUGE_DIR +#define DMM_HUGE_DIR "/mnt/dmm-huge" +#endif + +#endif /* _DMM_CONFIG_H_ */ diff --git a/src/framework/include/hal_api.h b/src/framework/include/hal_api.h index 24ed779..90c3100 100644 --- a/src/framework/include/hal_api.h +++ b/src/framework/include/hal_api.h @@ -17,16 +17,15 @@ #ifndef _HAL_API_H_ #define _HAL_API_H_ -#include "common_mem_mbuf.h" -#include "common_mem_mempool.h" -#include "common_func.h" - #ifdef __cplusplus /* *INDENT-OFF* */ extern "C" { /* *INDENT-ON* */ #endif +typedef void hal_mempool_t; +typedef void hal_mbuf_t; + #define HAL_ETH_MAX_QUEUE_NUM 4 #define HAL_ETH_QUEUE_STAT_CNTRS 16 @@ -98,7 +97,7 @@ typedef struct hal_netif_config { uint32_t queue_num; uint32_t ring_size[HAL_ETH_MAX_QUEUE_NUM]; - struct common_mem_mempool *ring_pool[HAL_ETH_MAX_QUEUE_NUM]; + hal_mempool_t *ring_pool[HAL_ETH_MAX_QUEUE_NUM]; } rx; struct @@ -125,9 +124,9 @@ uint32_t hal_get_mtu (hal_hdl_t hdl); void hal_get_macaddr (hal_hdl_t hdl, void *mac_addr); void hal_get_capability (hal_hdl_t hdl, hal_netif_capa_t * info); uint16_t hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, - struct common_mem_mbuf **rx_pkts, uint16_t nb_pkts); + hal_mbuf_t ** rx_pkts, uint16_t nb_pkts); uint16_t hal_send_packet (hal_hdl_t hdl, uint16_t queue_id, - struct common_mem_mbuf **tx_pkts, uint16_t nb_pkts); + hal_mbuf_t ** tx_pkts, uint16_t nb_pkts); uint32_t hal_link_status (hal_hdl_t hdl); int hal_stats (hal_hdl_t hdl, hal_netif_stats_t * stats); void hal_stats_reset (hal_hdl_t hdl); diff --git a/src/framework/include/nsfw_mem_api.h b/src/framework/include/nsfw_mem_api.h index 68adbe1..db7f5e7 100644 --- a/src/framework/include/nsfw_mem_api.h +++ b/src/framework/include/nsfw_mem_api.h @@ -83,7 +83,7 @@ typedef struct * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add * _(pid) at the end of name, nstack_123. */ - i8 aname[NSFW_MEM_NAME_LENGTH]; /*the length of name must be less than NSFW_MEM_APPNAME_LENGTH. */ + i8 aname[NSFW_MEM_NAME_LENGTH]; /*the length of name must be less than NSFW_MEM_APPNAME_LENGTH. */ } nsfw_mem_name; typedef struct diff --git a/src/framework/include/nsfw_mgr_com_api.h b/src/framework/include/nsfw_mgr_com_api.h index 094043e..56ec08f 100644 --- a/src/framework/include/nsfw_mgr_com_api.h +++ b/src/framework/include/nsfw_mgr_com_api.h @@ -107,7 +107,7 @@ typedef enum _fw_poc_type NSFW_PROC_MAX = 16 } fw_poc_type; -#define NSFW_DOMAIN_DIR "/var/run" +#define NSFW_DOMAIN_DIR "/var/log/nStack/ip_module/" #define NSTACK_MAX_PROC_NAME_LEN 20 typedef enum _nsfw_mgr_msg_rsp_code diff --git a/src/framework/include/nstack_log.h b/src/framework/include/nstack_log.h index 67e5b29..4e1ba81 100644 --- a/src/framework/include/nstack_log.h +++ b/src/framework/include/nstack_log.h @@ -41,7 +41,7 @@ #define NSTACK_GETVER_MODULE "nStack" #ifndef NSTACK_GETVER_VERSION - #error "need define version first" +#error "need define version first" #endif #define NSTACK_GETVER_BUILDTIME "[" __DATE__ "]" "[" __TIME__ "]" @@ -106,7 +106,7 @@ enum _LOG_PROCESS #define GET_FILE_NAME(name_have_path) strrchr(name_have_path,'/')?strrchr(name_have_path,'/')+1:name_have_path -#define NSTACK_LOG_NAME "/product/gpaas/log/nStack" +#define NSTACK_LOG_NAME "/var/log/nStack/" #define STACKX_LOG_NAME "running.log" @@ -118,7 +118,7 @@ enum _LOG_PROCESS #define FAILURE_LOG_NAME "fail_dump.log" -#define FLUSH_TIME 30 +#define FLUSH_TIME 10 #define APP_LOG_SIZE 30 #define APP_LOG_COUNT 10 diff --git a/src/framework/ipc/mgr_com/mgr_com.c b/src/framework/ipc/mgr_com/mgr_com.c index 2b35e2c..bc2aca2 100644 --- a/src/framework/ipc/mgr_com/mgr_com.c +++ b/src/framework/ipc/mgr_com/mgr_com.c @@ -32,6 +32,7 @@ #include <stddef.h> #include <sys/epoll.h> #include <fcntl.h> +#include <sys/stat.h> #include "nsfw_maintain_api.h" #include "nsfw_ps_api.h" @@ -320,8 +321,9 @@ nsfw_mgr_msg_free (nsfw_mgr_msg * msg) i32 nsfw_mgr_get_listen_socket () { - i32 fd, len; + i32 fd, len, retVal; struct sockaddr_un un; + char name[NSFW_MGRCOM_PATH_LEN] = { 0 }; if ((fd = nsfw_base_socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { @@ -329,7 +331,23 @@ nsfw_mgr_get_listen_socket () return -1; } - if (-1 == unlink ((char *) g_mgr_com_cfg.domain_path)) + retVal = STRCPY_S ((char *) name, sizeof (name), + (char *) g_mgr_com_cfg.domain_path); + if (EOK != retVal) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("module mgr get listen STRCPY_S failed! ret=%d", retVal); + return -1; + } + + if (EOK != STRCAT_S (name, NSFW_MGRCOM_PATH_LEN, NSFW_MAIN_FILE)) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("module mgr get listen STRCAT_S failed!"); + return -1; + } + + if (-1 == unlink ((char *) name)) { NSFW_LOGWAR ("unlink failed]error=%d", errno); } @@ -341,8 +359,8 @@ nsfw_mgr_get_listen_socket () } un.sun_family = AF_UNIX; - int retVal = STRCPY_S ((char *) un.sun_path, sizeof (un.sun_path), - (char *) g_mgr_com_cfg.domain_path); + retVal = STRCPY_S ((char *) un.sun_path, sizeof (un.sun_path), + (char *) name); if (EOK != retVal) { (void) nsfw_base_close (fd); @@ -358,9 +376,7 @@ nsfw_mgr_get_listen_socket () return -1; } - len = - offsetof (struct sockaddr_un, - sun_path) +strlen ((char *) g_mgr_com_cfg.domain_path); + len = offsetof (struct sockaddr_un, sun_path) +strlen ((char *) name); if (nsfw_base_bind (fd, (struct sockaddr *) &un, len) < 0) { @@ -1807,6 +1823,58 @@ nsfw_mgr_comm_fd_init (u32 proc_type) } /***************************************************************************** +* Prototype : nsfw_mgr_com_mkdir_domainpath +* Description : check whether the domain path exist.if not exist, create it. +* Input : char *pathname +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void nsfw_mgr_com_mkdir_domainpath (char *pathname); +void +nsfw_mgr_com_mkdir_domainpath (char *pathname) +{ + char dirname[NSFW_MGRCOM_PATH_LEN] = { 0 }; + int i, len; + + if (NULL == pathname) + { + NSFW_LOGERR ("the pathname is null."); + return; + } + + strncpy (dirname, pathname, NSFW_MGRCOM_PATH_LEN - 1); + len = strlen (dirname); + if (dirname[len - 1] != '/') + strncat (dirname, "/", 2); + + if (access (dirname, F_OK) == 0) + return; + + len = strlen (dirname); + + for (i = 1; i < len; i++) + { + if (dirname[i] == '/') + { + dirname[i] = 0; + if (access (dirname, F_OK) != 0) + { + if (mkdir (dirname, 0755) == -1) + { + NSFW_LOGERR ("mkdir:%s error", dirname); + return; + } + } + dirname[i] = '/'; + } + } + + return; +} + +/***************************************************************************** * Prototype : nsfw_mgr_com_module_init * Description : module init * Input : void* param @@ -1849,15 +1917,7 @@ nsfw_mgr_com_module_init (void *param) return -1; } - /* modify destMax, remove "-1" */ - if (EOK != - STRCAT_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, - NSFW_MAIN_FILE)) - { - NSFW_LOGERR ("module mgr init STRCAT_S failed!"); - lint_unlock_1 (); - return -1; - } + nsfw_mgr_com_mkdir_domainpath (mgr_cfg->domain_path); NSFW_LOGINF ("module mgr init]NSFW_PROC_MAIN domain_path=%s", mgr_cfg->domain_path); @@ -1880,16 +1940,6 @@ nsfw_mgr_com_module_init (void *param) return -1; } - /* modify destMax, remove "-1" */ - if (EOK != - STRCAT_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, - NSFW_MASTER_FILE)) - { - NSFW_LOGERR ("module mgr init STRCAT_S failed!"); - lint_unlock_1 (); - return -1; - } - NSFW_LOGINF ("module mgr init]NSFW_PROC_MASTER domain_path=%s", mgr_cfg->domain_path); diff --git a/src/framework/ipc/mgr_com/mgr_com.h b/src/framework/ipc/mgr_com/mgr_com.h index a5cdfcf..03f58c8 100644 --- a/src/framework/ipc/mgr_com/mgr_com.h +++ b/src/framework/ipc/mgr_com/mgr_com.h @@ -29,7 +29,7 @@ #include "pthread.h" #include "nsfw_mem_api.h" #include "common_mem_api.h" - +#include "common_mem_memzone.h" #include "common_func.h" #ifdef __cplusplus @@ -52,8 +52,8 @@ extern "C"{ #define MGR_COM_RECV_TIMEOUT (g_mgr_com_cfg.max_recv_timeout) #define MGR_COM_MAX_DROP_MSG (g_mgr_com_cfg.max_recv_drop_msg) -#define NSFW_MAIN_FILE "/ip_module/nStackMainMgr" -#define NSFW_MASTER_FILE "/ip_module/nStackMasterMgr" +#define NSFW_MAIN_FILE "nStackMainMgr" +#define NSFW_MASTER_FILE "nStackMasterMgr" #define NSFW_ALARM_FILE "/HuskyAlarm.domain" #define NSFW_MGRCOM_THREAD "nStackMgrCom" diff --git a/src/framework/ipc/ps/nsfw_fd_timer.c b/src/framework/ipc/ps/nsfw_fd_timer.c index 8c73ec0..55d35cb 100644 --- a/src/framework/ipc/ps/nsfw_fd_timer.c +++ b/src/framework/ipc/ps/nsfw_fd_timer.c @@ -22,6 +22,8 @@ #include "types.h" #include "list.h" +#include "common_mem_common.h" + #include "nstack_securec.h" #include "nsfw_init.h" #include "nsfw_mgr_com_api.h" diff --git a/src/framework/ipc/ps/nsfw_ps_module.c b/src/framework/ipc/ps/nsfw_ps_module.c index 0a02e6c..e600bf7 100644 --- a/src/framework/ipc/ps/nsfw_ps_module.c +++ b/src/framework/ipc/ps/nsfw_ps_module.c @@ -39,6 +39,7 @@ #include <linux/netlink.h> #include <dirent.h> #include <fnmatch.h> +#include "common_mem_common.h" #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/framework/ipc/ps/nsfw_soft_param.c b/src/framework/ipc/ps/nsfw_soft_param.c index d458040..91d7598 100644 --- a/src/framework/ipc/ps/nsfw_soft_param.c +++ b/src/framework/ipc/ps/nsfw_soft_param.c @@ -97,13 +97,15 @@ nsfw_soft_set_int (u32 param, char *buf, u32 buf_len) nsfw_set_soft_item *int_item = &g_soft_int_cfg[param]; if (NULL == int_item->data) { - NSFW_LOGERR ("data err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch + NSFW_LOGERR ("data err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, + int_item->min, int_item->max); return FALSE; } if (buf_value < int_item->min || buf_value > int_item->max) { - NSFW_LOGERR ("argv err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch + NSFW_LOGERR ("argv err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, + int_item->min, int_item->max); return FALSE; } diff --git a/src/framework/lib_common_mem/common_api.c b/src/framework/lib_common_mem/common_api.c index b535ee6..566b8be 100644 --- a/src/framework/lib_common_mem/common_api.c +++ b/src/framework/lib_common_mem/common_api.c @@ -29,7 +29,7 @@ sys_sem_init_v2 (sys_sem_t_v2 sem) /** Returns the current time in milliseconds, * may be the same as sys_jiffies or at least based on it. */ -long +u32_t sys_now (void) { struct timespec now; diff --git a/src/framework/lib_common_mem/common_buf.c b/src/framework/lib_common_mem/common_buf.c index 654bd46..9d9a127 100644 --- a/src/framework/lib_common_mem/common_buf.c +++ b/src/framework/lib_common_mem/common_buf.c @@ -88,7 +88,7 @@ int log_level = LOG_INFO; int -nscomm_pal_module_init (common_mem_pal_module_info * pinfo) +nscomm_pal_module_init (common_mem_pal_module_info * pinfo, u8 app_mode) { char tempargv[PATA_NUM_MAX][PATA_STRLENT]; char *argv[PATA_NUM_MAX]; @@ -98,6 +98,8 @@ nscomm_pal_module_init (common_mem_pal_module_info * pinfo) int agindex = 0; int intmask = 0; int retVal; + char name[10] = { '\0' }; + retVal = MEMSET_S (tempargv, sizeof (tempargv), '\0', sizeof (tempargv)); if (EOK != retVal) { @@ -115,15 +117,32 @@ nscomm_pal_module_init (common_mem_pal_module_info * pinfo) PARA1_SET (argv, tempargv, agindex, "nStackMain"); PARA2_SET (argv, tempargv, agindex, "-c", "0x1"); PARA2_SET (argv, tempargv, agindex, "-n", "4"); - PARA2_SET (argv, tempargv, agindex, "-m", "2048"); 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"); - /*[DTS2017032711606 ][2017-04-08][z00353090] There are some unsafe function ,need to be replace with safe function */ retVal = SPRINTF_S (tempbuf, PATA_STRLENT, "0x"); if (-1 == retVal) { diff --git a/src/framework/lib_common_mem/common_func.c b/src/framework/lib_common_mem/common_func.c index f68380f..5220374 100644 --- a/src/framework/lib_common_mem/common_func.c +++ b/src/framework/lib_common_mem/common_func.c @@ -137,7 +137,7 @@ dmm_pktmbuf_pool_iterator (struct common_mem_mempool * mp, uint32_t start, } int32_t elm_size = mp->elt_size + mp->header_size + mp->trailer_size; - struct common_mem_mbuf *elm_mbuf = (struct common_mem_mbuf *) (mp->elt_va_start + start * elm_size + mp->header_size); /*lint !e647 */ + 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; diff --git a/src/framework/log/nstack_log.c b/src/framework/log/nstack_log.c index 5e62ad7..6678996 100644 --- a/src/framework/log/nstack_log.c +++ b/src/framework/log/nstack_log.c @@ -576,6 +576,31 @@ app_default: } /***************************************************************************** +* Prototype : nstack_get_app_logname +* Description : get the name of app's log +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nstack_get_app_logname (char* log_name) +{ + int pid = getpid (); + char processname[FILE_NAME_LEN] = {0}; + + if (log_name == NULL) + return 1; + + strncpy (processname, program_invocation_short_name, 10); + + snprintf (log_name, FILE_NAME_LEN, "app_%s_%d.log", processname, pid); + + return 0; +} + +/***************************************************************************** * Prototype : nstack_log_init_app * Description : called by environment-specific log init function * Input : None @@ -592,6 +617,8 @@ nstack_log_init_app () int i = 0; int file_flag = 0; char app_log_path[FILE_NAME_LEN] = { 0 }; + int ret = 0; + char app_log_name[FILE_NAME_LEN] = { 0 }; /* log already initialized, just return */ if (LOG_PRO_INVALID != g_my_pro_type) @@ -661,7 +688,15 @@ nstack_log_init_app () glogSetLogSymlink (i, ""); nstack_log_count_set (APP_LOG_COUNT); glogMaxLogSizeSet (APP_LOG_SIZE); - glogSetLogFilenameExtension (APP_LOG_NAME); + ret = nstack_get_app_logname (app_log_name); + if (ret == 0) + { + glogSetLogFilenameExtension (app_log_name); + } + else + { + glogSetLogFilenameExtension (APP_LOG_NAME); + } glogFlushLogSecsSet (FLUSH_TIME); } else diff --git a/src/framework/mem/dmm_fshm.c b/src/framework/mem/dmm_fshm.c new file mode 100644 index 0000000..605c728 --- /dev/null +++ b/src/framework/mem/dmm_fshm.c @@ -0,0 +1,144 @@ +/* +* +* 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 <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include "dmm_config.h" +#include "dmm_share.h" +#include "dmm_fs.h" + +#define DMM_FSHM_FMT "%s/dmm-fshm-%d" /* VAR_DIR pid */ + +inline static void +set_fshm_path (struct dmm_share *share) +{ + (void) snprintf (share->path, sizeof (share->path), DMM_FSHM_FMT, + DMM_VAR_DIR, share->pid); +} + +/* +input: share->path, share->size, share->pid +output: share->base +*/ +int +dmm_fshm_create (struct dmm_share *share) +{ + int fd, ret; + void *base; + + set_fshm_path (share); + + fd = open (share->path, O_RDWR | O_CREAT, 0666); + if (fd < 0) + { + return -1; + } + + ret = ftruncate (fd, share->size); + if (ret < 0) + { + (void) close (fd); + return -1; + } + + base = mmap (NULL, share->size, + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); + if (base == MAP_FAILED) + { + (void) close (fd); + return -1; + } + + share->base = base; + + (void) close (fd); + return 0; +} + +int +dmm_fshm_delete (struct dmm_share *share) +{ + (void) munmap (share->base, share->size); + (void) unlink (share->path); + + return 0; +} + +/* +input: share->path, share->size, share->base(OPT) +output: share->base(if-null) +*/ +int +dmm_fshm_attach (struct dmm_share *share) +{ + int fd; + void *base; + + if (share->type != DMM_SHARE_FSHM) + { + return -1; + } + + fd = open (share->path, O_RDWR); + if (fd < 0) + { + return -1; + } + + if (share->size <= 0) + { + share->size = dmm_file_size (fd); + if (share->size == 0) + { + (void) close (fd); + return -1; + } + } + + base = mmap (share->base, share->size, + PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); + if (base == MAP_FAILED) + { + (void) close (fd); + return -1; + } + + if (NULL == share->base) + { + share->base = base; + } + else if (base != share->base) + { + (void) munmap (base, share->size); + (void) close (fd); + return -1; + } + + (void) close (fd); + return 0; +} + +int +dmm_fshm_detach (struct dmm_share *share) +{ + (void) munmap (share->base, share->size); + + return 0; +} diff --git a/src/framework/mem/dmm_group.c b/src/framework/mem/dmm_group.c new file mode 100644 index 0000000..35e6100 --- /dev/null +++ b/src/framework/mem/dmm_group.c @@ -0,0 +1,185 @@ +/* +* +* 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <sys/types.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/mman.h> + +//#include "dmm_memory.h" +#include "dmm_config.h" +#include "dmm_group.h" +#include "dmm_pause.h" + +#define DMM_GROUP_ACTIVE 0x55D5551 +#define DMM_GROUP_GLOBAL "global" +#define DMM_GROUP_ENV "DMM_GROUP" +#define DMM_GROUP_FMT "%s/dmm-group-%s" /* VAR_DIR group-name */ + +static struct flock group_lock = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = sizeof (struct dmm_group), +}; + +static int group_fd = -1; +struct dmm_group *main_group = NULL; + +inline static const char * +get_group_path () +{ + static char group_path[PATH_MAX] = ""; + + if (!group_path[0]) + { + const char *group = getenv (DMM_GROUP_ENV); + + if (!group || !group[0]) + group = DMM_GROUP_GLOBAL; + + (void) snprintf (group_path, sizeof (group_path), DMM_GROUP_FMT, + DMM_VAR_DIR, group); + group_path[sizeof (group_path) - 1] = 0; + } + + return group_path; +} + +void +dmm_group_active () +{ + main_group->group_init = DMM_GROUP_ACTIVE; +} + +int +dmm_group_create_main () +{ + int ret; + const char *path = get_group_path (); + + group_fd = open (path, O_RDWR | O_CREAT, 0664); + if (group_fd < 0) + { + return -1; + } + + ret = ftruncate (group_fd, sizeof (struct dmm_group)); + if (ret < 0) + { + (void) close (group_fd); + group_fd = -1; + return -1; + } + + ret = fcntl (group_fd, F_SETLK, &group_lock); + if (ret < 0) + { + (void) close (group_fd); + group_fd = -1; + return -1; + } + + main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group), + PROT_READ | PROT_WRITE, MAP_SHARED, + group_fd, 0); + + if (main_group == MAP_FAILED) + { + (void) close (group_fd); + group_fd = -1; + return -1; + } + + return 0; +} + +int +dmm_group_delete_main () +{ + if (main_group) + { + (void) munmap (main_group, sizeof (struct dmm_group)); + main_group = NULL; + } + + if (group_fd >= 0) + { + (void) close (group_fd); + group_fd = -1; + } + + (void) unlink (get_group_path ()); + + return 0; +} + +int +dmm_group_attach_main () +{ + const char *path = get_group_path (); + + group_fd = open (path, O_RDONLY); + if (group_fd < 0) + { + return -1; + } + + main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group *), + PROT_READ, MAP_SHARED, group_fd, 0); + if (main_group == MAP_FAILED) + { + (void) close (group_fd); + group_fd = -1; + return -1; + } + + while (main_group->group_init != DMM_GROUP_ACTIVE) + { + dmm_pause (); + } + + if (kill (main_group->share.pid, 0)) + { + (void) munmap (main_group->share.base, main_group->share.size); + (void) close (group_fd); + group_fd = -1; + return -1; + } + + return 0; +} + +int +dmm_group_detach_main () +{ + if (main_group) + { + (void) munmap (main_group, sizeof (struct dmm_group)); + main_group = NULL; + } + + if (group_fd >= 0) + { + (void) close (group_fd); + group_fd = -1; + } + + return 0; +} diff --git a/src/framework/mem/dmm_group.h b/src/framework/mem/dmm_group.h new file mode 100644 index 0000000..b11a22b --- /dev/null +++ b/src/framework/mem/dmm_group.h @@ -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. +*/ + +#ifndef _DMM_GROUP_H_ +#define _DMM_GROUP_H_ + +#include "dmm_share.h" + +struct dmm_group +{ + volatile int group_init; + struct dmm_share share; +}; + +extern struct dmm_group *main_group; + +void dmm_group_active (); +int dmm_group_create_main (); +int dmm_group_delete_main (); +int dmm_group_attach_main (); +int dmm_group_detach_main (); + +#endif /* _DMM_GROUP_H_ */ diff --git a/src/framework/mem/dmm_heap.c b/src/framework/mem/dmm_heap.c new file mode 100644 index 0000000..bc966ef --- /dev/null +++ b/src/framework/mem/dmm_heap.c @@ -0,0 +1,83 @@ +/* +* +* 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 <sys/types.h> + +#include "dmm_config.h" +#include "dmm_share.h" + +struct heap_path +{ + void *base; + size_t size; +}; + +int +dmm_heap_create (struct dmm_share *share) +{ + share->base = malloc (share->size); + + if (share->base) + { + struct heap_path *hp = (struct heap_path *) share->path; + hp->base = share->base; + hp->size = share->size; + return 0; + } + + return -1; +} + +int +dmm_heap_delete (struct dmm_share *share) +{ + free (share->base); + return 0; +} + +int +dmm_heap_attach (struct dmm_share *share) +{ + struct heap_path *hp = (struct heap_path *) share->path; + + if (share->base) + { + if (hp->base != share->base) + return -1; + } + else + { + share->base = hp->base; + } + + if (share->size) + { + if (share->size != hp->size) + return -1; + } + else + { + share->size = hp->size; + } + + return 0; +} + +int +dmm_heap_detach (struct dmm_share *share) +{ + return 0; +} diff --git a/src/framework/mem/dmm_huge.c b/src/framework/mem/dmm_huge.c new file mode 100644 index 0000000..735c507 --- /dev/null +++ b/src/framework/mem/dmm_huge.c @@ -0,0 +1,53 @@ +/* +* +* 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 <stdio.h> +#include <sys/types.h> + +#include "dmm_config.h" +#include "dmm_share.h" + +#define DMM_HUGE_FMT "%s/dmm-%d-%d" /* HUGE_DIR pid index */ + +inline static void +huge_set_path (struct dmm_share *share, int index) +{ + (void) snprintf (share->path, sizeof (share->path), DMM_HUGE_FMT, + DMM_HUGE_DIR, share->pid, index); +} + +int +dmm_huge_create (struct dmm_share *share) +{ + return -1; +} + +int +dmm_huge_delete (struct dmm_share *share) +{ + return -1; +} + +int +dmm_huge_attach (struct dmm_share *share) +{ + return -1; +} + +int +dmm_huge_detach (struct dmm_share *share) +{ + return -1; +} diff --git a/src/framework/mem/dmm_memory.c b/src/framework/mem/dmm_memory.c new file mode 100644 index 0000000..0352432 --- /dev/null +++ b/src/framework/mem/dmm_memory.c @@ -0,0 +1,133 @@ +/* +* +* 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 "dmm_config.h" +#include "dmm_memory.h" +#include "dmm_group.h" + +#define DMM_MEGABYTE (1024 * 1024) + +/* shared from main process */ +static struct dmm_share *main_share = NULL; +struct dmm_segment *main_seg = NULL; + +/* shared by process tree */ +static struct dmm_share base_share = { 0 }; + +struct dmm_segment *base_seg = NULL; + +int +dmm_mem_main_init () +{ + int ret; + + ret = dmm_group_create_main (); + if (ret) + { + return -1; + } + + main_share = &main_group->share; + main_share->type = DMM_MAIN_SHARE_TYPE; + main_share->size = DMM_MAIN_SHARE_SIZE * DMM_MEGABYTE; + main_share->base = NULL; + main_share->pid = getpid (); + ret = dmm_share_create (main_share); + if (ret) + { + return -1; + } + + main_seg = dmm_seg_create (main_share->base, main_share->size); + if (!main_seg) + { + return -1; + } + + dmm_group_active (); + + return 0; +} + +int +dmm_mem_main_exit () +{ + dmm_group_delete_main (); + return 0; +} + +int +dmm_mem_app_init () +{ + int ret; + + ret = dmm_group_attach_main (); + if (0 == ret) + { + main_share = &main_group->share; + ret = dmm_share_attach (main_share); + if (ret) + { + return -1; + } + + main_seg = dmm_seg_attach (main_share->base, main_share->size); + if (!main_seg) + { + return -1; + } + + /* now share main process share-memory */ + base_seg = main_seg; + } + else + { + base_share.type = DMM_SHARE_TYPE; + base_share.size = DMM_SHARE_SIZE * DMM_MEGABYTE; + base_share.base = NULL; + base_share.pid = getpid (); + ret = dmm_share_create (&base_share); + if (ret) + { + return -1; + } + + base_seg = dmm_seg_create (base_share.base, base_share.size); + if (!base_seg) + { + return -1; + } + } + + return 0; +} + +int +dmm_mem_app_exit () +{ + dmm_group_detach_main (); + + if (base_share.base) + dmm_share_delete (&base_share); + + base_share.base = NULL; + base_seg = NULL; + main_seg = NULL; + + return 0; +} diff --git a/src/framework/mem/dmm_memory.h b/src/framework/mem/dmm_memory.h new file mode 100644 index 0000000..2fac118 --- /dev/null +++ b/src/framework/mem/dmm_memory.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 _DMM_MEMORY_H_ +#define _DMM_MEMORY_H_ +#include <stdio.h> +#include <stdarg.h> +#include "dmm_share.h" +#include "dmm_segment.h" + +int dmm_mem_main_init (); +int dmm_mem_main_exit (); + +int dmm_mem_app_init (); +int dmm_mem_app_exit (); + +extern struct dmm_segment *main_seg; +extern struct dmm_segment *base_seg; + +inline static void * +dmm_map (size_t size, const char name[DMM_MEM_NAME_SIZE]) +{ + return dmm_mem_map (base_seg, size, name); +} + +inline static void * +dmm_mapv (size_t size, const char *name_fmt, ...) +{ + int len; + char name[DMM_MEM_NAME_SIZE]; + va_list ap; + + va_start (ap, name_fmt); + len = vsnprintf (name, DMM_MEM_NAME_SIZE, name_fmt, ap); + va_end (ap); + + if (len >= DMM_MEM_NAME_SIZE) + return NULL; + + return dmm_map (size, name); +} + +inline static void * +dmm_lookup (const char name[DMM_MEM_NAME_SIZE]) +{ + return dmm_mem_lookup (base_seg, name); +} + +inline static void * +dmm_lookupv (const char *name_fmt, ...) +{ + int len; + char name[DMM_MEM_NAME_SIZE]; + va_list ap; + + va_start (ap, name_fmt); + len = vsnprintf (name, DMM_MEM_NAME_SIZE, name_fmt, ap); + va_end (ap); + + if (len >= DMM_MEM_NAME_SIZE) + return NULL; + + return dmm_mem_lookup (base_seg, name); +} + +#endif /* _DMM_MEMORY_H_ */ diff --git a/src/framework/mem/dmm_segment.c b/src/framework/mem/dmm_segment.c new file mode 100644 index 0000000..6358506 --- /dev/null +++ b/src/framework/mem/dmm_segment.c @@ -0,0 +1,543 @@ +/* +* +* 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 <stdio.h> +#include <string.h> +#include "dmm_rwlock.h" +#include "dmm_segment.h" +#include "nstack_log.h" + +#define SECTION_SIZE 64 /* cache line size */ + +#define FIRST_NAME "FIRST SECTION FOR SEGMENT" +#define LAST_NAME "LAST SECTION FOR FREE HEAD" + +#define MEM_ERR(fmt, ...) \ + NS_LOGPID(LOGFW, "DMM-MEM", NSLOG_ERR, fmt, ##__VA_ARGS__) + +/* +init create: + \--total number + /--head no align \ can be used \--tail no align + / ___________________/\___________________ \ +/\/ \/\ +__<F>{S}[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]<L>__ +^ \ /\ /\____________ ________________/\ / +| | | \ / | +| | +--the segment | +--last section(free:0 used:0) +| +--first section(prev_rel:0 used:2 free:11 req_size:sizeof(dmm_segment)) ++--base address + +init: <F>{S}[ ]<L> +alloc A: <F>{S}[ ]<A>#########<L> +alloc B: <F>{S}[ ]<B>#########<A>#########<L> +free A: <F>{S}[ ]<B>#########[ ]<L> +alloc C: <F>{S}[ ]<C>###<B>#########[ ]<L> +*/ + +typedef struct dmm_section +{ + int prev_rel; + int used_num; + int free_num; + int __flags; /* reserved */ + size_t req_size; /* in bytes */ + int less_rel; /* for free list */ + int more_rel; /* for free list */ + char name[DMM_MEM_NAME_SIZE]; +} __attribute__ ((__aligned__ (SECTION_SIZE))) section_t; +SIZE_OF_TYPE_EQUAL_TO (section_t, SECTION_SIZE); + +struct dmm_segment +{ + void *base; /* base address(maybe not align) */ + size_t size; /* full size */ + section_t *first; /* aligned 64 */ + section_t *last; /* last section used to handle free list */ + dmm_rwlock_t lock; + int total_num; /* MAX:2147483647 ==> MAX size: 128M-64 */ + int used_num; + int sec_num; + size_t used_size; /* real alloc size bytes */ +}; + +/* calculate segment number, auto align 64, include 1 section_t */ +inline static int +CALC_NUM (size_t size) +{ + if (size) + { + const size_t MASK = SECTION_SIZE - 1; + return (size + MASK) / SECTION_SIZE + 1; + } + + return 2; /* if size is 0, then alloc 1 block */ +} + +inline static int +SEC_REL (const section_t * base, const section_t * sec) +{ + return sec - base; +} + +section_t * +REL_SEC (section_t * base, int rel) +{ + return base + rel; +} + +inline static int +SEC_INDEX (struct dmm_segment *seg, section_t * sec) +{ + return SEC_REL (seg->first, sec); +} + +inline static section_t * +LESS_SEC (section_t * sec) +{ + return sec + sec->less_rel; +} + +inline static section_t * +MORE_SEC (section_t * sec) +{ + return sec + sec->more_rel; +} + +inline static section_t * +PREV_SEC (section_t * sec) +{ + return sec + sec->prev_rel; +} + +inline static section_t * +NEXT_SEC (section_t * sec) +{ + return sec + (sec->free_num + sec->used_num); +} + +inline static int +CHECK_ADDR (struct dmm_segment *seg, void *mem) +{ + if (mem < (void *) seg->first) + return -1; + if (mem > (void *) seg->last) + return -1; + if ((long) mem & (SECTION_SIZE - 1)) + return -1; + + return 0; +} + +inline static section_t * +mem_lookup (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE]) +{ + section_t *sec; + + /* caller ensures the validity of the name */ + + for (sec = seg->last; sec != seg->first; sec = PREV_SEC (sec)) + { + if (sec->name[0] == 0) + continue; + if (0 == strcmp (sec->name, name)) + return sec; + } + + return NULL; +} + +static section_t * +mem_alloc (struct dmm_segment *seg, size_t size) +{ + const int num = CALC_NUM (size); + section_t *sec, *pos, *next, *less, *more; + + if (num > seg->total_num - seg->used_num) + { + /* no enough memory */ + return NULL; + } + + /* find enough free space */ + pos = seg->last; + do + { + pos = MORE_SEC (pos); + if (pos == seg->last) + { + /* no enough memory */ + return NULL; + } + } + while (num > pos->free_num); + + /* allocate pos pos section tail */ + + /* change next section's prev possion */ + next = NEXT_SEC (pos); + next->prev_rel = -num; + + /* create new section */ + sec = PREV_SEC (next); + sec->prev_rel = SEC_REL (sec, pos); + sec->used_num = num; + sec->req_size = size; + sec->free_num = 0; /* no free space */ + sec->less_rel = 0; + sec->more_rel = 0; + sec->name[0] = 0; + + /* adjust pos */ + pos->free_num -= num; + + less = LESS_SEC (pos); + more = MORE_SEC (pos); + + /* remove pos free list */ + less->more_rel = SEC_REL (less, more); + more->less_rel = SEC_REL (more, less); + pos->more_rel = 0; + pos->less_rel = 0; + + /* find position */ + while (less != seg->last) + { + if (pos->free_num >= less->free_num) + break; + less = LESS_SEC (less); + } + + /* insert into free list */ + more = MORE_SEC (less); + less->more_rel = SEC_REL (less, pos); + more->less_rel = SEC_REL (more, pos); + pos->more_rel = SEC_REL (pos, more); + pos->less_rel = SEC_REL (pos, less); + + /* adjust segment */ + seg->used_size += size; + seg->used_num += num; + seg->sec_num++; + + /* victory */ + return sec; +} + +static void +mem_free (struct dmm_segment *seg, section_t * sec) +{ + const int num = sec->used_num + sec->free_num; + section_t *next = NEXT_SEC (sec); + section_t *prev = PREV_SEC (sec); + section_t *more, *less; + + /* adjust next section's prev */ + next->prev_rel = SEC_REL (next, prev); + + if (sec->free_num) + { + /* remove from free list */ + more = MORE_SEC (sec); + less = LESS_SEC (sec); + more->less_rel = SEC_REL (more, less); + less->more_rel = SEC_REL (less, more); + } + + if (prev->free_num) + { + /* remove from free list */ + more = MORE_SEC (prev); + less = LESS_SEC (prev); + more->less_rel = SEC_REL (more, less); + less->more_rel = SEC_REL (less, more); + } + else + { + more = MORE_SEC (seg->last); + } + + /* put the space to prev's free space */ + prev->free_num += num; + + while (more != seg->last) + { + if (prev->free_num <= more->free_num) + break; + more = MORE_SEC (more); + } + less = LESS_SEC (more); + + /* insert */ + less->more_rel = SEC_REL (less, prev); + more->less_rel = SEC_REL (more, prev); + prev->more_rel = SEC_REL (prev, more); + prev->less_rel = SEC_REL (prev, less); + + /* adjust segment */ + seg->used_size -= sec->req_size; + seg->used_num -= sec->used_num; + seg->sec_num--; +} + +void +dmm_seg_dump (struct dmm_segment *seg) +{ + section_t *sec; + + dmm_read_lock (&seg->lock); + + (void) printf ("---- segment:%p base:%p size:%lu --------------\n" + " first[%d]:%p last[%d]:%p total_num:%d used_num:%d\n" + " sec_num:%d used_size:%lu use%%:%lu%% free%%:%lu%%\n", + seg, seg->base, seg->size, + SEC_INDEX (seg, seg->first), seg->first, + SEC_INDEX (seg, seg->last), seg->last, + seg->total_num, seg->used_num, + seg->sec_num, seg->used_size, + seg->used_size * 100 / seg->size, + (seg->total_num - + seg->used_num) * SECTION_SIZE * 100 / seg->size); + + (void) printf ("----------------------------------------\n" + "%18s %9s %9s %9s %9s %10s %9s %9s %s\n", + "PHYSICAL-ORDER", "section", "prev_rel", "used_num", + "free_num", "req_size", "less_rel", "more_rel", "name"); + + sec = seg->first; + while (1) + { + (void) printf ("%18p %9d %9d %9d %9d %10lu %9d %9d '%s'\n", + sec, SEC_INDEX (seg, sec), + sec->prev_rel, sec->used_num, sec->free_num, + sec->req_size, sec->less_rel, sec->more_rel, sec->name); + if (sec == seg->last) + break; + sec = NEXT_SEC (sec); + } + + (void) printf ("----------------------------------------\n" + "%18s %9s %9s\n", "FREE-ORDER", "section", "free_num"); + for (sec = MORE_SEC (seg->last); sec != seg->last; sec = MORE_SEC (sec)) + { + (void) printf ("%18p %9d %9d\n", + sec, SEC_INDEX (seg, sec), sec->free_num); + } + + (void) printf ("----------------------------------------\n"); + + dmm_read_unlock (&seg->lock); +} + +inline static int +align_section (void *base, size_t size, section_t ** first) +{ + const long MASK = ((long) SECTION_SIZE - 1); + const int SEG_NUM = CALC_NUM (sizeof (struct dmm_segment)); + + const long align = (long) base; + const long addr = (align + MASK) & (~MASK); + const size_t total = (size - (addr - align)) / SECTION_SIZE; + + if (total > 0x7fffFFFF) + return -1; + if (total < SEG_NUM + 1) /* first+segment + last */ + return -1; + + *first = (section_t *) addr; + return (int) total; +} + +struct dmm_segment * +dmm_seg_create (void *base, size_t size) +{ + const int SEG_NUM = CALC_NUM (sizeof (struct dmm_segment)); + section_t *first, *last; + struct dmm_segment *seg; + int total = align_section (base, size, &first); + + if (total <= 0) + return NULL; + + last = first + (total - 1); + + /* first section */ + first->prev_rel = 0; + first->used_num = SEG_NUM; + first->req_size = sizeof (struct dmm_segment); + first->free_num = total - (SEG_NUM + 1); + first->less_rel = SEC_REL (first, last); + first->more_rel = SEC_REL (first, last); + first->name[0] = 0; + (void) strncpy (&first->name[1], FIRST_NAME, sizeof (first->name) - 1); + + /* last section */ + last->prev_rel = SEC_REL (last, first); + last->used_num = 0; + last->req_size = 0; + last->free_num = 0; + last->less_rel = SEC_REL (last, first); + last->more_rel = SEC_REL (last, first); + last->name[0] = 0; + (void) strncpy (&last->name[1], LAST_NAME, sizeof (first->name) - 1); + + /* segment */ + seg = (struct dmm_segment *) (first + 1); + dmm_rwlock_init (&seg->lock); + seg->base = base; + seg->size = size; + seg->first = first; + seg->last = last; + seg->total_num = total; + seg->sec_num = 2; + seg->used_size = sizeof (struct dmm_segment); + seg->used_num = first->used_num; + + return seg; +} + +struct dmm_segment * +dmm_seg_attach (void *base, size_t size) +{ + section_t *first, *last; + struct dmm_segment *seg; + int total = align_section (base, size, &first); + + if (total <= 0) + return NULL; + + last = first + (total - 1); + seg = (struct dmm_segment *) (first + 1); + + if (seg->base != base) + return NULL; + if (seg->size != size) + return NULL; + if (seg->total_num != total) + return NULL; + + if (seg->first != first) + return NULL; + if (first->name[0] != 0) + return NULL; + if (strncmp (&first->name[1], FIRST_NAME, sizeof (first->name) - 1)) + return NULL; + + if (seg->last != last) + return NULL; + if (last->name[0] != 0) + return NULL; + if (strncmp (&last->name[1], LAST_NAME, sizeof (last->name) - 1)) + return NULL; + + return seg; +} + +void * +dmm_mem_alloc (struct dmm_segment *seg, size_t size) +{ + section_t *sec; + + dmm_write_lock (&seg->lock); + sec = mem_alloc (seg, size); + dmm_write_unlock (&seg->lock); + + return sec ? sec + 1 : NULL; +} + +int +dmm_mem_free (struct dmm_segment *seg, void *mem) +{ + if (CHECK_ADDR (seg, mem)) + { + MEM_ERR ("Invalid address:%p", mem); + return -1; + } + + dmm_write_lock (&seg->lock); + mem_free (seg, ((section_t *) mem) - 1); + dmm_write_unlock (&seg->lock); + + return 0; +} + +void * +dmm_mem_lookup (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE]) +{ + section_t *sec; + + if (!name || !name[0]) + return NULL; + + dmm_read_lock (&seg->lock); + sec = mem_lookup (seg, name); + dmm_read_unlock (&seg->lock); + + return sec ? sec + 1 : NULL; +} + +void * +dmm_mem_map (struct dmm_segment *seg, size_t size, + const char name[DMM_MEM_NAME_SIZE]) +{ + void *mem; + section_t *sec; + + if (!name || !name[0] || strlen (name) >= DMM_MEM_NAME_SIZE) + return NULL; + + dmm_write_lock (&seg->lock); + + sec = mem_lookup (seg, name); + if (sec) + { + MEM_ERR ("Map '%s' exist", name); + mem = NULL; + } + else if (!(sec = mem_alloc (seg, size))) + { + MEM_ERR ("alloc '%s' failed for size %lu", name, size); + mem = NULL; + } + else + { + (void) strncpy (sec->name, name, sizeof (sec->name)); + mem = sec + 1; + } + + dmm_write_unlock (&seg->lock); + + return mem; +} + +int +dmm_mem_unmap (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE]) +{ + section_t *sec; + + if (!name || !name[0]) + return -1; + + dmm_write_lock (&seg->lock); + + sec = mem_lookup (seg, name); + if (sec) + mem_free (seg, sec); + + dmm_write_unlock (&seg->lock); + + return sec != NULL ? 0 : -1; +} diff --git a/src/framework/mem/dmm_segment.h b/src/framework/mem/dmm_segment.h new file mode 100644 index 0000000..135f347 --- /dev/null +++ b/src/framework/mem/dmm_segment.h @@ -0,0 +1,35 @@ +/* +* +* 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 _DMM_SEGMENT_H_ +#define _DMM_SEGMENT_H_ + +#define DMM_MEM_NAME_SIZE 32 + +struct dmm_segment *dmm_seg_create (void *base, size_t size); +struct dmm_segment *dmm_seg_attach (void *base, size_t size); +void dmm_seg_dump (struct dmm_segment *seg); + +void *dmm_mem_alloc (struct dmm_segment *seg, size_t size); +int dmm_mem_free (struct dmm_segment *seg, void *mem); + +void *dmm_mem_lookup (struct dmm_segment *seg, + const char name[DMM_MEM_NAME_SIZE]); +void *dmm_mem_map (struct dmm_segment *seg, size_t size, + const char name[DMM_MEM_NAME_SIZE]); +int dmm_mem_unmap (struct dmm_segment *seg, + const char name[DMM_MEM_NAME_SIZE]); + +#endif /* #ifndef _DMM_SEGMENT_H_ */ diff --git a/src/framework/mem/dmm_share.h b/src/framework/mem/dmm_share.h new file mode 100644 index 0000000..0d0ff8f --- /dev/null +++ b/src/framework/mem/dmm_share.h @@ -0,0 +1,114 @@ +/* +* +* 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 _DMM_SHARE_H_ +#define _DMM_SHARE_H_ + +#define DMM_SHARE_PATH_MAX 100 + +enum dmm_share_type +{ + DMM_SHARE_HEAP, + DMM_SHARE_FSHM, + DMM_SHARE_HUGE, + + DMM_SHARE_ANY = -1 +}; + +struct dmm_share +{ + int type; /* share type enum dmm_share_type */ + pid_t pid; /* owner/creator pid */ + void *base; /* base logical address */ + size_t size; /* memory size */ + char path[DMM_SHARE_PATH_MAX]; /* share path */ +}; + +int dmm_heap_create (struct dmm_share *share); +int dmm_heap_delete (struct dmm_share *share); +int dmm_heap_attach (struct dmm_share *share); +int dmm_heap_detach (struct dmm_share *share); + +int dmm_fshm_create (struct dmm_share *share); +int dmm_fshm_delete (struct dmm_share *share); +int dmm_fshm_attach (struct dmm_share *share); +int dmm_fshm_detach (struct dmm_share *share); + +int dmm_huge_create (struct dmm_share *share); +int dmm_huge_delete (struct dmm_share *share); +int dmm_huge_attach (struct dmm_share *share); +int dmm_huge_detach (struct dmm_share *share); + +#define DMM_SHARE_DISPATCH(share, action) \ +({ \ + int _r; \ + switch (share->type) \ + { \ + case DMM_SHARE_HEAP: \ + _r = dmm_heap_##action(share); \ + break; \ + case DMM_SHARE_FSHM: \ + _r = dmm_fshm_##action(share); \ + break; \ + case DMM_SHARE_HUGE: \ + _r = dmm_huge_##action(share); \ + break; \ + default: \ + _r = -1; \ + } \ + _r; \ +}) + +/* create share memory +input: share->type, share->size, share->pid +output: share->base, share->path +*/ +inline static int +dmm_share_create (struct dmm_share *share) +{ + return DMM_SHARE_DISPATCH (share, create); +} + +/* delete share memory +input: share->type, share->base, share->size, share->path +*/ +inline static int +dmm_share_delete (struct dmm_share *share) +{ + return DMM_SHARE_DISPATCH (share, delete); +} + +/* attach share memory +input: share->type share->path [share->size] [share->base] +output: share->base, share->size +*/ +inline static int +dmm_share_attach (struct dmm_share *share) +{ + return DMM_SHARE_DISPATCH (share, attach); +} + +/* attach share memory +input: share->type share->size share->base +*/ +inline static int +dmm_share_detach (struct dmm_share *share) +{ + return DMM_SHARE_DISPATCH (share, detach); +} + +#undef DMM_SHARE_DISPATCH + +#endif /* #ifndef _DMM_SHARE_H_ */ diff --git a/src/nSocket/include/nstack_dmm_api.h b/src/nSocket/include/nstack_dmm_api.h index 481e144..ab06650 100644 --- a/src/nSocket/include/nstack_dmm_api.h +++ b/src/nSocket/include/nstack_dmm_api.h @@ -57,6 +57,7 @@ typedef enum typedef struct __nstack_extern_ops { int (*module_init) (void); /*stack module init */ + int (*module_init_child) (void); /*stack module init for child process */ int (*fork_init_child) (pid_t p, pid_t c); /*after fork, stack child process init again if needed. */ void (*fork_parent_fd) (int s, pid_t p); /*after fork, stack parent process proc again if needed. */ void (*fork_child_fd) (int s, pid_t p, pid_t c); /*after fork, child record pid for recycle if needed. */ @@ -87,6 +88,6 @@ typedef struct __nstack_proc_cb } nstack_proc_cb; typedef int (*nstack_stack_register_fn) (nstack_proc_cb * proc_fun, - nstack_event_cb * event_ops); + nstack_event_cb * event_ops); #endif diff --git a/src/nSocket/include/nstack_select.h b/src/nSocket/include/nstack_select.h index 5c84846..659c477 100644 --- a/src/nSocket/include/nstack_select.h +++ b/src/nSocket/include/nstack_select.h @@ -141,6 +141,8 @@ extern i32 select_add_cb (struct select_entry *entry); extern i32 select_rm_cb (struct select_entry *entry); extern i32 select_entry_reset (struct select_entry *entry); extern i32 select_module_init (); +extern i32 select_module_init_child (); + extern struct select_module_info *get_select_module (void); #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/kernel/linux_kernel_module.c b/src/nSocket/kernel/linux_kernel_module.c index 6a262d0..eb3dd8d 100644 --- a/src/nSocket/kernel/linux_kernel_module.c +++ b/src/nSocket/kernel/linux_kernel_module.c @@ -324,6 +324,7 @@ kernel_stack_register (nstack_proc_cb * ops, nstack_event_cb * val) ops->extern_ops.ep_ctl = kernel_ep_fd_add; ops->extern_ops.ep_prewait_proc = kernel_prewait_proc; ops->extern_ops.module_init = kernel_module_init; + ops->extern_ops.module_init_child = kernel_module_init; ops->extern_ops.stack_alloc_fd = kernel_fd_alloc; /* don't close file descriptor */ diff --git a/src/nSocket/nstack/event/epoll/nstack_eventpoll.c b/src/nSocket/nstack/event/epoll/nstack_eventpoll.c index 9a753e9..a8b3757 100644 --- a/src/nSocket/nstack/event/epoll/nstack_eventpoll.c +++ b/src/nSocket/nstack/event/epoll/nstack_eventpoll.c @@ -753,13 +753,15 @@ nsep_epoll_close (int sock) return 0; } - nsep_set_infoSockMap (sock, NULL); - if (NSTACK_EPOL_FD == epInfo->fdtype) { - return nsp_epoll_close_ep_fd (sock, epInfo); + ret = nsp_epoll_close_ep_fd (sock, epInfo); + nsep_set_infoSockMap (sock, NULL); + return ret; } + nsep_set_infoSockMap (sock, NULL); + nstack_each_modInx (modInx) { if (0 == (epInfo->epaddflag & (1 << modInx))) diff --git a/src/nSocket/nstack/event/select/nstack_select.c b/src/nSocket/nstack/event/select/nstack_select.c index ba64cff..930f1db 100644 --- a/src/nSocket/nstack/event/select/nstack_select.c +++ b/src/nSocket/nstack/event/select/nstack_select.c @@ -753,4 +753,26 @@ nssct_set_index (i32 fd, i32 inx) select_set_index (fd, inx); } +i32 +select_module_init_child () +{ + pthread_t select_thread_id; + i32 retval; + + if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL)) + { + goto ERR_RET; + } + + retval = pthread_setname_np (select_thread_id, "nstack_select_child"); + if (retval) + { + /*set thread name failed */ + } + return TRUE; + +ERR_RET: + return FALSE; +} + #endif /* NSTACK_SELECT_MODULE */ diff --git a/src/nSocket/nstack/nstack.c b/src/nSocket/nstack/nstack.c index 749f06d..861bc37 100644 --- a/src/nSocket/nstack/nstack.c +++ b/src/nSocket/nstack/nstack.c @@ -34,7 +34,6 @@ #include "nstack_fd_mng.h" #include "nstack_info_parse.h" #include "nstack_dmm_adpt.h" -#include "nstack_rd_mng.h" #include "nstack_rd.h" #include "nstack_module.h" #include "nstack_select.h" @@ -57,6 +56,8 @@ nStack_info_t g_nStackInfo = { /*if this flag was set, maybe all socket interface called during initializing*/ __thread int g_tloadflag = 0; +extern u8 app_mode; + /*check init stack*/ #define NSTACK_INIT_STATE_CHECK_RET(state) do {\ if ((state) == NSTACK_MODULE_SUCCESS) \ @@ -411,7 +412,7 @@ nstack_init_shmem () int deploytype = nstack_get_deploy_type (); - if (deploytype > NSTACK_MODEL_TYPE1) + if (deploytype != NSTACK_MODEL_TYPE1 && deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK ) { if (-1 == nsep_attach_memory ()) { @@ -443,16 +444,13 @@ nstack_init_shmem () NSTACK_STATIC int nstack_init_mem (void) { - int ret = ns_fail; - int initflag = 0; int deploytype = nstack_get_deploy_type (); /* record unmatched app version*/ /* check lib version match - Begin */ - if (deploytype > NSTACK_MODEL_TYPE1) + if (deploytype != NSTACK_MODEL_TYPE1 && deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK ) { check_main_version (); - initflag = 1; } ret = nstack_init_shmem (); @@ -462,14 +460,6 @@ nstack_init_mem (void) return ns_fail; } - /*stack-x rd mng init*/ - ret = nstack_rd_mng_int(initflag); - if (ns_success != ret) - { - NSSOC_LOGERR("nstack_rd_mng_int fail"); - return ns_fail; - } - /*rd info sys*/ ret = nstack_rd_sys(); if (ns_success != ret) @@ -597,7 +587,7 @@ nstack_for_epoll_init () NSSOC_LOGINF ("fork]g_nStackInfo.pid=%u,getpid=%d", g_nStackInfo.pid, getpid ()); - nstack_stack_module_init(); + nstack_stack_module_init_child(); } return 0; } @@ -767,11 +757,12 @@ nstack_fw_init () if (NSTACK_MODULE_INIT == g_nStackInfo.fwInited) { + g_nStackInfo.fwInited = NSTACK_MODULE_INITING; nstack_log_init_app(); if (0 != nstack_stack_module_load()) { - NSSOC_LOGERR("nstack stack module load fail"); + NSSOC_LOGERR("nstack stack module load fail"); g_nStackInfo.fwInited = NSTACK_MODULE_FAIL; return -1; } @@ -786,6 +777,10 @@ nstack_fw_init () if (deploytype == NSTACK_MODEL_TYPE1) { proc_type = NSFW_PROC_MAIN; + }else if (deploytype == NSTACK_MODEL_TYPE_SIMPLE_STACK) + { + proc_type = NSFW_PROC_MAIN; + app_mode=1; } stinfo.iargsnum = 0; diff --git a/src/nSocket/nstack/nstack.h b/src/nSocket/nstack/nstack.h index 6d40a7b..1ec88f0 100644 --- a/src/nSocket/nstack/nstack.h +++ b/src/nSocket/nstack/nstack.h @@ -55,6 +55,7 @@ extern "C"{ typedef enum { NSTACK_MODULE_INIT, + NSTACK_MODULE_INITING, NSTACK_MODULE_SUCCESS, NSTACK_MODULE_FAIL } nstack_module_state; diff --git a/src/nSocket/nstack/nstack_module.c b/src/nSocket/nstack/nstack_module.c index 91eda84..9566ab8 100644 --- a/src/nSocket/nstack/nstack_module.c +++ b/src/nSocket/nstack/nstack_module.c @@ -36,7 +36,6 @@ #include "nstack_dmm_adpt.h" #include "nstack_rd_init.h" #include "nstack_info_parse.h" -#include "nstack_rd_mng.h" /* *INDENT-OFF* */ nstack_module_info g_nstack_modules = { @@ -176,7 +175,6 @@ nstack_register_module () nstack_get_route_data rd_fun[] = { nstack_stack_rd_parse, - nstack_rd_ip_get }; pstacks = @@ -267,3 +265,23 @@ nstack_stack_module_init () } return 0; } + +int +nstack_stack_module_init_child () +{ + ns_uint32 idx; + for (idx = 0; idx < g_module_num; idx++) + { + if (g_nstack_modules.modules[idx].mops.extern_ops.module_init_child) + { + if (0 != + g_nstack_modules.modules[idx].mops. + extern_ops.module_init_child ()) + { + NSSOC_LOGERR ("nstack[%s] modx:%d init child fail", + g_nstack_modules.modules[idx].modulename, idx); + } + } + } + return 0; +} diff --git a/src/nSocket/nstack/nstack_module.h b/src/nSocket/nstack/nstack_module.h index 70b838f..ec81ac1 100644 --- a/src/nSocket/nstack/nstack_module.h +++ b/src/nSocket/nstack/nstack_module.h @@ -46,12 +46,12 @@ extern "C"{ #define NSTACK_EP_FREE_NEED_REF 1 /*when epoll information free, need to wait that stack would not notify event */ #define NSTACK_EP_FREE_NONEED_REF 0 -#define MODULE_NAME_MAX 64 +#define MODULE_NAME_MAX 128 typedef struct __NSTACK_MODULE_KEYS { ns_char modName[MODULE_NAME_MAX]; /*stack name */ - ns_char register_fn_name[MODULE_NAME_MAX]; /*stack register fun name */ + ns_char register_fn_name[MODULE_NAME_MAX]; /*stack register fun name */ ns_char libPath[MODULE_NAME_MAX]; /*if libtype is dynamic, it is the path of lib */ ns_char deploytype; /*delpoly model type: model type1, model type2, model type3 */ ns_char libtype; /*dynamic lib or static lib */ @@ -135,6 +135,7 @@ extern nstack_module_keys g_nstack_module_desc[]; for ((modInx) = 0; ((modInx) < nstack_get_modNum() && (pMod = nstack_get_module((modInx)))); (modInx)++) int nstack_stack_module_init (); +int nstack_stack_module_init_child (); int nstack_get_deploy_type (); diff --git a/src/nSocket/nstack/nstack_socket.c b/src/nSocket/nstack/nstack_socket.c index 5841676..cd1557b 100644 --- a/src/nSocket/nstack/nstack_socket.c +++ b/src/nSocket/nstack/nstack_socket.c @@ -150,7 +150,7 @@ nstack_socket (int domain, int itype, int protocol) int selectmod = -1; /*check whether module init finish or not */ - NSTACK_INIT_CHECK_RET (socket); + NSTACK_INIT_CHECK_RET (socket, domain, itype, protocol); NSSOC_LOGINF ("(domain=%d, type=%d, protocol=%d) [Caller]", domain, itype, protocol); @@ -287,6 +287,8 @@ nstack_bind (int fd, const struct sockaddr *addr, socklen_t addrlen) struct sockaddr_in *iaddr = NULL; nstack_rd_key rdkey = { 0 }; + NSTACK_INIT_CHECK_RET (bind, fd, addr, addrlen); + NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, addrlen); @@ -452,6 +454,8 @@ nstack_listen (int fd, int backlog) int tfd; int func_called = 0; + NSTACK_INIT_CHECK_RET (listen, fd, backlog); + NSSOC_LOGINF ("(sockfd=%d, backlog=%d) [Caller]", fd, backlog); if (fd < 0) { @@ -519,6 +523,8 @@ nstack_accept (int fd, struct sockaddr *addr, socklen_t * addr_len) nstack_fd_Inf *accInf; int ret = -1; + NSTACK_INIT_CHECK_RET (accept, fd, addr, addr_len); + NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, addr_len); if (fd < 0) @@ -672,6 +678,8 @@ nstack_accept4 (int fd, struct sockaddr *addr, int ret = -1; nstack_fd_Inf *accInf; + NSTACK_INIT_CHECK_RET (accept4, fd, addr, addr_len, flags); + NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%p, flags=%d) [Caller]", fd, addr, addr_len, flags); if (fd < 0) @@ -822,6 +830,8 @@ nstack_connect (int fd, const struct sockaddr *addr, socklen_t addrlen) int selectmod = -1; nstack_rd_key rdkey = { 0 }; + NSTACK_INIT_CHECK_RET (connect, fd, addr, addrlen); + NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, addrlen); @@ -947,6 +957,8 @@ nstack_shutdown (int fd, int how) return -1; } + NSTACK_INIT_CHECK_RET (shutdown, fd, how); + NSSOC_LOGINF ("(fd=%d, how=%d) [Caller]", fd, how); NSTACK_FD_LINUX_CHECK (fd, shutdown, fdInf, (fd, how)); @@ -1058,6 +1070,8 @@ nstack_close (int fd) nstack_fd_Inf *fdInf; int ret = -1; + NSTACK_INIT_CHECK_RET (close, fd); + /*linux fd check */ if (!(fdInf = nstack_getValidInf (fd))) { @@ -1119,6 +1133,8 @@ nstack_send (int fd, const void *buf, size_t len, int flags) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (send, fd, buf, len, flags); + NS_LOG_CTRL (LOG_CTRL_SEND, NSOCKET, "NSSOC", NSLOG_DBG, "(sockfd=%d, buf=%p, len=%zu, flags=%d) [Caller]", fd, buf, len, flags); @@ -1152,6 +1168,8 @@ nstack_recv (int fd, void *buf, size_t len, int flags) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (recv, fd, buf, len, flags); + NS_LOG_CTRL (LOG_CTRL_RECV, NSOCKET, "NSSOC", NSLOG_DBG, "(sockfd=%d, buf=%p, len=%zu, flags=%d) [Caller]", fd, buf, len, flags); @@ -1185,6 +1203,8 @@ nstack_write (int fd, const void *buf, size_t count) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (write, fd, buf, count); + NSTACK_FD_LINUX_CHECK (fd, write, fdInf, (fd, buf, count)); NS_LOG_CTRL (LOG_CTRL_WRITE, NSOCKET, "NSSOC", NSLOG_DBG, @@ -1217,6 +1237,8 @@ nstack_read (int fd, void *buf, size_t count) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (read, fd, buf, count); + NS_LOG_CTRL (LOG_CTRL_READ, NSOCKET, "NSSOC", NSLOG_DBG, "(fd=%d, buf=%p, count=%zu) [Caller]", fd, buf, count); @@ -1248,6 +1270,8 @@ nstack_writev (int fd, const struct iovec * iov, int iovcnt) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (writev, fd, iov, iovcnt); + NS_LOG_CTRL (LOG_CTRL_WRITEV, NSOCKET, "NSSOC", NSLOG_DBG, "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); @@ -1280,6 +1304,8 @@ nstack_readv (int fd, const struct iovec * iov, int iovcnt) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (readv, fd, iov, iovcnt); + NS_LOG_CTRL (LOG_CTRL_READV, NSOCKET, "NSSOC", NSLOG_DBG, "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); @@ -1318,6 +1344,8 @@ nstack_sendto (int fd, const void *buf, size_t len, int flags, int retval = 0; nstack_rd_key rdkey = { 0 }; + NSTACK_INIT_CHECK_RET (sendto, fd, buf, len, flags, dest_addr, addrlen); + NSSOC_LOGDBG ("(sockfd=%d, buf=%p, len=%zu, flags=%d, dest_addr=%p, addrlen=%u) [Caller]", fd, buf, len, flags, dest_addr, addrlen); @@ -1400,6 +1428,8 @@ nstack_sendmsg (int fd, const struct msghdr * msg, int flags) int retval = 0; nstack_rd_key rdkey = { 0 }; + NSTACK_INIT_CHECK_RET (sendmsg, fd, msg, flags); + NS_LOG_CTRL (LOG_CTRL_SENDMSG, NSOCKET, "NSSOC", NSLOG_DBG, "(sockfd=%d, msg=%p, flags=%d) [Caller]", fd, msg, flags); @@ -1482,6 +1512,8 @@ nstack_recvfrom (int fd, void *buf, size_t len, int flags, nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (recvfrom, fd, buf, len, flags, src_addr, addrlen); + NSSOC_LOGDBG ("(sockfd=%d, buf=%p, len=%zu, flags=%d, src_addr=%p, addrlen=%p) [Caller]", fd, buf, len, flags, src_addr, addrlen); @@ -1524,6 +1556,8 @@ nstack_recvmsg (int fd, struct msghdr * msg, int flags) nstack_fd_Inf *fdInf = NULL; int size = -1; + NSTACK_INIT_CHECK_RET (recvmsg, fd, msg, flags); + NS_LOG_CTRL (LOG_CTRL_RECVMSG, NSOCKET, "NSSOC", NSLOG_DBG, "(sockfd=%d, msg=%p, flags=%d) [Caller]", fd, msg, flags); @@ -1564,6 +1598,8 @@ nstack_getsockname (int fd, struct sockaddr *addr, socklen_t * addrlen) int tfd = -1; int ret = -1; + NSTACK_INIT_CHECK_RET (getsockname, fd, addr, addrlen); + NS_LOG_CTRL (LOG_CTRL_GETSOCKNAME, NSOCKET, "NSSOC", NSLOG_INF, "(fd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, addrlen); @@ -1634,6 +1670,8 @@ nstack_getpeername (int fd, struct sockaddr *addr, socklen_t * addrlen) int tfd; int ret = -1; + NSTACK_INIT_CHECK_RET (getpeername, fd, addr, addrlen); + NS_LOG_CTRL (LOG_CTRL_GETPEERNAME, NSOCKET, "NSSOC", NSLOG_INF, "(fd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, addrlen); @@ -1766,6 +1804,8 @@ nstack_getsockopt (int fd, int level, int optname, void *optval, int ret = -1; nstack_socket_ops *ops; + NSTACK_INIT_CHECK_RET (getsockopt, fd, level, optname, optval, optlen); + NS_LOG_CTRL (LOG_CTRL_GETSOCKOPT, NSOCKET, "NSSOC", NSLOG_INF, "(fd=%d, level=%d, optname=%d, optval=%p, optlen=%p) [Caller]", fd, level, optname, optval, optlen); @@ -1850,6 +1890,8 @@ nstack_setsockopt (int fd, int level, int optname, const void *optval, int lerror = 0; int flag = 0; + NSTACK_INIT_CHECK_RET (setsockopt, fd, level, optname, optval, optlen); + NSSOC_LOGINF ("(fd=%d, level=%d, optname=%d, optval=%p, optlen=%u) [Caller]", fd, level, optname, optval, optlen); @@ -1940,6 +1982,8 @@ nstack_ioctl (int fd, unsigned long request, unsigned long argp) int lerror = 0; int flag = 0; + NSTACK_INIT_CHECK_RET (ioctl, fd, request, argp); + NSSOC_LOGINF ("(fd=%d, request=%lu) [Caller]", fd, request); if (fd < 0) { @@ -2019,6 +2063,8 @@ nstack_fcntl (int fd, int cmd, unsigned long argp) int lerror = 0; int flag = 0; + NSTACK_INIT_CHECK_RET (fcntl, fd, cmd, argp); + NSSOC_LOGINF ("(fd=%d, cmd=%d) [Caller]", fd, cmd); if (fd < 0) { @@ -2142,6 +2188,8 @@ nstack_select (int nfds, fd_set * readfds, fd_set * writefds, int i; + NSTACK_INIT_CHECK_RET (select, nfds, readfds, writefds, exceptfds, timeout); + if ((nfds > __FD_SETSIZE) || (nfds < 0) || ((timeout) && ((timeout->tv_sec < 0) || (timeout->tv_usec < 0)))) { @@ -2319,6 +2367,8 @@ nstack_epoll_ctl (int epfd, int op, int fd, struct epoll_event *event) struct epoll_event ep_event = { 0 }; struct epitem *epi = NULL; + NSTACK_INIT_CHECK_RET (epoll_ctl, epfd, op, fd, event); + NSSOC_LOGINF ("(epfd=%d, op=%d, fd=%d, event=%p) [Caller]", epfd, op, fd, event); if (event) @@ -2450,7 +2500,7 @@ nstack_epoll_create (int size) nstack_socket_ops *ops; int ret = 0; - NSTACK_INIT_CHECK_RET (epoll_create); + NSTACK_INIT_CHECK_RET (epoll_create, size); NSSOC_LOGINF ("(size=%d) [Caller]", size); @@ -2580,6 +2630,8 @@ nstack_epoll_wait (int epfd, struct epoll_event *events, int maxevents, int evt = 0; int ret = 0; + NSTACK_INIT_CHECK_RET (epoll_wait, epfd, events, maxevents, timeout); + NSTACK_FD_LINUX_CHECK (epfd, epoll_wait, fdInf, (epfd, events, maxevents, timeout)); @@ -2706,6 +2758,8 @@ nstack_fork (void) pid_t pid; pid_t parent_pid = sys_get_hostpid_from_file (getpid ()); + NSTACK_INIT_CHECK_RET (fork); + common_mem_rwlock_write_lock (get_fork_lock ()); if (NSTACK_MODULE_SUCCESS == g_nStackInfo.fwInited) { @@ -2721,6 +2775,8 @@ nstack_fork (void) dmm_spinlock_lock_with_pid (nstack_get_fork_share_lock (), get_sys_pid ()); nsep_fork_child_proc (parent_pid); + + (void) select_module_init_child (); common_mem_spinlock_unlock (nstack_get_fork_share_lock ()); } else if (pid > 0) diff --git a/src/nSocket/nstack/nstack_socket.h b/src/nSocket/nstack/nstack_socket.h index 3bc4a10..3bb7843 100644 --- a/src/nSocket/nstack/nstack_socket.h +++ b/src/nSocket/nstack/nstack_socket.h @@ -190,12 +190,18 @@ UNLOCK_CLOSE (nstack_fd_local_lock_info_t * local_lock) #define UNLOCK_FOR_EP(local_lock) UNLOCK_CLOSE(local_lock) -#define NSTACK_INIT_CHECK_RET(fun) \ - if (nstack_fw_init()) { \ - NSSOC_LOGERR("nstack %s call, but initial not finished yet [return]", #fun); \ - nstack_set_errno(ENOSYS); \ - return -1; \ - } +#define NSTACK_INIT_CHECK_RET(fun, args...) \ + do { \ + if (NSTACK_MODULE_INITING == g_nStackInfo.fwInited) { \ + NSSOC_LOGINF ("call kernel func %s", #fun); \ + return nsfw_base_##fun(args); \ + } \ + if (nstack_fw_init()) { \ + NSSOC_LOGERR("nstack %s call, but initial not finished yet [return]", #fun); \ + nstack_set_errno(ENOSYS); \ + return -1; \ + } \ + }while(0) #define NSTACK_MODULE_ERROR_SET(Index) diff --git a/src/nSocket/nstack_rd/nstack_rd_init.c b/src/nSocket/nstack_rd/nstack_rd_init.c index 3025e88..b3d4158 100644 --- a/src/nSocket/nstack_rd/nstack_rd_init.c +++ b/src/nSocket/nstack_rd/nstack_rd_init.c @@ -39,7 +39,9 @@ if (!ptr)\ /* *INDENT-OFF* */ rd_stack_plane_map g_nstack_plane_info[] = { {{RD_LINUX_NAME}, {RD_LINUX_PLANENAME}, -1}, + {"rsocket", "nstack-rsocket", -1}, {{RD_STACKX_NAME}, {RD_STACKX_PLANENAME}, -1}, + {"vpp_hoststack", "nstack-vpp", -1}, }; /* *INDENT-ON* */ diff --git a/src/nSocket/nstack_rd/nstack_rd_proto.c b/src/nSocket/nstack_rd/nstack_rd_proto.c index 16f4e1f..81246c0 100644 --- a/src/nSocket/nstack_rd/nstack_rd_proto.c +++ b/src/nSocket/nstack_rd/nstack_rd_proto.c @@ -23,6 +23,7 @@ #include "nstack_rd_proto.h" #include "nstack_log.h" #include "nstack_securec.h" +#include "common_mem_common.h" /*copy rd data*/ int diff --git a/stacks/lwip_stack/CMakeLists.txt b/stacks/lwip_stack/CMakeLists.txt new file mode 100644 index 0000000..814e5a5 --- /dev/null +++ b/stacks/lwip_stack/CMakeLists.txt @@ -0,0 +1,115 @@ +######################################################################### +# +# 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. +######################################################################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +PROJECT(nStack) +SET(CMAKE_C_COMPILER "gcc") +SET(OS_RELEASE "" CACHE STRING "User-specified OS release.") +SET(EXECUTABLE_PATH ${CMAKE_CURRENT_LIST_DIR}/release/bin) +SET(LIB_PATH_STATIC ${PROJECT_BINARY_DIR}) +SET(LIB_PATH_SHARED ${CMAKE_CURRENT_LIST_DIR}/release/lib64) +SET(NSTACKTOOLS_PATH ${CMAKE_CURRENT_LIST_DIR}/release/tools) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH_STATIC}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_PATH}) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_PATH_SHARED}) + + +MESSAGE(STATUS "Top dir is: " ${CMAKE_CURRENT_LIST_DIR}) +MESSAGE(STATUS "Static library dir: " ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) +MESSAGE(STATUS "Executable binary dir: " ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +MESSAGE(STATUS "Shared library dir: " ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + +option(WITH_SECUREC_LIB "Option description" OFF) +option(WITH_HAL_LIB "Option description" OFF) + +if(WITH_SECUREC_LIB) + add_definitions(-DSECUREC_LIB) +endif() + +if(WITH_HAL_LIB) + add_definitions(-DHAL_LIB) +endif() + +SET(post_compile "${PROJECT_BINARY_DIR}/post_compile.sh") +FILE(WRITE ${post_compile} "#!/bin/bash\n") +FILE(APPEND ${post_compile} +" + +find ${CMAKE_CURRENT_LIST_DIR}/release/ -name \"*.sh\" -exec chmod +x {} \\; +find ${CMAKE_CURRENT_LIST_DIR}/release/ -name \"*.py\" -exec chmod +x {} \\; +ln -sfn ./run_nstack_main.sh ${CMAKE_CURRENT_LIST_DIR}/release/script/run_nstack.sh +echo post compile process success. +" +) + +ADD_CUSTOM_TARGET(DPDK ALL COMMAND sh post_compile.sh) + +execute_process( + COMMAND cp -rf ${CMAKE_CURRENT_LIST_DIR}/../../release/include ${CMAKE_CURRENT_LIST_DIR}/src/ + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/../../release/lib64/libnStackAPI.so ${CMAKE_CURRENT_LIST_DIR}/release/lib64/ + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/../../release/lib64/libdmm_api.so ${CMAKE_CURRENT_LIST_DIR}/release/lib64/ + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/../../build/libnStackMaintain.a ${CMAKE_CURRENT_LIST_DIR}/release/lib64/ + COMMAND cp ${CMAKE_CURRENT_LIST_DIR}/../../build/libsocket.a ${CMAKE_CURRENT_LIST_DIR}/build/ + COMMAND echo "stacklwip prepare ok" +) +execute_process( + COMMAND sh ${CMAKE_CURRENT_LIST_DIR}/release/lwip_helper_files/download_lwip.sh +) + +ADD_DEFINITIONS(-D_GNU_SOURCE -DNSTACK_GETVER_VERSION="18.07") + +SET(JSON_C_SRC ${CMAKE_CURRENT_LIST_DIR}/../../thirdparty/json/json-c-0.12.1) +INCLUDE(ExternalProject) +ExternalProject_Add( + JSON + SOURCE_DIR ${JSON_C_SRC} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND sh autogen.sh COMMAND sh ./configure --enable-static --with-pic + BUILD_COMMAND make -j 8 + INSTALL_COMMAND cp -f .libs/libjson-c.a ${LIB_PATH_STATIC}/ +) + +SET(SECUREC_SRC ${CMAKE_CURRENT_LIST_DIR}/../SecureC/src) +SET(SECUREC_SRC_H ${CMAKE_CURRENT_LIST_DIR}/../SecureC/include) + +if(WITH_SECUREC_LIB) +INCLUDE(ExternalProject) +ExternalProject_Add( + SECUREC + SOURCE_DIR ${SECUREC_SRC} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + BUILD_COMMAND COMMAND make -j 8 + INSTALL_COMMAND cp -f ${SECUREC_SRC}/../lib/libsecurec.so ${LIB_PATH_SHARED}/ +) +endif() + +SET(GLOG_SRC ${CMAKE_CURRENT_LIST_DIR}/../../thirdparty/glog/glog-0.3.4) +INCLUDE(ExternalProject) +ExternalProject_Add( + GLOG + SOURCE_DIR ${GLOG_SRC} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND autoreconf COMMAND sh configure CFLAGS=-fPIC CXXFLAGS=-fPIC + BUILD_COMMAND COMMAND make -j 8 + INSTALL_COMMAND cp -f ${GLOG_SRC}/.libs/libglog.a ${LIB_PATH_STATIC}/ +) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(lwip_src) +ADD_SUBDIRECTORY(lwip_src/socket) +ADD_SUBDIRECTORY(tools) +#ADD_SUBDIRECTORY(thirdparty/rsrdma) diff --git a/stacks/lwip_stack/app_conf/module_config.json b/stacks/lwip_stack/app_conf/module_config.json new file mode 100644 index 0000000..a179ad4 --- /dev/null +++ b/stacks/lwip_stack/app_conf/module_config.json @@ -0,0 +1,27 @@ +{ + "default_stack_name": "kernel", + "module_list": [ + { + "stack_name": "kernel", + "function_name": "kernel_stack_register", + "libname": "./", + "loadtype": "static", + "deploytype": "1", + "maxfd": "1024", + "minfd": "0", + "priorty": "1", + "stackid": "0", + }, + { + "stack_name": "stackx", + "function_name": "nstack_stack_register", + "libname": "libnstack.so", + "loadtype": "dynmic", + "deploytype": "3", + "maxfd": "1024", + "minfd": "0", + "priorty": "1", + "stackid": "1", + }, + ] +} diff --git a/stacks/lwip_stack/app_conf/nStackConfig.json b/stacks/lwip_stack/app_conf/nStackConfig.json new file mode 100644 index 0000000..3cc54c5 --- /dev/null +++ b/stacks/lwip_stack/app_conf/nStackConfig.json @@ -0,0 +1,32 @@ +{ +"cfg_seg_socket": [ +{ + "socket_num": 8192, + "arp_stale_time": 300, + "arp_bc_retrans_num": 5 +} +], +"cfg_seg_log": [ +{ + "run_log_size": 50, + "run_log_count": 10, + "mon_log_size": 10, + "mon_log_count": 10 +} +], +"cfg_seg_thread_pri": [ +{ + "comment":"0:SCHED_OTHER, 1:SCHED_FIFO, 2:SCHED_RR", + "sched_policy": 0, + "thread_pri": 0 +} +], +"cfg_seg_path": [ +{ + "stackpool_log_path": "/var/log/nStack", + "master_log_path": "/var/log/nStack", + "nstack_log_path": "/var/log/nStack", + "dpdk_log_path": "/var/log/nstack-dpdk" +} +] +} diff --git a/stacks/lwip_stack/app_conf/rd_config.json b/stacks/lwip_stack/app_conf/rd_config.json new file mode 100644 index 0000000..38374bc --- /dev/null +++ b/stacks/lwip_stack/app_conf/rd_config.json @@ -0,0 +1,26 @@ +{ + "ip_route": [ + { + "subnet": "192.168.1.1/24", + "type": "nstack-dpdk", + }, + { + "subnet": "192.167.1.1/24", + "type": "nstack-kernel", + }, + { + "subnet": "192.166.1.1/24", + "type": "nstack-kernel", + } + ], + "prot_route": [ + { + "proto_type": "1", + "type": "nstack-dpdk", + }, + { + "proto_type": "2", + "type": "nstack-kernel", + } + ], +} diff --git a/stacks/lwip_stack/build/.gitkeep b/stacks/lwip_stack/build/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/stacks/lwip_stack/build/.gitkeep diff --git a/stacks/lwip_stack/lwip_src/CMakeLists.txt b/stacks/lwip_stack/lwip_src/CMakeLists.txt new file mode 100644 index 0000000..4425905 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/CMakeLists.txt @@ -0,0 +1,98 @@ +######################################################################### +# +# 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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fPIE -pie -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") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack -mcmodel=medium") + +ADD_DEFINITIONS(-D_GNU_SOURCE) +ADD_DEFINITIONS(-DDPDK_MODULE=0) +if(WITH_HAL_LIB) +SET(RTP_CONFIG ${CMAKE_CURRENT_LIST_DIR}/../src/include/rtp_config.h) +else() + SET(PAL_H_DIRECTORIES "/usr/include/dpdk/") + SET(RTP_CONFIG ${PROJECT_SOURCE_DIR}/../../src/framework/common/base/include/common/common_sys_config.h) + INCLUDE_DIRECTORIES( + ${PAL_H_DIRECTORIES} + ) +endif() +SET(COMPLE_CONFIG ${CMAKE_CURRENT_LIST_DIR}/../src/include/compile_config.h) +SET(MGR_COM ${CMAKE_CURRENT_LIST_DIR}/../src/include/mgr_com.h) +ADD_DEFINITIONS(-include ${RTP_CONFIG}) +ADD_DEFINITIONS(-include ${COMPLE_CONFIG}) +ADD_DEFINITIONS(-include ${MGR_COM}) +if(WITH_SECUREC_LIB) +LINK_LIBRARIES(pthread rt securec) +else() +LINK_LIBRARIES(pthread rt) +endif() +LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../../../SecureC/include + ${CMAKE_CURRENT_LIST_DIR}/../../../thirdparty/json/json-c-0.12.1/ + ${CMAKE_CURRENT_LIST_DIR}/../../../thirdparty/glog/glog-0.3.4/src/ + ${CMAKE_CURRENT_LIST_DIR}/../src/include/ + ${CMAKE_CURRENT_LIST_DIR}/lwip/include/ + ${CMAKE_CURRENT_LIST_DIR}/lwip/include/lwip/ +) + +FILE(GLOB API api/*.c) +FILE(GLOB_RECURSE CORE core/*.c) +FILE(GLOB INSTANCE instance/*.c) +FILE(GLOB IPMODULE ip_module/*.c) +FILE(GLOB NETIF netif/*.c) +FILE(GLOB RECYCLE recycle/*.c) +FILE(GLOB_RECURSE MAINTAIN maintain/*.c) +FILE(GLOB COMMON common/*.c) +FILE(GLOB_RECURSE LWIPSRC lwip/arch/*.c lwip/core/*.c lwip/netif/*.c) +FOREACH(item ${LWIPSRC}) + IF(${item} MATCHES "slipif.c") + LIST(REMOVE_ITEM LWIPSRC ${item}) + ENDIF(${item} MATCHES "slipif.c") +ENDFOREACH(item) + +ADD_LIBRARY(stacklwip STATIC ${API} ${ARCH} ${CORE} ${NETIF} ${NETTOOL} ${IPMODULE} ${COMMON} ${INSTANCE} ${RECYCLE} ${MAINTAIN} ${LWIPSRC}) +ADD_DEPENDENCIES(stacklwip JSON GLOG DPDK) +TARGET_INCLUDE_DIRECTORIES( + stacklwip + BEFORE + PRIVATE + common/ + socket/ + include/ + include/util/ + include/log/ + include/ipv4/ + include/ipv4/stackx + include/stackx/ + include/netif/ + include/nstack/ + include/ip_module/ + lwip/include/lwip/ + lwip/include/lwip/arch/ + lwip/include/lwip/apps/ + lwip/include/lwip/priv/ + lwip/include/lwip/prot/ + lwip/include/netif/ + lwip/include/netif/ppp/ + lwip/include/netif/ppp/polarssl/ + ${CMAKE_CURRENT_LIST_DIR}/../src/sbr/ + ${CMAKE_CURRENT_LIST_DIR}/../src/include/ + ${CMAKE_CURRENT_LIST_DIR}/../src/alarm/ +) + diff --git a/stacks/lwip_stack/lwip_src/api/spl_api.c b/stacks/lwip_stack/lwip_src/api/spl_api.c new file mode 100644 index 0000000..5c8af7d --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_api.c @@ -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. +*/ + +#include "nsfw_init.h" +//#include "sockets.h" +//#include <netinet/in.h> + +#include "stackx_spl_share.h" +#include "stackx/spl_api.h" +//#include "stackx/ip.h" +#include "sharedmemory.h" +#include "spl_hal.h" +#include "hal_api.h" +#include "alarm_api.h" +#include "nsfw_mt_config.h" +#include "nsfw_recycle_api.h" +#include "nstack_dmm_adpt.h" + +/* main entry for stackx */ +int +spl_main_init (void *args) +{ + (void) args; + if (init_by_main_thread () < 0) + { + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME ("STACKX_MAIN") +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_ALARM_MODULE) +NSFW_MODULE_DEPENDS (NSTACK_DMM_MODULE) +NSFW_MODULE_INIT (spl_main_init) +/* *INDENT-ON* */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_api_msg.c b/stacks/lwip_stack/lwip_src/api/spl_api_msg.c new file mode 100644 index 0000000..0986ed4 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_api_msg.c @@ -0,0 +1,3262 @@ +/* +* +* 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_msg.h" +#include "spl_opt.h" +#include "spl_ip_addr.h" +//#include "stackx_socket.h" +#include "cpuid.h" +//#include "sockets.h" +#include <netinet/in.h> +#include <errno.h> + +#include "stackx_prot_com.h" +#include "spl_api.h" +//#include "stackx/ip.h" +#include "sc_dpdk.h" +#include "spl_sbr.h" +//#include "maintain/spl_dfx.h" +#include "stackx_tx_box.h" +#include "spl_instance.h" +#include "spl_sockets.h" + +#include "nstack_dmm_adpt.h" + +#include "tcp.h" +#include "udp.h" +#include "pbuf.h" +#include "tcp_priv.h" +#include "init.h" +#include "timeouts.h" + +#include "stackx_pbuf_comm.h" +#include "spl_netbuf.h" +#include "spl_hal.h" +#include "sys_arch.h" +#include "tcpip.h" +#include "debug.h" +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif + +extern struct tcp_pcb *tcp_bound_pcbs; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ +extern struct tcp_pcb **const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; +extern stackx_instance *p_def_stack_instance; +extern u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +#define TCP_FN_NULL 0 +#define TCP_FN_DEFAULT 1 +#define TCP_FN_STACKX 2 +#define TCP_FN_MAX 3 + +struct callback_fn tcp_fn[TCP_FN_MAX] = { + {NULL, NULL, NULL, NULL, NULL, NULL, NULL}, + {NULL, spl_tcp_recv_null, NULL, NULL, NULL, NULL}, + {spl_sent_tcp, spl_recv_tcp, spl_do_connected, spl_poll_tcp, spl_err_tcp, + NULL, spl_accept_function}, +}; + +// extern int nstack_get_nstack_fd_snapshot_from_proto_fd(int proto_fd); +extern void tcp_drop_conn (spl_netconn_t * conn); +extern void unlink_pcb (struct common_pcb *cpcb); +extern struct queue *get_msgbox (int tos); + +#define SPL_SET_NONBLOCKING_CONNECT(conn, val) \ +do { \ + if (val) \ + { \ + (conn)->flags |= SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ + } \ + else \ + { \ + (conn)->flags &= ~SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ + } \ + } while (0) + +#define SPL_IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) + +extern int tcpip_thread_control; + +void +spl_event_callback (struct spl_netconn *conn, enum spl_netconn_evt evt, + int postFlag) +{ + NSPOL_LOGDBG (SOCK_INFO, "Get event]conn=%p,evt=%d,postFlag=%d", conn, evt, + postFlag); + /* Get socket */ + if (!conn) + { + NSPOL_LOGDBG (SOCK_INFO, "conn=NULL"); + return; + } + + switch (evt) + { + case SPL_NETCONN_EVT_RCVPLUS: + __sync_fetch_and_add (&conn->rcvevent, 1); + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); + } + break; + case SPL_NETCONN_EVT_RCVMINUS: // This will never be reached + __sync_fetch_and_sub (&conn->rcvevent, 1); + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); + } + break; + case SPL_NETCONN_EVT_SENDPLUS: + conn->sendevent = 1; + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLOUT); + } + break; + case SPL_NETCONN_EVT_SENDMINUS: + conn->sendevent = 0; + + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLOUT); + } + break; + case SPL_NETCONN_EVT_ERROR: + conn->errevent |= EPOLLERR; + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); + conn->errevent = 0; + } + break; +#if 1 + case SPL_NETCONN_EVT_ACCEPT: + __sync_fetch_and_add (&conn->rcvevent, 1); + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), EPOLLIN); + } + break; + + case SPL_NETCONN_EVT_HUP: + conn->errevent |= EPOLLHUP; + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); + conn->errevent = 0; + } + break; + case SPL_NETCONN_EVT_RDHUP: + conn->errevent |= EPOLLRDHUP; + if ((conn->epoll_flag) && (postFlag)) + { + nstack_event_callback (ADDR_SHTOL (conn->epInfo), conn->errevent); + conn->errevent = 0; + } + break; +#endif + + default: + NSTCP_LOGERR ("unknown event]conn=%p,event=%d", conn, evt); + return; + } + return; +} + +u8 +get_shut_op (data_com_msg * m) +{ + if (m && m->param.module_type == MSG_MODULE_SBR + && m->param.major_type == SPL_TCPIP_NEW_MSG_API) + { + if (m->param.minor_type == SPL_API_DO_CLOSE) + return ((msg_close *) (m->buffer))->shut; + + if (m->param.minor_type == SPL_API_DO_DELCON) + return ((msg_delete_netconn *) (m->buffer))->shut; + } + + return SPL_NETCONN_SHUT_RDWR; +} + +/* + Never using head/tail to judge whether need to do enque/deque, just do enque&deque, the return val will tell you ring is full/empty or not + rtp_perf_ring never provid ring_full/ring_empty function; + one more thing the rtp_ring_enque/deque result must be checked. +*/ +err_t +accept_enqueue (spl_netconn_t * conn, void *p) +{ + if (conn == NULL) + { + NSPOL_LOGERR ("accept_enqueue: invalid input]conn=%p", conn); + return ERR_VAL; + } + + NSPOL_LOGDBG (NEW_RING_DEBUG, "accept_enqueue]conn=%p,p=%p", conn, p); + mring_handle ring = conn->recv_ring; + if (NULL == ring) + { + NSPOL_LOGERR ("conn=%p accept new conn=%p enqueue ring addr is null", + conn, p); + return ERR_VAL; + } + + err_t retVal = ERR_MEM; + int enQSucCnt = 0; + int nTryCnt = 0; + do + { + enQSucCnt = nsfw_mem_ring_enqueue (ring, (void *) p); + if (1 == enQSucCnt) + { + retVal = ERR_OK; + break; + } + else if (0 == enQSucCnt) + { + sys_sleep_ns (0, 3000); + nTryCnt++; + } + else + { + retVal = ERR_VAL; + break; + } + } + while (nTryCnt < MAX_TRY_GET_MEMORY_TIMES); + + return retVal; +} + +err_t +accept_dequeue (spl_netconn_t * lconn, void **new_buf, + u32_t timeout /*miliseconds */ ) +{ + struct timespec starttm; + struct timespec endtm; + long timediff; + long timediff_sec; + u32_t timeout_sec = timeout / 1000; + +#define FAST_SLEEP_TIME 10000 +#define SLOW_SLEEP_TIME 500000 +#define FAST_RETRY_COUNT 100 + unsigned int retry_count = 0; + + if (NULL == lconn || NULL == new_buf) + { + NSPOL_LOGERR ("accept_dequeue invalid input]conn=%p,newbuf=%p", lconn, + new_buf); + return ERR_ARG; + } + + if (timeout != 0) + { + /* Handle system time change side-effects */ + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm))) + { + //NSPOL_LOGERR("Failed to get time]errno=%d", errno); + } + } + + mring_handle ring = lconn->recv_ring; + if (ring == NULL) + { + NSPOL_LOGERR ("Get rtp_perf_ring failed]conn=%p", lconn); + return ERR_ARG; + } + + int nDequeRt; + int retVal; + while (1) + { + if ((lconn->shut_status) && (-1 != (int) timeout)) + { + retVal = ERR_VAL; + break; + } + + nDequeRt = nsfw_mem_ring_dequeue (ring, new_buf); + if (nDequeRt == 1) + { + retVal = ERR_OK; + break; + } + else if (nDequeRt == 0) + { + if ((int) timeout == -1) + { + retVal = ERR_WOULDBLOCK; + break; + } + + if (timeout != 0) + { + /* Handle system time change side-effects */ + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &endtm))) + { + //NSPOL_LOGERR("Failed to get time, errno = %d", errno); + } + timediff_sec = endtm.tv_sec - starttm.tv_sec; + if (timediff_sec >= timeout_sec) + { + timediff = endtm.tv_nsec > starttm.tv_nsec ? + (timediff_sec * 1000) + (endtm.tv_nsec - + starttm.tv_nsec) / + USEC_TO_SEC : (timediff_sec * 1000) - + ((starttm.tv_nsec - endtm.tv_nsec) / USEC_TO_SEC); + + /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value + will be negetive if still 0.5 ms is not elapsed. this is intended and we should + not typecast to any unsigned type during this below if check */ + if (timediff > (long) timeout) + { + retVal = ERR_TIMEOUT; + break; + } + } + } + + /* reduce CPU usage in blocking mode */ + if (retry_count < FAST_RETRY_COUNT) + { + sys_sleep_ns (0, FAST_SLEEP_TIME); + retry_count++; + } + else + { + sys_sleep_ns (0, SLOW_SLEEP_TIME); + } + + continue; + } + else + { + retVal = ERR_VAL; + break; + } + } + + return retVal; +} + +err_t +sp_enqueue (struct common_pcb * cpcb, void *p) +{ + mring_handle ring = NULL; + spl_netconn_t *conn = NULL; + int enQueRet = 0; + + if (cpcb == NULL || (NULL == (conn = cpcb->conn))) + { + NSTCP_LOGERR ("conn NULL!"); + return ERR_VAL; + } + + NSPOL_LOGDBG (NEW_RING_DEBUG, "]conn=%p,buf=%p", cpcb->conn, p); + ring = conn->recv_ring; + if (NULL == ring) + { + NSPOL_LOGERR ("Get rtp_perf_ring failed]conn=%p.", conn); + return ERR_CLSD; + } + + /* clear LOOP_SEND_FLAG to indicate that this pbuf has been given to upper layer */ + struct spl_pbuf *tmpbuf = p; + while (tmpbuf) + { + tmpbuf->res_chk.u8Reserve &= ~LOOP_SEND_FLAG; + tmpbuf = tmpbuf->next; + } + + enQueRet = nsfw_mem_ring_enqueue (ring, p); + if (1 != enQueRet) + { + NS_LOG_CTRL (LOG_CTRL_RECV_QUEUE_FULL, LOGTCP, "NSTCP", NSLOG_WAR, + "ringvbox_enqueue buf is full]conn=%p.", conn); + + return ERR_MEM; + } + + return ERR_OK; +} + +/** + * Receive callback function for UDP netconns. + * Posts the packet to conn->recvmbox or deletes it on memory error. + * + * @see udp.h (struct udp_pcb.recv) for parameters + */ + +static void +spl_recv_udp (void *arg, struct udp_pcb *pcb, struct pbuf *p, + const ip_addr_t * ipaddr, u16_t port) +{ + struct spl_netbuf *buf; + spl_netconn_t *conn = (spl_netconn_t *) arg; + struct spl_pbuf *spb = NULL; //?? + + if (NULL == pcb) + { + NSPOL_LOGERR ("recv_udp must have a pcb argument"); + pbuf_free (p); + return; + } + + if (NULL == arg) + { + NSPOL_LOGERR ("recv_udp must have an argument"); + pbuf_free (p); + return; + } + /* //@TODO: malloc and Copy splbuf */ + struct common_pcb *cpcb = (struct common_pcb *) (conn->comm_pcb_data); + + buf = (struct spl_netbuf *) ((char *) p + sizeof (struct spl_pbuf)); + buf->p = spb; + spl_ip_addr_set (&buf->addr, ipaddr); + buf->port = port; + + err_t ret = sp_enqueue (cpcb, (void *) p); + if (ret != ERR_OK) + { + NSPOL_LOGDBG (UDP_DEBUG, "mbox post failed"); + spl_netbuf_delete (buf); + return; + } + else + { + /* Register event with callback */ + NSPOL_LOGDBG (UDP_DEBUG | LWIP_DBG_TRACE, + "recv a udp packet: and api_event"); + SPL_API_EVENT (cpcb->conn, SPL_NETCONN_EVT_RCVPLUS, 1); + } +} + +/** + * Receive callback function for TCP netconns. + * Posts the packet to conn->recvmbox, but doesn't delete it on errors. + * + * @see tcp.h (struct tcp_pcb.recv) for parameters and return value + */ + +err_t +spl_recv_tcp (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct spl_pbuf *spl_pb = NULL; + u32_t len; + + if (NULL == pcb) + { + NSTCP_LOGERR ("recv_tcp must have a pcb argument"); + pbuf_free (p); + return ERR_ARG; + } + + if (NULL == arg) + { + NSTCP_LOGERR ("must have an argument]pcb=%p", pcb); + pbuf_free (p); + return ERR_ARG; + } + + spl_netconn_t *conn = (spl_netconn_t *) arg; + + /* Unlike for UDP or RAW pcbs, don't check for available space + using recv_avail since that could break the connection + (data is already ACKed) */ + /* don't overwrite fatal errors! */ + (void) err; + if (p == NULL) + { + return ERR_OK; + } + + len = p->tot_len; + + u16_t proc_id = spl_get_lcore_id (); + + spl_pb = spl_pbuf_alloc_hugepage (SPL_PBUF_TRANSPORT, + p->tot_len + + g_offSetArry[SPL_PBUF_TRANSPORT], + SPL_PBUF_HUGE, proc_id, conn); + + if (!spl_pb) + { + NSPOL_LOGINF (TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); + return ERR_MEM; + } + + pbuf_to_splpbuf_copy (spl_pb, p); + pbuf_free (p); + + if (sp_enqueue ((struct common_pcb *) conn->comm_pcb_data, (void *) spl_pb) + != ERR_OK) + { + NSPOL_LOGDBG (TCP_DEBUG, "sp_enqueue!=ERR_OK]conn=%p", conn); + spl_pbuf_free (spl_pb); + return ERR_MEM; + } + + SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 1); + conn->recv_avail_prod += len; + + return ERR_OK; +} + +/** + * Poll callback function for TCP netconns. + * Wakes up an application thread that waits for a connection to close + * or data to be sent. The application thread then takes the + * appropriate action to go on. + * + * Signals the conn->sem. + * netconn_close waits for conn->sem if closing failed. + * + * @see tcp.h (struct tcp_pcb.poll) for parameters and return value + */ +err_t +spl_poll_tcp (void *arg, struct tcp_pcb * pcb) +{ + spl_netconn_t *conn = (spl_netconn_t *) arg; + struct tcp_pcb *tpcb = NULL; + + if (NULL == conn) + { + NSPOL_LOGERR ("conn==NULL"); + return ERR_VAL; + } + + if (conn->state == SPL_NETCONN_WRITE) + { + (void) do_writemore (conn); + + /* do_close_internal, can release th PCB + and connection CB. so checking NETCONN_FLAG_CHECK_WRITESPACE should not be + done after do_close_internal. anyway this flag is used with data send.(do_writemore) */ + /* Did a nonblocking write fail before? Then check available write-space. */ + if (conn->flags & SPL_NETCONN_FLAG_CHECK_WRITESPACE) + { + tpcb = (struct tcp_pcb *) conn->private_data; + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((tpcb != NULL) && (tcp_sndbuf (tpcb) > TCP_SNDLOWAT) && + (tcp_sndqueuelen (tpcb) < TCP_SNDQUEUELOWAT)) + { + conn->flags &= ~SPL_NETCONN_FLAG_CHECK_WRITESPACE; + SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); + } + } + } + else if (conn->state == SPL_NETCONN_CLOSE) + { + (void) do_close_internal ((struct common_pcb *) conn->comm_pcb_data, 0); + } + + /* @todo: implement connect timeout here? */ + return ERR_OK; +} + +/** + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +spl_tcp_recv_null (void *arg, struct tcp_pcb * pcb, struct pbuf * p, + err_t err) +{ + LWIP_UNUSED_ARG (arg); + + if (p != NULL) + { + tcp_recved (pcb, p->tot_len); + pbuf_free (p); + } + else if (err == ERR_OK) + { + return tcp_close (pcb); + } + + return ERR_OK; +} + +/** + * Sent callback function for TCP netconns. + * Signals the conn->sem and calls API_EVENT. + * netconn_write waits for conn->sem if send buffer is low. + * + * @see tcp.h (struct tcp_pcb.sent) for parameters and return value + */ +err_t +spl_sent_tcp (void *arg, struct tcp_pcb * pcb, u16_t len) +{ + spl_netconn_t *conn = (spl_netconn_t *) arg; + + if (NULL == conn) + { + NSPOL_LOGERR ("conn==NULL"); + return ERR_VAL; + } + + if (conn->state == SPL_NETCONN_WRITE) + { + (void) do_writemore (conn); + } + else if (conn->state == SPL_NETCONN_CLOSE) + { + (void) do_close_internal ((struct common_pcb *) conn->comm_pcb_data, 0); + } + + /* conn is already checked for NULL above with ASSERT */ + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if (conn->snd_buf > TCP_SNDLOWAT) + { + conn->flags &= ~SPL_NETCONN_FLAG_CHECK_WRITESPACE; + if (((struct common_pcb *) conn->comm_pcb_data)->model == SOCKET_STACKX) + SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); + } + + return ERR_OK; +} + +/** + * Error callback function for TCP netconns. + * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. + * The application thread has then to decide what to do. + * + * @see tcp.h (struct tcp_pcb.err) for parameters + */ +void +spl_err_tcp (void *arg, err_t err) +{ + spl_netconn_t *conn; + enum spl_netconn_state old_state; + data_com_msg *forFree = NULL; + + struct common_pcb *cpcb; + + NSTCP_LOGINF ("Enter err_tcp."); + + conn = (spl_netconn_t *) arg; + cpcb = (struct common_pcb *) (conn->comm_pcb_data); + + old_state = conn->state; + conn->state = SPL_NETCONN_NONE; + + /* Call unlink pcb no matter what */ + unlink_pcb (cpcb); + if (old_state == SPL_NETCONN_CLOSE) + { + /* RST during close: let close return success & dealloc the netconn */ + err = ERR_OK; + SPL_NETCONN_SET_SAFE_ERR (conn, ERR_OK); + } + else + { + SPL_NETCONN_SET_SAFE_ERR (conn, err); + } + + NSTCP_LOGWAR ("inform HUP and ERROR event."); + SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 0); + SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 0); + SPL_API_EVENT (conn, SPL_NETCONN_EVT_ERROR, 0); + SPL_API_EVENT (conn, SPL_NETCONN_EVT_HUP, 1); + + if ((old_state == SPL_NETCONN_WRITE) || (old_state == SPL_NETCONN_CLOSE) + || (old_state == SPL_NETCONN_CONNECT)) + { + int was_nonblocking_connect = spl_netconn_is_nonblocking (conn); + SPL_SET_NONBLOCKING_CONNECT (conn, 0); + + if (!was_nonblocking_connect) + { + /* set error return code */ + if (NULL == cpcb->current_msg) + { + NSPOL_LOGERR ("conn->current_msg==NULL"); + return; + } + + /* current msg could be connect msg or write_buf_msg */ + SET_MSG_ERR (cpcb->current_msg, err); + /* signal app to exit */ + if (old_state == SPL_NETCONN_CONNECT + && !spl_netconn_is_nonblocking (conn)) + { + SYNC_MSG_ACK (cpcb->current_msg); + } + + /* no matter it's connect msg or write msg, we will no process it any more */ + cpcb->current_msg = NULL; + + /* but, if msg is write_buf_msg, then we should release the pbuf in msg */ + if (cpcb->msg_head != NULL) + { + /* current_msg should be write_buf_msg */ + msg_write_buf *tmp_msg = cpcb->msg_head; + while (tmp_msg != NULL) + { + + forFree = MSG_ENTRY (tmp_msg, data_com_msg, buffer); + spl_pbuf_free (tmp_msg->p); + tmp_msg = tmp_msg->next; + + // free msg + ASYNC_MSG_FREE (forFree); + } + cpcb->current_msg = NULL; + cpcb->msg_head = cpcb->msg_tail = NULL; + } + } + } + else + { + + } +} + +/** + * Setup a tcp_pcb with the correct callback function pointers + * and their arguments. + * + * @param conn the TCP netconn to setup + */ +NSTACK_STATIC void +setup_tcp (struct tcp_pcb *pcb, spl_netconn_t * conn) +{ + struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; + + /* callback have the same value as cpcb->conn */ + cpcb->conn = conn; + tcp_arg (pcb, (void *) conn); + tcp_recv (pcb, tcp_fn[TCP_FN_STACKX].recv_fn); + tcp_sent (pcb, tcp_fn[TCP_FN_STACKX].sent_fn); + tcp_poll (pcb, tcp_fn[TCP_FN_STACKX].poll_fn, 4); + tcp_err (pcb, tcp_fn[TCP_FN_STACKX].err_fn); + +} + +/** + * Accept callback function for TCP netconns. + * Allocates a new netconn and posts that to conn->acceptmbox. + * + * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value + */ +err_t +spl_accept_function (void *arg, struct tcp_pcb *newpcb, err_t err) +{ + spl_netconn_t *newconn; + spl_netconn_t *lconn = (spl_netconn_t *) arg; /* listen conneciton */ + struct common_pcb *cpcb = NULL; + + NSPOL_LOGDBG (API_MSG_DEBUG, "]state=%s", + tcp_debug_state_str (newpcb->state)); + + if (lconn == NULL) + { + NSPOL_LOGERR ("accept_function: conn is NULL"); + return ERR_VAL; + } + + /* We have to set the callback here even though + * the new socket is unknown. conn->socket is marked as -1. */ + newconn = ss_malloc_conn (lconn->conn_pool, SPL_NETCONN_TCP); + if (newconn == NULL) + { + NSPOL_LOGERR ("conn alloc failed"); + return ERR_MEM; + } + + cpcb = alloc_common_pcb (SPL_NETCONN_TCP); + if (cpcb == NULL) + { + return ERR_MEM; + } + + /* used by application to recycle conn */ + newconn->recycle.accept_from = lconn; + newconn->conn_pool = lconn->conn_pool; + + newconn->recv_obj = (i64) & newconn->private_data; + newconn->private_data = (i64) newpcb; + newconn->comm_pcb_data = (i64) cpcb; + + NSFW_LOGINF ("alloc accept conn]conn=%p,pcb=%p,lconn=%p", newconn, newpcb, + lconn); + newconn->shut_status = 0xFFFF; + newconn->last_err = ERR_OK; + newconn->CanNotReceive = 0; + newconn->flags = 0; + + newconn->state = SPL_NETCONN_NONE; + newconn->mss = newpcb->mss; + newconn->remote_ip.addr = newpcb->remote_ip.addr; + newconn->remote_port = newpcb->remote_port; + ss_set_local_ip (newconn, newpcb->local_ip.addr); + ss_set_local_port (newconn, newpcb->local_port); + + setup_tcp (newpcb, newconn); + newpcb->state = ESTABLISHED; + update_tcp_state (newconn, ESTABLISHED); + + /*Initialize flow control variables */ + newconn->tcp_sndbuf = CONN_TCP_MEM_DEF_LINE; + newconn->tcp_wmem_alloc_cnt = 0; + newconn->tcp_wmem_sbr_free_cnt = 0; + newconn->tcp_wmem_spl_free_cnt = 0; + newconn->snd_buf = 0; + + newconn->bind_thread_index = lconn->bind_thread_index; + ss_set_msg_box (newconn, + ss_get_instance_msg_box (newconn->bind_thread_index, 0)); + + /* no protection: when creating the pcb, the netconn is not yet known + to the application thread */ + newconn->last_err = err; + + NSPOL_LOGDBG (TCP_DEBUG, + "trypost]newconn=%p, tcp=%p state=%d conn state=%d ", newconn, + newpcb, newpcb->state, newconn->state); + if (accept_enqueue (lconn, (void *) newconn) != ERR_OK) + { + /* remove all references to this netconn from the pcb */ + NSPOL_LOGERR ("sp_enqueue!=ERR_OK]ring = %p", newconn->recv_ring); + + tcp_arg (newpcb, NULL); + tcp_recv (newpcb, tcp_fn[TCP_FN_NULL].recv_fn); + tcp_sent (newpcb, tcp_fn[TCP_FN_NULL].sent_fn); + tcp_poll (newpcb, tcp_fn[TCP_FN_NULL].poll_fn, 0); + tcp_err (newpcb, tcp_fn[TCP_FN_NULL].err_fn); + /* drop conn */ + tcp_drop_conn (newconn); + return ERR_MEM; + } + + SPL_API_EVENT (lconn, SPL_NETCONN_EVT_ACCEPT, 1); + /* tcp_accepted_with_return_value(newpcb); */ + + return ERR_OK; +} + +int +common_pcb_init (struct common_pcb *cpcb) +{ + // u32 threadnum = p_lwip_instance->rss_queue_id + 1;//0 for app + + cpcb->hostpid = get_sys_pid (); + + cpcb->socket = 0; + /* run and close repeatly nstackmain coredum */ + cpcb->close_progress = 0; + cpcb->model = SOCKET_STACKX; + cpcb->current_msg = NULL; + cpcb->msg_head = cpcb->msg_tail = NULL; + cpcb->write_offset = 0; + + cpcb->recv_timeout = cpcb->send_timeout = 0; + + cpcb->sk_rcvlowat = 1; + + cpcb->l4_tick = 0; + cpcb->dataSentFlag = 0; + cpcb->recv_ring_not_empty = 0; + + return 0; +} + +int +common_pcb_reset (struct common_pcb *cpcb) +{ + cpcb->conn = NULL; + cpcb->hostpid = 0; + + cpcb->socket = 0; + /* run and close repeatly nstackmain coredum */ + cpcb->close_progress = 0; + cpcb->model = 0; + cpcb->current_msg = NULL; + cpcb->msg_head = cpcb->msg_tail = NULL; + cpcb->write_offset = 0; + + cpcb->recv_timeout = cpcb->send_timeout = 0; + + cpcb->sk_rcvlowat = 0; + + cpcb->l4_tick = 0; + cpcb->dataSentFlag = 0; + cpcb->recv_ring_not_empty = 0; + + return 0; +} + +void +unlink_pcb (struct common_pcb *cpcb) +{ + if (cpcb && cpcb->conn) + { + /* whatever the private data will be reset */ + cpcb->conn->private_data = 0; + update_tcp_state (cpcb->conn, CLOSED); + } + else + { + NSPOL_LOGINF (API_MSG_DEBUG, "conn is detached already!"); + } +} + +void +unlink_recv_ring (spl_netconn_t * conn) +{ + if (conn) + conn->recv_ring_valid = 0; +} + +void +recycle_tmr (void *arg) +{ + if (arg == NULL) + { + NSPOL_LOGERR ("recycle_message is NULL!"); + } + else + { + (void) ss_recycle_conn (arg, do_try_delconn); + } +} + +/** + * Create a new pcb of a specific type. + * Called from do_newconn(). + * + * @param msg the api_msg_msg describing the connection type + * @return msg->conn->err, but the return value is currently ignored + */ +int +spl_pcb_new (msg_new_netconn * pmsg) +{ + u16_t thread_index = spl_get_lcore_id (); + struct common_pcb *cpcb = NULL; + enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; + + /* Allocate a PCB for this connection */ + switch (SPL_NETCONNTYPE_GROUP (pmsg->type)) + { + case SPL_NETCONN_UDP: + { + struct udp_pcb *u = udp_new_ip_type (iptype); + if (u == NULL) + { + return ERR_MEM; + } + + if (pmsg->type == SPL_NETCONN_UDPNOCHKSUM) + { + udp_setflags (u, UDP_FLAGS_NOCHKSUM); + } + + cpcb = (struct common_pcb *) alloc_common_pcb (SPL_NETCONN_UDP); + if (cpcb == NULL) + { + return ERR_MEM; + } + + pmsg->conn->comm_pcb_data = (i64) cpcb; + pmsg->conn->private_data = (i64) u; + udp_recv (u, spl_recv_udp, (void *) pmsg->conn); + break; + } + + case SPL_NETCONN_TCP: + { + struct tcp_pcb *t = tcp_new_ip_type (iptype); + if (t == NULL) + { + return ERR_MEM; + } + + cpcb = alloc_common_pcb (SPL_NETCONN_TCP); + if (cpcb == NULL) + { + return ERR_MEM; + } + + pmsg->conn->comm_pcb_data = (i64) cpcb; + pmsg->conn->private_data = (i64) t; + setup_tcp (t, pmsg->conn); + break; + } + + default: + /* Unsupported netconn type, e.g. protocol disabled */ + NSPOL_LOGERR ("Unsupported netconn type!"); + return ERR_VAL; + } + + /* type and socket value for all type */ + cpcb->socket = pmsg->socket; + cpcb->conn = pmsg->conn; + cpcb->bind_thread_index = thread_index; + + /* used to find pcb when a msg is received */ + return ERR_OK; +} + +/** + * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in + * these mboxes + * + * @param conn the netconn to free + * @bytes_drained bytes drained from recvmbox + * @accepts_drained pending connections drained from acceptmbox + */ +int +netconn_drain (enum spl_netconn_type type, spl_netconn_t * conn) +{ + int i, n; + mring_handle ring = NULL; + void *addr[32] = { 0 }; + int not_empty = 0; + + /* This runs in tcpip_thread, so we don't need to lock against rx packets */ + ring = conn->recv_ring; + do + { + /*every times get atmost 32 to release */ + n = nsfw_mem_ring_dequeuev (ring, addr, 32); + for (i = 0; i < n; i++) + { + /* if the con is UDP, buffer type also is struct spl_netbuf,it is same as RAW */ + if ((type == SPL_NETCONN_RAW) || (type == SPL_NETCONN_UDP)) + { + spl_pbuf_free ((struct spl_pbuf *) addr[i]); + if (type == SPL_NETCONN_UDP) + { + UDP_STATS_INC (udp.drop); + } + } + else + { + spl_pbuf_free ((struct spl_pbuf *) addr[i]); + } + + if (not_empty == 0) + not_empty = 1; + } + } + while (0 != n); + return not_empty; +} + +/* need free mbuf inside recv ring before free conn */ +void +free_conn_by_spl (spl_netconn_t * conn) +{ + struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; + + free_common_pcb (cpcb); + + (void) netconn_drain (conn->type, conn); + ss_free_conn (conn); +} + +int +do_close_finished (struct common_pcb *cpcb, u8_t close_finished, u8_t shut, + err_t err, int OpShutDown) +{ + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + spl_netconn_t *conn = cpcb->conn; + + if (!close_finished) + { + /* Closing succeeded */ + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + if (LISTEN == tpcb->state) + { + NSPOL_LOGERR ("Closing a listen pcb may not fail!"); + return ERR_VAL; + } + + tcp_sent (tpcb, tcp_fn[TCP_FN_STACKX].sent_fn); + tcp_poll (tpcb, tcp_fn[TCP_FN_STACKX].poll_fn, 1); + tcp_err (tpcb, tcp_fn[TCP_FN_STACKX].err_fn); + tcp_arg (tpcb, conn); + /* don't restore recv callback: we don't want to receive any more data */ + } + else + { + /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ + if (cpcb->current_msg) + { + SET_MSG_ERR (cpcb->current_msg, err); + cpcb->current_msg = NULL; + } + + conn->state = SPL_NETCONN_NONE; + NSTCP_LOGINF ("release pcb]conn=%p,pcb=%p", conn, tpcb); + unlink_pcb (cpcb); + } + + return ERR_OK; +} + +NSTACK_STATIC void +reset_tcp_callback (struct tcp_pcb *tpcb, struct common_pcb *cpcb, u8 shut) +{ + spl_netconn_t *conn = cpcb->conn; + + /* some callbacks have to be reset if tcp_close is not successful */ + if (shut & SPL_NETCONN_SHUT_RD) + { + conn->CanNotReceive = 1; + tcp_recv (tpcb, tcp_fn[TCP_FN_NULL].recv_fn); + tcp_accept (tpcb, tcp_fn[TCP_FN_NULL].accept_fn); + } + + if (shut & SPL_NETCONN_SHUT_WR) + { + tcp_sent (tpcb, tcp_fn[TCP_FN_NULL].sent_fn); + } + + if (shut == SPL_NETCONN_SHUT_RDWR) + { + tcp_poll (tpcb, tcp_fn[TCP_FN_NULL].poll_fn, 0); + tcp_err (tpcb, tcp_fn[TCP_FN_NULL].err_fn); + } +} + +/** + * Internal helper function to close a TCP netconn: since this sometimes + * doesn't work at the first attempt, this function is called from multiple + * places. + * + * @param conn the TCP netconn to close + */ +err_t +do_close_internal (struct common_pcb *cpcb, int OpShutDown) +{ + err_t err; + u8_t shut, ucclose; + u8_t close_finished = 0; + + if (NULL == cpcb) + { + NSTCP_LOGERR ("invalid conn"); + return ERR_ARG; + } + + spl_netconn_t *conn = cpcb->conn; + if (SPL_NETCONN_TCP != cpcb->type || SPL_NETCONN_CLOSE != conn->state) + { + NSTCP_LOGERR ("conn=%p, err_type=%d, error_state=%d", + conn, cpcb->type, conn->state); + return ERR_VAL; + } + + struct tcp_pcb *tpcb = (struct tcp_pcb *) (conn->private_data); + + if (cpcb->current_msg != NULL) + shut = get_shut_op (cpcb->current_msg); + else + shut = SPL_NETCONN_SHUT_RDWR; + + /* shutting down both ends is the same as closing */ + ucclose = (shut == SPL_NETCONN_SHUT_RDWR); + + /* Set back some callback pointers */ + if (ucclose) + { + conn->CanNotReceive = 1; + tcp_arg (tpcb, conn); + } + + if (tpcb->state == LISTEN) + { + tcp_accept (tpcb, tcp_fn[TCP_FN_NULL].accept_fn); + } + else + { + reset_tcp_callback (tpcb, cpcb, shut); + } + + /* Try to close the connection */ + if (shut == SPL_NETCONN_SHUT_RDWR && !OpShutDown) + { + err = tcp_close (tpcb); + } + else + { + err = + tcp_shutdown (tpcb, shut & SPL_NETCONN_SHUT_RD, + shut & SPL_NETCONN_SHUT_WR); + } + + if (err == ERR_OK) + { + close_finished = 1; + } + else + { + if (err == ERR_MEM) + { + /* Blocking close, check the timeout */ + close_finished = 1; + if (ucclose) + { + /* in this case, we want to RST the connection */ + tcp_abort (tpcb); + err = ERR_OK; + } + } + else + { + /* Closing failed for a non-memory error: give up */ + close_finished = 1; + } + } + + err_t err1 = do_close_finished (cpcb, close_finished, + shut, err, OpShutDown); + if (err1 != ERR_OK) + { + NSTCP_LOGERR ("return err1]pcb=%p,err1=%d", tpcb, err1); + return err1; + } + return err; + + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ +} + +void +do_try_delconn (void *close_data, u32 delay_sec) +{ + msg_delete_netconn *dmsg = (msg_delete_netconn *) close_data; + data_com_msg *m = MSG_ENTRY (dmsg, data_com_msg, buffer); + struct common_pcb *cpcb = NULL; + + spl_netconn_t *conn = dmsg->conn; + + /* no receiver in some recycle cases */ + if (0 == m->param.comm_receiver) + { + if (NULL == conn) + { + NSFW_LOGERR ("release err conn!]pid=%d", dmsg->pid); + /* need to free pbufs which are attached to msg */ + do_pbuf_free (dmsg->buf); + return; + } + + cpcb = (struct common_pcb *) conn->comm_pcb_data; + } + else + { + cpcb = COMM_PRIVATE_PTR (m); + } + + /* no pcb in some recycle cases */ + if (conn->private_data == 0) + { + /* though pcb is gone, still need to clean the mbox */ + if (conn != NULL) + (void) netconn_drain (conn->type, conn); + + NSFW_LOGWAR ("release conn pcb null]pcb=%p", m->param.receiver); + /* need to free pbufs which are attached to msg */ + do_pbuf_free (dmsg->buf); + return; + } + + if (delay_sec) + { + NSFW_LOGWAR ("delay to recycle!]pcb=%p, msg=%d", cpcb, dmsg); + sys_timeout (delay_sec * 1000, recycle_tmr, dmsg); + return; + } + + do_delconn (cpcb, dmsg); + + /* after the do_delconn, the PCB maybe released, but the conn is ok */ + sys_sem_s_signal (&dmsg->conn->close_completed); + + return; +} + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_delconn (struct common_pcb *cpcb, msg_delete_netconn * dmsg) +{ + spl_netconn_t *conn = cpcb->conn; + data_com_msg *pmsg = MSG_ENTRY (dmsg, data_com_msg, buffer); + + /*if already close, just return */ + /* run and close repeatly nstackmain coredum */ + if (1 == cpcb->close_progress) + { + SET_MSG_ERR (pmsg, ERR_OK); + return; + } + cpcb->close_progress = 1; + + /* Pbuf free should be done in network stack */ + do_pbuf_free (dmsg->buf); + + /* @todo TCP: abort running write/connect? */ + if ((conn->state != SPL_NETCONN_NONE) + && (conn->state != SPL_NETCONN_LISTEN) + && (conn->state != SPL_NETCONN_CONNECT)) + { + /* this only happens for TCP netconns */ + if (SPL_NETCONN_TCP != cpcb->type) + { + NSTCP_LOGERR ("msg->conn->type error!]conn=%p,msg->conn->type=%d", + conn, cpcb->type); + SET_MSG_ERR (pmsg, ERR_VAL); + return; + } + NSPOL_LOGINF (SOCK_INFO, "conn is not for free state]conn=%p,state=%d", + conn, conn->state); + + //need to release pcb + if (cpcb->current_msg != NULL && cpcb->msg_tail != NULL) + { + NSPOL_LOGINF (SOCK_INFO, + "conn there is data in conn->current_msg when close the conn]conn=%p,state=%d", + conn, conn->state); + (void) do_writemore (cpcb->conn); + } + } + + /* + the accpet connections waiting in listen queue will be clear in + netconn_drain. + */ + if (conn->state == SPL_NETCONN_LISTEN) + { + /* This function does nothing in original code. */ + } + else + { + /* Drain pbuf from non-listen mboxes */ + if (netconn_drain (cpcb->type, conn)) + { + cpcb->recv_ring_not_empty = 1; + + NSPOL_LOGWAR (SOCK_INFO, + "still some data leave in recv ring when close"); + } + } + + /* conn will be released outside */ + + switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) + { + + case SPL_NETCONN_UDP: + { + struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; + upcb->recv_arg = NULL; + udp_remove (upcb); + break; + } + + case SPL_NETCONN_TCP: + { + conn->state = SPL_NETCONN_CLOSE; + dmsg->shut = SPL_NETCONN_SHUT_RDWR; + cpcb->current_msg = pmsg; + + if (ERR_INPROGRESS == do_close_internal (cpcb, 0)) + { + return; + } + } + default: + break; + } + + /* tcp netconns don't come here! */ + +} + +/** + * Bind a pcb contained in a netconn + * Called from netconn_bind. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IPaddress and port to bind to + */ +void +do_bind (struct common_pcb *cpcb, msg_bind * bmsg) +{ + spl_netconn_t *conn = cpcb->conn; + data_com_msg *pmsg = MSG_ENTRY (bmsg, data_com_msg, buffer); + ip_addr_t stIpaddr; + + stIpaddr.addr = bmsg->ipaddr.addr; + + if (SPL_ERR_IS_FATAL (conn->last_err) + && ERR_CANTASSIGNADDR != conn->last_err) + { + NSTCP_LOGERR ("bind but conn has err]pcb=%p,conn=%p,err=%d", cpcb, conn, + conn->last_err); + SET_MSG_ERR (pmsg, conn->last_err); + } + else + { + if (!ip_addr_isany (&bmsg->ipaddr) + && !ip_addr_ismulticast (&bmsg->ipaddr)) + { + if (!get_netif_by_ip (bmsg->ipaddr.addr) + && !netif_check_broadcast_addr (&bmsg->ipaddr)) + { + NSPOL_LOGERR ("ip is not exist]pcb=%p,ip=%u", cpcb, + bmsg->ipaddr.addr); + SET_MSG_ERR (pmsg, ERR_CANTASSIGNADDR); + return; + } + } + + SET_MSG_ERR (pmsg, ERR_VAL); + switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) + { + case SPL_NETCONN_UDP: + SET_MSG_ERR (pmsg, + udp_bind ((struct udp_pcb *) (cpcb-> + conn->private_data), + &stIpaddr, bmsg->port)); + + /* Set local Ip, willbe used during connect */ + struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; + ss_set_local_ip (cpcb->conn, upcb->local_ip.addr); + ss_set_local_port (cpcb->conn, upcb->local_port); + NSTCP_LOGINF ("updated Ip to spl_netconn_t] %x", + upcb->local_ip.addr); + + NSUDP_LOGINF + ("udp_bind return]pcb=%p,IP=%u.%u.%u.%u,port=%u,err=%d", + (struct udp_pcb *) cpcb->conn->private_data, + &bmsg->ipaddr == NULL ? 0 : ip4_addr1_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr2_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr3_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr4_16 (&stIpaddr), bmsg->port, + GET_MSG_ERR (pmsg)); + break; + + case SPL_NETCONN_TCP: + SET_MSG_ERR (pmsg, + tcp_bind ((struct tcp_pcb *) cpcb->conn->private_data, + &stIpaddr, bmsg->port)); + + /* Set local Ip, willbe used during connect */ + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + NSTCP_LOGINF ("updated Ip to spl_netconn_t] %x", + tpcb->local_ip.addr); + ss_set_local_ip (cpcb->conn, tpcb->local_ip.addr); + ss_set_local_port (cpcb->conn, tpcb->local_port); + + NSTCP_LOGINF + ("tcp_bind return]pcb=%p,IP=%u.%u.%u.%u,port=%u,err=%d", + (struct tcp_pcb *) cpcb->conn->private_data, + &bmsg->ipaddr == NULL ? 0 : ip4_addr1_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr2_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr3_16 (&stIpaddr), + &bmsg->ipaddr == NULL ? 0 : ip4_addr4_16 (&stIpaddr), bmsg->port, + GET_MSG_ERR (pmsg)); + break; + default: + break; + } + } + + conn->last_err = GET_MSG_ERR (pmsg); + NSPOL_LOGDBG (TESTSOCKET_DEBUG | LWIP_DBG_TRACE, "the msg is doing bind"); + NSTCP_LOGINF ("the msg is doing bind"); +} + +/** + * TCP callback function if a connection (opened by tcp_connect/do_connect) has + * been established (or reset by the remote host). + * + * @see tcp.h (struct tcp_pcb.connected) for parameters and return values + */ +err_t +spl_do_connected (void *arg, struct tcp_pcb *pcb, err_t err) +{ + spl_netconn_t *conn = (spl_netconn_t *) arg; + struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; + data_com_msg *m = cpcb->current_msg; + int was_blocking; + + if (conn == NULL) + { + NSTCP_LOGERR ("conn is NULL!]arg=%p", arg); + return ERR_ARG; + } + + if (SPL_NETCONN_CONNECT != conn->state) + { + NSTCP_LOGERR ("conn->state error!]conn=%p,state=%d", conn, conn->state); + return ERR_VAL; + } + + if ((NULL == m) && (0 == spl_netconn_is_nonblocking (conn))) + { + NSTCP_LOGERR ("conn->current_msg!]conn=%p,current_msg=%p", conn, m); + return ERR_VAL; + } + + if (m != NULL) + { + SET_MSG_ERR (m, err); + } + + if ((cpcb->type == SPL_NETCONN_TCP) && (err == ERR_OK)) + { + setup_tcp (pcb, conn); + } + + ss_set_local_ip (conn, pcb->local_ip.addr); + ss_set_local_port (conn, pcb->local_port); + conn->remote_ip.addr = pcb->remote_ip.addr; + conn->remote_port = pcb->remote_port; + + conn->mss = pcb->mss; + cpcb->current_msg = NULL; + + was_blocking = !SPL_IN_NONBLOCKING_CONNECT (conn); + SPL_SET_NONBLOCKING_CONNECT (conn, 0); + conn->state = SPL_NETCONN_NONE; + SPL_NETCONN_SET_SAFE_ERR (conn, ERR_OK); + + SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); + + if (was_blocking && m != NULL) + { + SYNC_MSG_ACK (m); + } + + return ERR_OK; +} + +int +do_internal_tcp_connect (struct common_pcb *cpcb, struct tcp_pcb *tpcb, + msg_connect * cmsg) +{ + spl_netconn_t *conn = cpcb->conn; + data_com_msg *pmsg = MSG_ENTRY (cmsg, data_com_msg, buffer); + ip_addr_t ip_addr; + + ip_addr.addr = cmsg->ipaddr.addr; + + /* Prevent connect while doing any other action. */ + if (conn->state != SPL_NETCONN_NONE) + { + if (conn->state == SPL_NETCONN_CONNECT + || conn->state == SPL_NETCONN_WRITE) + { + if (tpcb->state != ESTABLISHED) + { + SET_MSG_ERR (pmsg, ERR_ALREADY); + } + else + { + SET_MSG_ERR (pmsg, ERR_ISCONN); + } + } + else + { + SET_MSG_ERR (pmsg, ERR_ISCONN); + } + + NSTCP_LOGINF + ("tcp_connect]pcb=%p,state=%d,remote_ip=%u.%u.%u.%u,remote_port=%u,local_ip=%u.%u.%u.%u,local_port=%u,err=%d", + tpcb, conn->state, ip4_addr1_16 (&ip_addr), ip4_addr2_16 (&ip_addr), + ip4_addr3_16 (&ip_addr), ip4_addr4_16 (&ip_addr), cmsg->port, + ip4_addr1_16 (&tpcb->local_ip), ip4_addr2_16 (&tpcb->local_ip), + ip4_addr3_16 (&tpcb->local_ip), ip4_addr4_16 (&tpcb->local_ip), + tpcb->local_port, GET_MSG_ERR (pmsg)); + } + else + { + setup_tcp (tpcb, conn); + SET_MSG_ERR (pmsg, + tcp_connect (tpcb, &ip_addr, cmsg->port, + tcp_fn[TCP_FN_STACKX].connected_fn)); + conn->mss = tpcb->mss; + SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); + SPL_API_EVENT (conn, NETCONN_EVT_RCVMINUS, 1); + + NSTCP_LOGINF + ("tcp_connect]pcb=%p,state=%d,remote_ip=%u.%u.%u.%u,remote_port=%u,local_ip=%u.%u.%u.%u,local_port=%u,err=%d", + tpcb, conn->state, ip4_addr1_16 (&ip_addr), ip4_addr2_16 (&ip_addr), + ip4_addr3_16 (&ip_addr), ip4_addr4_16 (&ip_addr), cmsg->port, + ip4_addr1_16 (&tpcb->local_ip), ip4_addr2_16 (&tpcb->local_ip), + ip4_addr3_16 (&tpcb->local_ip), ip4_addr4_16 (&tpcb->local_ip), + tpcb->local_port, GET_MSG_ERR (pmsg)); + if (GET_MSG_ERR (pmsg) == ERR_OK) + { + int nonblock = spl_netconn_is_nonblocking (conn); + SPL_SET_NONBLOCKING_CONNECT (conn, nonblock); + conn->state = SPL_NETCONN_CONNECT; + if (nonblock) + { + SET_MSG_ERR (pmsg, ERR_INPROGRESS); + } + else + { + cpcb->current_msg = pmsg; + /* sys_sem_signal() is called from do_connected (or err_tcp()), + * when the connection is established! */ + return -1; + } + } + } + + return 0; +} + +/** + * Connect a pcb contained inside a netconn + * Called from netconn_connect. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IPaddress and port to connect to + */ +void +do_connect (struct common_pcb *cpcb, msg_connect * cmsg) +{ + data_com_msg *pmsg = MSG_ENTRY (cmsg, data_com_msg, buffer); + ip_addr_t ipaddr; + + SET_MSG_ERR (pmsg, ERR_OK); + + if (cpcb == NULL) + { + /* This may happen when calling netconn_connect() a second time */ + NSTCP_LOGERR ("conn connect but conn has err]msg=%p", pmsg); + SET_MSG_ERR (pmsg, ERR_CLSD); + return; + } + + ipaddr.addr = cmsg->ipaddr.addr; + switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) + { + case SPL_NETCONN_UDP: + { + struct udp_pcb *upcb = (struct udp_pcb *) (cpcb->conn->private_data); + if (ip_addr_isany (&upcb->local_ip)) + { + upcb->local_ip.addr = cmsg->local_ip.addr; + ss_set_local_ip (cpcb->conn, upcb->local_ip.addr); + } + + SET_MSG_ERR (pmsg, udp_connect (upcb, &ipaddr, cmsg->port)); + if (ERR_OK == pmsg->param.err) + { + cpcb->conn->remote_ip.addr = cmsg->ipaddr.addr; + cpcb->conn->remote_port = cmsg->port; + } + break; + } + case SPL_NETCONN_TCP: + { + struct tcp_pcb *tpcb = (struct tcp_pcb *) (cpcb->conn->private_data); + if (ip_addr_isany (&tpcb->local_ip)) + { + tpcb->local_ip.addr = cmsg->local_ip.addr; + ss_set_local_ip (cpcb->conn, tpcb->local_ip.addr); + } + + if (0 != do_internal_tcp_connect (cpcb, tpcb, cmsg)) + { + return; + } + + } + break; + default: + NSPOL_LOGERR ("Invalid netconn type]type=%d", cpcb->type); + SET_MSG_ERR (pmsg, ERR_VAL); + break; + } + + /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), + so use TCPIP_APIMSG_ACK() here. + Do as lwip-2.0.0. set conn->last_error here. */ + SPL_NETCONN_SET_SAFE_ERR (cpcb->conn, GET_MSG_ERR (pmsg)); +} + +/* Pbuf free should be done in network stack */ +void +do_pbuf_free (struct spl_pbuf *buf) +{ + if (buf) + { + struct spl_pbuf *pCur = buf; + while (buf) + { + pCur = buf; + buf = buf->freeNext; + spl_pbuf_free (pCur); + } + } +} + +/** + * Set a TCP pcb contained in a netconn into listen mode + * Called from netconn_listen. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_listen (struct common_pcb *cpcb, msg_listen * lmsg) +{ + err_t err = ERR_OK; + spl_netconn_t *conn = cpcb->conn; + data_com_msg *pmsg = MSG_ENTRY (lmsg, data_com_msg, buffer); + + if (SPL_ERR_IS_FATAL (conn->last_err)) + { + NSTCP_LOGERR ("conn listern but conn has err]conn=%p,err=%d", + conn, conn->last_err); + SET_MSG_ERR (pmsg, conn->last_err); + } + else + { + SET_MSG_ERR (pmsg, ERR_CONN); + + if (cpcb->type == SPL_NETCONN_TCP) + { + if (conn->state == SPL_NETCONN_NONE) + { + struct tcp_pcb *lpcb; + if (((struct tcp_pcb *) (cpcb->conn->private_data))->state != + CLOSED) + { + /* connection is not closed, cannot listen */ + SET_MSG_ERR (pmsg, ERR_VAL);; + } + else + { + u8_t backlog = TCP_DEFAULT_LISTEN_BACKLOG; + + lpcb = + tcp_listen_with_backlog_and_err ((struct tcp_pcb + *) (cpcb-> + conn->private_data), + backlog, &err); + if (lpcb == NULL) + { + /* in this case, the old pcb is still allocated */ + SET_MSG_ERR (pmsg, err); + } + else + { + SET_MSG_ERR (pmsg, ERR_OK); + /* conn now is put on lpcb */ + conn->state = SPL_NETCONN_LISTEN; + + /* NOTE: pmsg->conn->comm_pcb_data == (i64)cpcb; should be already same. */ + conn->private_data = (i64) lpcb; + + tcp_arg (lpcb, conn); + tcp_accept (lpcb, tcp_fn[TCP_FN_STACKX].accept_fn); + + SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); + SPL_API_EVENT (conn, NETCONN_EVT_RCVMINUS, 1); + } + } + } + else if (conn->state == SPL_NETCONN_LISTEN) + { + SET_MSG_ERR (pmsg, ERR_OK); + } + } + NSTCP_LOGINF ("listen]conn=%p,pcb=%p,connstate=%d,err=%d", + conn, cpcb, conn->state, GET_MSG_ERR (pmsg)); + + } + +} + +/** + * Send some data on a RAW or UDP pcb contained in a netconn + * Called from netconn_send + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_send (struct common_pcb *cpcb, msg_send_buf * smsg) +{ + struct spl_pbuf *p = smsg->p; + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + spl_netconn_t *conn = cpcb->conn; + + pbuf_set_recycle_flg (p, MBUF_HLD_BY_SPL); /* release buf hold by app on abnormal exit */ + + if (SPL_ERR_IS_FATAL (conn->last_err)) + { + SET_MSG_ERR (m, conn->last_err); + spl_pbuf_free (p); + return; + } + + switch (SPL_NETCONNTYPE_GROUP (cpcb->type)) + { + case SPL_NETCONN_UDP: + { + struct udp_pcb *upcb = (struct udp_pcb *) (cpcb->conn->private_data); + if (ip_addr_isany (&upcb->local_ip)) + { + upcb->local_ip.addr = smsg->local_ip.addr; + ss_set_local_ip (conn, smsg->local_ip.addr); + } + + //spl_ip_addr_t *destIP = &smsg->addr; + + //@TODO udp send need to update like TCP. copy pbuf here. Once testing done for TCP we'll update it here. + if (ip_addr_isany (&smsg->addr)) + { + //SET_MSG_ERR(m, udp_send(upcb, p)); + /* destIP.addr == IPADDR_ANY means it is from stackx_send + and the destination is stored in remote_ip and remote port */ + //destIP = &upcb->remote_ip; + } + else + { + //SET_MSG_ERR(m, udp_sendto(upcb, p, &smsg->addr, smsg->port)); + } + break; + } + + default: + SET_MSG_ERR (m, ERR_CONN); + break; + } + + return; +} + +/** + * Indicate data has been received from a TCP pcb contained in a netconn + * Called from netconn_recv + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_recv (struct common_pcb *cpcb, msg_recv_buf * rmsg) +{ + data_com_msg *m = MSG_ENTRY (rmsg, data_com_msg, buffer); + SET_MSG_ERR (m, ERR_OK); + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + + if (NULL == tpcb) + { + if (rmsg->p) + { + NSPOL_LOGDBG (TCP_DEBUG, + "When pcb was freed: do recv, and free pbuf"); + spl_pbuf_free (rmsg->p); + rmsg->p = NULL; + } + + return; + } + + if (cpcb->conn->type == SPL_NETCONN_TCP) + { + /* Pbuf free should be done in network stack */ + if (rmsg->p) + { + NSPOL_LOGDBG (TCP_DEBUG, "do recv, and free pbuf"); + spl_pbuf_free (rmsg->p); + rmsg->p = NULL; + } + tcp_recved (tpcb, rmsg->len * TCP_MSS); + } +} + +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ + +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ +err_t +do_writemore (struct spl_netconn *conn) +{ + err_t err = ERR_OK; + u16_t len = 0, available; + u8_t write_finished = 0; + struct tcp_pcb *tpcb = (struct tcp_pcb *) conn->private_data; + common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; + size_t diff; + const void *dataptr; + + if ((NULL == tpcb) || (NULL == conn) || (SPL_NETCONN_WRITE != conn->state) + || (NULL == cpcb->current_msg)) + { + NSPOL_LOGERR ("conn=NULL"); + return ERR_ARG; + } + + msg_write_buf *wmsg = (msg_write_buf *) cpcb->current_msg->buffer; +start_write: + + if (NULL == wmsg->p) + { + NSPOL_LOGERR ("wmsg->p is NULL]conn=%p,pcb=%p", conn, tpcb); + return ERR_VAL; + } + + u8_t apiflags = wmsg->apiflags; + struct spl_pbuf *current_w_pbuf = wmsg->p; + current_w_pbuf->res_chk.u8Reserve |= NEED_ACK_FLAG; + wmsg->p = current_w_pbuf->next; + current_w_pbuf->next = NULL; + + dataptr = (const u8_t *) current_w_pbuf->payload + cpcb->write_offset; + diff = current_w_pbuf->len - cpcb->write_offset; + + if (diff > 0xffffUL) + { + len = 0xffff; + apiflags |= TCP_WRITE_FLAG_MORE; + } + else + { + len = (u16_t) diff; + } + + available = tcp_sndbuf (tpcb); + if (!available) + { + err = ERR_MEM; + goto err_mem; + } + + if (available < len) + { + /* don't try to write more than sendbuf */ + len = available; + apiflags |= TCP_WRITE_FLAG_MORE; + } + + err = tcp_write (tpcb, dataptr, len, apiflags); + if ((err == ERR_OK) || (err == ERR_MEM)) + { + err_mem: + if ((tcp_sndbuf (tpcb) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen (tpcb) >= TCP_SNDQUEUELOWAT)) + { + SPL_API_EVENT (conn, NETCONN_EVT_SENDMINUS, 1); + } + } + if (err == ERR_OK) + { + cpcb->write_offset += len; + tcp_output (tpcb); + + if (cpcb->write_offset == current_w_pbuf->len) + { + cpcb->write_offset = 0; + spl_pbuf_free (current_w_pbuf); + if (NULL == wmsg->p) + { + /* this message is finished */ + cpcb->write_offset = 0; + SET_MSG_ERR (cpcb->current_msg, err); + + /* go to next msg */ + data_com_msg *forFreemsg = cpcb->current_msg; + msg_write_buf *msg_head_prev = cpcb->msg_head; + cpcb->msg_head = cpcb->msg_head->next; + + /* no msg remain */ + if (cpcb->msg_head == NULL) + { + write_finished = 1; + if (cpcb->msg_tail != NULL + && msg_head_prev != cpcb->msg_tail) + { + NSPOL_LOGWAR (TCP_DEBUG, + "err maybe lost one mesg]conn=%p,pcb=%p", + conn, tpcb); + } + cpcb->msg_tail = NULL; + cpcb->current_msg = NULL; + conn->state = SPL_NETCONN_NONE; + } + else /* go to handle next message */ + { + + cpcb->current_msg = + MSG_ENTRY (cpcb->msg_head, data_com_msg, buffer); + wmsg = cpcb->msg_head; + write_finished = 0; + } + + ASYNC_MSG_FREE (forFreemsg); + } + + } + else + { + if (cpcb->write_offset > current_w_pbuf->len) + { + NSPOL_LOGERR ("Big trouble write_offset > current_w_pbuf->len"); + } + + current_w_pbuf->next = wmsg->p; + wmsg->p = current_w_pbuf; + } + if ((write_finished == 0) && (NULL != wmsg->p)) + { + goto start_write; + } + } + else if (err == ERR_MEM) + { + current_w_pbuf->next = wmsg->p; + wmsg->p = current_w_pbuf; + tcp_output (tpcb); + } + else + { + NSPOL_LOGERR ("]pcb=%p, error when send %d", tpcb, err); + write_finished = 1; + cpcb->write_offset = 0; + current_w_pbuf->next = wmsg->p; + wmsg->p = current_w_pbuf; + tcp_abort (tpcb); + return err; + } + NSTCP_LOGINF ("do_writemore finished with err %d", err); + return ERR_OK; +} + +/** + * Send some data on a TCP pcb contained in a netconn + * Called from netconn_write + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_write (struct common_pcb *cpcb, msg_write_buf * wmsg) +{ + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + spl_netconn_t *conn = cpcb->conn; + data_com_msg *m = MSG_ENTRY (wmsg, data_com_msg, buffer); + + pbuf_set_recycle_flg (wmsg->p, MBUF_HLD_BY_SPL); /* release buf hold by app on abnormal exit */ + + int tcpState = -1; + + /* if msg->conn is null, then return */ + if (NULL == conn) + { + NSPOL_LOGERR ("Invalid param]msg->conn=%p", conn); + SET_MSG_ERR (m, ERR_VAL); + goto err_return; + } + + tcpState = tpcb->state; + + if ((SPL_ERR_IS_FATAL (conn->last_err)) + && !((ERR_CLSD == conn->last_err) && (CLOSE_WAIT == tcpState))) + { + SET_MSG_ERR (m, conn->last_err); + } + else + { + if (cpcb->type == SPL_NETCONN_TCP) + { + if (cpcb->current_msg != NULL) + { + if (NULL == cpcb->msg_head || NULL == cpcb->msg_tail) + { + /* if possible only if connect is not finished and it's + blocking, then the current_msg is connect msg. + */ + NSPOL_LOGERR ("netconn do_write msg is null]msg_type=%d", + cpcb->current_msg->param.minor_type); + goto err_return; + } + + /* only msg_write_buf will be in msg_head-msg_tail queue */ + wmsg->next = NULL; + cpcb->msg_tail->next = wmsg; + cpcb->msg_tail = wmsg; + (void) do_writemore (conn); + NSTCP_LOGINF ("do_write finished...."); + return; + } + + if (conn->state != SPL_NETCONN_NONE) + { + /* netconn is connecting, closing or in blocking write */ + NSPOL_LOGINF (TCP_DEBUG, + "msg->conn->state != SPL_NETCONN_NONE..netconn is connecting, " + "closing or in blocking write]conn=%p", conn); + SET_MSG_ERR (m, ERR_INPROGRESS); + } + /* this means we should start to process this message */ + else if (tpcb != NULL) + { + conn->state = SPL_NETCONN_WRITE; + + /* set all the variables used by do_writemore */ + if (0 != cpcb->write_offset) + { + NSPOL_LOGERR ("already writing or closing]conn=%p", conn); + goto err_return; + } + + if (0 == wmsg->len) + { + NSPOL_LOGERR ("msg->msg.w.len=0]conn=%p", conn); + goto err_return; + } + + /* record the msg will be processed */ + cpcb->current_msg = m; + if (cpcb->msg_head != NULL || cpcb->msg_tail != NULL) + { + NSPOL_LOGERR ("error maybe lost mesg]conn=%p", conn); + } + cpcb->msg_head = cpcb->msg_tail = wmsg; + wmsg->next = NULL; + cpcb->write_offset = 0; + + (void) do_writemore (conn); + + if ((conn->snd_buf) > TCP_SNDLOWAT) + { + if (cpcb->model == SOCKET_STACKX) + SPL_API_EVENT (conn, SPL_NETCONN_EVT_SENDPLUS, 1); + } + NSTCP_LOGINF ("do_write finished %d", conn->snd_buf); + + /* for both cases: if do_writemore was called, don't ACK the APIMSG + since do_writemore ACKs it! */ + return; + } + else + { + SET_MSG_ERR (m, ERR_CONN); + } + } + else + { + SET_MSG_ERR (m, ERR_VAL); + } + } + NSTCP_LOGINF ("do_write finished"); + +err_return: + pbuf_free_safe (wmsg->p); + ASYNC_MSG_FREE (m); + + return; +} + +void +do_getsockname (struct common_pcb *cpcb, msg_getaddrname * amsg) +{ + spl_netconn_t *conn; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct sockaddr_in *paddr = (struct sockaddr_in *) &amsg->sock_addr; + + data_com_msg *m = MSG_ENTRY (amsg, data_com_msg, buffer); + + if ((NULL == cpcb) || !(conn = cpcb->conn)) + { + NSTCP_LOGERR ("failed to get sock"); + paddr->sin_family = 0; + paddr->sin_port = 0; + paddr->sin_addr.s_addr = 0; + SET_MSG_ERR (m, ERR_CONN); + return; + } + + NS_LOG_CTRL (LOG_CTRL_GETSOCKNAME, LOGTCP, "NSTCP", NSLOG_DBG, + "cpcb=%p,conn=%p,cmd=%u", cpcb, cpcb->conn, amsg->cmd); + + paddr->sin_family = AF_INET; + SET_MSG_ERR (m, ERR_OK); + + if (amsg->cmd == 0) + { + if (cpcb->type == SPL_NETCONN_TCP) + { + tcp = (struct tcp_pcb *) cpcb->conn->private_data; + /* add judgement:(NETCONN_LISTEN == conn->state) in following if words */ + /* If connect is not done in TCP then the remote address will not be there so need to update proper error code + if the application call the getpeername in TCP mode */ + if ((SPL_NETCONN_LISTEN == conn->state) + || (tcp->remote_ip.addr == 0) || (tcp->remote_port == 0)) + { + paddr->sin_family = 0; + paddr->sin_port = 0; + paddr->sin_addr.s_addr = 0; + SET_MSG_ERR (m, ERR_CONN); + } + else + { + paddr->sin_port = spl_htons (tcp->remote_port); + paddr->sin_addr.s_addr = tcp->remote_ip.addr; + } + } + else if (cpcb->type == SPL_NETCONN_UDP) + { + udp = (struct udp_pcb *) cpcb->conn->private_data; + /* If connect is not done in UDP then the remote address will not be there so need to update proper error code + if the application call the getpeername in UDP mode + */ + if ((udp->remote_ip.addr == 0) || (udp->remote_port == 0)) + { + paddr->sin_family = 0; + paddr->sin_port = 0; + paddr->sin_addr.s_addr = 0; + SET_MSG_ERR (m, ERR_CONN); + } + else + { + paddr->sin_port = spl_htons (udp->remote_port); + paddr->sin_addr.s_addr = udp->remote_ip.addr; + } + } + } + else + { + if (cpcb->type == SPL_NETCONN_TCP) + { + tcp = (struct tcp_pcb *) cpcb->conn->private_data; + paddr->sin_port = spl_htons (tcp->local_port); + paddr->sin_addr.s_addr = tcp->local_ip.addr; + } + else if (cpcb->type == SPL_NETCONN_UDP) + { + udp = (struct udp_pcb *) cpcb->conn->private_data; + paddr->sin_port = spl_htons (udp->local_port); + paddr->sin_addr.s_addr = udp->local_ip.addr; + } + } +} + +/** + * Close a TCP pcb contained in a netconn + * Called from netconn_close + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_close (struct common_pcb *cpcb, msg_close * cmsg) +{ + spl_netconn_t *conn = cpcb->conn; + data_com_msg *m = MSG_ENTRY (cmsg, data_com_msg, buffer); + + NSTCP_LOGDBG ("msg->conn=%p,state=%d", conn, conn->state); + + /* @todo: abort running write/connect? */ + if ((conn->state != SPL_NETCONN_NONE) + && (conn->state != SPL_NETCONN_LISTEN) + && (conn->state != SPL_NETCONN_CONNECT)) + { + if (SPL_NETCONN_TCP != cpcb->type) + { + NSTCP_LOGERR ("msg->conn=%p,type=%d", conn, cpcb->type); + return; + } + NSTCP_LOGWAR ("msg->conn=%p,state=%d", conn, conn->state); + SET_MSG_ERR (m, ERR_INPROGRESS); + } + else if (cpcb->type == SPL_NETCONN_TCP) //clear codeDEX warning , CID:24336, cpcb can't be null. + { + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + + if (tpcb == NULL) + { + NSTCP_LOGERR ("tpcb null msg->conn=%p,type=%d", conn, cpcb->type); + return; + } + if ((cmsg->shut != SPL_NETCONN_SHUT_RDWR) + && (conn->state == SPL_NETCONN_LISTEN)) + { + /* LISTEN doesn't support half shutdown */ + NSTCP_LOGERR + ("LISTEN doesn't support half shutdown!]conn=%p,pcb=%p,state=%d", + conn, tpcb, conn->state); + SET_MSG_ERR (m, ERR_CONN); + } + else + { + if (cmsg->shut & SPL_NETCONN_SHUT_RD) + { + /* Drain and delete mboxes */ + (void) netconn_drain (cpcb->type, conn); + unlink_recv_ring (conn); + } + + if (((NULL != cpcb->current_msg) + && (conn->state != SPL_NETCONN_CONNECT)) + || (0 != cpcb->write_offset)) + { + NSTCP_LOGERR + ("already writing or closing]conn=%p,pcb=%p,offset=%zu,curmsg=%p", + conn, tpcb, cpcb->write_offset, cpcb->current_msg); + SET_MSG_ERR (m, ERR_CONN); + return; + } + + if (conn->state == SPL_NETCONN_CONNECT) + { + if (cpcb->current_msg != NULL + && cpcb->current_msg->param.minor_type == + SPL_API_DO_CONNECT) + { + SET_MSG_ERR (m, ERR_RST); + SYNC_MSG_ACK (cpcb->current_msg); + } + else + { + NSTCP_LOGINF + ("already in connecting]conn=%p,cpcb=%p,msg=%p", conn, + cpcb, cpcb->current_msg); + } + /* maybe need to clean cpcb->msg_head */ + } + + conn->state = SPL_NETCONN_CLOSE; + cpcb->current_msg = m; + (void) do_close_internal (cpcb, 1); + + if (SPL_NETCONN_SHUT_RD == cmsg->shut + || SPL_NETCONN_SHUT_RDWR == cmsg->shut) + { + SPL_API_EVENT (conn, SPL_NETCONN_EVT_RCVPLUS, 1); + } + + return; + } + } + else + { + SET_MSG_ERR (m, ERR_VAL); + } +} + +/*trans kerner option to stackx option*/ +int +ks_to_stk_opt (int opt) +{ + int stack_opt = opt; + switch (opt) + { + case SO_DEBUG: + stack_opt = SOF_DEBUG; + break; + case SO_ACCEPTCONN: + stack_opt = SOF_ACCEPTCONN; + break; + case SO_BROADCAST: + stack_opt = SOF_BROADCAST; + break; + case SO_KEEPALIVE: + stack_opt = SOF_KEEPALIVE; + break; + case SO_REUSEADDR: + stack_opt = SOF_REUSEADDR; + break; + case SO_DONTROUTE: + stack_opt = SOF_DONTROUTE; + break; + case SO_USELOOPBACK: + stack_opt = SOF_USELOOPBACK; + break; + case SO_OOBINLINE: + stack_opt = SOF_OOBINLINE; + break; + default: + stack_opt = opt; + break; + } + return stack_opt; +} + +void +do_get_tcpproto_getsockopt_internal (struct common_pcb *cpcb, + msg_setgetsockopt * smsg) +{ + int optname; + void *optval; + struct tcp_pcb *tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + + optname = smsg->optname; + optval = &smsg->optval; + + switch (optname) + { + case SPL_TCP_NODELAY: + *(int *) optval = tcp_nagle_disabled (tpcb); + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,TCP_NODELAY=%s", + cpcb->socket, (*(int *) optval) ? "on" : "off"); + break; + + case SPL_TCP_KEEPIDLE: + *(int *) optval = (int) (tpcb->keep_idle / 1000); + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPIDLE=%d", + cpcb->socket, *(int *) optval); + break; + case SPL_TCP_KEEPINTVL: + *(int *) optval = (int) (tpcb->keep_intvl / 1000); + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPINTVL=%d", + cpcb->socket, *(int *) optval); + break; + case SPL_TCP_KEEPCNT: + *(int *) optval = (int) tpcb->keep_cnt; + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,SPL_TCP_KEEPCNT=%d", + cpcb->socket, *(int *) optval); + break; + + default: + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); + SET_MSG_ERR (m, EOPNOTSUPP); + break; + } +} + +void +do_get_ipproto_getsockopt_internal (struct common_pcb *cpcb, + msg_setgetsockopt * smsg) +{ + int optname; + u32_t optlen; + void *optval; + + struct ip_pcb *ipcb = (struct ip_pcb *) (cpcb); + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + + optname = smsg->optname; + optval = &smsg->optval; + optlen = smsg->optlen; + + switch (optname) + { + case IP_TTL: + *(int *) optval = ipcb->ttl; + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,IP_TTL=%d", + cpcb->socket, *(int *) optval); + break; + case IP_TOS: + smsg->optlen = + (optlen < sizeof (u32_t)) ? sizeof (u8_t) : sizeof (u32_t); + if (smsg->optlen == sizeof (u8_t)) + { + *(u8_t *) optval = ipcb->tos; + } + else + { + *(u32_t *) optval = (u32_t) ipcb->tos; + } + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,IP_TOS=%d", + cpcb->socket, *(int *) optval); + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); + break; + } +} + +void +do_get_solsocket_getsockopt_internal (struct common_pcb *cpcb, + msg_setgetsockopt * smsg) +{ + int optname; + void *optval; + struct tcp_pcb *tpcb = NULL; + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + struct tcp_pcb *pcb = (struct tcp_pcb *) cpcb->conn->private_data; + + optname = smsg->optname; + optval = &smsg->optval; + + switch (optname) + { + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_REUSEADDR: + *(int *) optval = + (ip_get_option ((struct ip_pcb *) cpcb, ks_to_stk_opt (optname))) ? 1 + : 0; + NSPOL_LOGDBG (SOCKETS_DEBUG, "]fd=%d,optname=%d,optval=%s", + cpcb->socket, optname, (*(int *) optval ? "on" : "off")); + break; + case SO_ACCEPTCONN: + tpcb = (struct tcp_pcb *) cpcb->conn->private_data; + if ((smsg->optlen < sizeof (int)) || (NULL == tpcb)) + { + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, + "(SOL_SOCKET, SO_ACCEPTCONN) failed]fd=%d,tcp=%p,optlen=%u", + cpcb->socket, cpcb, smsg->optlen); + break; + } + if (tpcb->state == LISTEN) + { + *(int *) optval = 1; + } + else + { + *(int *) optval = 0; + } + NSPOL_LOGDBG (SOCKETS_DEBUG, + "(SOL_SOCKET, SO_ACCEPTCONN)]fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + break; + case SO_TYPE: + switch (cpcb->type) + { + case SPL_NETCONN_RAW: + *(int *) optval = SOCK_RAW; + break; + case SPL_NETCONN_TCP: + *(int *) optval = SOCK_STREAM; + break; + case SPL_NETCONN_UDP: + *(int *) optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int *) optval = cpcb->type; + NSPOL_LOGDBG (SOCKETS_DEBUG, + "(SOL_SOCKET, SO_TYPE): unrecognized socket type]fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + } /* switch (sock->conn->type) */ + NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_TYPE)]fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + break; + case SO_RCVTIMEO: + (*(struct timeval *) optval).tv_sec = + spl_netconn_get_recvtimeout (cpcb) / 1000; + (*(struct timeval *) optval).tv_usec = + (spl_netconn_get_recvtimeout (cpcb) % 1000) * 1000; + NSPOL_LOGDBG (SOCKETS_DEBUG, + "stackx_getsockopt(SOL_SOCKET, SO_RCVTIMEO)]fd=%d,sec=%ld,usec=%ld", + cpcb->socket, (*(struct timeval *) optval).tv_sec, + (*(struct timeval *) optval).tv_usec); + break; + case SO_SNDTIMEO: + (*(struct timeval *) optval).tv_sec = + spl_netconn_get_sendtimeout (cpcb) / 1000; + (*(struct timeval *) optval).tv_usec = + (spl_netconn_get_sendtimeout (cpcb) % 1000) * 1000; + NSPOL_LOGDBG (SOCKETS_DEBUG, + "(SOL_SOCKET, SO_SNDTIMEO)]fd=%dsec=%ld,usec=%ld", + cpcb->socket, (*(struct timeval *) optval).tv_sec, + (*(struct timeval *) optval).tv_usec); + break; + case SO_SNDBUF: + { + u16_t mss = (pcb->mss > TCP_MSS + || pcb->mss == 0) ? TCP_MSS : pcb->mss; + *(int *) optval = spl_netconn_get_sendbufsize (cpcb->conn) * mss; + /*If user has not configured any sendbuffer value then we should return minimum + promissed for the connection based on the flow control. */ + if (*(int *) optval == 0) + { + *(int *) optval = CONN_TCP_MEM_MIN_LINE * mss; + } + NSPOL_LOGDBG (SOCKETS_DEBUG, + "(SOL_SOCKET, SO_SNDBUF)]fd=%d,optval=%d", cpcb->socket, + *(int *) optval); + break; + } + case SO_NO_CHECK: + *(int *) optval = + (udp_flags ((struct udp_pcb *) cpcb->conn->private_data) & + UDP_FLAGS_NOCHKSUM) ? 1 : 0; + NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_NO_CHECK)fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + break; + case SO_SNDLOWAT: + *(int *) optval = 1; + NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_SNDLOWAT)fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + break; + + case SO_RCVLOWAT: + *(int *) optval = spl_netconn_get_reclowbufsize (cpcb); + NSPOL_LOGDBG (SOCKETS_DEBUG, "(SOL_SOCKET, SO_RCVLOWAT)fd=%d,optval=%d", + cpcb->socket, *(int *) optval); + break; + case SO_ERROR: + *(int *) optval = GET_MSG_ERR (m); + SET_MSG_ERR (m, 0); + NSPOL_LOGDBG (SOCKETS_DEBUG, "SOL_SOCKET]fd=%d,optval=%d", cpcb->socket, + *(int *) optval); + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported opt]optname=%d", optname); + break; + } +} + +void +do_getsockopt_internal (struct common_pcb *cpcb, msg_setgetsockopt * smsg) +{ + int level; + + if (NULL == smsg) + { + NSTCP_LOGERR ("arg NULL"); + return; + } + + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + + level = smsg->level; + switch (level) + { + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + do_get_solsocket_getsockopt_internal (cpcb, smsg); + + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + do_get_ipproto_getsockopt_internal (cpcb, smsg); + + break; + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + do_get_tcpproto_getsockopt_internal (cpcb, smsg); + + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported level]level=%d", level); + break; + } /* switch (level) */ +} + +void +do_tcpsock_setsockopt (spl_netconn_t * conn, msg_setgetsockopt * smsg) +{ + const void *optval; + int optname; + struct common_pcb *cpcb = (struct common_pcb *) conn->comm_pcb_data; + struct tcp_pcb *tpcb = (struct tcp_pcb *) conn->private_data; + + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + + optname = smsg->optname; + optval = &smsg->optval; + + switch (optname) + { + case SPL_TCP_NODELAY: + if (*(int *) optval) + { + tcp_nagle_disable (tpcb); + } + else + { + tcp_nagle_enable (tpcb); + } + + NSTCP_LOGDBG ("IPPROTO_TCP, TCP_NODELAY]fd=%d,optval=%s", + cpcb->socket, (*(int *) optval) ? "on" : "off"); + break; + + case SPL_TCP_KEEPIDLE: + /* CID 52121 (#2 of 3): Other violation (HW_VPP_C_FIND_OPERATORS_2_1_1_3) */ + if ((u32_t) (*(int *) optval) >= INT_MAX / 1000) + { + NSTCP_LOGWAR ("optval too big]optval=%u", + (u32_t) (*(int *) optval)); + *(int *) optval = INT_MAX / 1000; + } + + tpcb->keep_idle = 1000 * (u32_t) (*(int *) optval); + + if (tpcb->keep_idle > TCP_KEEPIDLE_DEFAULT) + { + NSTCP_LOGWAR + ("(%d, IPPROTO_TCP, SPL_TCP_KEEPIDLE. value bigger than 7200000UL so setting to default 7200000UL) requested is -> %" + U32_F " ", cpcb->socket, tpcb->keep_idle); + tpcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + } + + NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPIDLE](fd=%d,keep_idle=%" U32_F + " ", cpcb->socket, tpcb->keep_idle); + + /* Not required lwip_slowtmr will take care about timer. */ + break; + case SPL_TCP_KEEPINTVL: + /* CID 52121 (#1 of 3): Other violation (HW_VPP_C_FIND_OPERATORS_2_1_1_3) */ + if ((u32_t) (*(int *) optval) >= INT_MAX / 1000) + { + NSTCP_LOGWAR ("optval too big]optval=%u", + (u32_t) (*(int *) optval)); + *(int *) optval = INT_MAX / 1000; + } + + tpcb->keep_intvl = 1000 * (u32_t) (*(int *) optval); + + if (tpcb->keep_intvl > TCP_KEEPIDLE_DEFAULT) /*max timer value supported */ + { + NSTCP_LOGWAR + ("(%d, IPPROTO_TCP, SPL_TCP_KEEPINTVL. value bigger than 7200000UL so setting to default 7200000UL) requested is -> %" + U32_F " ", cpcb->socket, tpcb->keep_intvl); + tpcb->keep_intvl = TCP_KEEPIDLE_DEFAULT; + } + NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPINTVL]fd=%d,keep_intvl=%" U32_F + " ", cpcb->socket, tpcb->keep_intvl); + break; + case SPL_TCP_KEEPCNT: + tpcb->keep_cnt = (u32_t) (*(int *) optval); + NSTCP_LOGDBG ("IPPROTO_TCP, SPL_TCP_KEEPCNT]fd=%d,keep_cnt=%" U32_F " ", + cpcb->socket, tpcb->keep_cnt); + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); + break; + } +} + +void +do_ipsock_setsockopt (struct common_pcb *cpcb, msg_setgetsockopt * smsg) +{ + const void *optval; + u32_t optlen; + int optname; + + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + + struct udp_pcb *upcb = (struct udp_pcb *) cpcb->conn->private_data; + struct ip_pcb *ipcb = (struct ip_pcb *) upcb; + + optname = smsg->optname; + optval = &smsg->optval; + optlen = smsg->optlen; + + int val = 0; + int bNotAllowSet = 0; + switch (optname) + { + case IP_TTL: + ipcb->ttl = (u8_t) (*(int *) optval); + NSIP_LOGDBG ("IPPROTO_IP,IP_TTL]fd=%d,ttl=%u", cpcb->socket, ipcb->ttl); + break; + case IP_TOS: + bNotAllowSet = (cpcb->dataSentFlag != 0) + && ((SPL_NETCONN_TCP == cpcb->type) + || (SPL_NETCONN_UDP == cpcb->type) + || (SPL_NETCONN_RAW == cpcb->type)); + /*not allow set tos value when sending data */ + if (bNotAllowSet) + { + SET_MSG_ERR (m, ERR_VAL); + break; + } + + if (optlen >= sizeof (u32_t)) + { + val = (int) (*(const int *) optval); + } + else if (optlen >= sizeof (u8_t)) + { + val = (int) (*(const u8_t *) optval); + } + + if (SPL_NETCONN_TCP == cpcb->type) + { + val &= ~INET_ECN_MASK; + val |= ipcb->tos & INET_ECN_MASK; + } + ipcb->tos = (u8_t) (val); + + smsg->msg_box = (get_msgbox ((u8_t) val))->llring; + + NSIP_LOGDBG ("IPPROTO_IP,IP_TOS]]fd=%d,tos=%u", cpcb->socket, + ipcb->tos); + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); + break; + } +} + + /*Made seperate functions to reduce code complexity */ +void +do_setsockopt_recvtimeout_internal (const void *optval, + struct common_pcb *cpcb) +{ + if ((*(struct timeval *) optval).tv_sec < 0) + { + spl_netconn_set_recvtimeout (cpcb, 0); + } + else + { + spl_netconn_set_recvtimeout (cpcb, MAX_WAIT_TIMEOUT); + if ((*(struct timeval *) optval).tv_sec != 0 + || (*(struct timeval *) optval).tv_usec != 0) + { + if ((*(struct timeval *) optval).tv_sec < + ((MAX_WAIT_TIMEOUT / 1000) - 1)) + { + spl_netconn_set_recvtimeout (cpcb, + (*(struct timeval *) optval).tv_sec + * 1000 + + (*(struct timeval *) + optval).tv_usec / 1000); + } + } + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, + "SOL_SOCKET, SO_RCVTIMEO]conn=%p,fd=%d,optval=%d", cpcb, + cpcb->socket, cpcb->recv_timeout); +} + +void +do_setsockopt_sndtimeout_internal (const void *optval, + struct common_pcb *cpcb) +{ + if ((*(struct timeval *) optval).tv_sec < 0) + { + spl_netconn_set_sendtimeout (cpcb, 0); + } + else + { + spl_netconn_set_sendtimeout (cpcb, MAX_WAIT_TIMEOUT); + if ((*(struct timeval *) optval).tv_sec != 0 + || (*(struct timeval *) optval).tv_usec != 0) + { + if ((*(struct timeval *) optval).tv_sec < + ((MAX_WAIT_TIMEOUT / 1000) - 1)) + { + spl_netconn_set_sendtimeout (cpcb, + (*(struct timeval *) optval).tv_sec + * 1000 + + (*(struct timeval *) + optval).tv_usec / 1000); + } + } + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, + "SOL_SOCKET, SO_SNDTIMEO]conn=%p,fd=%d,optval=%d", cpcb, + cpcb->socket, cpcb->send_timeout); +} + +#define IS_TCP_PCB(cpcb) (cpcb && (cpcb->conn) && (SPL_NETCONN_TCP == cpcb->conn->type)) +NSTACK_STATIC inline void +set_opt_sol_socket (struct common_pcb *cpcb, struct tcp_pcb *pcb, + data_com_msg * m, int level, int optname, + const void *optval) +{ + switch (optname) + { + /* The option flags */ + case SO_BROADCAST: + + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + case SO_REUSEADDR: + + if (NULL == pcb) + { + NSPOL_LOGERR ("conn->pcb.ip is null"); + break; + } + + if (*(const int *) optval) + { + ip_set_option ((struct ip_pcb *) pcb, ks_to_stk_opt (optname)); + } + else + { + ip_reset_option ((struct ip_pcb *) pcb, ks_to_stk_opt (optname)); + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, "]conn=%p,fd=%d,optname=0x%x,optval=%s", + cpcb, cpcb->socket, optname, + (*(const int *) optval ? "on" : "off")); + + /* No use now, since tcp_slowtmr will take care about not sending/sending of keepalive */ + break; + + case SO_RCVLOWAT: + spl_netconn_set_reclowbufsize (cpcb, *(int *) optval); + NSPOL_LOGDBG (SOCKETS_DEBUG, + "SOL_SOCKET, SO_RCVLOWAT]conn=%p,fd=%d,optval=%d", cpcb, + cpcb->socket, cpcb->sk_rcvlowat); + break; + + case SO_RCVTIMEO: + /*to reduce code complexity */ + do_setsockopt_recvtimeout_internal (optval, cpcb); + break; + + case SO_SNDTIMEO: + /*to reduce code complexity */ + do_setsockopt_sndtimeout_internal (optval, cpcb); + break; + + case SO_SNDBUF: + { + /* udp pcb invalid access will cause coredump */ + if (!IS_TCP_PCB (cpcb)) + { + NSPOL_LOGDBG (SOCKETS_DEBUG, + "not support for non tcp socket]optname=%d, level=%d", + optname, level); + return; + } + + u16_t mss = (pcb->mss > TCP_MSS + || pcb->mss == 0) ? TCP_MSS : pcb->mss; + + if (*(int *) optval < (int) mss) + { + /*set value of one TCP_MSS */ + spl_netconn_set_sendbufsize (cpcb->conn, 1); + } + else + { + spl_netconn_set_sendbufsize (cpcb->conn, + (*(int *) optval) / (int) mss); + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, + "SOL_SOCKET, SO_SNDBUF]conn=%p,fd=%d,optval=%d", cpcb, + cpcb->socket, cpcb->conn->send_bufsize * mss); + break; + } + + case SO_NO_CHECK: + /* How udp is coming here.. ?? @TODO: May be move to someother function.? */ + /* solve segment issue when the PCB is not exist */ + if (NULL == cpcb) + { + NSPOL_LOGERR ("conn->pcb.udp is null"); + break; + } + + struct udp_pcb *upcb = (struct udp_pcb *) pcb; + + if (*(int *) optval) + { + udp_setflags (upcb, udp_flags (upcb) | UDP_FLAGS_NOCHKSUM); + } + else + { + udp_setflags (upcb, udp_flags (upcb) & ~UDP_FLAGS_NOCHKSUM); + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, + "SOL_SOCKET, SO_NO_CHECK]conn=%p,fd=%d,optval=0x%x", cpcb, + cpcb->socket, upcb->flags); + break; + + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]optname=%d", optname); + break; + } /* switch (optname) */ + +} + +void +do_setsockopt_internal (struct common_pcb *cpcb, msg_setgetsockopt * smsg) +{ + int level, optname; + const void *optval; + + data_com_msg *m = MSG_ENTRY (smsg, data_com_msg, buffer); + struct tcp_pcb *pcb = (struct tcp_pcb *) cpcb->conn->private_data; + + if (NULL == smsg) + { + NSTCP_LOGERR ("arg null!"); + return; + } + + level = smsg->level; + optname = smsg->optname; + optval = &smsg->optval; + + switch (level) + { + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + set_opt_sol_socket (cpcb, pcb, m, SOL_SOCKET, optname, optval); + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + + if (NULL == cpcb) + { + NSPOL_LOGERR ("conn->pcb.ip is null"); + break; + } + + do_ipsock_setsockopt (cpcb, smsg); + + break; + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* udp pcb invalid access will cause coredump */ + if (!IS_TCP_PCB (cpcb)) + { + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, + "not support for non tcp socket]optname=%d,level=%d", + optname, level); + return; + } + + if (NULL == cpcb) + { + NSPOL_LOGERR ("conn->pcb.tcp is null"); + break; + } + + do_tcpsock_setsockopt (cpcb->conn, smsg); + + break; + default: + SET_MSG_ERR (m, ERR_VAL); + NSPOL_LOGDBG (SOCKETS_DEBUG, "unsupported]level=%d", level); + break; + } /* switch (level) */ +} + +/*app send its version info to nStackMain */ +void +do_app_touch (msg_app_touch * smsg) +{ + //write app version info to running.log + NSPOL_LOGINF (SOCKETS_DEBUG, "hostpid=%u,app_version=%s", smsg->hostpid, + smsg->app_version); +} + +void +tcp_free_accept_ring (spl_netconn_t * conn) +{ + err_t de_err = ERR_OK; + spl_netconn_t *newconn; + while (1) + { + newconn = NULL; + /* -1 means nonblocking */ + de_err = accept_dequeue (conn, (void **) &newconn, (u32_t) - 1); + if (de_err == ERR_WOULDBLOCK || newconn == NULL) + return; + + tcp_drop_conn (newconn); + } +} + +void +tcp_drop_conn (spl_netconn_t * conn) +{ + /* usually we should not access pcb by recv_obj, but no choice */ + struct tcp_pcb *pcb = (struct tcp_pcb *) conn->private_data; + + /* free conn first, even pcb is NULL */ + free_conn_by_spl (conn); + + if (pcb == NULL) + { + NSTCP_LOGWAR + ("a tcp connection in accept queue without pcb!]newconn=%p", conn); + return; + } + + /* tell peer conneciton is reset */ + NSTCP_LOGWAR ("sending RST in accept waiting queue!]pcb=%p", pcb); + + tcp_rst (pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + + tcp_pcb_remove (&tcp_active_pcbs, pcb); + memp_free (MEMP_TCP_PCB, pcb); +} + +void +update_tcp_state (spl_netconn_t * conn, enum tcp_state state) +{ + spl_tcp_state_t spl_state; + + if (conn != NULL) + { + switch (state) + { + case CLOSED: + spl_state = SPL_CLOSED; + break; + case LISTEN: + spl_state = SPL_LISTEN; + break; + case SYN_SENT: + spl_state = SPL_SYN_SENT; + break; + case SYN_RCVD: + spl_state = SPL_SYN_RCVD; + break; + case ESTABLISHED: + spl_state = SPL_ESTABLISHED; + break; + case FIN_WAIT_1: + spl_state = SPL_FIN_WAIT_1; + break; + case FIN_WAIT_2: + spl_state = SPL_FIN_WAIT_2; + break; + case CLOSE_WAIT: + spl_state = SPL_CLOSE_WAIT; + break; + case CLOSING: + spl_state = SPL_CLOSING; + break; + case LAST_ACK: + spl_state = SPL_LAST_ACK; + break; + case TIME_WAIT: + spl_state = SPL_TIME_WAIT; + break; + default: + spl_state = SPL_CLOSED; + break; + } + if (conn->tcp_state != spl_state) + { + conn->tcp_state = spl_state; + NSTCP_LOGINF ("conn=%p,private_data=%p,state=%d", conn, + conn->private_data, spl_state); + } + } +} + +void +do_update_pcbstate () +{ + struct tcp_pcb *tpcb; + int i; + for (i = 0; i < NUM_TCP_PCB_LISTS; i++) + { + for (tpcb = *tcp_pcb_lists[i]; tpcb != NULL; tpcb = tpcb->next) + { + if (tpcb->callback_arg) + { + update_tcp_state ((spl_netconn_t *) tpcb->callback_arg, + tpcb->state); + } + } + } + + return; +} + +void +init_stackx_lwip () +{ + lwip_init (); + sys_timeouts_init (); + return; +} + +void +free_common_pcb (struct common_pcb *cpcb) +{ + if (res_free (&cpcb->res_chk)) + { + NSFW_LOGERR ("conn refree!]conn=%p", cpcb->conn); + return; + } + + common_pcb_reset (cpcb); + + mring_handle pool = p_def_stack_instance->cpcb_seg; + if (nsfw_mem_ring_enqueue (pool, (void *) cpcb) != 1) + { + NSSBR_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + } + return; +} + +struct common_pcb * +alloc_common_pcb (enum spl_netconn_type type) +{ + struct common_pcb *cpcb = NULL; + + if (nsfw_mem_ring_dequeue (p_def_stack_instance->cpcb_seg, (void **) &cpcb) + != 1) + { + NSSBR_LOGERR ("malloc conn failed"); + return NULL; + } + + NSFW_LOGINF ("alloc_common_pcb]cpcb=%p", cpcb); + + common_pcb_init (cpcb); + cpcb->type = type; + return cpcb; +} diff --git a/stacks/lwip_stack/lwip_src/api/spl_netbuf.c b/stacks/lwip_stack/lwip_src/api/spl_netbuf.c new file mode 100644 index 0000000..9c682fc --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_netbuf.c @@ -0,0 +1,58 @@ +/* +* +* 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 (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ +//#include "sc_dpdk.h" +#include "spl_netbuf.h" + +void +spl_netbuf_delete (struct spl_netbuf *buf) +{ + if (likely (buf != NULL)) + { + spl_pbuf_free (PTR_SHTOL (struct spl_pbuf *, buf->p)); + } +} diff --git a/stacks/lwip_stack/lwip_src/api/spl_netifapi.c b/stacks/lwip_stack/lwip_src/api/spl_netifapi.c new file mode 100644 index 0000000..ab1446a --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_netifapi.c @@ -0,0 +1,288 @@ +/* +* +* 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 "spl_opt.h" + +#if STACKX_NETIF_API + +#include "nsfw_msg_api.h" +#include "netifapi.h" +#include <sys/socket.h> +//#include <netinet/in.h> + +#include "stackx_spl_share.h" +#include "spl_sbr.h" +#include "stackx/spl_api.h" +#include "tcpip.h" +#include "sc_dpdk.h" +#include "spl_instance.h" +#include "spl_hal.h" +#include "spl_def.h" +#include <inet.h> + +struct netifExt *gNetifExt = NULL; + +/** + * common operation for sbr message. + * + * @param msg the api_msg_msg describing the connection type + */ +int +do_halmsg (data_com_msg * m) +{ + NSPOL_LOGDBG (TESTSOCKET_DEBUG | STACKX_DBG_TRACE, + "the msg is from HAL module, minor(%u)", m->param.minor_type); + return 0; +} + +static int +_do_add_netif (data_com_msg * m) +{ + NSPOL_LOGINF (NETIF_DEBUG, "_do_add_netif\n"); + + m->param.err = ERR_OK; + msg_add_netif *_m = (msg_add_netif *) m->buffer; + _m->function (_m); + SYNC_MSG_ACK (m); + return 0; +} + +struct netif * +find_netif_by_if_name (char *if_name) +{ + + struct netifExt *netifEx = gNetifExt; + struct netif *netif = NULL; + + while (netifEx != NULL) + { + if (!(strcmp (netifEx->if_name, if_name))) + { + for (netif = netif_list; netif != NULL; netif = netif->next) + { + if (netifEx->id == netif->num) + return netif; + } + + } + netifEx = netifEx->next; + } + + return NULL; +} + +/*@TODO: May be moved to some other file ? Like HAL*/ +struct netif * +get_netif_by_ip (unsigned int ip) +{ + struct netif *netif; + + if (ip == 0) + { + return NULL; + } + + for (netif = netif_list; netif != NULL; netif = netif->next) + { + if (ip == netif->ip_addr.addr) + { + NSPOL_LOGINF (NETIF_DEBUG, "netif_find: found %x %c %c", ip, + netif->name[0], netif->name[1]); + return netif; + } + } + NSPOL_LOGINF (NETIF_DEBUG, "netif_find: Not found %x", ip); + return NULL; +} + +/* +@TODO: +*/ +struct netif * +netif_check_broadcast_addr (spl_ip_addr_t * addr) +{ + return NULL; +} + +struct netifExt * +getNetifExt (u16_t id) +{ + + struct netifExt *netifEx; + netifEx = gNetifExt; + + while (netifEx != NULL) + { + if (netifEx->id == id) + { + return netifEx; + } + netifEx = netifEx->next; + } + + return NULL; +} + +int +netifExt_add (struct netif *netif) +{ + + /* If Netif Ext already created for it then just return sucess */ + if (getNetifExt (netif->num)) + return 0; + + struct netifExt *netifEx = malloc (sizeof (struct netifExt)); + if (!netifEx) + { + return -1; + } + + if (memset (netifEx, 0, sizeof (struct netifExt)) < 0) + { + return -1; + } + + NSPOL_LOGINF (NETIF_DEBUG, "netifExt_added \n"); + + netifEx->id = netif->num; + + /* add this netif to the list */ + netifEx->next = gNetifExt; + gNetifExt = netifEx; + return 0; +} + +void +do_netifapi_netif_add (msg_add_netif * pmsg) +{ + struct netif *netif = NULL; + ip_addr_t ipaddr; + ip_addr_t netmask; + ip_addr_t gw; + + data_com_msg *m = MSG_ENTRY (pmsg, data_com_msg, buffer); + ipaddr.addr = pmsg->ipaddr->addr; + netmask.addr = pmsg->netmask->addr; + gw.addr = pmsg->gw->addr; + + NSPOL_LOGINF (NETIF_DEBUG, "do_netifapi_netif_add \n"); + netif = netif_add (pmsg->netif, + &ipaddr, + &netmask, &gw, pmsg->state, pmsg->init, pmsg->input); + + if (NULL == netif) + { + SET_MSG_ERR (m, ERR_IF); + } + else + { + + SET_MSG_ERR (m, ERR_OK); + NSPOL_LOGINF (NETIF_DEBUG, "netif created name %c%c%d\n", + netif->name[0], netif->name[1], netif->num); + pmsg->voidfunc (pmsg->netif); + add_disp_netif (pmsg->netif); + } + +} + +err_t +spl_netifapi_netif_add (struct netif *pnetif, + spl_ip_addr_t * ipaddr, + spl_ip_addr_t * netmask, + spl_ip_addr_t * gw, + void *state, + netif_init_fn init, + netif_input_fn input, netifapi_void_fn voidfunc) +{ + msg_add_netif stmsg; + + stmsg.function = do_netifapi_netif_add; + stmsg.netif = pnetif; + stmsg.ipaddr = ipaddr; + stmsg.netmask = netmask; + stmsg.gw = gw; + stmsg.state = state; + stmsg.init = init; + stmsg.input = input; + stmsg.voidfunc = voidfunc; + return tcpip_netif_add (&stmsg); +} + +int +add_netif_ip (char *netif_name, unsigned int ip, unsigned int mask) +{ + struct netif *pnetif; + int retval; + + if (get_netif_by_ip (ip)) + { + NSPOL_LOGERR ("ip is exist]IP=%s", inet_ntoa (ip)); + return -1; + } + NSPOL_LOGINF (NETIF_DEBUG, "add_netif_ip] IP=%s", inet_ntoa (ip)); + + pnetif = find_netif_by_if_name (netif_name); + if (pnetif == NULL) + { + return -1; + } + + pnetif->ip_addr.addr = ip; + pnetif->netmask.addr = mask; + + if (ip) + { + retval = etharp_request (pnetif, &pnetif->ip_addr); + + if (ERR_OK != retval) + { + NSPOL_LOGERR ("etharp_request failed]retval=%d,netif=%p,ip=%u", retval, pnetif, pnetif->ip_addr.addr); //inet_ntoa is not thread-safe, print u32 instead. + } + } + + NSPOL_LOGINF (NETIF_DEBUG, "add_netif_ip]netif_name=%s,IP=%s,mask=0x%08x", + netif_name, inet_ntoa (ip), spl_htonl (mask)); + return 0; +} + +/*lint -e438*/ +int +del_netif_ip (char *netif_name, unsigned int ip) +{ + struct netif *pnetif; + //struct netif* vnetif = NULL; + //struct netif** ref; + + pnetif = find_netif_by_if_name (netif_name); + if (NULL == pnetif) + { + return -1; + } + + NSPOL_LOGINF (NETIF_DEBUG, "del_netif_ip] IP=%s", inet_ntoa (ip)); + + pnetif->ip_addr.addr = 0; + pnetif->netmask.addr = 0; + return 0; +} + +REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_HAL, SPL_TCPIP_MSG_NETIFAPI, + do_halmsg); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_HAL, SPL_TCPIP_MSG_NETIFAPI, + NETIF_DO_ADD, _do_add_netif); + +#endif /* STACKX_NETIF_API */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_sbr.c b/stacks/lwip_stack/lwip_src/api/spl_sbr.c new file mode 100644 index 0000000..4c510a5 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_sbr.c @@ -0,0 +1,495 @@ +/* +* +* 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 "stackx_spl_share.h" +#include "spl_api.h" +#include "ip.h" +#include "spl_api_msg.h" +#include "stackx_spl_msg.h" +#include "internal_msg.h" +#include "spl_sbr.h" +#include "spl_pbuf.h" + +/** + * common operation for sbr message. + * + * @param msg the api_msg_msg describing the connection type + */ +int +do_sbrmsg (data_com_msg * m) +{ + return 0; +} + +/** + * Create a new pcb of a specific type inside a netconn. + * Called from netconn_new_with_proto_and_callback. + * + * @param msg the api_msg_msg describing the connection type + */ +static int +_do_newconn (data_com_msg * m) +{ + m->param.err = ERR_OK; + + msg_new_netconn *_m = (msg_new_netconn *) m->buffer; + m->param.err = spl_pcb_new (_m); + + if (ERR_OK != m->param.err) + { + NSPOL_LOGERR ("pcb_new err]conn=%p,pid=%u,err=%d", _m->conn, + m->param.recycle_pid, m->param.err); + goto ERROR; + } + + NSFW_LOGINF ("alloc pcb]conn=%p,pcb=%p,pid=%u", _m->conn, + _m->conn->private_data, m->param.recycle_pid); + + /* sbr use it to set receiver after new connction */ + m->param.receiver = (i64) & _m->conn->private_data; + m->param.comm_receiver = (i64) & _m->conn->comm_pcb_data; + _m->conn->recv_obj = m->param.receiver; + + SYNC_MSG_ACK (m); + return 0; + +ERROR: + SYNC_MSG_ACK (m); + return 0; +} + +int +_do_connect (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + m->param.err = ERR_CLSD; + SYNC_MSG_ACK (m); + return 0; + } + + msg_connect *_m = (msg_connect *) m->buffer; + do_connect (cpcb, _m); + + /** + * err == ERR_OK only applies for blocking connction, so others mean + * in progress for nonblocking connection or failed to connect + * cpcb may be NULL, so don't change the order of the 2 ifs. + */ + if (m->param.err != ERR_OK || cpcb->type != SPL_NETCONN_TCP) + SYNC_MSG_ACK (m); + + return 0; +} + +/** + * Close a TCP pcb contained in a netconn + * Called from netconn_close + * + * @param msg the api_msg_msg pointing to the connection + */ +int +_do_close (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb != NULL) + { + msg_close *_m = (msg_close *) m->buffer; + do_close (cpcb, _m); + } + + /* if cpcb == NULL, assuming the close is okay, err = ERR_OK */ + SYNC_MSG_ACK (m); + + return 0; +} + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the data_com_msg to handle + */ +static int +_do_delconn (data_com_msg * m) +{ + m->param.err = ERR_OK; + msg_delete_netconn *_m = (msg_delete_netconn *) m->buffer; + + if (0 == (--_m->msg_box_ref)) + { + /* the aync msg is released inside */ + ss_recycle_conn ((void *) _m, do_try_delconn); + } + + return 0; +} + +/** + * handle message to send UDP packets. + * + * @param msg the data_com_msg to handle + */ +static int +_do_send (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + msg_send_buf *_m = (msg_send_buf *) m->buffer; + if (cpcb == NULL) + { + NS_LOG_CTRL (LOG_CTRL_SEND, STACKX, "NSPOL", NSLOG_ERR, + "failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + spl_pbuf_free (_m->p); + _m->p = NULL; + ASYNC_MSG_FREE (m); + return -1; + } + + do_send (cpcb, _m); + + ASYNC_MSG_FREE (m); + + return 0; +} + +/** + * handle message to send TCP packets. + * + * @param msg the data_com_msg to handle + */ +static int +_do_write (data_com_msg * m) +{ + m->param.err = ERR_OK; + + void *tpcb = TCP_PRIVATE_PTR (m); + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + + msg_write_buf *_m = (msg_write_buf *) m->buffer; + if ((tpcb == NULL) || (cpcb == NULL)) + { + NS_LOG_CTRL (LOG_CTRL_WRITE, STACKX, "NSPOL", NSLOG_ERR, + "failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + spl_pbuf_free (_m->p); + _m->p = NULL; + ASYNC_MSG_FREE (m); + return -1; + } + + do_write (cpcb, _m); + + return 0; +} + +/** + * handle message to receive. + * + * @param msg the data_com_msg to handle + */ +static int +_do_recv (data_com_msg * m) +{ + m->param.err = ERR_OK; + + msg_recv_buf *_m = (msg_recv_buf *) m->buffer; + void *tpcb = TCP_PRIVATE_PTR (m); + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + + if ((tpcb == NULL) || (cpcb == NULL)) + { + NS_LOG_CTRL (LOG_CTRL_RECV, STACKX, "NSPOL", NSLOG_ERR, + "failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + spl_pbuf_free (_m->p); + _m->p = NULL; + ASYNC_MSG_FREE (m); + return -1; + } + + do_recv (cpcb, _m); + ASYNC_MSG_FREE (m); + return 0; +} + +/** + * handle message to bind local address. + * + * @param msg the data_com_msg to handle + */ +static int +_do_bind (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + NSPOL_LOGERR ("failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + m->param.err = ERR_VAL; + SYNC_MSG_ACK (m); + return -1; + } + + msg_bind *_m = (msg_bind *) m->buffer; + do_bind (cpcb, _m); + + SYNC_MSG_ACK (m); + + return 0; +} + +/** + * handle message to listen for new connection. + * + * @param msg the data_com_msg to handle + */ +static int +_do_listen (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + NSPOL_LOGERR ("failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + m->param.err = ERR_CONN; + SYNC_MSG_ACK (m); + return -1; + } + + msg_listen *_m = (msg_listen *) m->buffer; + do_listen (cpcb, _m); + + /* Update since pcb may have been changed */ + //m->param.receiver = (i64)&_m->conn->private_data; + SYNC_MSG_ACK (m); + return 0; +} + +/** + * handle message to set socket option. + * + * @param msg the data_com_msg to handle + */ +static int +_do_setsockopt (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + + NSPOL_LOGERR ("failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + m->param.err = ERR_VAL; + SYNC_MSG_ACK (m); + return -1; + } + + msg_setgetsockopt *_m = (msg_setgetsockopt *) m->buffer; + do_setsockopt_internal (cpcb, _m); + + SYNC_MSG_ACK (m); + + return 0; +} + +/** + * handle message to get socket option. + * + * @param msg the data_com_msg to handle + */ +static int +_do_getsockopt (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + NSPOL_LOGERR ("failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + m->param.err = ERR_VAL; + SYNC_MSG_ACK (m); + return -1; + } + + msg_setgetsockopt *_m = (msg_setgetsockopt *) m->buffer; + do_getsockopt_internal (cpcb, _m); + + SYNC_MSG_ACK (m); + + return 0; +} + +/** + * handle message to free pbuf which never used afterwards by application. + * + * @param msg the data_com_msg to handle + */ + +static int +_do_pbuf_free (data_com_msg * m) +{ + m->param.err = ERR_OK; + + msg_free_buf *_m = (msg_free_buf *) m->buffer; + do_pbuf_free (_m->buf); + + ASYNC_MSG_FREE (m); + + return 0; +} + +static int +_do_getsock_name (data_com_msg * m) +{ + m->param.err = ERR_OK; + + struct common_pcb *cpcb = COMM_PRIVATE_PTR (m); + if (cpcb == NULL) + { + NSPOL_LOGERR ("failed to find target pcb, drop the message]" + "module=%u, major=%u, minor=%u", + m->param.module_type, + m->param.major_type, m->param.minor_type); + + m->param.err = ERR_VAL; + SYNC_MSG_ACK (m); + return -1; + } + + msg_getaddrname *_m = (msg_getaddrname *) m->buffer; + do_getsockname (cpcb, _m); + + SYNC_MSG_ACK (m); + + return 0; +} + +/* app send its version info to nStackMain */ +static int +_do_app_touch (data_com_msg * m) +{ + m->param.err = ERR_OK; + + msg_app_touch *_m = (msg_app_touch *) m->buffer; + do_app_touch (_m); + + ASYNC_MSG_FREE (m); + return 0; +} + +/** + * process message from sbr module, all the processing function + * is registered when nstack is up. + * + * @param msg the api_msg_msg pointing to the connection + */ +int +spl_sbr_process (data_com_msg * m) +{ + if (m == NULL) + { + NSPOL_LOGERR ("message is NULL"); + return -1; + } + + return call_msg_fun (m); +} + +int +spl_unsupport_process (data_com_msg * m) +{ + NSPOL_LOGINF (TCPIP_DEBUG, "module_type=%u,major_type=%u,minor_type=%u", + m->param.module_type, m->param.major_type, + m->param.minor_type); + if (MSG_SYN_POST == m->param.op_type) + { + m->param.err = ERR_EPROTONOSUPPORT; + SYNC_MSG_ACK (m); + } + else + { + ASYNC_MSG_FREE (m); + } + + return -1; +} + +REGIST_MSG_UNSUPPORT_FUN (spl_unsupport_process); +REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + do_sbrmsg); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_NEWCONN, _do_newconn); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_CONNECT, _do_connect); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_CLOSE, _do_close); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_DELCON, _do_delconn); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_SEND, _do_send); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_WRITE, _do_write); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_RECV, _do_recv); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_BIND, _do_bind); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_LISTEN, _do_listen); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_GET_SOCK_OPT, _do_getsockopt); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_SET_SOCK_OPT, _do_setsockopt); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_PBUF_FREE, _do_pbuf_free); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, + SPL_API_DO_GETSOCK_NAME, _do_getsock_name); +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_SBR, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_APP_TOUCH, _do_app_touch); /* app send its version info to nStackMain */ diff --git a/stacks/lwip_stack/lwip_src/api/spl_tcpip.c b/stacks/lwip_stack/lwip_src/api/spl_tcpip.c new file mode 100644 index 0000000..b627bcf --- /dev/null +++ b/stacks/lwip_stack/lwip_src/api/spl_tcpip.c @@ -0,0 +1,1547 @@ +/* +* +* 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 "spl_opt.h" +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include "memp.h" +#include "mem.h" +#include "spl_pbuf.h" +//#include "sockets.h" +//#include <netinet/in.h> + +#include "stackx_spl_share.h" +#include "spl_api.h" +#include "spl_tcpip.h" +#include "init.h" +#include "stackx/internal_msg.h" +#include "netif/sc_dpdk.h" +#include "sharedmemory.h" +#include "stackx_instance.h" +#include "netif/common.h" +//#include "nettool/nettool.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "spl_hal.h" +#include "spl_sbr.h" +#include "spl_tcpip.h" + +#include "spl_instance.h" +#include "nsfw_mem_api.h" +#include "nsfw_msg_api.h" +#include "configuration_reader.h" + +#include "nsfw_ps_api.h" +#include "alarm_api.h" +#include "nstack_share_res.h" +#include "spl_timers.h" + +#include "etharp.h" +#include "raw.h" +#include "udp.h" +#include "tcp.h" +#include "igmp.h" +#include "memp.h" +#include "inet.h" +#include "sys_arch.h" + +#include "sys.h" + +#define NSTACK_MAIN_MAX_PARA 19 +#define NSTACK_MAIN_MIN_PARA 1 + +#define DPDK_DEFAULT_EAL_MEM_SIZE (1024) + +#define OPT_EAL_MEM_SIZE "--eal-mem-size=" + +/********************/ +/* extern variables */ +/********************/ +extern mring_handle spl_get_msg_pool (); +extern mring_handle spl_get_conn_pool (); +extern u32 spl_get_conn_num (); +extern err_t ethernet_input (struct pbuf *p, struct netif *netif); + +/* tcpip main thread sleep time, configured by user(nStackMain "-sleep" option) */ +extern int g_tcpip_thread_sleep_time; + +/* netif related */ +extern struct stackx_port_info *head_used_port_list; + +extern u32_t uStackArgIndex; + +extern int g_tcpip_thread_stat; + +/********************/ +/* global variables */ +/********************/ + +/* timer thread id */ +sys_thread_t g_timerThread_id = 0; + +/*Add an associative mapping relationship to p_stackx_instance based on lcore_id */ + +int globalArgc = 0; + +/* Set different mem args to PAL and EAL */ +char **gArgv = NULL; + +int g_dpdk_argc = 0; +char **g_dpdk_argv = NULL; + +/*The sum of the four queue processing messages does not exceed TASK_BURST*/ +static u32 g_highestMboxNum = 12; +static u32 g_mediumMboxNum = 8; +static u32 g_lowestMboxNum = 4; +static u32 g_primaryMboxNum = 8; + +/* [set ip_tos2prio size to IPTOS_TOS_MASK >> 1) + 1] */ +u8_t ip_tos2prio[(IPTOS_TOS_MASK >> 1) + 1] = { + TC_PRIO_BESTEFFORT, + ECN_OR_COST (FILLER), + TC_PRIO_BESTEFFORT, + ECN_OR_COST (BESTEFFORT), + TC_PRIO_BULK, + ECN_OR_COST (BULK), + TC_PRIO_BULK, + ECN_OR_COST (BULK), + TC_PRIO_INTERACTIVE, + ECN_OR_COST (INTERACTIVE), + TC_PRIO_INTERACTIVE, + ECN_OR_COST (INTERACTIVE), + TC_PRIO_INTERACTIVE_BULK, + ECN_OR_COST (INTERACTIVE_BULK), + TC_PRIO_INTERACTIVE_BULK, + ECN_OR_COST (INTERACTIVE_BULK) +}; + +/********************/ +/* extern functions */ +/********************/ +extern err_t ethernetif_init (struct netif *pnetif); +extern int nstack_stackx_init (int flag); +extern void tcp_sys_rmem_init (); +extern void ethernetif_packets_input (struct netif *pstnetif); + +/********************************/ +/* function forward declaration */ +/********************************/ + +static inline u32 priority_sched_mbox (struct stackx_stack *share_memory, + void **box, u32 n); +static inline char +rt_tos2priority (u8_t tos) +{ + return ip_tos2prio[IPTOS_TOS (tos) >> 1]; +} + +u64 +timer_get_threadid () +{ + return g_timerThread_id; +} + +#if (DPDK_MODULE != 1) +NSTACK_STATIC inline void +do_recv_task (struct disp_netif_list *dnlist, u16 index_task) +{ + struct netifExt *pnetifExt = NULL; + + while (dnlist) + { + struct netif *currentNetif = dnlist->netif; + dnlist = dnlist->next; + + pnetifExt = getNetifExt (currentNetif->num); + if (NULL == pnetifExt) + return; + + if (currentNetif != NULL && pnetifExt->num_packets_recv > index_task) + { + ethernetif_packets_input (currentNetif); + } + } +} + +static inline int +is_valid_sleep_time (int sleep_time) +{ +#define TCP_IP_THREAD_MAX_SLEEP_TIME 500 + if ((sleep_time < 0) || (sleep_time > TCP_IP_THREAD_MAX_SLEEP_TIME)) + { + return 0; + } + + return 1; +} + +static int +thread_init () +{ + sigset_t mask; + + if (0 != sigemptyset (&mask)) + { + NSTCP_LOGERR ("sigemptyset function call error"); + return -1; + } + + if (0 != sigaddset (&mask, SIGRTMIN)) + { + NSTCP_LOGERR ("sigaddset function call error"); + return -1; + } + + if ((pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0) + || (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0)) + { + NSTCP_LOGERR ("pthread setcancel function call error"); + return -1; + } + + if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0) + { + NSPOL_LOGERR ("pthread_sigmask function call error"); + return -1; + } + + return 0; +} + +alarm_result +spl_socket_resource_check_func (void) +{ + + mring_handle conn_ring = spl_get_conn_pool (); + unsigned int rate_use = 0; + alarm_result ret_alarm; + u32 ring_size = 0, ring_not_used_count = 0; + u32 socket_num = spl_get_conn_num (); + + ring_size = nsfw_mem_ring_size (conn_ring); + + if (0 == socket_num) + { + /* assign a valid id, then return */ + ret_alarm.alarm_id_get = ALARM_EVENT_MAX; + return ret_alarm; + } + + ring_not_used_count = nsfw_mem_ring_using_count (conn_ring); + + rate_use = (ring_size - ring_not_used_count) * 100 / socket_num; + + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + + if (rate_use >= USEAGE_HIGHT) + { + ret_alarm.alarm_flag_get = ALARM_PRODUCT; + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + NSPOL_LOGWAR (TCPIP_DEBUG, + "app using too much socket resources,the rate is bigger than 80%"); + } + else if (rate_use <= USEAGE_LOW) + { + ret_alarm.alarm_flag_get = ALARM_CLEAN; + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + } + else + { + ret_alarm.alarm_id_get = ALARM_EVENT_MAX; + } + + ret_alarm.alarm_reason_get = ALARM_REASON_SOCKET; + + return ret_alarm; + +} + +alarm_result +spl_msg_buf_resource_check_func (void) +{ + + mring_handle msg_ring = spl_get_msg_pool (); + unsigned int rate_use = 0; + alarm_result ret_alarm; + u32 ring_size = 0, ring_not_used_count = 0; + + ring_size = nsfw_mem_ring_size (msg_ring); + + if (0 == ring_size) + { + /* assign a valid id, then return */ + ret_alarm.alarm_id_get = ALARM_EVENT_MAX; + return ret_alarm; + } + + ring_not_used_count = nsfw_mem_ring_using_count (msg_ring); + + rate_use = (ring_size - ring_not_used_count) * 100 / ring_size; + + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + + if (rate_use >= USEAGE_HIGHT) + { + ret_alarm.alarm_flag_get = ALARM_PRODUCT; + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + } + else if (rate_use <= USEAGE_LOW) + { + ret_alarm.alarm_flag_get = ALARM_CLEAN; + ret_alarm.alarm_id_get = ALARM_EVENT_NSTACK_RESOURCE_ALARM; + } + else + { + ret_alarm.alarm_id_get = ALARM_EVENT_MAX; + } + + ret_alarm.alarm_reason_get = ALARM_REASON_MSG_BUF; + + return ret_alarm; + +} + +NSTACK_STATIC int +tcpip_thread_init () +{ + if (thread_init () != 0) + { + return -1; + } + + if (!is_valid_sleep_time (g_tcpip_thread_sleep_time)) + { + g_tcpip_thread_sleep_time = 0; + } + + alarm_para tcp_alarm_para; + tcp_alarm_para.period_alarm.time_length = 5; /* 5 second period */ + tcp_alarm_para.alarm_reason_count = 2; /*both resource */ + tcp_alarm_para.func_alarm_check_period[0] = spl_socket_resource_check_func; + tcp_alarm_para.alarm_reason_set[0] = ALARM_REASON_SOCKET; + tcp_alarm_para.func_alarm_check_period[1] = spl_msg_buf_resource_check_func; + tcp_alarm_para.alarm_reason_set[1] = ALARM_REASON_MSG_BUF; + (void) ns_reg_alarm (ALARM_EVENT_NSTACK_RESOURCE_ALARM, ALARM_PERIOD_CHECK, + &tcp_alarm_para); + + ns_send_init_alarm (ALARM_EVENT_NSTACK_RESOURCE_ALARM); + + printmeminfo (); + return 0; +} + +sys_mbox_t +get_primary_box () +{ + return &p_def_stack_instance->lstack.primary_mbox; +} + +NSTACK_STATIC inline u16 +tcpip_netif_recv (struct disp_netif_list * nif_list) +{ + + u16 num_recv_task = 0, netif_packet_num; + + struct netif *tmpnetif = NULL; + struct netifExt *pnetifExt = NULL; + + while (nif_list) + { + tmpnetif = nif_list->netif; + + netif_packet_num = spl_hal_recv (tmpnetif, 0); + pnetifExt = getNetifExt (tmpnetif->num); + if (NULL == pnetifExt) + return 0; + + /* store the packet number in each netif */ + pnetifExt->num_packets_recv = netif_packet_num; + + /** + * num_recv_task is the maximum packets of the netif among + * all the netifs. + */ + if (num_recv_task < netif_packet_num) + { + num_recv_task = netif_packet_num; + } + + nif_list = nif_list->next; + } + + return num_recv_task; +} + +NSTACK_STATIC inline void +no_task_in_one_loop () +{ +} + +#endif + +/** + * Pass a received packet to tcpip_thread for input processing + * + * @param p the received packet, p->payload pointing to the Ethernet header or + * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or + * SPL_NETIF_FLAG_ETHERNET flags) + * @param inp the network interface on which the packet was received + */ +err_t +spl_tcpip_input (struct pbuf *p, struct netif *inp) +{ + err_t ret; + NSPOL_LOGINF (TCPIP_DEBUG, "PACKET]p=%p,inp=%p", (void *) p, (void *) inp); + print_pbuf_payload_info (p, false); + + /* every netif has been set NETIF_FLAG_ETHARP flag, no need else branch */ + ret = ethernet_input (p, inp); + return ret; +} + +int +_do_spl_callback_msg (data_com_msg * m) +{ + NSPOL_LOGDBG (TCPIP_DEBUG, "tcpip_thread: CALLBACK]msg=%p", (void *) m); + + m->param.err = ERR_OK; + + msg_internal_callback *callback = (msg_internal_callback *) (m->buffer); + if (!callback->function) + { + NSTCP_LOGERR ("function ptr is null in SPL_TCPIP_MSG_CALLBACK msg"); + ASYNC_MSG_FREE (m); + return 0; + } + + callback->function (callback->ctx); + ASYNC_MSG_FREE (m); + + return 0; +} + +/***************************************************************************** +* Prototype : get_msgbox +* Description : According to the socket tos value to determine which priority queue to send +* Input : struct stackx_stack *sharedmemory, struct netconn *conn, enum api_msg_type type +* Output : Queue pointer +* Return Value : Queue pointer +* Calls : +* Called By : +* +*****************************************************************************/ +struct queue * +get_msgbox (int tos) +{ + struct stackx_stack *sharedmemory = &p_def_stack_instance->lstack; + + if ((MSG_PRIO_QUEUE_NUM < 3) || (0 == tos)) + { + return &sharedmemory->primary_mbox; + } + + char prio = rt_tos2priority ((u8_t) tos); + if ((TC_PRIO_INTERACTIVE == prio)) + { + NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the highest mbox....."); + return &sharedmemory->priority_mbox[0]; + } + else if ((TC_PRIO_BESTEFFORT == prio) || (TC_PRIO_INTERACTIVE_BULK == prio)) + { + NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the medium mbox....."); + return &sharedmemory->priority_mbox[1]; + } + else if ((TC_PRIO_BULK == prio) || (TC_PRIO_FILLER == prio)) + { + NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the lowest mbox....."); + return &sharedmemory->priority_mbox[2]; + } + + NSPOL_LOGDBG (SOCKETS_DEBUG, "sent to the primary mbox....."); + return &sharedmemory->primary_mbox; +} + +/***************************************************************************** +* Prototype : priority_sched_mbox +* Description : According to the priority from the message queue to take +* the message to deal with each cycle to take the total number of messages +* not exceed to TASK_BURST +* Input : struct stackx_stack *sharedmemory, struct netconn *conn, enum api_msg_type type +* Output : Queue pointer +* Return Value : Queue pointer +* Calls : +* Called By : +* +*****************************************************************************/ +static inline u32 +priority_sched_mbox (struct stackx_stack *share_memory, void **box, u32 n) +{ + /* high:primary:medium:low -> 3:2:2:1(total:TASK_BURST) */ + if (unlikely + ((g_highestMboxNum + g_mediumMboxNum + g_primaryMboxNum + + g_lowestMboxNum) != n)) + { + g_mediumMboxNum = n >> 2; + g_lowestMboxNum = n >> 3; + g_primaryMboxNum = n >> 2; + g_highestMboxNum = + n - g_mediumMboxNum - g_primaryMboxNum - g_lowestMboxNum; + } + + u32 highestMboxNum = g_highestMboxNum; + u32 primaryMboxNum = g_primaryMboxNum; + u32 lowestMboxNum = g_lowestMboxNum; + u32 mediumMboxNum = g_mediumMboxNum; + + u32 totalNum = 0; + u32 num = 0; + u32 oldLowestNum = 0; + + num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[0].llring, + (box + totalNum), highestMboxNum); + if (unlikely (num > highestMboxNum)) + { + num = highestMboxNum; + NSTCP_LOGERR + ("something wrong:num>highestMboxNum]num=%u,highestMboxNum=%u", num, + highestMboxNum); + } + + totalNum += num; + + u32 temp = highestMboxNum - num; + /* bisect the left number of highest */ + primaryMboxNum += (temp >> 1); + mediumMboxNum += temp - (temp >> 1); + + num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[1].llring, + (box + totalNum), mediumMboxNum); + if (unlikely (num > mediumMboxNum)) + { + num = mediumMboxNum; + NSTCP_LOGERR + ("something wrong.num>mediumMboxNum]num=%u,mediumMboxNum=%u", num, + mediumMboxNum); + } + + totalNum += num; + primaryMboxNum += mediumMboxNum - num; //occupy the left number of medium + + /* dynamically adjust g_mediumMboxNum and g_highestMboxNum, according to 'num' */ + oldLowestNum = g_mediumMboxNum; + if (0 == num) + { + g_mediumMboxNum = 1; + } + else if (num < g_mediumMboxNum) + { + g_mediumMboxNum = num; + } + else + { + g_mediumMboxNum = n >> 2; + } + + g_highestMboxNum += oldLowestNum - g_mediumMboxNum; + + num = nsfw_mem_ring_dequeuev (share_memory->primary_mbox.llring, + (box + totalNum), primaryMboxNum); + if (unlikely (num > primaryMboxNum)) + { + num = primaryMboxNum; + NSTCP_LOGERR + ("something wrong.num>primaryMboxNum]num=%u,primaryMboxNum=%u", num, + primaryMboxNum); + } + + totalNum += num; + lowestMboxNum += primaryMboxNum - num; //occupy the left number of primary + + /* dynamically adjust g_primaryMboxNum and g_highestMboxNum, according to 'num' */ + oldLowestNum = g_primaryMboxNum; + if (0 == num) + { + g_primaryMboxNum = 1; + } + else if (num < g_primaryMboxNum) + { + g_primaryMboxNum = num; + } + else + { + g_primaryMboxNum = n >> 2; + } + + g_highestMboxNum += oldLowestNum - g_primaryMboxNum; + + if (lowestMboxNum > (n - totalNum)) + { + lowestMboxNum = n - totalNum; + } + + num = nsfw_mem_ring_dequeuev (share_memory->priority_mbox[2].llring, + (box + totalNum), lowestMboxNum); + if (unlikely (num > lowestMboxNum)) + { + num = lowestMboxNum; + NSTCP_LOGERR + ("something wrong.num>lowestMboxNum]num=%u,lowestMboxNum=%u", num, + lowestMboxNum); + } + + totalNum += num; + + /* dynamically adjust g_lowestMboxNum and g_highestMboxNum, according to 'num' */ + oldLowestNum = g_lowestMboxNum; + if (0 == num) + { + g_lowestMboxNum = 1; + } + else if (num < g_lowestMboxNum) + { + g_lowestMboxNum = num; + } + else + { + g_lowestMboxNum = n >> 3; + } + + g_highestMboxNum += oldLowestNum - g_lowestMboxNum; + + return totalNum; +} + +/** + * call ltt_apimsg in STACKX TIMER THREAD + * + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return error code given back by the function that was called + */ +err_t +ltt_apimsg (sys_timeout_handler h, void *arg) +{ + data_com_msg *p_msg_entry; + sys_mbox_t mbox = get_primary_box (); + if (sys_mbox_valid (&mbox)) + { + if (-1 == spl_msg_malloc (&p_msg_entry)) + { + NSPOL_LOGERR ("ltt_apimsg:spl_msg_malloc failed."); + return -1; + } + + p_msg_entry->param.module_type = MSG_MODULE_TIMER; + p_msg_entry->param.major_type = SPL_TCPIP_MSG_TIMER; + p_msg_entry->param.minor_type = TIMER_MSG_TIMEOUT; + p_msg_entry->param.op_type = MSG_ASYN_POST; + + sys_sem_init (&p_msg_entry->param.op_completed); + + msg_timer *tmsg = (msg_timer *) (p_msg_entry->buffer); + tmsg->act = h; + tmsg->arg = arg; + + if (msg_post (p_msg_entry, mbox->llring) < 0) + { + NSPOL_LOGERR + ("msg post is failed]module_type=%u, major_type=%u, minor_type=%u", + p_msg_entry->param.module_type, p_msg_entry->param.major_type, + p_msg_entry->param.minor_type); + spl_msg_free (p_msg_entry); + return ERR_VAL; + } + + return ERR_OK; + } + + NSPOL_LOGERR ("mbox is invalid"); + return ERR_VAL; +} + +int +_do_spl_timer_msg (data_com_msg * m) +{ + NSPOL_LOGDBG (TESTSOCKET_DEBUG | STACKX_DBG_TRACE, + "the msg is from TIMER module, minor(%u)", + m->param.minor_type); + return 0; +} + +static int +_do_timeout_handle (data_com_msg * m) +{ + m->param.err = ERR_OK; + msg_timer *tmo_msg = (msg_timer *) m->buffer; + if (!tmo_msg->act) + { + NSTCP_LOGERR ("TIMER_MSG_TIMEOUT msg act is NULL"); + ASYNC_MSG_FREE (m); + return -1; + } + + timeout_phandler (tmo_msg->act, tmo_msg->arg); + ASYNC_MSG_FREE (m); + return 0; +} + +static int +_do_clear_timer (data_com_msg * m) +{ + NSTCP_LOGDBG ("TIMER_CLEAR API]msg=%p", (void *) m); + + msg_timer *handle = (msg_timer *) (m->buffer); + if (!handle->act) + { + NSTCP_LOGERR ("function ptr is null in TIMER_MSG_CLEAR msg"); + SET_MSG_ERR (m, ERR_VAL); + return 0; + } + + //stackxTcpPcbClearTimer((struct tcp_pcb *)handle->act, (unsigned long)handle->arg); + spl_msg_free (m); + + return 0; +} + +err_t +ltt_clearTmrmsg (void *pcb, void *arg) +{ + data_com_msg *p_msg_entry; + sys_mbox_t mbox = get_primary_box (); + if (sys_mbox_valid (&mbox)) + { + if (-1 == spl_msg_malloc (&p_msg_entry) || (NULL == p_msg_entry)) + { + NSPOL_LOGERR ("ltt_clearTmrmsg:spl_msg_malloc failed."); + return -1; + } + + p_msg_entry->param.module_type = MSG_MODULE_TIMER; + p_msg_entry->param.major_type = SPL_TCPIP_MSG_TIMER; + p_msg_entry->param.minor_type = TIMER_MSG_CLEAR; + p_msg_entry->param.op_type = MSG_ASYN_POST; + p_msg_entry->param.receiver = 0; + sys_sem_init (&p_msg_entry->param.op_completed); + + msg_timer *tmo = (msg_timer *) (p_msg_entry->buffer); + tmo->act = pcb; + tmo->arg = arg; + + if (msg_post (p_msg_entry, mbox->llring) < 0) + { + NSPOL_LOGERR + ("msg post is failed]module_type=%u, major_type=%u, minor_type=%u", + p_msg_entry->param.module_type, p_msg_entry->param.major_type, + p_msg_entry->param.minor_type); + spl_msg_free (p_msg_entry); + return ERR_VAL; + } + + return ERR_OK; + } + + NSPOL_LOGERR ("mbox is invalid"); + return ERR_VAL; +} + +#if STACKX_NETIF_API +err_t +tcpip_netif_post (data_com_msg * m) +{ + err_t err = ERR_OK; + sys_mbox_t mbox = get_primary_box (); + + if (NULL == mbox || !sys_mbox_valid (&mbox)) + { + NSPOL_LOGERR ("mbox not initialed well"); + err = ERR_MEM; + goto err_exit; + } + + if (NULL == mbox->llring) + { + int tryCount = 0; +#define TCP_NETIF_WAITINIT_MAX_COUNT 10 + NSPOL_LOGWAR (TCPIP_DEBUG, "mbox->llring not initialed yet..."); + sys_sleep_ns (0, 100000000); + while (!mbox->llring && (++tryCount < TCP_NETIF_WAITINIT_MAX_COUNT)) + { + NSPOL_LOGWAR (TCPIP_DEBUG, "mbox->llring not initialed yet..."); + sys_sleep_ns (0, 100000000); + } + + if (NULL == mbox->llring) + { + NSPOL_LOGERR ("failed to get a valid mbox->llring"); + err = ERR_MEM; + goto err_exit; + } + } + + NSPOL_LOGINF (TCPIP_DEBUG, "post tcpip_netif_msg..."); + + if (msg_post_with_lock_rel (m, mbox->llring) < 0) + { + err = ERR_VAL; + } + else + { + err = m->param.err; + } + +err_exit: + /* it's a sync message */ + spl_msg_free (m); + return err; +} + +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_netif_add (msg_add_netif * tmp) +{ + data_com_msg *p_msg_entry = NULL; + msg_add_netif *nmsg = NULL; + + if (spl_msg_malloc (&p_msg_entry) == -1) + { + NSPOL_LOGERR ("tcpip_netifapi:spl_msg_malloc failed."); + return ERR_MEM; + } + + p_msg_entry->param.module_type = MSG_MODULE_HAL; + p_msg_entry->param.major_type = SPL_TCPIP_MSG_NETIFAPI; + p_msg_entry->param.minor_type = NETIF_DO_ADD; + p_msg_entry->param.op_type = MSG_SYN_POST; + p_msg_entry->param.receiver = 0; + sys_sem_init (&p_msg_entry->param.op_completed); + + nmsg = (msg_add_netif *) p_msg_entry->buffer; + nmsg->function = tmp->function; + nmsg->netif = tmp->netif; + nmsg->ipaddr = tmp->ipaddr; + nmsg->netmask = tmp->netmask; + nmsg->gw = tmp->gw; + nmsg->state = tmp->state; + nmsg->init = tmp->init; + nmsg->input = tmp->input; + nmsg->voidfunc = tmp->voidfunc; + + return tcpip_netif_post (p_msg_entry); +} + +#endif /* STACKX_NETIF_API */ + +/* Added for congestion control, maybe not used end */ + +extern err_t init_ptimer (void); +extern struct cfg_item_info g_cfg_item_info[CFG_SEG_MAX][MAX_CFG_ITEM]; + +/*=========== set share config for nStackMain =============*/ +static inline mzone_handle +create_mem_zone (nsfw_mem_zone * zone_info) +{ + return nsfw_mem_zone_create (zone_info); +} + +static inline int +set_zone_info (nsfw_mem_zone * zone_info, nsfw_mem_name * name_info, u32 len) +{ + if (EOK != + MEMCPY_S (&(zone_info->stname), sizeof (nsfw_mem_name), name_info, + sizeof (nsfw_mem_name))) + { + NSPOL_DUMP_LOGERR ("create pool failed, MEMCPY_S failed."); + return -1; + } + + zone_info->length = len; + zone_info->isocket_id = NSFW_SOCKET_ANY; + + return 0; +} + +int +set_share_config () +{ + static nsfw_mem_name g_cfg_mem_info = + { NSFW_SHMEM, NSFW_PROC_MAIN, NSTACK_SHARE_CONFIG }; + + nsfw_mem_zone zone_info; + if (set_zone_info (&zone_info, &g_cfg_mem_info, get_cfg_share_mem_size ()) < + 0) + { + return -1; + } + + mzone_handle base_cfg_mem = create_mem_zone (&zone_info); + if (NULL == base_cfg_mem) + { + NSPOL_LOGERR ("get config share mem failed."); + return -1; + } + + if (set_share_cfg_to_mem (base_cfg_mem) < 0) + { + NSPOL_LOGERR ("set share config failed."); + return -1; + } + + return 0; +} + +int +init_by_tcpip_thread () +{ + if (spl_init_app_res () != 0) + { + NSPOL_LOGERR ("spl_init_app_res failed"); + return -1; + } + + if (init_instance () != 0) + { + return -1; + } + if (tcpip_thread_init () != 0) + { + NSTCP_LOGERR ("tcpip_thread_init failed!"); + return -1; + } + + init_stackx_lwip (); + + return 0; +} + +void +spl_tcpip_thread (void *arg) +{ + g_tcpip_thread_stat = 1; + + if (init_by_tcpip_thread () != 0) + { + return; + } + + struct stackx_stack *share_memory = &p_def_stack_instance->lstack; + struct disp_netif_list **iflist = &p_def_stack_instance->netif_list; + + u32 run_count = 0; + u16 task_loop; + u16 num_recv_task = 0, num_send_timer_task = 0; + u16 index_task = 0; + int tcpip_thread_sleep_interval = g_tcpip_thread_sleep_time * 1000; + void *task_queue[TASK_BURST]; + data_com_msg *msg; + + while (1) + { + /* try to receive packet from hal layer */ + num_recv_task = tcpip_netif_recv (*iflist); + + /* try to receive message from sbr layer */ + num_send_timer_task = priority_sched_mbox (share_memory, + task_queue, TASK_BURST); + + if (num_recv_task) + { + NSPOL_LOGINF (TCPIP_DEBUG, "num_recv_task %d", num_recv_task); + } + + /* Statistics the total number of messages */ + + /* Separate statistics on socket api messages */ + /* handle the request from upper layer and lower layer one by one */ + task_loop = (num_send_timer_task > num_recv_task ? + num_send_timer_task : num_recv_task); + if (task_loop == 0) + { + no_task_in_one_loop (); + + if (run_count++ > 20) + { + sys_sleep_ns (0, tcpip_thread_sleep_interval); + } + continue; + } + + run_count = 0; + index_task = 0; + + /* at least one task to be handled */ + while (task_loop > index_task) + { + /* handle one packet from hal layer (for multi-nic case, do it for each) */ + if (num_recv_task > index_task) + { + do_recv_task (*iflist, index_task); + } + + /* handle one message from sbr layer */ + if (num_send_timer_task > index_task) + { + msg = (data_com_msg *) (task_queue[index_task]); + + spl_process (msg); + } + + do_update_pcbstate (); + + index_task++; + } + } +} + +int +create_tcpip_thread () +{ + int ret; + u64 arg = 0; + + /* main tcpip thread */ + char thread_name[32] = TCPIP_THREAD_NAME; + + sys_thread_t thread = sys_thread_new (thread_name, spl_tcpip_thread, + (void *) arg, + TCPIP_THREAD_STACKSIZE, + g_cfg_item_info[CFG_SEG_PRI] + [CFG_SEG_THREAD_PRI_PRI].value); + + cpu_set_t cpuset; + CPU_ZERO (&cpuset); /*lint !e534 */ + CPU_SET (g_nstack_bind_cpu, &cpuset); /*lint !e522 */ + ret = pthread_setaffinity_np (thread, sizeof (cpuset), &cpuset); + if (ret != 0) + { + NSPOL_LOGERR ("pthread_setaffinity_np failed]thread_name=%s,ret=%d", + TCPIP_THREAD_NAME, ret); + } + + return 0; +} + +int +create_timer_thread () +{ +#if 1 + if (init_ptimer () != ERR_OK) + { + NSPOL_LOGERR ("init_ptimer failed"); + return -1; + } + + sys_thread_t thread_timer = + sys_thread_new (PTIMER_THREAD_NAME, ptimer_thread, NULL, + TCPIP_THREAD_STACKSIZE, 0); + cpu_set_t cpuset_timer; + CPU_ZERO (&cpuset_timer); + CPU_SET (1, &cpuset_timer); + int ret = pthread_setaffinity_np (thread_timer, sizeof (cpuset_timer), + &cpuset_timer); + if (ret != 0) + { + NSPOL_LOGERR ("TCP init Timer Trhead Failed!"); + } + + g_timerThread_id = thread_timer; +#endif + return 0; +} + +int +init_ip_module_reader () +{ + output_api api = { 0 }; + api.post_to = post_ip_module_msg; + api.add_netif_ip = add_netif_ip; + api.del_netif_ip = del_netif_ip; + regist_output_api (&api); + + if (init_configuration_reader () < 0) + { + NSPOL_LOGERR ("init_configuration_reader failed"); + return -1; + } + + return 0; +} + +extern int init_unmatch_version (void); +extern int init_stackx_global_tick (void); + +int +init_by_main_thread () +{ + NSPOL_LOGINF (TCPIP_DEBUG, "init_by_main_thread start version 1.4"); + + uStackArgIndex++; + if (spl_hal_init (g_dpdk_argc, (char **) g_dpdk_argv) < 0) + { + NSPOL_LOGERR ("spl_hal_init failed"); + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 1"); + + if (init_unmatch_version () != 0) + { + return -1; + } + + NSPOL_LOGINF (TCPIP_DEBUG, "stage 2"); + if (init_stackx_global_tick () != 0) + { + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 3"); + + if (spl_init_group_array () != 0) + { + NSPOL_LOGERR ("spl_init_group_array failed"); + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 4"); + + if (set_share_config () != 0) + { + NSPOL_LOGERR ("set_share_config failed."); + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 5"); + + if (create_timer_thread () != 0) + { + //NSPOL_LOGERR(TCPIP_DEBUG,"init_timer_thread failed."); + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 6"); + + if (create_tcpip_thread () != 0) + { + NSPOL_LOGERR ("init_tcpip_thread failed."); + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage 7"); + + if (init_ip_module_reader () != 0) + { + return -1; + } + NSPOL_LOGINF (TCPIP_DEBUG, "stage end"); + + return 0; +} + +void +create_netif (struct stackx_port_info *p_port_info) +{ + int ret; + struct spl_ip_addr ip, mask, gw; + struct netifExt *netifEx = NULL; + struct netif *netif = malloc (sizeof (struct netif)); + if (!netif) + { + NSPOL_LOGERR ("malloc failed"); + return; + } + + if (MEMSET_S (netif, sizeof (struct netif), 0, sizeof (struct netif)) < 0) + { + NSPOL_LOGERR ("MEMSET_S failed"); + goto error; + } + + NSPOL_LOGINF (TCPIP_DEBUG, "I get netif]ip=%s,gw=%s,mask=%s,name=%c %c", + p_port_info->linux_ip.ip_addr_linux, + p_port_info->linux_ip.ip_addr_linux, + p_port_info->linux_ip.mask_linux, + netif->name[0], netif->name[1]); + + if (inet_aton (p_port_info->linux_ip.ip_addr_linux, &ip) + && inet_aton (p_port_info->linux_ip.ip_addr_linux, &gw) + && inet_aton (p_port_info->linux_ip.mask_linux, &mask)) + { + ret = + spl_netifapi_netif_add (netif, &ip, &mask, &gw, NULL, ethernetif_init, + spl_tcpip_input, netif_set_up); + if (ERR_OK != ret) + { + NSPOL_LOGERR ("netifapi_netif_add failed]ret=%d", ret); + goto error; + } +#if 1 + if (0 != netifExt_add (netif)) + return; + +#endif + netifEx = getNetifExt (netif->num); + if (NULL == netifEx) + return; + + netifEx->hdl = p_port_info->linux_ip.hdl; + ret = + STRCPY_S (netifEx->if_name, sizeof (netifEx->if_name), + p_port_info->linux_ip.if_name); + if (EOK != ret) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", ret); + goto error; + } + return; + } + +error: + free (netif); +} + +int +post_ip_module_msg (void *arg, ip_module_type Type, + ip_module_operate_type operate_type) +{ + data_com_msg *p_msg_entry; + msg_ip_module *imsg; + sys_mbox_t mbox = get_primary_box (); + + if (!mbox) + { + NSOPR_LOGERR ("get_cur_mbox failed"); + return ERR_MEM; + } + + if (sys_mbox_valid (&mbox)) + { + if (spl_msg_malloc (&p_msg_entry) == -1) + { + NSOPR_LOGERR ("ip_route_apimsg:spl_msg_malloc failed."); + return ERR_MEM; + } + + sys_sem_init (&p_msg_entry->param.op_completed); + p_msg_entry->param.module_type = MSG_MODULE_IP; + p_msg_entry->param.op_type = MSG_SYN_POST; + + imsg = (msg_ip_module *) (p_msg_entry->buffer); + imsg->arg = arg; + imsg->type = Type; + imsg->operate_type = operate_type; + + NSOPR_LOGINF ("post ip_module msg to tcpip_thread]action=%d,type=%d", + operate_type, Type); + + if (msg_post (p_msg_entry, mbox->llring) != 0) + { + NSOPR_LOGERR + ("msg_post failed,this can not happen]action=%d,type=%d", + operate_type, Type); + } + + spl_msg_free (p_msg_entry); + + return ERR_OK; + } + + NSOPR_LOGERR ("mbox is invalid"); + return ERR_VAL; +} + +int +process_ip_module_msg (void *arg, ip_module_type module_type, + ip_module_operate_type operate_type) +{ + int retval = process_configuration (arg, module_type, operate_type); + + NSOPR_LOGINF ("tcpip_thread: ip_module cmd exec over, send SYNC_MSG_ACK"); + return retval; +} + +int +init_new_network_configuration () +{ + if (spl_hal_port_init () < 0) + { + return -1; + } + + return 0; +} + +static int +_process_ip_module_msg (data_com_msg * m) +{ + m->param.err = ERR_OK; + msg_ip_module *_m = (msg_ip_module *) m->buffer; + int ret = process_ip_module_msg (_m->arg, _m->type, _m->operate_type); + SYNC_MSG_ACK (m); + return ret; +} + +int +spl_post_msg (u16 mod, u16 maj, u16 min, u16 op, char *data, u16 data_len, + u32 src_pid) +{ + data_com_msg *p_msg_entry; + + sys_mbox_t mbox = get_primary_box (); + if (!sys_mbox_valid (&mbox)) + { + NSPOL_LOGERR + ("get mbox null!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", mod, maj, + min, op, data, data_len); + return ERR_MEM; + } + + if (spl_msg_malloc (&p_msg_entry) == -1) + { + NSPOL_LOGERR ("get msg null!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", + mod, maj, min, op, data, data_len); + return ERR_MEM; + } + + sys_sem_init (&p_msg_entry->param.op_completed); + p_msg_entry->param.module_type = mod; + p_msg_entry->param.major_type = maj; + p_msg_entry->param.minor_type = min; + p_msg_entry->param.op_type = op; + p_msg_entry->param.src_pid = src_pid; + + int retVal; + if (NULL != data) + { + retVal = + MEMCPY_S ((char *) p_msg_entry->buffer, sizeof (p_msg_entry->buffer), + data, data_len); + if (EOK != retVal) + { + NSPOL_LOGERR ("MEMCPY_S failed %d.", retVal); + spl_msg_free (p_msg_entry); + return ERR_MEM; + } + } + + if (msg_post_with_lock_rel (p_msg_entry, mbox->llring) != 0) + { + NSPOL_LOGERR + ("post msg error!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", mod, + maj, min, op, data, data_len); + spl_msg_free (p_msg_entry); + return ERR_MEM; + } + + if (MSG_SYN_POST == op) + { + spl_msg_free (p_msg_entry); + } + + NSOPR_LOGDBG ("post msg suc!]mod=%u,maj=%u,min=%u,op=%u,data=%p,len=%u", + mod, maj, min, op, data, data_len); + return ERR_OK; +} + +/* +* Added by eliminate duplicated code degree, the function is moved to the public places +*adjust memory size for pal and eal mem size: this func do the following things: +*1. copy argv to gArgv and g_dpdk_argv +*2. remove OPT_EAL_MEM_SIZE option so that the rtp and rte options process won't reprt unrecognized option error. +*3. set eal mem size and pal_mem_size = mem - eal_mem_size +*/ +int +adjust_mem_arg (int argc, char *argv[]) +{ + int i = 0; + int j = 0; + int retVal; + char *tmp = NULL; + char *tmp2 = NULL; + int arg_mem_index = -1; + char *saveptr1 = NULL; + int mem_size = 0; + int mem_size_parsed = 0; // if multi -m argument is set, then only deal with the first one + int eal_mem_size = DPDK_DEFAULT_EAL_MEM_SIZE; // Default + + if ((argc < NSTACK_MAIN_MIN_PARA) || (argc > NSTACK_MAIN_MAX_PARA)) + { + NSPOL_LOGERR ("The number of parameters is incorrect"); + return -1; + } + + globalArgc = argc; + g_dpdk_argc = argc; + gArgv = (char **) malloc (sizeof (char *) * argc); + if (gArgv == NULL) + { + NSPOL_LOGERR ("Failed to alloc memory for adjust mem args\n"); + goto ERROR_INIT; + } + + g_dpdk_argv = (char **) malloc (sizeof (char *) * argc); + if (g_dpdk_argv == NULL) + { + NSPOL_LOGERR ("Failed to alloc memory for adjust mem args\n"); + goto ERROR_INIT; + } + + retVal = + MEMSET_S (gArgv, sizeof (char *) * argc, 0, sizeof (char *) * argc); + if (EOK != retVal) + { + NSPOL_LOGERR ("MEMSET_S failed %d.", retVal); + goto ERROR_INIT; + } + retVal = + MEMSET_S (g_dpdk_argv, sizeof (char *) * argc, 0, sizeof (char *) * argc); + if (EOK != retVal) + { + NSPOL_LOGERR ("MEMSET_S failed %d.", retVal); + goto ERROR_INIT; + } + + for (i = 0; i < argc; i++) + { + if (!strcmp ("-m", argv[i]) && !mem_size_parsed && (i + 1 < argc)) + { + gArgv[j] = argv[i]; + g_dpdk_argv[j] = argv[i]; + i++; + j++; + gArgv[j] = (char *) malloc (32); + g_dpdk_argv[j] = (char *) malloc (32); + /* gArgv[j] is NULL and g_dpdk_argv[j] isnot NULL, need free g_dpdk_argv[j] */ + arg_mem_index = j; + if ((!gArgv[j]) || (!g_dpdk_argv[j])) + { + NSPOL_LOGERR ("malloc failed."); + goto ERROR_PARSE_MALLOC; + } + mem_size = atoi (argv[i]); + /* add memory range check,avoid handle wrongly later begin */ + if (mem_size < 0) + { + goto ERROR_PARSE_MALLOC; + } + + j++; + mem_size_parsed = 1; + } + else + if (!strncmp (OPT_EAL_MEM_SIZE, argv[i], strlen (OPT_EAL_MEM_SIZE))) + { + tmp = strdup (argv[i]); + if (tmp == NULL) + { + goto ERROR_PARSE_MALLOC; + } + /* Always use re-entrant functions in multi-threaded environments */ + tmp2 = strtok_r (tmp, "=", &saveptr1); + tmp2 = strtok_r (NULL, "=", &saveptr1); + if (tmp2) + { + eal_mem_size = atoi (tmp2); + /* add memory range check,avoid handle wrongly later */ + if (eal_mem_size < 0) + { + free (tmp); + goto ERROR_PARSE_MALLOC; + } + } + free (tmp); + tmp = NULL; + /*remove this option since dpdk can't recognize it and may cause error. */ + /*so we should deduct the count by 1. */ + globalArgc -= 1; + g_dpdk_argc -= 1; + } + else + { + gArgv[j] = argv[i]; + g_dpdk_argv[j] = argv[i]; + j++; + } + } + + /* -m arg is set */ + if (arg_mem_index >= 0) + { + retVal = + SPRINTF_S (gArgv[arg_mem_index], 32, "%d", mem_size - eal_mem_size); + if (-1 == retVal) + { + NSPOL_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + goto ERROR_PARSE_MALLOC; + } + retVal = SPRINTF_S (g_dpdk_argv[arg_mem_index], 32, "%d", eal_mem_size); + if (-1 == retVal) + { + NSPOL_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + goto ERROR_PARSE_MALLOC; + } + } + else + { + // do nothing for no mem arg and leave it for default process of pal and eal. + } + + return 0; +ERROR_PARSE_MALLOC: + if (arg_mem_index >= 0 && gArgv[arg_mem_index]) + { + free (gArgv[arg_mem_index]); + gArgv[arg_mem_index] = NULL; + } + + if (arg_mem_index >= 0 && g_dpdk_argv[arg_mem_index]) + { + free (g_dpdk_argv[arg_mem_index]); + g_dpdk_argv[arg_mem_index] = NULL; + } + +ERROR_INIT: + if (gArgv) + { + free (gArgv); + gArgv = NULL; + globalArgc = 0; + } + + if (g_dpdk_argv) + { + free (g_dpdk_argv); + g_dpdk_argv = NULL; + g_dpdk_argc = 0; + } + + return -1; +} + +REGIST_MSG_MODULE_FUN (MSG_MODULE_IP, _process_ip_module_msg); + +REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_SPL, SPL_TCPIP_MSG_CALLBACK, + _do_spl_callback_msg); + +REGIST_MSG_MODULE_MAJOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, + _do_spl_timer_msg); + +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, + TIMER_MSG_TIMEOUT, _do_timeout_handle); + +REGIST_MSG_MODULE_MAJOR_MINOR_FUN (MSG_MODULE_TIMER, SPL_TCPIP_MSG_TIMER, + TIMER_MSG_CLEAR, _do_clear_timer); diff --git a/stacks/lwip_stack/lwip_src/common/rb_tree.c b/stacks/lwip_stack/lwip_src/common/rb_tree.c new file mode 100644 index 0000000..3dcb37a --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/rb_tree.c @@ -0,0 +1,393 @@ +/* +* +* 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 "rb_tree.h" + +static void +__rb_rotate_right (struct rb_node *node, struct rb_root *root) +{ + struct rb_node *left = node->rb_left; + struct rb_node *parent = rb_parent (node); + + if ((node->rb_left = left->rb_right)) + { + rb_set_parent (left->rb_right, node); + } + + left->rb_right = node; + + rb_set_parent (left, parent); + + if (parent) + { + if (node == parent->rb_right) + { + parent->rb_right = left; + } + else + { + parent->rb_left = left; + } + } + else + { + root->rb_node = left; + } + + rb_set_parent (node, left); +} + +static void +__rb_rotate_left (struct rb_node *node, struct rb_root *root) +{ + struct rb_node *parent = rb_parent (node); + + struct rb_node *right = node->rb_right; + + if ((node->rb_right = right->rb_left)) + { + rb_set_parent (right->rb_left, node); + } + + right->rb_left = node; + rb_set_parent (right, parent); + + if (parent) /* judge parent node */ + { + if (node == parent->rb_left) + { + parent->rb_left = right; + } + else + { + parent->rb_right = right; + } + } + else + { + root->rb_node = right; + } + + rb_set_parent (node, right); +} + +static void +__rb_erase_color (struct rb_node *rb_tree_node, + struct rb_node *rb_tree_parent, + struct rb_root *rb_tree_root) +{ + struct rb_node *rb_tree_other; + + while ((!rb_tree_node || rb_is_black (rb_tree_node)) + && (rb_tree_node != rb_tree_root->rb_node)) + { + if (rb_tree_parent == NULL) + { + break; + } + + if (rb_tree_parent->rb_left == rb_tree_node) + { + rb_tree_other = rb_tree_parent->rb_right; + if (rb_is_red (rb_tree_other)) + { + rb_set_black (rb_tree_other); + rb_set_red (rb_tree_parent); + __rb_rotate_left (rb_tree_parent, rb_tree_root); + rb_tree_other = rb_tree_parent->rb_right; + } + + if ((!rb_tree_other->rb_left + || rb_is_black (rb_tree_other->rb_left)) + && (!rb_tree_other->rb_right + || rb_is_black (rb_tree_other->rb_right))) + { + rb_set_red (rb_tree_other); + rb_tree_node = rb_tree_parent; + rb_tree_parent = rb_parent (rb_tree_node); + } + else + { + if (!rb_tree_other->rb_right + || rb_is_black (rb_tree_other->rb_right)) + { + rb_set_black (rb_tree_other->rb_left); + rb_set_red (rb_tree_other); + __rb_rotate_right (rb_tree_other, rb_tree_root); + rb_tree_other = rb_tree_parent->rb_right; + } + + rb_set_color (rb_tree_other, rb_color (rb_tree_parent)); + rb_set_black (rb_tree_parent); + rb_set_black (rb_tree_other->rb_right); + __rb_rotate_left (rb_tree_parent, rb_tree_root); + rb_tree_node = rb_tree_root->rb_node; + break; + } + } + else + { + rb_tree_other = rb_tree_parent->rb_left; + if (rb_is_red (rb_tree_other)) + { + rb_set_black (rb_tree_other); + rb_set_red (rb_tree_parent); + __rb_rotate_right (rb_tree_parent, rb_tree_root); + rb_tree_other = rb_tree_parent->rb_left; + } + + if ((!rb_tree_other->rb_left + || rb_is_black (rb_tree_other->rb_left)) + && (!rb_tree_other->rb_right + || rb_is_black (rb_tree_other->rb_right))) + { + rb_set_red (rb_tree_other); + rb_tree_node = rb_tree_parent; + rb_tree_parent = rb_parent (rb_tree_node); + } + else + { + if (!rb_tree_other->rb_left + || rb_is_black (rb_tree_other->rb_left)) + { + rb_set_black (rb_tree_other->rb_right); + rb_set_red (rb_tree_other); + __rb_rotate_left (rb_tree_other, rb_tree_root); + rb_tree_other = rb_tree_parent->rb_left; + } + + rb_set_color (rb_tree_other, rb_color (rb_tree_parent)); + rb_set_black (rb_tree_parent); + rb_set_black (rb_tree_other->rb_left); + __rb_rotate_right (rb_tree_parent, rb_tree_root); + rb_tree_node = rb_tree_root->rb_node; + break; + } + } + } + + if (rb_tree_node) + { + rb_set_black (rb_tree_node); + } +} + +void +rb_insert_color (struct rb_node *rb_tree_node, struct rb_root *rb_tree_root) +{ + struct rb_node *rb_tree_parent, *rb_tree_gparent; + + if (!rb_tree_node || !rb_tree_root) + return; + + while ((rb_tree_parent = rb_parent (rb_tree_node)) + && rb_is_red (rb_tree_parent)) + { + rb_tree_gparent = rb_parent (rb_tree_parent); + + if (rb_tree_parent == rb_tree_gparent->rb_left) + { + { + register struct rb_node *rb_tree_uncle = + rb_tree_gparent->rb_right; + if (rb_tree_uncle && rb_is_red (rb_tree_uncle)) + { + rb_set_black (rb_tree_uncle); + rb_set_black (rb_tree_parent); + rb_set_red (rb_tree_gparent); + rb_tree_node = rb_tree_gparent; + continue; + } + } + + if (rb_tree_parent->rb_right == rb_tree_node) + { + register struct rb_node *rb_tree_tmp; + __rb_rotate_left (rb_tree_parent, rb_tree_root); + rb_tree_tmp = rb_tree_parent; + rb_tree_parent = rb_tree_node; + rb_tree_node = rb_tree_tmp; + } + + rb_set_black (rb_tree_parent); + rb_set_red (rb_tree_gparent); + __rb_rotate_right (rb_tree_gparent, rb_tree_root); + } + else + { + { + register struct rb_node *rb_tree_uncle = rb_tree_gparent->rb_left; + if (rb_tree_uncle && rb_is_red (rb_tree_uncle)) + { + rb_set_black (rb_tree_uncle); + rb_set_black (rb_tree_parent); + rb_set_red (rb_tree_gparent); + rb_tree_node = rb_tree_gparent; + continue; + } + } + + if (rb_tree_parent->rb_left == rb_tree_node) + { + register struct rb_node *rb_tree_tmp; + __rb_rotate_right (rb_tree_parent, rb_tree_root); + rb_tree_tmp = rb_tree_parent; + rb_tree_parent = rb_tree_node; + rb_tree_node = rb_tree_tmp; + } + + rb_set_black (rb_tree_parent); + rb_set_red (rb_tree_gparent); + __rb_rotate_left (rb_tree_gparent, rb_tree_root); + } + } + + rb_set_black (rb_tree_root->rb_node); +} + +void +rb_erase (struct rb_node *node, struct rb_root *root) +{ + struct rb_node *child, *parent; + int color; + + if (!node || !root) + return; + + if (!node->rb_left) + { + child = node->rb_right; + } + else if (!node->rb_right) + { + child = node->rb_left; + } + else + { + struct rb_node *old = node, *left; + + node = node->rb_right; + while ((left = node->rb_left) != NULL) + { + node = left; + } + + if (rb_parent (old)) + { + if (rb_parent (old)->rb_left == old) + { + rb_parent (old)->rb_left = node; + } + else + { + rb_parent (old)->rb_right = node; + } + } + else + { + root->rb_node = node; + } + + child = node->rb_right; + parent = rb_parent (node); + color = rb_color (node); + + if (parent == old) + { + parent = node; + } + else + { + if (child) + { + rb_set_parent (child, parent); + } + + parent->rb_left = child; + + node->rb_right = old->rb_right; + rb_set_parent (old->rb_right, node); + } + + node->rb_parent_color = old->rb_parent_color; + node->rb_left = old->rb_left; + rb_set_parent (old->rb_left, node); + + goto color; + } + + parent = rb_parent (node); + color = rb_color (node); + + if (child) + { + rb_set_parent (child, parent); + } + + if (parent) + { + if (parent->rb_left == node) + { + parent->rb_left = child; + } + else + { + parent->rb_right = child; + } + } + else + { + root->rb_node = child; + } + +color: + if (color == RB_BLACK) + { + __rb_erase_color (child, parent, root); + } +} + +struct rb_node * +rb_next (const struct rb_node *node) +{ + struct rb_node *parent; + + if (!node) + return NULL; + + if (rb_parent (node) == node) + { + return NULL; + } + + if (node->rb_right) + { + node = node->rb_right; + while (node->rb_left) + { + node = node->rb_left; + } + + return (struct rb_node *) node; + } + + while ((parent = rb_parent (node)) && (node == parent->rb_right)) + { + node = parent; + } + + return parent; +} diff --git a/stacks/lwip_stack/lwip_src/common/rb_tree.h b/stacks/lwip_stack/lwip_src/common/rb_tree.h new file mode 100644 index 0000000..87174fa --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/rb_tree.h @@ -0,0 +1,112 @@ +/* +* +* 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 _UNX_RBTREE_H +#define _UNX_RBTREE_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif +#include <stdint.h> +#include "types.h" +#include "common_pal_bitwide_adjust.h" + +#define rb_parent(a) ((struct rb_node *)((a)->rb_parent_color & ~3)) +#define rb_color(a) ((a)->rb_parent_color & 1) + +struct rb_node +{ + union + { + unsigned long rb_parent_color; + u64 rb_parent_color_a; + }; + +#define RB_RED 0 +#define RB_BLACK 1 + union + { + struct rb_node *rb_right; + u64 rb_right_a; + }; + + union + { + struct rb_node *rb_left; + u64 rb_left_a; + }; +}; + +#define rb_set_red(c) do { (c)->rb_parent_color &= ~1; } while (0) +#define rb_set_black(c) do { (c)->rb_parent_color |= 1; } while (0) + +/* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct rb_root +{ + union + { + struct rb_node *rb_node; + u64 rb_node_a; + }; +}; + +#define rb_is_red(e) (!rb_color(e)) +#define rb_is_black(e) rb_color(e) + +static inline void +rb_set_color (struct rb_node *rb1, int color2) +{ + rb1->rb_parent_color = (rb1->rb_parent_color & ~1) | color2; +} + +static inline void +rb_set_parent (struct rb_node *rb1, struct rb_node *pa) +{ + rb1->rb_parent_color = (rb1->rb_parent_color & 3) | (unsigned long) pa; +} + +#define RB_ROOT (struct rb_root) { NULL, } + +extern void rb_erase (struct rb_node *, struct rb_root *); + +extern void rb_insert_color (struct rb_node *, struct rb_root *); + +extern struct rb_node *rb_next (const struct rb_node *); + +#define rb_entry(ptr, type, member) container_of(ptr, type, member) + +#define RB_EMPTY_ROOT(root1) ((root1)->rb_node == NULL) +#define RB_CLEAR_NODE(node2) (rb_set_parent(node2, node2)) +#define RB_EMPTY_NODE(node1) (rb_parent(node1) == node1) + +static inline void +rb_link_node (struct rb_node *node1, struct rb_node *parent1, + struct rb_node **rb_link1) +{ + node1->rb_left = node1->rb_right = NULL; + node1->rb_parent_color = (unsigned long) parent1; + *rb_link1 = node1; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#endif /* _UNX_RBTREE_H */ diff --git a/stacks/lwip_stack/lwip_src/common/spl_def.h b/stacks/lwip_stack/lwip_src/common/spl_def.h new file mode 100644 index 0000000..b62d179 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/spl_def.h @@ -0,0 +1,142 @@ +/* +* +* 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 __STACKX_DEF_H__ +#define __STACKX_DEF_H__ + +/* arch.h might define NULL already */ +//#include "lwip/arch.h" +#include "spl_opt.h" +#include "stackx_types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define STACKX_MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define STACKX_MIN(x, y) (((x) < (y)) ? (x) : (y)) + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define STACKX_MAKE_U16(a, b) ((a << 8) | b) +#else +#define STACKX_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef STACKX_PLATFORM_BYTESWAP +#define STACKX_PLATFORM_BYTESWAP 0 +#endif + +#ifndef STACKX_PREFIX_BYTEORDER_FUNCS + +/* workaround for naming collisions on some platforms */ + +#ifdef spl_htons +#undef spl_htons +#endif /* htons */ +#ifdef spl_htonl +#undef spl_htonl +#endif /* spl_htonl */ +#ifdef spl_ntohs +#undef spl_ntohs +#endif /* spl_ntohs */ +#ifdef spl_ntohl +#undef spl_ntohl +#endif /* spl_ntohl */ + +#define spl_htons(x) stackx_htons(x) +#define spl_ntohs(x) stackx_ntohs(x) +#define spl_htonl(x) stackx_htonl(x) +#define spl_ntohl(x) stackx_ntohl(x) +#endif /* STACKX_PREFIX_BYTEORDER_FUNCS */ + +#if BYTE_ORDER == BIG_ENDIAN +#define stackx_htons(x) (x) +#define stackx_ntohs(x) (x) +#define stackx_htonl(x) (x) +#define stackx_ntohl(x) (x) +#define SPL_PP_HTONS(x) (x) +#define SPL_PP_NTOHS(x) (x) +#define SPL_PP_HTONL(x) (x) +#define SPL_PP_NTOHL(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#if STACKX_PLATFORM_BYTESWAP +#define stackx_htons(x) STACKX_PLATFORM_HTONS(x) +#define stackx_ntohs(x) STACKX_PLATFORM_HTONS(x) +#define stackx_htonl(x) STACKX_PLATFORM_HTONL(x) +#define stackx_ntohl(x) STACKX_PLATFORM_HTONL(x) +#else /* STACKX_PLATFORM_BYTESWAP */ + /** + * Convert an u16_t from host- to network byte order. + * + * @param n u16_t in host byte order + * @return n in network byte order + */ +static inline u16_t +stackx_htons (u16_t x) +{ + return ((x & 0xff) << 8) | ((x & 0xff00) >> 8); +} + +static inline u16_t +stackx_ntohs (u16_t x) +{ + return stackx_htons (x); +} + + /** + * Convert an u32_t from host- to network byte order. + * + * @param n u32_t in host byte order + * @return n in network byte order + */ +static inline u32_t +stackx_htonl (u32_t x) +{ + return ((x & 0xff) << 24) | + ((x & 0xff00) << 8) | + ((x & 0xff0000UL) >> 8) | ((x & 0xff000000UL) >> 24); +} + +static inline u32_t +stackx_ntohl (u32_t x) +{ + return stackx_htonl (x); +} +#endif /* STACKX_PLATFORM_BYTESWAP */ + +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define SPL_PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define SPL_PP_NTOHS(x) SPL_PP_HTONS(x) +#define SPL_PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define SPL_PP_NTOHL(x) SPL_PP_HTONL(x) + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_DEF_H__ */ diff --git a/stacks/lwip_stack/lwip_src/common/spl_opt.h b/stacks/lwip_stack/lwip_src/common/spl_opt.h new file mode 100644 index 0000000..98e6466 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/spl_opt.h @@ -0,0 +1,329 @@ +/* +* +* 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 __STACKX_OPT_H__ +#define __STACKX_OPT_H__ + +#include "stackxopts.h" +#include "stackx_debug.h" +#include "compiling_check.h" + +#define PBUF_VLAN_HLEN 0 + +//#define SIZEOF_ETH_HDR (14) + +#ifndef STACKX_NETIF_API +#define STACKX_NETIF_API 1 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ + */ + +#define PTIMER_THREAD_NAME "ptimer_thread" + +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "spl_tcpip_thread" +#endif + +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef INT_64_MAX +#define INT_64_MAX 9223372036854775807 +#endif + +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- + */ + +#ifndef STACKX_DBG_TYPES_ON +#define STACKX_DBG_TYPES_ON STACKX_DBG_ON //ON +#endif + +#ifndef INTERRUPT_DEBUG +#define INTERRUPT_DEBUG STACKX_DBG_ON //ON +#endif + +#ifndef TESTSOCKET_DEBUG +#define TESTSOCKET_DEBUG STACKX_DBG_ON //ON +#endif + +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG STACKX_DBG_ON +#endif + +#ifndef NETIF_DEBUG +#define NETIF_DEBUG STACKX_DBG_ON +#endif + +#ifndef PBUF_DEBUG +#define PBUF_DEBUG STACKX_DBG_ON +#endif + +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG STACKX_DBG_ON +#endif + +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG STACKX_DBG_ON +#endif + +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG STACKX_DBG_ON +#endif + +#ifndef NS_EPOLL_DBG +#define NS_EPOLL_DBG STACKX_DBG_ON +#endif + +#ifndef ICMP_DEBUG +#define ICMP_DEBUG STACKX_DBG_ON +#endif + +#ifndef IGMP_DEBUG +#define IGMP_DEBUG STACKX_DBG_ON +#endif + +#ifndef INET_DEBUG +#define INET_DEBUG STACKX_DBG_ON +#endif + +#ifndef IP_DEBUG +#define IP_DEBUG STACKX_DBG_ON +#endif + +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG STACKX_DBG_ON +#endif + +#ifndef RAW_DEBUG +#define RAW_DEBUG STACKX_DBG_ON +#endif + +#ifndef MEMP_DEBUG +#define MEMP_DEBUG STACKX_DBG_ON +#endif + +#ifndef SYS_DEBUG +#define SYS_DEBUG STACKX_DBG_OFF +#endif + +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_DEBUG +#define TCP_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_TEST_DEBUG +#define TCP_TEST_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_FLOW_CTL_DEBUG +#define TCP_FLOW_CTL_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG STACKX_DBG_ON +#endif + +#ifndef UDP_DEBUG +#define UDP_DEBUG STACKX_DBG_ON +#endif + +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG STACKX_DBG_ON +#endif + +#ifndef NEW_RING_DEBUG +#define NEW_RING_DEBUG STACKX_DBG_ON +#endif + +#ifndef PACKET_DISPATCH +#define PACKET_DISPATCH 1 +#endif + +#ifndef NETSTAT_SWITCH +#define NETSTAT_SWITCH 1 +#endif + +#ifndef DISTRIBUTOR_DEBUG + +#define DISTRIBUTOR_DEBUG STACKX_DBG_ON +#endif +#define PBUF_REF_DEBUG STACKX_DBG_ON + +#ifndef CONTEXT_TIMER_DEBUG +#define CONTEXT_TIMER_DEBUG STACKX_DBG_OFF +#endif + +#if (DISTRIBUTOR_DEBUG == STACKX_DBG_ON) +#define PD_DISTRIBUTOR_DEBUG + +#define DISTRIBUTOR_SINGLE +#ifdef DISTRIBUTOR_SINGLE + +#ifndef __STACKX_DEBUG_H__ +#define STACKX_DBG_OFF 0x80U +#define STACKX_DBG_ON 0x00U +#endif + +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG STACKX_DBG_ON +#endif +#ifndef NETIF_DEBUG +#define NETIF_DEBUG STACKX_DBG_ON +#endif +#ifndef PBUF_DEBUG +#define PBUF_DEBUG STACKX_DBG_ON +#endif +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG STACKX_DBG_ON +#endif +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG STACKX_DBG_ON +#endif +#ifndef ICMP_DEBUG +#define ICMP_DEBUG STACKX_DBG_ON +#endif +#ifndef IGMP_DEBUG +#define IGMP_DEBUG STACKX_DBG_ON +#endif +#ifndef INET_DEBUG +#define INET_DEBUG STACKX_DBG_ON +#endif +#ifndef IP_DEBUG +#define IP_DEBUG STACKX_DBG_ON +#endif +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG STACKX_DBG_ON +#endif +#ifndef RAW_DEBUG +#define RAW_DEBUG STACKX_DBG_ON +#endif +#ifndef MEMP_DEBUG +#define MEMP_DEBUG STACKX_DBG_ON +#endif +#ifndef SYS_DEBUG +#define SYS_DEBUG STACKX_DBG_ON +#endif +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_DEBUG +#define TCP_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_TEST_DEBUG +#define TCP_TEST_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG STACKX_DBG_ON +#endif +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG STACKX_DBG_ON +#endif +#ifndef UDP_DEBUG +#define UDP_DEBUG STACKX_DBG_ON +#endif +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG STACKX_DBG_ON +#endif + +#define SC_DPDK_INFO STACKX_DBG_ON +#define SOCK_INFO STACKX_DBG_ON +#ifndef STACKX_DBG_OFF +#define STACKX_DBG_OFF 0x00U +#endif + +#ifndef NS_EPOLL_DBG +#define NS_EPOLL_DBG STACKX_DBG_ON +#endif + +#ifndef DFX_DBG +#define DFX_DBG STACKX_DBG_ON +#endif + +#endif +#endif /* DISTRIBUTOR_DEBUG */ + +#ifndef STACKX_FLOW_CTL +#define STACKX_FLOW_CTL 0 +#endif + +#endif /* __STACKX_OPT_H__ */ diff --git a/stacks/lwip_stack/lwip_src/common/stackx_app_res.c b/stacks/lwip_stack/lwip_src/common/stackx_app_res.c new file mode 100644 index 0000000..5c30271 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_app_res.c @@ -0,0 +1,972 @@ +/* +* +* 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 "stackx_app_res.h" +#include "nstack_securec.h" +#include "common_pal_bitwide_adjust.h" +#include "nstack_log.h" +#include "stackx_common.h" +#include "nsfw_maintain_api.h" +#include "stackx_tx_box.h" +#include "nsfw_msg_api.h" +#include "nsfw_recycle_api.h" +#include "common_mem_mbuf.h" +#include "stackx_pbuf.h" +#include "nsfw_mt_config.h" +#include "nsfw_mem_api.h" +#include "spl_opt.h" +#define SPL_MAX_MSG_NUM (MBOX_RING_SIZE*8*MAX_THREAD_NUM) + +spl_app_res_group *g_spl_app_res_group = NULL; + +spl_app_res_group_array *g_res_group_array = NULL; + +#ifdef SYS_MEM_RES_STAT +mpool_handle g_app_tx_pool[SBR_TX_POOL_NUM]; +#endif + +/*************************************************** +* description: +***************************************************/ +int +spl_init_group_array () +{ + g_res_group_array = + (spl_app_res_group_array *) sbr_create_mzone (SPL_RES_GROUP_ARRAY, + sizeof + (spl_app_res_group_array)); + if (!g_res_group_array) + { + NSPOL_LOGERR ("create g_res_group_array failed"); + return -1; + } + + u32 i; + for (i = 0; i < SBR_TX_POOL_NUM; ++i) + { + g_res_group_array->pid_array[i] = 0; + } + + for (i = 0; i < MAX_THREAD_NUM; ++i) + { + g_res_group_array->res_group[i] = NULL; + } + + g_res_group_array->thread_num = 0; + return 0; +} + +/*************************************************** +* description: +***************************************************/ +int +sbr_attach_group_array () +{ + g_res_group_array = + (spl_app_res_group_array *) sbr_lookup_mzone (SPL_RES_GROUP_ARRAY); + if (!g_res_group_array) + { + NSPOL_LOGERR ("attach g_res_group_array failed"); + return -1; + } + + return 0; +} + +/*************************************************** +* description: +***************************************************/ +int +spl_add_instance_res_group (u32 thread_index, spl_app_res_group * group) +{ + if (thread_index >= MAX_THREAD_NUM) + { + NSPOL_LOGERR + ("thread_index >= MAX_THREAD_NUM]thread_index=%u, MAX_THREAD_NUM=%u", + thread_index, MAX_THREAD_NUM); + return -1; + } + + if (g_res_group_array->res_group[thread_index] != NULL) + { + NSPOL_LOGERR + ("g_res_group_array in thread_index is not NULL, this can not happen"); + return -1; + } + + g_res_group_array->res_group[thread_index] = group; + __sync_add_and_fetch (&g_res_group_array->thread_num, 1); + return 0; +} + +/*************************************************** +* description: +***************************************************/ +int +spl_add_mbox (mring_handle mbox_array[], u32 array_size) +{ + if (array_size != SPL_MSG_BOX_NUM) + { + NSPOL_LOGERR ("array_size must be %u, but not", SPL_MSG_BOX_NUM); + return -1; + } + + u32 i; + for (i = 0; i < array_size; ++i) + { + g_spl_app_res_group->mbox_array[i] = mbox_array[i]; + } + + return 0; +} + +/***************************************************************************** +* Prototype : spl_create_group +* Description : create group +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +spl_app_res_group * +spl_create_group () +{ + spl_app_res_group *group = + (spl_app_res_group *) sbr_create_mzone (SPL_APP_RES_GROUP_NAME, + sizeof (spl_app_res_group)); + if (!group) + { + NSPOL_LOGERR ("Create app_res_group zone fail]name=%s, size=%u", + SPL_APP_RES_GROUP_NAME, sizeof (spl_app_res_group)); + return NULL; + } + + group->msg_pool = NULL; + group->conn_pool = NULL; + group->conn_array = NULL; + group->recv_ring_pool = NULL; + + u32 i; + for (i = 0; i < SBR_TX_POOL_NUM; ++i) + { + group->tx_pool_array[i] = NULL; + } + + for (i = 0; i < SPL_MSG_BOX_NUM; ++i) + { + group->mbox_array[i] = NULL; + } + + group->extend_member_bit = 0; + + NSPOL_LOGINF (SC_DPDK_INFO, "Create app_res_group zone ok]name=%s, size=%u", + SPL_APP_RES_GROUP_NAME, sizeof (spl_app_res_group)); + MEM_STAT (SPL_APP_RES, SPL_APP_RES_GROUP_NAME, NSFW_SHMEM, + sizeof (spl_app_res_group)); + return group; +} + +/***************************************************************************** +* Prototype : _spl_create_ring_pool +* Description : create ring pool +* Input : char* pool_name +* char* array_name +* nsfw_mpool_type type +* Output : None +* Return Value : static inline mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +static inline mring_handle +_spl_create_ring_pool (char *pool_name, char *array_name, + nsfw_mpool_type type, u32 num, u32 ring_size) +{ + mring_handle pool = sbr_create_ring (pool_name, num - 1); + + if (!pool) + { + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "Create ring pool ok]name=%s, num=%u, size=%d", + pool_name, num, nsfw_mem_get_len (pool, NSFW_MEM_RING)); + MEM_STAT (SPL_APP_RES, pool_name, NSFW_SHMEM, + nsfw_mem_get_len (pool, NSFW_MEM_RING)); + + mring_handle *array = malloc (num * sizeof (mring_handle)); + if (!array) + { + NSPOL_LOGERR ("malloc fail]size=%u", num * sizeof (mring_handle)); + return NULL; + } + + if (sbr_create_multi_ring (array_name, ring_size - 1, num, + array, type) != 0) + { + free (array); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "Create multi rings ok]name=%s, ring_size=%u, ring_num=%u, total_mem=%d", + array_name, ring_size, num, + (nsfw_mem_get_len (array[0], NSFW_MEM_RING) * num)); + MEM_STAT (SPL_APP_RES, array_name, NSFW_SHMEM, + nsfw_mem_get_len (array[0], NSFW_MEM_RING) * num); + + unsigned int i = 0; + while (i < num) + { + if (nsfw_mem_ring_enqueue (pool, (void *) array[i]) != 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + free (array); + return NULL; + } + + i++; + } + + free (array); + return pool; +} + +/***************************************************************************** +* Prototype : spl_create_ring_pool +* Description : create ring pool +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_create_ring_pool (spl_app_res_group * group) +{ + group->recv_ring_pool = + _spl_create_ring_pool (SPL_RECV_RING_POOL_NAME, SPL_RECV_RING_ARRAY_NAME, + NSFW_MRING_SPSC, CUR_CFG_SOCKET_NUM, + SPL_MAX_RING_SIZE); + if (!group->recv_ring_pool) + { + NSPOL_LOGERR ("Create recv ring pool failed"); + return -1; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "Create recv ring pool ok]name=%s", + SPL_RECV_RING_POOL_NAME); + return 0; +} + +int +spl_force_netconn_free (void *data) +{ + spl_netconn_t *conn = (spl_netconn_t *) data; + if (TRUE == conn->res_chk.alloc_flag) + { + if (NULL != conn->recycle.accept_from) + { + return FALSE; + } + + if (TRUE != nsfw_pidinfo_empty (&conn->recycle.pid_info)) + { + return FALSE; + } + } + ss_reset_conn (conn); + (void) res_free (&conn->res_chk); + + if (nsfw_mem_ring_enqueue (ss_get_conn_pool (conn), (void *) conn) != 1) + { + NSSBR_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + } + NSFW_LOGINF ("force free conn]conn=%p", conn); + return TRUE; +} + +/***************************************************************************** +* Prototype : spl_create_netconn_pool +* Description : create netconn pool +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_create_netconn_pool (spl_app_res_group * group) +{ + spl_netconn_t **conn_array = + (spl_netconn_t **) sbr_create_mzone (SPL_CONN_ARRAY_NAME, + sizeof (spl_netconn_t *) * + CUR_CFG_SOCKET_NUM); + + if (!conn_array) + { + return -1; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "Create connn_array zone ok]name=%s, size=%zu", + SPL_CONN_ARRAY_NAME, + sizeof (spl_netconn_t *) * CUR_CFG_SOCKET_NUM); + mring_handle pool = + sbr_create_pool (SPL_CONN_POOL_NAME, CUR_CFG_SOCKET_NUM - 1, + SBR_FD_NETCONN_SIZE); + + if (!pool) + { + return -1; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "Create conn_pool ok]name=%s, num=%u, total_mem=%d", + SPL_CONN_POOL_NAME, CUR_CFG_SOCKET_NUM, + nsfw_mem_get_len (pool, NSFW_MEM_SPOOL)); + + sbr_recycle_group *recycle_group = + (sbr_recycle_group *) sbr_create_mzone (SPL_RECYCLE_GROUP, + sizeof (sbr_recycle_group)); + if (!recycle_group) + { + return -1; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "Create recycle_group zone ok]name=%s, size=%u", + SPL_RECYCLE_GROUP, sizeof (sbr_recycle_group)); + + recycle_group->conn_array = conn_array; + recycle_group->conn_num = spl_get_conn_num (); + recycle_group->conn_pool = pool; + recycle_group->extend_member_bit = 0; + recycle_group->msg_pool = group->msg_pool; + + spl_netconn_t *conn = NULL; + unsigned int i = 0; + while (i < CUR_CFG_SOCKET_NUM) + { + if (nsfw_mem_ring_dequeue (pool, (void **) &conn) != 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_dequeue failed,this can not happen"); + return -1; + } + + ss_reset_conn (conn); + conn->recycle.group = recycle_group; + + if (nsfw_mem_ring_dequeue (group->recv_ring_pool, &conn->recv_ring) != + 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_dequeue failed,this can not happen"); + return -1; + } + + conn_array[i] = conn; + + if (nsfw_mem_ring_enqueue (pool, (void *) conn) != 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + return -1; + } + + i++; + } + + group->conn_pool = pool; + group->conn_array = conn_array; + + MEM_STAT (SPL_APP_RES, SPL_RECYCLE_GROUP, NSFW_SHMEM, + sizeof (sbr_recycle_group)); + MEM_STAT (SPL_APP_RES, SPL_CONN_ARRAY_NAME, NSFW_SHMEM, + sizeof (spl_netconn_t *) * CUR_CFG_SOCKET_NUM); + MEM_STAT (SPL_APP_RES, SPL_CONN_POOL_NAME, NSFW_SHMEM, + nsfw_mem_get_len (group->conn_pool, NSFW_MEM_SPOOL)); + return 0; +} + +int +spl_force_msg_free (void *data) +{ + data_com_msg *m = (data_com_msg *) data; + if (NULL == m) + { + return FALSE; + } + + NSFW_LOGINF ("force free msg]msg=%p", data); + (void) res_free (&m->param.res_chk); + m->param.recycle_pid = 0; + if (nsfw_mem_ring_enqueue (m->param.msg_from, (void *) m) != 1) + { + NSFW_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + } + return TRUE; +} + +/***************************************************************************** +* Prototype : spl_create_msg_pool +* Description : create msg pool +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_create_msg_pool (spl_app_res_group * group) +{ + mring_handle pool = + sbr_create_pool (SPL_MSG_POOL_NAME, SPL_MAX_MSG_NUM - 1, MAX_MSG_SIZE); + + if (!pool) + { + return -1; + } + + data_com_msg *m = NULL; + unsigned int i = 0; + while (i < SPL_MAX_MSG_NUM) + { + if (nsfw_mem_ring_dequeue (pool, (void **) &m) != 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_dequeue failed,this can not happen"); + return -1; + } + + m->param.msg_from = pool; + m->param.recycle_pid = 0; + sys_sem_init (&m->param.op_completed); + + if (nsfw_mem_ring_enqueue (pool, (void *) m) != 1) + { + NSPOL_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + return -1; + } + + i++; + } + + group->msg_pool = pool; + + NSPOL_LOGINF (SC_DPDK_INFO, + "Create app msg pool ok]name=%s, num=%u, size=%u, total_mem=%d", + SPL_MSG_POOL_NAME, SPL_MAX_MSG_NUM, MAX_MSG_SIZE, + nsfw_mem_get_len (group->msg_pool, NSFW_MEM_SPOOL)); + MEM_STAT (SPL_APP_RES, SPL_MSG_POOL_NAME, NSFW_SHMEM, + nsfw_mem_get_len (group->msg_pool, NSFW_MEM_SPOOL)); + return 0; +} + +/***************************************************************************** +* Prototype : spl_regist_recycle +* Description : regist recycle +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_regist_recycle (spl_app_res_group * group) +{ + void *ret = + nsfw_recycle_reg_obj (NSFW_REC_PRO_DEFAULT, NSFW_REC_SBR_SOCKET, NULL); + + if (!ret) + { + NSSBR_LOGERR ("failed"); + return -1; + } + + if (NULL == group) + { + NSSBR_LOGERR ("g_spl_app_res_group null"); + return -1; + } + + nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_SPOOL, 90, 3, 16, + CUR_CFG_SOCKET_NUM / 128, CUR_CFG_SOCKET_NUM - 1, + SBR_FD_NETCONN_SIZE, + offsetof (spl_netconn_t, res_chk), + (void *) group->conn_pool, + (void *) group->conn_pool, + spl_force_netconn_free + }; + + (void) nsfw_res_mgr_reg (&scn_cfg); + + nsfw_res_scn_cfg scn_cfg_msg = { NSFW_RES_SCAN_SPOOL, 60, 3, 16, + SPL_MAX_MSG_NUM / 128, SPL_MAX_MSG_NUM, + MAX_MSG_SIZE, + offsetof (data_com_msg, param.res_chk), + (void *) group->msg_pool, + (void *) group->msg_pool, + spl_force_msg_free + }; + (void) nsfw_res_mgr_reg (&scn_cfg_msg); + + return 0; +} + +void +spl_reg_tx_pool_mgr (mpool_handle pool_array[], u32 num) +{ + u32 loop; + for (loop = 0; loop < num; loop++) + { + (void) spl_reg_res_txrx_mgr (pool_array[loop]); // will only return 0, no need to check return value + } + + return; +} + +/***************************************************************************** +* Prototype : sbr_create_tx_pool +* Description : create tx pool,spl call this fun +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_create_tx_pool (mpool_handle pool_array[], u32 array_size) +{ + data_com_msg *tx_msg_array = + (data_com_msg *) sbr_create_mzone (SBR_TX_MSG_ARRAY_NAME, + (size_t) sizeof (data_com_msg) * + SBR_TX_MSG_NUM); + + if (!tx_msg_array) + { + NSSBR_LOGERR ("Create tx_msg_array zone fail]name=%s, num=%u, size=%u", + SBR_TX_MSG_ARRAY_NAME, SBR_TX_MSG_NUM, + (size_t) sizeof (data_com_msg) * SBR_TX_MSG_NUM); + return -1; + } + + MEM_STAT (SBR_TX_POOL_NAME, SBR_TX_MSG_ARRAY_NAME, NSFW_SHMEM, + (size_t) sizeof (data_com_msg) * SBR_TX_MSG_NUM); + NSSBR_LOGINF + ("Create tx_msg_array zone ok]name=%s, ptr=%p, num=%u, size=%u", + SBR_TX_MSG_ARRAY_NAME, tx_msg_array, SBR_TX_MSG_NUM, + sizeof (data_com_msg) * SBR_TX_MSG_NUM); + + mpool_handle mp; + int ret; + char tx_pool_name[64]; + u32 loop; + for (loop = 0; loop < array_size; loop++) + { + ret = + SPRINTF_S (tx_pool_name, sizeof (tx_pool_name), "%s_%d", + SBR_TX_POOL_NAME, loop); + if (-1 == ret) + { + NSSBR_LOGERR ("SPRINTF_S failed]ret=%d", ret); + return -1; + } + + nsfw_mem_mbfpool pool_param; + if (STRCPY_S + (pool_param.stname.aname, NSFW_MEM_NAME_LENTH, tx_pool_name) != 0) + { + NSSBR_LOGERR ("STRCPY_S failed]name=%s", tx_pool_name); + return -1; + } + + pool_param.isocket_id = -1; + pool_param.stname.entype = NSFW_SHMEM; + pool_param.enmptype = NSFW_MRING_MPMC; + pool_param.uscash_size = 0; + pool_param.uspriv_size = 0; + pool_param.usdata_room = TX_MBUF_MAX_LEN; + pool_param.usnum = SBR_TX_POOL_MBUF_NUM - 1; + + mp = nsfw_mem_mbfmp_create (&pool_param); + if (!mp) + { + NSSBR_LOGERR ("Create tx_mbuf_pool fail]name=%s, num=%u, room=%u", + tx_pool_name, SBR_TX_POOL_MBUF_NUM, + pool_param.usdata_room); + return -1; + } + else + { + struct common_mem_mbuf *mbuf = NULL; + struct spl_pbuf *buf = NULL; + int i = 0; + while (i < (int) SBR_TX_POOL_MBUF_NUM) + { + mbuf = nsfw_mem_mbf_alloc (mp, NSFW_SHMEM); + if (!mbuf) + { + NSSBR_LOGERR + ("nsfw_mem_mbf_alloc failed,this can not happen"); + return -1; + } + + buf = + (struct spl_pbuf *) ((char *) mbuf + + sizeof (struct common_mem_mbuf)); + int idx = loop * (int) SBR_TX_POOL_MBUF_NUM + i; + sys_sem_init (&tx_msg_array[idx].param.op_completed); + tx_msg_array[idx].param.msg_from = NULL; + buf->msg = (void *) &tx_msg_array[idx]; + (void) res_free (&buf->res_chk); //no need to check return value, as it will do free operation depends on alloc_flag + + if (nsfw_mem_mbf_free (mbuf, NSFW_SHMEM) < 0) + { + NSSBR_LOGERR + ("nsfw_mem_mbf_free failed,this can not happen"); + return -1; + } + + i++; + } + + pool_array[loop] = mp; +#ifdef SYS_MEM_RES_STAT + g_app_tx_pool[loop] = mp; +#endif + } + } + + spl_reg_tx_pool_mgr (pool_array, array_size); + + NSSBR_LOGINF ("Create all tx_mbuf_pool ok]pool_num=%d, total_mem=%d", + array_size, nsfw_mem_get_len (pool_array[0], + NSFW_MEM_MBUF) * array_size); + MEM_STAT (SBR_TX_POOL_NAME, SBR_TX_POOL_NAME, NSFW_SHMEM, + nsfw_mem_get_len (pool_array[0], NSFW_MEM_MBUF) * array_size); + return 0; +} + +spl_app_res_group * +spl_create_res_group () +{ + spl_app_res_group *group = spl_create_group (); + if (NULL == group) + { + NSPOL_LOGERR ("spl_create_group failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_create_group ok"); + + if (spl_create_ring_pool (group) != 0) + { + NSPOL_LOGERR ("spl_create_ring_pool failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_create_ring_pool ok"); + + if (spl_create_msg_pool (group) != 0) + { + NSPOL_LOGERR ("spl_create_msg_pool failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_create_msg_pool ok"); + + if (spl_create_netconn_pool (group) != 0) + { + NSPOL_LOGERR ("spl_create_netconn_pool failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_create_netconn_pool ok"); + + if (spl_regist_recycle (group) != 0) + { + NSPOL_LOGERR ("spl_regist_recycle failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_regist_recycle ok"); + + if (spl_create_tx_pool (group->tx_pool_array, SBR_TX_POOL_NUM) != 0) + { + NSPOL_LOGERR ("spl_create_tx_pool failed"); + return NULL; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "spl_create_tx_pool ok"); + + return group; +} + +/***************************************************************************** +* Prototype : spl_init_app_res +* Description : init app res +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +spl_init_app_res () +{ + g_spl_app_res_group = spl_create_res_group (); + if (NULL == g_spl_app_res_group) + { + NSPOL_LOGERR ("spl_create_group failed"); + return -1; + } + + return spl_add_instance_res_group (0, g_spl_app_res_group); +} + +/***************************************************************************** +* Prototype : spl_get_conn_array +* Description : get conn array +* Input : u32 pid +* Output : None +* Return Value : spl_netconn_t** +* Calls : +* Called By : +* +*****************************************************************************/ +spl_netconn_t ** +spl_get_conn_array (u32 pid) +{ + return (spl_netconn_t **) ADDR_SHTOL (g_spl_app_res_group->conn_array); +} + +/***************************************************************************** +* Prototype : spl_get_conn_pool +* Description : get conn pool +* Input : None +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +spl_get_conn_pool () +{ + return (mring_handle) ADDR_SHTOL (g_spl_app_res_group->conn_pool); +} + +/***************************************************************************** +* Prototype : spl_get_msg_pool +* Description : get msg pool +* Input : None +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +spl_get_msg_pool () +{ + return (mring_handle) ADDR_SHTOL (g_spl_app_res_group->msg_pool); +} + +/***************************************************************************** +* Prototype : spl_recycle_msg +* Description : recycle msg +* Input : void *data +* void* argv +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +spl_recycle_msg (void *data, void *argv) +{ + if (!data) + { + NSPOL_LOGERR ("data is NULL]data=%p,pid=%p", data, argv); + return -1; + } + + data_com_msg *m = (data_com_msg *) data; + u64 pid_64 = (u64) argv; + u32 pid = (u32) pid_64; + if (pid == m->param.recycle_pid) + { + ASYNC_MSG_FREE (m); + } + + return 0; +} + +/***************************************************************************** +* Prototype : spl_recycle_msg_pool +* Description : recycle msg pool +* Input : u32 pid +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +spl_recycle_msg_pool (u32 pid) +{ + mring_handle msg_pool = spl_get_msg_pool (); + if (!msg_pool) + { + NSPOL_LOGERR ("msg_pool is NULL,this can not happen]pid=%u", pid); + return; + } + + u64 pid_64 = pid; + (void) nsfw_mem_sp_iterator (msg_pool, 0, SPL_MAX_MSG_NUM, spl_recycle_msg, + (void *) pid_64); +} + +/***************************************************************************** +* Prototype : spl_get_conn_num +* Description : get conn num +* Input : None +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +spl_get_conn_num () +{ + return CUR_CFG_SOCKET_NUM; +} + +/*************************************************** +* description: +***************************************************/ +int +sbr_malloc_tx_pool (u32 pid, mpool_handle pool[], u32 pool_num) +{ + int loop; + for (loop = 0; loop < SBR_TX_POOL_NUM; loop++) + { + if ((0 == g_res_group_array->pid_array[loop]) + && + __sync_bool_compare_and_swap (&g_res_group_array->pid_array[loop], + 0, pid)) + { + u32 i; + for (i = 0; i < g_res_group_array->thread_num && i < pool_num; ++i) + { + spl_app_res_group *group = + (spl_app_res_group *) + ADDR_SHTOL (g_res_group_array->res_group[i]); + pool[i] = ADDR_SHTOL (group->tx_pool_array[loop]); + } + + NSSBR_LOGINF ("get tx pool]pid=%d,loop=%d.", pid, loop); + return 0; + } + } + + for (loop = 0; loop < SBR_TX_POOL_NUM; loop++) + { + NSSBR_LOGERR ("no free pool]loop=%d,pid=%d", loop, + g_res_group_array->pid_array[loop]); + } + + return -1; +} + +/*************************************************** +* description: +***************************************************/ +void +spl_free_tx_pool (u32 pid) +{ + int loop; + for (loop = 0; loop < SBR_TX_POOL_NUM; loop++) + { + if (pid == g_res_group_array->pid_array[loop]) + { + u32 i; + for (i = 0; i < g_res_group_array->thread_num; ++i) + { + (void) + nsfw_mem_mbuf_pool_recycle (g_res_group_array->res_group + [i]->tx_pool_array[loop]); + } + + if (!__sync_bool_compare_and_swap + (&g_res_group_array->pid_array[loop], pid, 0)) + { + NSSBR_LOGERR ("free tx_pool failed]loop=%d,pid=%d", loop, pid); + } + else + { + NSSBR_LOGDBG ("free tx_pool ok]loop=%d,pid=%d", loop, pid); + } + + break; + } + } +} + +/*************************************************** +* description: +***************************************************/ +mring_handle +sbr_get_instance_conn_pool (u32 thread_index) +{ + if (thread_index >= g_res_group_array->thread_num) + { + return NULL; + } + + spl_app_res_group *group = + (spl_app_res_group *) + ADDR_SHTOL (g_res_group_array->res_group[thread_index]); + return ADDR_SHTOL (group->conn_pool); +} + +/*************************************************** +* description: +***************************************************/ +mring_handle * +ss_get_instance_msg_box (u16 thread_index, u16 idx) +{ + if (thread_index >= g_res_group_array->thread_num) + { + thread_index = 0; + } + + if (idx >= SPL_MSG_BOX_NUM) + { + idx = 0; + } + + spl_app_res_group *group = + (spl_app_res_group *) + ADDR_SHTOL (g_res_group_array->res_group[thread_index]); + return ADDR_SHTOL (group->mbox_array[idx]); +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_app_res.h b/stacks/lwip_stack/lwip_src/common/stackx_app_res.h new file mode 100644 index 0000000..435f2f6 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_app_res.h @@ -0,0 +1,103 @@ +/* +* +* 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 STACKX_APP_RES_H +#define STACKX_APP_RES_H +#include "types.h" +#include "nsfw_mem_api.h" +#include "stackxopts.h" +#include "stackx_spl_share.h" +#include "nsfw_mt_config.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define SPL_RES_GROUP_ARRAY "spl_res_group_array" + +#define SPL_APP_RES "spl_app_res" +#define SPL_APP_RES_GROUP_NAME "spl_app_res_group" +#define SPL_TX_POOL_NAME "spl_tx_pool" +#define SPL_CONN_POOL_NAME "spl_conn_pool" +#define SPL_CONN_ARRAY_NAME "spl_conn_array" +#define SPL_DFX_ARRAY_NAME "spl_dfx_array" +#define SPL_MSG_POOL_NAME "spl_msg_pool" +#define SPL_RECYCLE_GROUP "spl_recycle_group" +#define SPL_RECV_RING_POOL_NAME "spl_recv_ring_pool" +#define SPL_RECV_RING_ARRAY_NAME "spl_recv_array" + +#define SBR_TX_POOL_NUM APP_POOL_NUM +#define SBR_TX_POOL_MBUF_NUM TX_MBUF_POOL_SIZE +#define SBR_TX_MSG_NUM (SBR_TX_POOL_NUM * SBR_TX_POOL_MBUF_NUM) + +#define SBR_TX_POOL_ARRAY_NAME "sbr_tx_pool_array" +#define SBR_TX_POOL_NAME "sbr_tx_pool" +#define SBR_TX_MSG_ARRAY_NAME "sbr_tx_msg_array" + +#define SPL_MAX_MSG_NUM (MBOX_RING_SIZE*8*MAX_THREAD_NUM) + +typedef struct +{ + PRIMARY_ADDR mring_handle msg_pool; + PRIMARY_ADDR mring_handle conn_pool; + PRIMARY_ADDR spl_netconn_t **conn_array; + PRIMARY_ADDR mring_handle recv_ring_pool; + PRIMARY_ADDR mpool_handle tx_pool_array[SBR_TX_POOL_NUM]; + PRIMARY_ADDR mring_handle mbox_array[SPL_MSG_BOX_NUM]; + i64 extend_member_bit; +} spl_app_res_group; + +typedef struct +{ + u32 pid_array[SBR_TX_POOL_NUM]; + PRIMARY_ADDR spl_app_res_group *res_group[MAX_THREAD_NUM]; + u16 thread_num; +} spl_app_res_group_array; + +extern spl_app_res_group *g_spl_app_res_group; +extern spl_app_res_group_array *g_res_group_array; + +/* call it main thread */ +int spl_init_group_array (); + +/* call these in tcpip thread */ +int spl_init_app_res (); +spl_netconn_t **spl_get_conn_array (u32 pid); +mring_handle spl_get_conn_pool (); +mring_handle spl_get_msg_pool (); +void spl_recycle_msg_pool (u32 pid); +u32 spl_get_conn_num (); +void spl_free_tx_pool (u32 pid); +int spl_add_mbox (mring_handle mbox_array[], u32 array_size); +int spl_add_instance_res_group (u32 thread_index, spl_app_res_group * group); + +/* call these in app */ +int sbr_malloc_tx_pool (u32 pid, mpool_handle pool[], u32 pool_num); +int sbr_attach_group_array (); +mring_handle sbr_get_instance_conn_pool (u32 thread_index); + +/* call these in app and spl */ +mring_handle *ss_get_instance_msg_box (u16 thread_index, u16 index); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common.c b/stacks/lwip_stack/lwip_src/common/stackx_common.c new file mode 100644 index 0000000..750df74 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_common.c @@ -0,0 +1,357 @@ +/* +* +* 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 <stdarg.h> +#include <stddef.h> +#include "stackx_common.h" +#include "nstack_securec.h" +#include "nstack_log.h" +#include "types.h" +#include "stackx_types.h" + +int +spl_snprintf (char *buffer, int buflen, const char *format, ...) +{ + int len; + va_list ap; + + if ((NULL == buffer) || (0 >= buflen)) + { + return -1; + } + + if (format == NULL) + { + buffer[0] = '\0'; + return -1; + } + + (void) va_start (ap, format); + len = VSNPRINTF_S (buffer, buflen, buflen - 1, format, ap); + if (-1 == len) + { + va_end (ap); + return -1; + } + + va_end (ap); + if ((len >= buflen) && (buflen > 0) && (buffer != NULL)) + { + buffer[buflen - 1] = '\0'; + } + + return len; +} + +/***************************************************************************** +* Prototype : sbr_create_mzone +* Description : create mzone +* Input : const char* name +* size_t size +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +sbr_create_mzone (const char *name, size_t size) +{ + if (!name) + { + NSFW_LOGERR ("name is NULL"); + return NULL; + } + + mzone_handle zone; + nsfw_mem_zone param; + + param.isocket_id = -1; + param.length = size; + param.stname.entype = NSFW_SHMEM; + + if (STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSFW_LOGERR ("STRCPY_S failed]name=%s", name); + return NULL; + } + + zone = nsfw_mem_zone_create (¶m); + if (!zone) + { + NSFW_LOGERR ("nsfw_mem_zone_create failed]name=%s, size:%zu", name, + size); + return NULL; + } + + return zone; +} + +/***************************************************************************** +* Prototype : sbr_lookup_mzone +* Description : lookup mzone +* Input : const char* name +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +sbr_lookup_mzone (const char *name) +{ + if (!name) + { + NSFW_LOGERR ("name is NULL"); + return NULL; + } + + mzone_handle zone; + nsfw_mem_name param; + + param.entype = NSFW_SHMEM; + param.enowner = NSFW_PROC_MAIN; + if (STRCPY_S (param.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSFW_LOGERR ("STRCPY_S failed]name=%s", name); + return NULL; + } + + zone = nsfw_mem_zone_lookup (¶m); + if (!zone) + { + NSFW_LOGERR ("nsfw_mem_zone_lookup failed]name=%s", name); + return NULL; + } + + return zone; +} + +/***************************************************************************** +* Prototype : sbr_create_pool +* Description : create pool +* Input : const char* name +* i32 num +* u16 size +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +sbr_create_pool (const char *name, i32 num, u16 size) +{ + if (!name) + { + NSFW_LOGERR ("name is NULL"); + return NULL; + } + + nsfw_mem_sppool param; + if (EOK != MEMSET_S (¶m, sizeof (param), 0, sizeof (param))) + { + NSFW_LOGERR ("memset error]name=%s", name); + return NULL; + } + + param.enmptype = NSFW_MRING_MPMC; + param.useltsize = size; + param.usnum = num; + param.stname.entype = NSFW_SHMEM; + param.isocket_id = -1; + if (STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSFW_LOGERR ("STRCPY_S failed]name=%s", name); + return NULL; + } + + mring_handle ring = nsfw_mem_sp_create (¶m); + if (!ring) + { + NSFW_LOGERR ("Create pool failed]name=%s, num=%d, size=%u", name, num, + size); + } + + return ring; +} + +/***************************************************************************** +* Prototype : sbr_create_ring +* Description : create ring +* Input : const char* name +* i32 num +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +sbr_create_ring (const char *name, i32 num) +{ + if (!name) + { + NSFW_LOGERR ("name is NULL"); + return NULL; + } + + nsfw_mem_mring param; + if (EOK != MEMSET_S (¶m, sizeof (param), 0, sizeof (param))) + { + NSFW_LOGERR ("memset error]name=%s", name); + return NULL; + } + + param.enmptype = NSFW_MRING_MPMC; + param.isocket_id = -1; + param.usnum = num; + param.stname.entype = NSFW_SHMEM; + + if (STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSFW_LOGERR ("STRCPY_S failed]name=%s", name); + return NULL; + } + + mring_handle ring = nsfw_mem_ring_create (¶m); + if (!ring) + { + NSFW_LOGERR ("Create ring failed]name=%s, num=%d", name, num); + } + + return ring; +} + +/***************************************************************************** +* Prototype : sbr_create_multi_ring +* Description : create multi ring +* Input : const char* name +* u32 ring_size +* i32 ring_num +* mring_handle* array +* nsfw_mpool_type type +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_create_multi_ring (const char *name, u32 ring_size, i32 ring_num, + mring_handle * array, nsfw_mpool_type type) +{ + if (!name) + { + NSFW_LOGERR ("name is NULL"); + return -1; + } + + if (!array) + { + NSFW_LOGERR ("array is NULL"); + return -1; + } + + nsfw_mem_mring param; + + if (EOK != MEMSET_S (¶m, sizeof (param), 0, sizeof (param))) + { + NSSBR_LOGERR ("Error to memset]name=%s", name); + return -1; + } + + param.enmptype = type; + param.stname.entype = NSFW_SHMEM; + if (STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSSBR_LOGERR ("STRCPY_S failed]name=%s", name); + return -1; + } + + param.usnum = ring_size; + param.isocket_id = -1; + if (nsfw_mem_sp_ring_create (¶m, array, ring_num) != 0) + { + NSSBR_LOGERR ("Create ring pool failed]name=%s, ring_num=%d", name, + ring_num); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_lookup_ring +* Description : lookup ring +* Input : const char* name +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +sbr_lookup_ring (const char *name) +{ + nsfw_mem_name param; + + param.entype = NSFW_SHMEM; + param.enowner = NSFW_PROC_MAIN; + if (STRCPY_S (param.aname, NSFW_MEM_NAME_LENTH, name) != 0) + { + NSFW_LOGERR ("STRCPY_S failed]name=%s", name); + return NULL; + } + + mring_handle ring = nsfw_mem_ring_lookup (¶m); + if (!ring) + { + NSFW_LOGERR ("lookup ring failed]name=%s", name); + } + + return ring; +} + +int +sbr_timeval2msec (struct timeval *pTime, u64 * msec) +{ + if ((pTime->tv_sec < 0) || (pTime->tv_usec < 0)) + { + NSFW_LOGERR ("time->tv_sec is nagative"); + return -1; + } + + if (STACKX_MAX_U64_NUM / 1000 < (u64_t) pTime->tv_sec) + { + NSFW_LOGERR ("tout.tv_sec is too large]tout.tv_sec=%lu", pTime->tv_sec); + return -1; + } + + u64 sec2msec = 1000 * pTime->tv_sec; + u64 usec2msec = pTime->tv_usec / 1000; + + if (STACKX_MAX_U64_NUM - sec2msec < usec2msec) + { + NSFW_LOGERR + ("nsec2msec plus sec2usec is too large]usec2msec=%lu,usec2msec=%lu", + usec2msec, sec2msec); + return -1; + } + + *msec = sec2msec + usec2msec; + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common.h b/stacks/lwip_stack/lwip_src/common/stackx_common.h new file mode 100644 index 0000000..1df97d5 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_common.h @@ -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. +*/ + +#ifndef STACKX_COMMON_H +#define STACKX_COMMON_H +#include "nsfw_mem_api.h" +//#include "lwip/cc.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +int spl_snprintf (char *buffer, int buflen, const char *format, ...); +mzone_handle sbr_create_mzone (const char *name, size_t size); +mzone_handle sbr_lookup_mzone (const char *name); +mring_handle sbr_create_pool (const char *name, i32 num, u16 size); +mring_handle sbr_create_ring (const char *name, i32 num); +int sbr_create_multi_ring (const char *name, u32 ring_size, i32 ring_num, + mring_handle * array, nsfw_mpool_type type); +mring_handle sbr_lookup_ring (const char *name); +int sbr_timeval2msec (struct timeval *pTime, u64 * msec); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h b/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h new file mode 100644 index 0000000..d2d01e5 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h @@ -0,0 +1,146 @@ +/* +* +* 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 STACKX_COMMON_OPT_H +#define STACKX_COMMON_OPT_H +#include <sys/ioctl.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#ifndef O_NONBLOCK +#define O_NONBLOCK 0X800 /* nonblocking I/O */ +#endif + +#if !defined (FIONREAD) || !defined (FIONBIO) +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_INOUT (IOC_IN | IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */ +#define _IO(x, y) (((x) << 8) | (y) | IOC_VOID) +#define _IOR(x, y, t) (IOC_OUT | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) +#define _IOW(x, y, t) (IOC_IN | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) +#endif + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) +#endif + +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) +#endif + +#ifndef F_GETFL +#define F_GETFL 3 +#endif + +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +#ifndef SPL_SHUT_RD +#define SPL_SHUT_RD 0 +#define SPL_SHUT_WR 1 +#define SPL_SHUT_RDWR 2 +#endif + +/* Flags for struct netconn.flags (u8_t) */ + +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define SPL_NETCONN_FLAG_WRITE_DELAYED 0x01 + +/** Should this netconn avoid blocking? */ +#define SPL_NETCONN_FLAG_NON_BLOCKING 0x02 + +/** Was the last connect action a non-blocking one? */ +#define SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 + +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define SPL_NETCONN_FLAG_NO_AUTO_RECVED 0x08 + +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +#define SPL_NETCONN_FLAG_CHECK_WRITESPACE 0x10 + +/* For the netconn API, these values are use as a bitmask! */ +#define SPL_NETCONN_SHUT_RD 1 +#define SPL_NETCONN_SHUT_WR 2 +#define SPL_NETCONN_SHUT_RDWR (SPL_NETCONN_SHUT_RD | SPL_NETCONN_SHUT_WR) +#define STACKX_TIMER_THREAD_SUPPORT 1 + +/* Flags for netconn_write (u8_t) */ +#define SPL_NETCONN_NOFLAG 0x00 +#define SPL_NETCONN_NOCOPY 0x00 +#define SPL_NETCONN_COPY 0x01 +#define SPL_NETCONN_MORE 0x02 +#define SPL_NETCONN_DONTBLOCK 0x04 + +#define SPL_TCP_NODELAY 0x01 +#define SPL_TCP_KEEPALIVE 0x02 +#define SPL_TCP_KEEPIDLE 0x04 +#define SPL_TCP_KEEPINTVL 0x05 +#define SPL_TCP_KEEPCNT 0x06 +#define SPL_TCP_LINGER2 0x08 +#define SPL_TCP_DEFER_ACCEPT 0x09 + +typedef enum spl_netconn_type +{ + SPL_NETCONN_INVALID = 0, + SPL_NETCONN_TCP = 0x10, + SPL_NETCONN_UDP = 0x20, + SPL_NETCONN_UDPLITE = 0x21, + SPL_NETCONN_UDPNOCHKSUM = 0x22, + SPL_NETCONN_RAW = 0x40, +} spl_netconn_type_t; + +typedef enum spl_netconn_state +{ + SPL_NETCONN_NONE, + SPL_NETCONN_WRITE, + SPL_NETCONN_LISTEN, + SPL_NETCONN_CONNECT, + SPL_NETCONN_CLOSE, +} spl_netconn_state_t; + +typedef enum spl_tcp_state +{ + SPL_CLOSED = 0, + SPL_LISTEN = 1, + SPL_SYN_SENT = 2, + SPL_SYN_RCVD = 3, + SPL_ESTABLISHED = 4, + SPL_FIN_WAIT_1 = 5, + SPL_FIN_WAIT_2 = 6, + SPL_CLOSE_WAIT = 7, + SPL_CLOSING = 8, + SPL_LAST_ACK = 9, + SPL_TIME_WAIT = 10 +} spl_tcp_state_t; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_debug.h b/stacks/lwip_stack/lwip_src/common/stackx_debug.h new file mode 100644 index 0000000..7c6395e --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_debug.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 __STACKX_DEBUG_H__ +#define __STACKX_DEBUG_H__ + +//#include "lwip/arch.h" +#include <pthread.h> + +#include <sys/syscall.h> + +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** lower two bits indicate dbug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define STACKX_DBG_LEVEL_ALL 0x00 +#define STACKX_DBG_LEVEL_OFF STACKX_DBG_LEVEL_ALL /* compatibility define only */ +#define STACKX_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define STACKX_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define STACKX_DBG_LEVEL_SEVERE 0x03 +#define STACKX_DBG_MASK_LEVEL 0x00 + +/** flag to enable that dbug message */ +#define STACKX_DBG_ON NS_LOG_STACKX_ON + +/** flag to disable that dbug message */ +#define STACKX_DBG_OFF NS_LOG_STACKX_OFF + +/** flag for indicating a tracing_message (to follow program flow) */ +#define STACKX_DBG_TRACE NS_LOG_STACKX_TRACE + +/** flag for indicating a state dbug message (to follow module states) */ +#define STACKX_DBG_STATE NS_LOG_STACKX_STATE + +/** flag for indicating newly added code, not thoroughly tested yet */ +#define STACKX_DBG_FRESH NS_LOG_STACKX_FRESH + +/** flag for to halt after printing this dbug message */ +#define STACKX_DBG_HALT NS_LOG_STACKX_HALT + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_DEBUG_H__ */ diff --git a/stacks/lwip_stack/lwip_src/common/stackx_err.h b/stacks/lwip_stack/lwip_src/common/stackx_err.h new file mode 100644 index 0000000..1d0fc20 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_err.h @@ -0,0 +1,68 @@ +/* +* +* 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 STACKX_ERR_H +#define STACKX_ERR_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ +#define ERR_INPROGRESS -5 /* Operation in progress */ +#define ERR_VAL -6 /* Illegal value. */ +#define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ +#define ERR_ISCONN -9 /* Already connected. */ + +#define SPL_ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_ABRT -10 /* Connection aborted. */ +#define ERR_RST -11 /* Connection reset. */ +#define ERR_CLSD -12 /* Connection closed. */ +#define ERR_CONN -13 /* Not connected. */ + +#define ERR_ARG -14 /* Illegal argument. */ + +#define ERR_IF -15 /* Low-level netif error */ +#define ERR_ALREADY -16 /* previous connect attemt has not yet completed */ +#define ERR_PROTOTYPE -17 /* prototype error or some other generic error. + the operation is not allowed on current socket */ + +#define ERR_CALLBACK -18 /* callback error */ +#define ERR_CANTASSIGNADDR -19 /* Cannot assign requested address */ +#define ERR_CONTAINER_ID -20 /*Illegal container id */ +#define ERR_NOTSOCK -21 /*not a socket */ + +#define ERR_CLOSE_WAIT -22 /*closed in established state */ + +#define ERR_EPROTONOSUPPORT -23 /* Protocol not supported */ + +#define ERR_FAULTRECOVERY -24 /*SPL just recovered from a fatal fault */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c new file mode 100644 index 0000000..306bcaf --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c @@ -0,0 +1,280 @@ +/* +* +* 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 <stddef.h> +#include "stackx_ip_addr.h" +#include "nstack_log.h" +#include "spl_def.h" + +/* Here for now until needed in other places in stackx*/ +#ifndef isprint +#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#endif + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IPaddress in ascii represenation (e.g. "127.0.0.1") + * @return ipaddress in network order + */ +u32 +spl_ipaddr_addr (const char *cp) +{ + spl_ip_addr_t val; + + if (spl_ipaddr_aton (cp, &val)) + { + return ip4_addr_get_u32 (&val); + } + + return (SPL_IPADDR_NONE); +} + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broad cast address. + * + * @param cp IPaddress in ascii represenation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ipaddress in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +spl_ipaddr_aton (const char *cp, spl_ip_addr_t * addr) +{ + u32 val; + u8 base; + char c; + u32 parts[4]; + u32 *pp = parts; + + if (cp == NULL) + { + return 0; + } + + c = *cp; + for (;;) + { + /* + * Get number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit (c)) + { + return (0); + } + + val = 0; + base = 10; + if (c == '0') + { + c = *++cp; + if ((c == 'x') || (c == 'X')) + { + base = 16; + c = *++cp; + } + else + { + base = 8; + } + } + + for (;;) + { + if (isdigit (c)) + { + val = (val * base) + (int) (c - '0'); + c = *++cp; + } + else if ((base == 16) && isxdigit (c)) + { + val = (val << 4) | (int) (c + 10 - (islower (c) ? 'a' : 'A')); + c = *++cp; + } + else + { + break; + } + } + + if (c == '.') + { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + { + return (0); + } + + *pp++ = val; + c = *++cp; + } + else + { + break; + } + } + + /* + * Check for trailing characters. + */ + if ((c != '\0') && !isspace (c)) + { + return (0); + } + + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) + { + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) + { + return (0); + } + + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + { + return (0); + } + + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + { + return (0); + } + + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + default: + NSPOL_LOGERR ("unhandled"); + + return (0); + } + + if (addr) + { + ip4_addr_set_u32 (addr, spl_htonl (val)); + } + + return (1); +} + +/** + * Convert numeric IPaddress into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ipaddress in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * represenation of addr + */ +char * +spl_ipaddr_ntoa (const spl_ip_addr_t * addr) +{ + static char str[16]; + + return spl_ipaddr_ntoa_r (addr, str, 16); +} + +/** + * Same as spl_ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ipaddress in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char * +spl_ipaddr_ntoa_r (const spl_ip_addr_t * addr, char *buf, int buflen) +{ + u32 s_addr; + char inv[3]; + char *rp; + u8 *ap; + u8 rem; + u8 n; + u8 i; + int len = 0; + + s_addr = ip4_addr_get_u32 (addr); + + rp = buf; + ap = (u8 *) & s_addr; + for (n = 0; n < 4; n++) + { + i = 0; + do + { + rem = *ap % (u8) 10; + *ap /= (u8) 10; + inv[i++] = '0' + rem; + } + while (*ap); + + while (i--) + { + if (len++ >= buflen) + { + return NULL; + } + + *rp++ = inv[i]; + } + + if (len++ >= buflen) + { + return NULL; + } + + *rp++ = '.'; + ap++; + } + + *--rp = 0; + return buf; +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h new file mode 100644 index 0000000..9f2dc07 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h @@ -0,0 +1,82 @@ +/* +* +* 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 STACKX_IP_ADDR_H +#define STACKX_IP_ADDR_H +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +typedef struct spl_ip_addr +{ + u32 addr; +} spl_ip_addr_t; + +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) + +/** 0.0.0.0 */ +#define IPADDR_ANY ((u32_t)0x00000000UL) + +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) + +/** 255.255.255.255 */ +#define SPL_IPADDR_NONE ((u32)0xffffffffUL) + +/** Set address to IPADDR_ANY (no need for spl_htonl()) */ +#define spl_ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) + +/** Set complete address to zero */ +#define spl_ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) + +/** IPv4 only: set the IPaddress given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) + +/** IPv4 only: get the IPaddress as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) + +/** For backwards compatibility */ +#define spl_ip_ntoa(ipaddr) spl_ipaddr_ntoa(ipaddr) + +u32 spl_ipaddr_addr (const char *cp); +int spl_ipaddr_aton (const char *cp, spl_ip_addr_t * addr); + +/** returns ptr to static buffer; not reentrant! */ +char *spl_ipaddr_ntoa (const spl_ip_addr_t * addr); +char *spl_ipaddr_ntoa_r (const spl_ip_addr_t * addr, char *buf, int buflen); + +#define spl_inet_addr(cp) spl_ipaddr_addr(cp) +#define spl_inet_aton(cp, paddr) spl_ipaddr_aton(cp, (spl_ip_addr_t*)(paddr)) +#define spl_inet_ntoa(paddr) spl_ipaddr_ntoa((spl_ip_addr_t*)&(paddr)) +#define spl_inet_ntoa_r(addr, buf, buflen) spl_ipaddr_ntoa_r((spl_ip_addr_t*)&(addr), buf, buflen) + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h b/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h new file mode 100644 index 0000000..6ca2598 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h @@ -0,0 +1,146 @@ +/* +* +* 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 STACKX_IP_TOS_H +#define STACKX_IP_TOS_H +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_LOWCOST 0x02 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_MINCOST IPTOS_LOWCOST +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_ROUTINE 0x00 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) + +#define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) + +#define TC_PRIO_BESTEFFORT 0 +#define TC_PRIO_FILLER 1 +#define TC_PRIO_BULK 2 +#define TC_PRIO_INTERACTIVE_BULK 4 +#define TC_PRIO_INTERACTIVE 6 +#define TC_PRIO_CONTROL 7 +#define TC_PRIO_MAX 15 + +#define ECN_OR_COST(class ) TC_PRIO_ ## class + +static u8 stackx_ip_tos2prio[(IPTOS_TOS_MASK >> 1) + 1] = { + TC_PRIO_BESTEFFORT, + ECN_OR_COST (FILLER), + TC_PRIO_BESTEFFORT, + ECN_OR_COST (BESTEFFORT), + TC_PRIO_BULK, + ECN_OR_COST (BULK), + TC_PRIO_BULK, + ECN_OR_COST (BULK), + TC_PRIO_INTERACTIVE, + ECN_OR_COST (INTERACTIVE), + TC_PRIO_INTERACTIVE, + ECN_OR_COST (INTERACTIVE), + TC_PRIO_INTERACTIVE_BULK, + ECN_OR_COST (INTERACTIVE_BULK), + TC_PRIO_INTERACTIVE_BULK, + ECN_OR_COST (INTERACTIVE_BULK) +}; + +static inline char +stackx_rt_tos2priority (u8 tos) +{ + return stackx_ip_tos2prio[IPTOS_TOS (tos) >> 1]; +} + +typedef enum +{ + STACKX_PRIM, + STACKX_HIGH, + STACKX_MEDIUM, + STACKX_LOW +} stackx_prio; + +static inline stackx_prio +stackx_get_prio (u8 tos) +{ + if (0 == tos) + { + return STACKX_PRIM; + } + char prio = stackx_rt_tos2priority (tos); + if ((TC_PRIO_INTERACTIVE == prio)) + { + return STACKX_HIGH; + } + else if ((TC_PRIO_BESTEFFORT == prio) || (TC_PRIO_INTERACTIVE_BULK == prio)) + { + return STACKX_MEDIUM; + } + else if ((TC_PRIO_BULK == prio) || (TC_PRIO_FILLER == prio)) + { + return STACKX_LOW; + } + + return STACKX_PRIM; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/common/base/include/nsfw_getopt.h b/stacks/lwip_stack/lwip_src/common/stackx_netbuf.h index f1394cf..a8be1a7 100644 --- a/src/framework/common/base/include/nsfw_getopt.h +++ b/stacks/lwip_stack/lwip_src/common/stackx_netbuf.h @@ -14,34 +14,27 @@ * limitations under the License. */ -#ifndef NSFW_GETOPT_H -#define NSFW_GETOPT_H 1 +#ifndef STACKX_NETBUF_H +#define STACKX_NETBUF_H +#include "stackx_pbuf.h" -#if defined(__cplusplus) +#ifdef __cplusplus /* *INDENT-OFF* */ extern "C" { /* *INDENT-ON* */ #endif -#define nsfw_no_argument 0 -#define nsfw_required_argument 1 -#define nsfw_optional_argument 2 - -struct option +typedef struct spl_netbuf { - const char *name; - int has_arg; - int *flag; - int val; -}; - -int nsfw_getopt_long (int argc, char *const argv[], const char *optstring, - const struct option *longopts, int *longindex); + struct spl_pbuf *p; + spl_ip_addr_t addr; + u16 port; +} spl_netbuf; -extern char *nsfw_optarg; -extern int nsfw_optind, nsfw_opterr, nsfw_optopt; +#define netbuf_fromaddr(buf) (&((buf)->addr)) +#define netbuf_fromport(buf) ((buf)->port) -#if defined(__cplusplus) +#ifdef __cplusplus /* *INDENT-OFF* */ } /* *INDENT-ON* */ diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c new file mode 100644 index 0000000..c176a4b --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c @@ -0,0 +1,223 @@ +/* +* +* 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 "stackx_spl_share.h" +#include "stackx_pbuf.h" +#include "common_mem_mbuf.h" +#include "nstack_securec.h" +#include "nsfw_maintain_api.h" +#include "stackx_tcp_opt.h" +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif + +/***************************************************************************** +* Prototype : sbr_malloc_pbuf +* Description : malloc spl_pbuf,use it in app +* Input : mpool_handle mp +* u16 len +* u32 mbuf_data_size +* u16 offset +* Output : None +* Return Value : struct pbuf* +* Calls : +* Called By : +* +*****************************************************************************/ +struct spl_pbuf * +sbr_malloc_pbuf (mpool_handle mp, u16 len, u32 mbuf_data_size, u16 offset) +{ + if ((len < offset) || (len > mbuf_data_size)) + { + NSSBR_LOGERR ("len is invalid]len=%u", len); + return NULL; + } + + struct common_mem_mbuf *mbuf = NULL; + struct spl_pbuf *buf = NULL; + + mbuf = nsfw_mem_mbf_alloc (mp, NSFW_SHMEM); + if (unlikely (mbuf == NULL)) + { + NS_LOG_CTRL (LOG_CTRL_HUGEPAGE_ALLOC_FAIL, LOGSBR, "NSSBR", NSLOG_WAR, + "alloc mbuf failed"); + return NULL; + } + + mbuf->data_len = len; + mbuf->next = NULL; + mbuf->nb_segs = 1; + mbuf->pkt_len = len; + buf = (struct spl_pbuf *) ((char *) mbuf + sizeof (struct common_mem_mbuf)); + res_alloc (&buf->res_chk); + buf->next = 0; + void *tmp = common_pktmbuf_mtod (mbuf, void *); + buf->payload = (void *) (ADDR_LTOSH (tmp) + offset); + buf->tot_len = len - offset; + buf->len = len - offset; + buf->type = SPL_PBUF_HUGE; + buf->flags = 0; + buf->freeNext = NULL; + buf->conn_a = 0; + buf->proto_type = SPL_PBUF_PROTO_NONE; + NSSBR_LOGDBG ("malloc pbuf ok]buf=%p,PRIMARY_ADDR=%p", buf, + ADDR_LTOSH (buf)); + return buf; +} + +u32_t +spl_pbuf_copy_partial (struct spl_pbuf * buf, void *dataptr, u32_t len, + u32_t offset) +{ + struct spl_pbuf *p = buf; + u32_t buf_copy_len; + u32_t copied_total = 0; + char *databuf = (char *) dataptr; + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for (p = buf; len != 0 && p != NULL; + p = PTR_SHTOL (struct spl_pbuf *, p->next_a)) + { + if (offset != 0 && offset >= p->len) + { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } + else if (p->len - offset > len) + { + /* copy from this buffer. maybe only partially. */ + (void) common_memcpy (databuf, ADDR_SHTOL (p->payload_a + offset), + len); + copied_total += len; + break; + } + else + { + buf_copy_len = p->len - offset; + /* copy the necessary parts of the buffer */ + (void) common_memcpy (databuf, ADDR_SHTOL (p->payload_a + offset), + buf_copy_len); + + copied_total += buf_copy_len; + databuf += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + + return copied_total; +} + +int +spl_tx_force_buf_free (void *data) +{ + struct common_mem_mbuf *mbuf = data; + if (NULL == mbuf) + { + return FALSE; + } + + struct spl_pbuf *p_buf = + (struct spl_pbuf *) (((char *) mbuf) + sizeof (struct common_mem_mbuf)); + u8 tempflag = p_buf->res_chk.u8Reserve; + if ((mbuf->refcnt == 0) || (tempflag & DPDK_SEND_FLAG)) + { + return FALSE; + } + + NSFW_LOGINF ("free mbuf]%p", data); + (void) nsfw_mem_mbf_free ((mbuf_handle) mbuf, NSFW_SHMEM); + return TRUE; +} + +int +spl_force_buf_free (void *data) +{ + struct common_mem_mbuf *mbuf = data; + + if (NULL == mbuf || (mbuf->refcnt == 0)) + { + return FALSE; + } + + NSFW_LOGINF ("free mbuf]%p", data); + (void) nsfw_mem_mbf_free ((mbuf_handle) mbuf, NSFW_SHMEM); + return TRUE; +} + +int +spl_reg_res_tx_mgr (mpool_handle * pool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) pool; + if (NULL == mp) + { + return 0; + } + + nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16, + mp->size / 128, mp->size, + mp->elt_size, + sizeof (struct common_mem_mbuf) + offsetof (struct spl_pbuf, res_chk), + mp, + mp->pool_data, + spl_tx_force_buf_free + }; + (void) nsfw_res_mgr_reg (&scn_cfg); + return 0; +} + +int +spl_reg_res_rxmt_mgr (mpool_handle * pool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) pool; + if (NULL == mp) + { + return 0; + } + + nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16, + mp->size / 128, mp->size, + mp->elt_size, + sizeof (struct common_mem_mbuf) + offsetof (struct spl_pbuf, res_chk), + mp, + mp->pool_data, + spl_tx_force_buf_free + }; /*Can use same function for time */ + (void) nsfw_res_mgr_reg (&scn_cfg); + return 0; +} + +int +spl_reg_res_txrx_mgr (mpool_handle * pool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) pool; + if (NULL == mp) + { + return 0; + } + + nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16, + mp->size / 128, mp->size, + mp->elt_size, + sizeof (struct common_mem_mbuf) + offsetof (struct spl_pbuf, res_chk), + mp, + mp->pool_data, + spl_force_buf_free + }; + (void) nsfw_res_mgr_reg (&scn_cfg); + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h new file mode 100644 index 0000000..60f1772 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h @@ -0,0 +1,82 @@ +/* +* +* 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 STACKX_PBUF_H +#define STACKX_PBUF_H + +#include "common_mem_base_type.h" +#include "common_mem_mbuf.h" +#include "nsfw_mem_api.h" +#include "stackx_pbuf_comm.h" +#ifdef HAL_LIB +#else +#include "common_pal_bitwide_adjust.h" +#endif + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define NEED_ACK_FLAG 0x01 /* This spl_pbuf may have multiple references. */ +#define PBUF_FREE_FLAG 0x04 /* This spl_pbuf has been free. */ +#define DPDK_SEND_FLAG 0x10 /* This spl_pbuf has been sent to DPDK. */ +#define LOOP_SEND_FLAG 0x40 /* This spl_pbuf has been looped to IP layer and not received by app layer yet. */ + +struct spl_pbuf *sbr_malloc_pbuf (mpool_handle mp, u16 len, + u32 mbuf_data_size, u16 offset); +void sbr_free_pbuf (struct spl_pbuf *p); +u32 spl_pbuf_copy_partial (struct spl_pbuf *p, void *dataptr, u32_t len, + u32_t offset); +int spl_reg_res_txrx_mgr (mpool_handle * pool); +int spl_reg_res_tx_mgr (mpool_handle * pool); + +/* release buf hold by app on abnormal exit */ +/* + *For TX mbuf: recycle_flg can be: MBUF_UNUSED, MBUF_HLD_BY_APP, MBUF_HLD_BY_SPL. + *For TX mbuf: recycle_flg can be: MBUF_UNSUED, app pid. + */ +static inline void +pbuf_set_recycle_flg (struct spl_pbuf *p, uint32_t flg) +{ + uint32_t *recycle_flg; + struct spl_pbuf *q = p; + struct common_mem_mbuf *m; + + while (q != NULL) + { + m = + (struct common_mem_mbuf *) ((char *) q - + sizeof (struct common_mem_mbuf)); +#ifdef HAL_LIB +#else + recycle_flg = + (uint32_t *) ((char *) (m->buf_addr) + RTE_PKTMBUF_HEADROOM - + sizeof (uint32_t)); +#endif + *recycle_flg = flg; + q = (struct spl_pbuf *) ADDR_SHTOL (q->next_a); + } +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h b/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h new file mode 100644 index 0000000..6a21312 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h @@ -0,0 +1,109 @@ +/* +* +* 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 STACKX_PBUF_COMM_H +#define STACKX_PBUF_COMM_H +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define SPL_PBUF_TRANSPORT_HLEN 20 +#define SPL_PBUF_UDP_HLEN 8 +#define SPL_PBUF_IP_HLEN 20 + +#define SPL_PBUF_VLAN_HLEN 0 + +#ifndef SPL_PBUF_LINK_HLEN +#define SPL_PBUF_LINK_HLEN (14 + SPL_PBUF_VLAN_HLEN) +#endif + +typedef enum spl_pbuf_layer +{ + SPL_PBUF_TRANSPORT, + SPL_PBUF_UDP, + SPL_PBUF_IP, + SPL_PBUF_LINK, + SPL_PBUF_RAW, + SPL_PBUF_MAX_LAYER, +} spl_pbuf_layer; + +typedef enum spl_pbuf_type +{ + SPL_PBUF_RAM, /* pbuf data is stored in RAM */ + SPL_PBUF_ROM, /* pbuf data is stored in ROM */ + SPL_PBUF_REF, /* pbuf comes from the pbuf pool */ + SPL_PBUF_POOL, /* pbuf payload refers to RAM */ + SPL_PBUF_HUGE /* pbuf is stored in HugePage memory in struct common_mem_mbuf */ +} spl_pbuf_type; + +enum spl_pbuf_proto +{ + SPL_PBUF_PROTO_NONE, + SPL_PBUF_TCP_SEND, + SPL_PBUF_TCP_RECV +} spl_pbuf_proto; + +typedef struct spl_pbuf +{ + /** next pbuf in singly linked pbuf chain */ + union + { + struct spl_pbuf *next; + u64 next_a; + }; + + /** pointer to the actual data in the buffer */ + union + { + void *payload; + u64 payload_a; + }; + + union + { + void *msg; + u64 msg_a; + }; + + union + { + void *conn; + u64 conn_a; + }; + + struct spl_pbuf *freeNext; // This pointer will point to next pbuf you want to free in stackx + + u32 tot_len; + u32 len; + int proto_type; + u16 ref; + u8 type; + u8 flags; + nsfw_res res_chk; + +} spl_pbuf; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h b/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h new file mode 100644 index 0000000..119c26a --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h @@ -0,0 +1,239 @@ +/* +* +* 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 STACKX_SPL_MSG_H +#define STACKX_SPL_MSG_H +#include "nsfw_msg.h" +#include "stackx_ip_addr.h" +#include "stackx_spl_share.h" +#include "stackx_common_opt.h" +#include <sys/socket.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +enum spl_tcpip_msg_type +{ + SPL_TCPIP_NEW_MSG_API, +#if STACKX_TIMER_THREAD_SUPPORT + SPL_TCPIP_MSG_TIMER, +#endif +#if STACKX_NETIF_API + SPL_TCPIP_MSG_NETIFAPI, +#endif + SPL_TCPIP_MSG_CALLBACK, + SPL_TCPIP_MSG_IP_MODULE, + + SPL_TCPIP_MSG_MAX, //the number of enum + SPL_TCPIP_MSG_BOTTOM = MAX_MAJOR_TYPE //the max number of enum +}; + +enum api_msg_type +{ + SPL_API_DO_NEWCONN = 0, + SPL_API_DO_DELCON, + SPL_API_DO_RECV, + SPL_API_DO_GETADDR, + SPL_API_DO_BIND, + SPL_API_DO_CONNECT, + SPL_API_DO_LISTEN, + SPL_API_DO_CLOSE, + SPL_API_DO_SET_SOCK_OPT, + SPL_API_DO_GET_SOCK_OPT, + SPL_API_DO_SEND, + SPL_API_DO_WRITE, + SPL_API_DO_POST, + SPL_API_DO_SHOW, + SPL_API_DO_EXTREN_SOCK_SET, + SPL_API_DO_ENABLE_TRACE, + SPL_API_GET_PROTOCOL, + SPL_API_DO_IOCTL_OPT, + SPL_API_DO_GETSOCK_NAME, + SPL_API_DO_DUMP_L4, + SPL_API_DO_PBUF_FREE, + SPL_API_DO_APP_TOUCH, /* app send its version info to nStackMain */ + + SPL_API_MSG_MAX, //the number of enum + SPL_API_MSG_BOTTOM = MAX_MINOR_TYPE //the max number of enum +}; + +/* TODO: move thes to apporpriate file */ +#define TCP_RTO_MAX ((unsigned)(120*1000)) /* 120s */ +#define TCP_RTO_MIN ((unsigned)(200)) /* 200ms */ + +#define TCP_TIMEOUT_INIT ((unsigned)(1*1000)) /* RFC6298 2.1 initial RTO value */ +#define CONN_TCP_MEM_MIN_LINE ((TX_MBUF_POOL_SIZE)/1024) //conn level : min value of send_buf +#define CONN_TCP_MEM_DEF_LINE ((TX_MBUF_POOL_SIZE)/128) //conn level : default value of send_buf +#define CONN_TCP_MEM_MAX_LINE ((TX_MBUF_POOL_SIZE)/12) + +#define SOF_DEBUG 0x01U +#define SOF_ACCEPTCONN 0x02U +#define SOF_DONTROUTE 0x10U +#define SOF_USELOOPBACK 0x40U +#define SOF_LINGER 0x80U +#define SOF_OOBINLINE 0x0100U +#define SOF_REUSEPORT 0x0200U + +/* General structure for calling APIs*/ +typedef struct api_param_t +{ + data_com_msg *m; + i64 comm_private_data; +} api_param; + +/* SPL_API_DO_SEND */ +typedef struct +{ + PRIMARY_ADDR struct spl_pbuf *p; + spl_ip_addr_t local_ip; + spl_ip_addr_t addr; + spl_ip_addr_t srcAddr; + u16 port; + u16 srcPort; + u16 toport_chksum; + u8 tos; + u8 pad; + u8 flags; + i64 extend_member_bit; +} msg_send_buf; + +/* SPL_API_DO_BIND */ +typedef struct +{ + spl_ip_addr_t ipaddr; + u16 port; + i64 extend_member_bit; +} msg_bind; + +/* SPL_API_DO_CLOSE */ +typedef struct +{ + long time_started; + u8 shut; + i64 extend_member_bit; +} msg_close; + +/* SPL_API_DO_CONNECT */ +typedef struct +{ + spl_ip_addr_t local_ip; + spl_ip_addr_t ipaddr; + u16 port; + i64 extend_member_bit; +} msg_connect; + +/* SPL_API_DO_DELCON */ +typedef struct +{ + PRIMARY_ADDR struct spl_netconn *conn; + PRIMARY_ADDR struct spl_pbuf *buf; + long time_started; + pid_t pid; + u8 shut; + u8 msg_box_ref; /* use it for priority */ + u8 notify_omc; /* bool */ + i64 extend_member_bit; +} msg_delete_netconn; + +/* SPL_API_DO_WRITE */ +typedef struct msg_write_buf_T +{ + PRIMARY_ADDR struct spl_pbuf *p; + struct msg_write_buf_T *next; + size_t len; + u8 apiflags; + i64 extend_member_bit; +} msg_write_buf; + +/* SPL_API_DO_LISTEN */ +typedef struct +{ + mring_handle conn_pool; + u8 backlog; + i64 extend_member_bit; +} msg_listen; + +/* SPL_API_DO_NEWCONN */ +typedef struct +{ + PRIMARY_ADDR struct spl_netconn *conn; + spl_netconn_type_t type; + u8 proto; + int socket; + i64 extend_member_bit; +} msg_new_netconn; + +/* SPL_API_DO_RECV */ +typedef struct +{ + PRIMARY_ADDR struct spl_pbuf *p; + u32 len; + i64 extend_member_bit; +} msg_recv_buf; + +/* SPL_API_DO_GETSOCK_NAME */ +typedef struct +{ + struct sockaddr sock_addr; + u8 cmd; + i64 extend_member_bit; +} msg_getaddrname; + +/* SPL_API_DO_GET_SOCK_OPT,SPL_API_DO_SET_SOCK_OPT */ +typedef struct +{ + int level; + int optname; + PRIMARY_ADDR mring_handle msg_box; /* IP_TOS, spl will get new msg box for app */ + union + { + int int_optval; + //struct in_addr inaddr_optval; + //struct linger _linger; + struct timeval timeval_optval; + //ipmreq ipmreq_optval; //Multicast support later + } optval; + + u32 optlen; + i64 extend_member_bit; +} msg_setgetsockopt; + +/* SPL_API_DO_PBUF_FREE */ +typedef struct +{ + PRIMARY_ADDR struct spl_pbuf *buf; + i64 extend_member_bit; +} msg_free_buf; + +/* app send its version info to nStackMain */ +#define NSTACK_VERSION_LEN 128 +/* SPL_API_DO_APP_TOUCH */ +typedef struct +{ + u32_t hostpid; + char app_version[NSTACK_VERSION_LEN]; +} msg_app_touch; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c new file mode 100644 index 0000000..4fa91d8 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c @@ -0,0 +1,198 @@ +/* +* +* 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 "stackx_spl_msg.h" +#include "stackx_spl_share.h" +#include "nstack_log.h" +#include "nsfw_msg_api.h" +#include "nsfw_recycle_api.h" + +/***************************************************************************** +* Prototype : ss_reset_conn_recycle +* Description : reset conn recycle +* Input : netconn_recycle* recycle +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_reset_conn_recycle (netconn_recycle * recycle) +{ + recycle->accept_from = NULL; + recycle->is_listen_conn = 0; + (void) nsfw_pidinfo_init (&recycle->pid_info); + recycle->fork_ref = 0; + recycle->delay_msg = NULL; + recycle->delay_flag = SS_DELAY_STOPPED; +} + +/***************************************************************************** +* Prototype : ss_reset_conn +* Description : reset conn +* Input : spl_netconn_t* conn +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +ss_reset_conn (spl_netconn_t * conn) +{ + conn->recv_obj = 0; + conn->private_data = 0; + conn->msg_box = NULL; + conn->snd_buf = 0; + conn->epoll_flag = 0; + conn->recv_avail_prod = 0; + conn->recv_avail_cons = 0; + conn->rcvevent = 0; + conn->state = SPL_NETCONN_NONE; + conn->sendevent = 0; + conn->errevent = 0; + conn->shut_status = 0xFFFF; + conn->flags = 0; + conn->last_err = 0; + conn->CanNotReceive = 0; + conn->bind_thread_index = 0; + conn->tcp_sndbuf = 0; + conn->tcp_wmem_alloc_cnt = 0; + conn->tcp_wmem_sbr_free_cnt = 0; + conn->tcp_wmem_spl_free_cnt = 0; + conn->mss = 0; + conn->remote_port = 0; + conn->remote_ip.addr = 0; + conn->local_ip.addr = 0; + conn->local_port = 0; + conn->type = SPL_NETCONN_INVALID; + conn->tcp_state = SPL_CLOSED; + ss_reset_conn_recycle (&conn->recycle); + conn->extend_member_bit = 0; + conn->epInfo = NULL; +} + +/***************************************************************************** +* Prototype : ss_init_conn +* Description : init conn +* Input : spl_netconn_t* conn +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_init_conn (spl_netconn_t * conn, mring_handle pool, + spl_netconn_type_t type) +{ + res_alloc (&conn->res_chk); + + conn->type = type; + conn->recycle.fork_ref = 1; + conn->recv_ring_valid = 1; + sys_sem_init (&conn->close_completed); + NSSBR_LOGINF ("malloc conn ok]conn=%p,pool=%p", conn, pool); +} + +/***************************************************************************** +* Prototype : ss_malloc_conn +* Description : malloc conn, only used in spl +* Input : mring_handle pool +* netconn_type_t type +* Output : None +* Return Value : spl_netconn_t* +* Calls : +* Called By : +* +*****************************************************************************/ +spl_netconn_t * +ss_malloc_conn (mring_handle pool, spl_netconn_type_t type) +{ + spl_netconn_t *conn = NULL; + + if (nsfw_mem_ring_dequeue (pool, (void **) &conn) != 1) + { + NSSBR_LOGERR ("malloc conn failed"); + return NULL; + } + + ss_init_conn (conn, pool, type); + return conn; +} + +/***************************************************************************** +* Prototype : ss_malloc_conn_app +* Description : malloc conn, only used in app +* Input : mring_handle pool +* netconn_type_t type +* Output : None +* Return Value : spl_netconn_t* +* Calls : +* Called By : +* +*****************************************************************************/ +spl_netconn_t * +ss_malloc_conn_app (mring_handle pool, spl_netconn_type_t type) +{ + spl_netconn_t *conn = NULL; + + if (nsfw_mem_ring_dequeue (pool, (void **) &conn) != 1) + { + NSSBR_LOGERR ("malloc conn failed"); + return NULL; + } + + if (ss_add_pid (conn, get_sys_pid ()) < 0) + { + NSSBR_LOGERR ("ss_add_pid failed]conn=%p", conn); + } + + ss_init_conn (conn, pool, type); + return conn; +} + +/***************************************************************************** +* Prototype : ss_free_conn +* Description : free conn +* Input : spl_netconn_t* conn +* mring_handle pool +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +ss_free_conn (spl_netconn_t * conn) +{ + ss_reset_conn (conn); + + if (res_free (&conn->res_chk)) + { + NSFW_LOGERR ("conn refree!]conn=%p", conn); + return; + } + + mring_handle pool = ss_get_conn_pool (conn); + if (nsfw_mem_ring_enqueue (pool, (void *) conn) != 1) + { + NSSBR_LOGERR ("nsfw_mem_ring_enqueue failed,this can not happen"); + } + + NSSBR_LOGINF ("free conn ok]conn=%p,pool=%p", conn, pool); +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h new file mode 100644 index 0000000..2d35dd0 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h @@ -0,0 +1,490 @@ +/* +* +* 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 STACKX_SPL_SHARE_H +#define STACKX_SPL_SHARE_H +#include "types.h" +#include "common_mem_api.h" +#include "nsfw_mem_api.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_ip_addr.h" +#include <sys/types.h> +#include "spl_opt.h" +#include "stackx_ip_tos.h" +#include "stackx_common_opt.h" +#include "stackx_tx_box.h" +#include "pidinfo.h" +//#include "stackx_dfx_api.h" +#include "compiling_check.h" +#include "nsfw_msg.h" +#include "stackx_spl_msg.h" +#include "hal_api.h" +#include "stackx_types.h" +#include <errno.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define MSG_PRIO_QUEUE_NUM 3 +COMPAT_PROTECT (MSG_PRIO_QUEUE_NUM, 3); + +#define SPL_MSG_BOX_NUM (MSG_PRIO_QUEUE_NUM + 1) + +#define SBR_FD_NETCONN_SIZE (256 * 3) +COMPAT_PROTECT (SBR_FD_NETCONN_SIZE, 256 * 3); + +#define SS_NETCONN_SIZE (256 * 2) +#define SBR_FD_SIZE (SBR_FD_NETCONN_SIZE - SS_NETCONN_SIZE) + +typedef struct +{ + PRIMARY_ADDR mring_handle msg_pool; + PRIMARY_ADDR mring_handle conn_pool; + PRIMARY_ADDR struct spl_netconn **conn_array; + u32 conn_num; + i64 extend_member_bit; +} sbr_recycle_group; + +typedef enum +{ + SS_DELAY_STARTED, + SS_DELAY_STOPPING, + SS_DELAY_STOPPED, + SS_DELAY_AGAIN +} ss_delay_flag; + +typedef enum +{ + NORMAL_RECV_RING = 0, + CUSTOM_RECV_RING = 1, +} recv_ring_type; + +typedef struct +{ + PRIMARY_ADDR sbr_recycle_group *group; + PRIMARY_ADDR struct spl_netconn *accept_from; /* for recycle fd in listen */ + void *delay_msg; + nsfw_pidinfo pid_info; + volatile i16 fork_ref; + i8 is_listen_conn; + i8 delay_flag; +} netconn_recycle; + +typedef struct spl_netconn +{ + i64 recv_obj; + i64 comm_pcb_data; /* only used by spl */ + i64 private_data; /* only used by spl */ + PRIMARY_ADDR mring_handle msg_box; + PRIMARY_ADDR mring_handle recv_ring; + volatile u32 snd_buf; + volatile i32 epoll_flag; + /*here using prod/cons to instead recv_avail, avoid atomic oper. */ + volatile u32_t recv_avail_prod; /*the product of recv_avail */ + volatile u32_t recv_avail_cons; /*the consume of recv_avail */ + volatile i32 rcvevent; + spl_netconn_state_t state; + u16 sendevent; + u16 errevent; + volatile u16 shut_status; + u8 flags; + i8 last_err; + u8 CanNotReceive; + u8 recv_ring_valid; + u16 bind_thread_index; + u16 mss; + sys_sem_st close_completed; + mring_handle conn_pool; /* where the conn in pcb is from */ + + void *epInfo; + + /* The following shared field access rules: protocol stack process + * is responsible for writing, socket api process read only + */ + i32 send_bufsize; + i32 tcp_sndbuf; + u32 tcp_wmem_alloc_cnt; + u32 tcp_wmem_sbr_free_cnt; + volatile u32 tcp_wmem_spl_free_cnt; + u16 remote_port; + u16 local_port; + spl_ip_addr_t remote_ip; + spl_ip_addr_t local_ip; + spl_netconn_type_t type; + spl_tcp_state_t tcp_state; + + /* for recycle */ + netconn_recycle recycle; + nsfw_res res_chk; + i64 extend_member_bit; +} spl_netconn_t; /* sizeof(spl_netconn_t) need < SS_NETCONN_SIZE */ +SIZE_OF_TYPE_PLUS8_NOT_LARGER_THAN (spl_netconn_t, SS_NETCONN_SIZE); + +typedef struct +{ + /** + * it will increase after every restart which used for + * tell different runnings. + */ + u32 running_ref_no; + + /* only increased when fault to restart */ + u32 fault_ref_no; + + /* the procedures before upgrade are finished successfully */ + u32 prepare_upgrade_done; + +} spl_init_info_t; + +typedef struct netifExt +{ + struct netifExt *next; + u16_t id; + char if_name[HAL_MAX_NIC_NAME_LEN]; + hal_hdl_t hdl; + u16_t num_packets_recv; +} netifExt; + +static inline mring_handle +ss_get_msg_pool (spl_netconn_t * sh) +{ + sbr_recycle_group *group = + (sbr_recycle_group *) ADDR_SHTOL (sh->recycle.group); + return ADDR_SHTOL (group->msg_pool); +} + +static inline mring_handle +ss_get_conn_pool (spl_netconn_t * sh) +{ + sbr_recycle_group *group = + (sbr_recycle_group *) ADDR_SHTOL (sh->recycle.group); + return ADDR_SHTOL (group->conn_pool); +} + +static inline int +ss_is_nonblock_flag (spl_netconn_t * sh) +{ + return (sh->flags & SPL_NETCONN_FLAG_NON_BLOCKING) != 0; +} + +static inline int +ss_get_nonblock_flag (spl_netconn_t * sh) +{ + return ss_is_nonblock_flag (sh) ? O_NONBLOCK : 0; +} + +static inline void +ss_set_nonblock_flag (spl_netconn_t * sh, u32 flag) +{ + if (flag) + { + sh->flags |= SPL_NETCONN_FLAG_NON_BLOCKING; + } + else + { + sh->flags &= ~SPL_NETCONN_FLAG_NON_BLOCKING; + } +} + +static inline int +ss_get_last_errno (spl_netconn_t * sh) +{ + return sh->last_err; +} + +static inline i32 +ss_get_recv_event (spl_netconn_t * sh) +{ + return sh->rcvevent; +} + +static inline int +ss_can_not_recv (spl_netconn_t * sh) +{ + return sh->CanNotReceive; +} + +static inline int +ss_is_shut_rd (spl_netconn_t * sh) +{ + int status = sh->shut_status; + return ((SPL_SHUT_RD == status) || (SPL_SHUT_RDWR == status)); +} + +static inline void +ss_set_shut_status (spl_netconn_t * sh, u16 how) +{ + sh->shut_status = how; +} + +static inline u16 +ss_get_shut_status (spl_netconn_t * sh) +{ + return sh->shut_status; +} + +static inline void +ss_sub_recv_event (spl_netconn_t * sh) +{ + __sync_fetch_and_sub (&sh->rcvevent, 1); +} + +static inline void +ss_add_recv_event (spl_netconn_t * sh) +{ + __sync_fetch_and_add (&sh->rcvevent, 1); +} + +static inline i64 +ss_get_recv_obj (spl_netconn_t * sh) +{ + return sh->recv_obj; +} + +static inline i64 +ss_get_private_data (spl_netconn_t * sh) +{ + return sh->private_data; +} + +static inline i64 +ss_get_comm_private_data (spl_netconn_t * sh) +{ + return sh->comm_pcb_data; +} + +static inline int +ss_recv_ring_valid (spl_netconn_t * sh) +{ + return sh->recv_ring_valid; +} + +static inline mring_handle +ss_get_recv_ring (spl_netconn_t * sh) +{ + return (mring_handle) ADDR_SHTOL (sh->recv_ring); +} + +static inline void +ss_set_send_event (spl_netconn_t * sh, u16 value) +{ + sh->sendevent = value; +} + +static inline int +ss_is_noautorecved_flag (spl_netconn_t * sh) +{ + return (sh->flags & SPL_NETCONN_FLAG_NO_AUTO_RECVED) != 0; +} + +static inline int +ss_get_noautorecved_flag (spl_netconn_t * sh) +{ + return ss_is_noautorecved_flag (sh) ? SPL_NETCONN_FLAG_NO_AUTO_RECVED : 0; +} + +static inline void +ss_set_noautorecved_flag (spl_netconn_t * sh, u8 flag) +{ + if (flag) + { + sh->flags |= SPL_NETCONN_FLAG_NO_AUTO_RECVED; + } + else + { + sh->flags &= ~SPL_NETCONN_FLAG_NO_AUTO_RECVED; + } +} + +static inline void +ss_set_state (spl_netconn_t * sh, spl_netconn_state_t state) +{ + sh->state = state; +} + +static inline int +ss_is_write_state (spl_netconn_t * sh) +{ + return (SPL_NETCONN_WRITE == sh->state); +} + +static inline int +ss_is_listen_state (spl_netconn_t * sh) +{ + return (SPL_NETCONN_LISTEN == sh->state); +} + +static inline void +ss_sub_recv_avail (spl_netconn_t * sh, int value) +{ + sh->recv_avail_cons += value; +} + +static inline i32 +ss_get_recv_avail (spl_netconn_t * sh) +{ + return sh->recv_avail_prod - sh->recv_avail_cons; +} + +static inline u16 +ss_get_mss (spl_netconn_t * sh) +{ + return sh->mss; +} + +static inline spl_ip_addr_t * +ss_get_remote_ip (spl_netconn_t * sh) +{ + return &(sh->remote_ip); +} + +static inline u16 +ss_get_remote_port (spl_netconn_t * sh) +{ + return sh->remote_port; +} + +static inline spl_tcp_state_t +ss_get_tcp_state (spl_netconn_t * sh) +{ + return sh->tcp_state; +} + +static inline u16 +ss_get_bind_thread_index (spl_netconn_t * sh) +{ + return sh->bind_thread_index; +} + +static inline void +ss_set_bind_thread_index (spl_netconn_t * sh, u16 bind_thread_index) +{ + sh->bind_thread_index = bind_thread_index; +} + +static inline void +ss_set_msg_box (spl_netconn_t * sh, mring_handle box) +{ + sh->msg_box = (mring_handle) ADDR_LTOSH (box); +} + +static inline mring_handle +ss_get_msg_box (spl_netconn_t * sh) +{ + return (mring_handle) ADDR_SHTOL (sh->msg_box); +} + +static inline spl_ip_addr_t * +ss_get_local_ip (spl_netconn_t * sh) +{ + return &sh->local_ip; +} + +static inline void +ss_set_local_ip (spl_netconn_t * sh, u32 addr) +{ + if (!sh) + { + return; + } + sh->local_ip.addr = addr; +} + +static inline u16 +ss_get_local_port (spl_netconn_t * sh) +{ + return sh->local_port; +} + +static inline void +ss_set_local_port (spl_netconn_t * sh, u16 local_port) +{ + sh->local_port = local_port; +} + +static inline void +ss_set_accept_from (spl_netconn_t * sh, spl_netconn_t * accept_from) +{ + sh->recycle.accept_from = accept_from; +} + +static inline void +ss_set_is_listen_conn (spl_netconn_t * sh, i8 is_listen_conn) +{ + sh->recycle.is_listen_conn = is_listen_conn; +} + +static inline i32 +ss_inc_fork_ref (spl_netconn_t * sh) +{ + return __sync_add_and_fetch (&sh->recycle.fork_ref, 1); +} + +static inline i32 +ss_dec_fork_ref (spl_netconn_t * sh) +{ + return __sync_sub_and_fetch (&sh->recycle.fork_ref, 1); +} + +static inline i32 +ss_get_fork_ref (spl_netconn_t * sh) +{ + return sh->recycle.fork_ref; +} + +static inline int +ss_add_pid (spl_netconn_t * sh, pid_t pid) +{ + return nsfw_add_pid (&sh->recycle.pid_info, pid); +} + +static inline int +ss_del_pid (spl_netconn_t * sh, pid_t pid) +{ + return nsfw_del_pid (&sh->recycle.pid_info, pid); +} + +static inline int +ss_is_pid_exist (spl_netconn_t * sh, pid_t pid) +{ + return nsfw_pid_exist (&sh->recycle.pid_info, pid); +} + +static inline int +ss_is_pid_array_empty (spl_netconn_t * sh) +{ + return nsfw_pidinfo_empty (&sh->recycle.pid_info); +} + +spl_netconn_t *ss_malloc_conn (mring_handle pool, spl_netconn_type_t type); +spl_netconn_t *ss_malloc_conn_app (mring_handle pool, + spl_netconn_type_t type); +void ss_free_conn (spl_netconn_t * conn); +void ss_reset_conn (spl_netconn_t * conn); + +typedef void (*ss_close_conn_fun) (void *close_data, u32 delay_sec); +int ss_recycle_conn (void *close_data, ss_close_conn_fun close_conn); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h b/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h new file mode 100644 index 0000000..cac3dcb --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h @@ -0,0 +1,42 @@ +/* +* +* 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 __STACKX_TCP_OPT_H__ +#define __STACKX_TCP_OPT_H__ + +#include "spl_opt.h" + +/* TCP Options flags */ +#define TF_ACK_DELAY ((u32_t)0x01U) /* Delayed ACK. */ +#define TF_ACK_NOW ((u32_t)0x02U) /* Immediate ACK. */ +#define TF_WINDOWSCALING ((u32_t)0x40U) /* Window scaling option enabled */ +#define TF_INFR ((u32_t)0x04U) /* In fast recovery. */ +#define TF_TIMESTAMP ((u32_t)0x08U) /* Timestamp option enabled */ +#define TF_RXCLOSED ((u32_t)0x10U) /* rx closed by tcp_shutdown */ +#define TF_FIN ((u32_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((u32_t)0x100U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((u32_t)0x80U) + +/* TCP segment Options flags */ +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ +#define TF_SEG_OPTS_WS (u8_t)0x08U /* Include window scaling option. */ + +#define STACKX_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ + (flags & TF_SEG_OPTS_TS ? 12 : 0) + \ + (flags & TF_SEG_OPTS_WS ? 4 : 0) +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c new file mode 100644 index 0000000..74673ad --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c @@ -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. +*/ + +#include "stackxopts.h" +#include "nstack_log.h" +#include "stackx_tx_box.h" +#include "nsfw_mt_config.h" + +#define MZ_STACKX_RING_NAME "VppTCP_Ring" +#define MZ_STACKX_PRIORITY_RING_NAME "VppTCP_Priority%u_Ring" + +/* + * Given the stackx ring name template above, get the queue name + */ +const char * +get_stackx_ring_name () +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) */ + static char rbuffer[sizeof (MZ_STACKX_RING_NAME) + 16]; + + int retVal = + spl_snprintf (rbuffer, sizeof (rbuffer) - 1, MZ_STACKX_RING_NAME); + + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return rbuffer; +} + +const char * +get_stackx_priority_ring_name (unsigned priority) +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) */ + static char prbuffer[sizeof (MZ_STACKX_PRIORITY_RING_NAME) + 32]; + + int retVal = spl_snprintf (prbuffer, sizeof (prbuffer) - 1, + MZ_STACKX_PRIORITY_RING_NAME, priority); + + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return prbuffer; +} diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h new file mode 100644 index 0000000..edfba5c --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h @@ -0,0 +1,39 @@ +/* +* +* 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 STACKX_TX_BOX_H +#define STACKX_TX_BOX_H +#include "sys/types.h" +#include "nsfw_mem_api.h" +#include "stackx_common.h" +#include "nsfw_mt_config.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +const char *get_stackx_ring_name (); +const char *get_stackx_priority_ring_name (unsigned priority); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackx_types.h b/stacks/lwip_stack/lwip_src/common/stackx_types.h new file mode 100644 index 0000000..6c78a20 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackx_types.h @@ -0,0 +1,68 @@ +/* +* +* 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 STACKX_TYPES_H +#define STACKX_TYPES_H + +#include <sys/time.h> +#include <sys/types.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#if 1 +#ifndef STACKX_MAX_S16_NUM +#define STACKX_MAX_S16_NUM ((s16_t)0x7fff) +#endif + +#ifndef STACKX_MAX_U16_NUM +#define STACKX_MAX_U16_NUM ((u16_t)0xFfff) +#endif + +#ifndef STACKX_MAX_U32_NUM +#define STACKX_MAX_U32_NUM ((u32_t)0xffffffff) +#endif + +#ifndef STACKX_MAX_S32_NUM +#define STACKX_MAX_S32_NUM ((s32_t)0x7fffffff) +#endif + +#ifndef STACKX_MAX_U64_NUM +#define STACKX_MAX_U64_NUM ((u64_t)0xffffffffffffffff) +#endif + +#ifndef STACKX_MAX_S64_NUM +#define STACKX_MAX_S64_NUM ((s64_t)0x7fffffffffffffff) +#endif +#endif + +#if 1 +typedef uint64_t u64_t; +typedef int64_t s64_t; + +typedef uint32_t u32_t; +typedef int32_t s32_t; + +typedef uint16_t u16_t; +typedef int16_t s16_t; + +typedef uint8_t u8_t; +typedef int8_t s8_t; + +typedef uintptr_t mem_ptr_t; +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/common/stackxopts.h b/stacks/lwip_stack/lwip_src/common/stackxopts.h new file mode 100644 index 0000000..15fc6b8 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/common/stackxopts.h @@ -0,0 +1,53 @@ +/* +* +* 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 STACKX_OPTS_H +#define STACKX_OPTS_H + +struct memory_statics +{ + char name[120]; + long size; +}; + +extern u32 g_type; +extern struct memory_statics memory_used_size[80]; + +#define DPDK_MEMORY_COUNT(memory, len)\ +{\ + if (g_type < MAX_MEMORY_USED_SIZE)\ + {\ + const char * ptr_memory = memory;\ + if (ptr_memory && EOK != STRCPY_S(memory_used_size[g_type].name, sizeof(memory_used_size[g_type].name), ptr_memory))\ + {\ + NSPOL_LOGERR("STRCPY_S failed.");\ + }\ + memory_used_size[g_type].size =(long) len;\ + g_type++;\ + }\ +} + +#define SPL_MAX_UDP_MSG_LEN (0xFFFF -28) +#define RECV_MAX_POOL 4 +#define MAX_TRY_GET_MEMORY_TIMES 4 +#define MAX_MEMORY_USED_SIZE 80 +#define SPL_IP_HLEN 20 +#define SPL_TCP_HLEN 20 +#define SPL_TCP_MAX_OPTION_LEN 40 +#define SPL_FRAME_MTU 1500 +#define SPL_TCP_SEND_MAX_SEG_PER_MSG 5 + +#endif diff --git a/stacks/lwip_stack/lwip_src/core/global_tick.c b/stacks/lwip_stack/lwip_src/core/global_tick.c new file mode 100644 index 0000000..ee180c9 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/global_tick.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 "nstack_share_res.h" +#include "nstack_securec.h" + +extern nstack_tick_info_t g_nstack_timer_tick; + +int +init_stackx_global_tick (void) +{ + nsfw_mem_zone mzone; + + if (STRCPY_S + (mzone.stname.aname, NSFW_MEM_NAME_LENGTH, NSTACK_GLOBAL_TICK_SHM) != 0) + { + NSPOL_LOGERR ("STRCPY_S fail"); + return -1; + } + + mzone.stname.entype = NSFW_SHMEM; + mzone.isocket_id = -1; + mzone.length = sizeof (uint64_t); + mzone.ireserv = 0; + + g_nstack_timer_tick.tick_ptr = (uint64_t *) nsfw_mem_zone_create (&mzone); + if (NULL == g_nstack_timer_tick.tick_ptr) + { + NSPOL_LOGERR ("Failed to create global timer tick memory"); + return -1; + } + + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/core/spl_pbuf.c b/stacks/lwip_stack/lwip_src/core/spl_pbuf.c new file mode 100644 index 0000000..03e30ed --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/spl_pbuf.c @@ -0,0 +1,597 @@ +/* +* +* 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 "spl_opt.h" + +#include "spl_def.h" +#include "spl_pbuf.h" +#include "stackx_pbuf.h" + +#include "stackx_spl_share.h" +#include "spl_api.h" + +#include "nsfw_maintain_api.h" +#include "netif/sc_dpdk.h" +#include <common_mem_mbuf.h> + +#include <string.h> +#include "nstack_log.h" +#include "nstack_securec.h" +#include "spl_instance.h" + +#include "sys.h" +#include "mem.h" +#include "memp.h" +//#include "sockets.h" +//#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct spl_pbuf)) +u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +u16_t g_offSetArry[SPL_PBUF_MAX_LAYER] = + { PBUF_TRANSPORT_HLEN + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + SPL_PBUF_UDP_HLEN + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + SPL_PBUF_LINK_HLEN, + 0 +}; + +inline struct spl_pbuf * +spl_pbuf_alloc_hugepage (spl_pbuf_layer layer, u16_t length, + spl_pbuf_type Type, u16_t proc_id, void *net_conn) +{ + struct spl_pbuf *p; + u16_t offset; + u16_t count = 0; + spl_netconn_t *conn = (spl_netconn_t *) net_conn; + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "spl_pbuf_alloc_hugepage]length=%" U16_F, length); + + /* determine header offset */ + if (likely (layer < SPL_PBUF_MAX_LAYER)) + { + offset = g_offSetArry[layer]; + } + else + { + NSPOL_LOGERR ("spl_pbuf_alloc_hugepage: bad pbuf layer"); + return NULL; + } + + if (unlikely (length < offset || Type != SPL_PBUF_HUGE)) + { + NSPOL_LOGERR ("input is invalid!]length=%u, Type = %d", length, Type); + return NULL; + } + + p = spl_mbuf_malloc (length, SPL_PBUF_HUGE, &count); + + if (p == NULL) + { + /* last_log_prt_time and unprint_log_count indeed have multi-thread issue, + * but their values don't have precision requirement. No risk. */ + NS_LOG_CTRL (LOG_CTRL_HUGEPAGE_ALLOC_FAIL, STACKX, "NSPOL", NSLOG_ERR, + "pbuf_alloc_huge: Could not allocate PBUF for SPL_PBUF_HUGE"); + + return NULL; + } + + if (conn) + { + p->conn_a = ADDR_LTOSH (conn); + } + else + { + p->conn_a = 0; + } + + p->tot_len -= offset; + p->len -= offset; + p->next_a = 0; + + p->payload_a = p->payload_a + offset; + + p->proto_type = SPL_PBUF_PROTO_NONE; + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_alloc]length=%" U16_F ",p=%p", length, (void *) p); + return p; +} + +inline int +spl_pbuf_internal_copy (struct spl_pbuf *dst, struct spl_pbuf *src) +{ + u32_t dst_len = dst->len; + u32_t src_len = src->len; + u32_t dst_pos = 0; + u32_t src_pos = 0; + while (dst != NULL && src != NULL) + { + if (dst_len > src_len) + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + src_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + dst_len -= src_len; + dst_pos += src_len; + src = ADDR_SHTOL (src->next_a); + src_len = src != NULL ? src->len : 0; + src_pos = 0; + } + else if (dst_len < src_len) + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + dst_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + src_len -= dst_len; + src_pos += dst_len; + dst = ADDR_SHTOL (dst->next_a); + dst_len = dst != NULL ? dst->len : 0; + dst_pos = 0; + } + else + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + dst_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + src = ADDR_SHTOL (src->next_a); + src_len = src != NULL ? src->len : 0; + src_pos = 0; + dst = ADDR_SHTOL (dst->next_a); + dst_len = dst != NULL ? dst->len : 0; + dst_pos = 0; + } + } + return 0; +} + +void +spl_pbuf_realloc (struct spl_pbuf *p, u32_t new_len) +{ + if (NULL != p && p->type == SPL_PBUF_HUGE) + { + p->tot_len = new_len; + p->len = new_len; + return; + } +} + +void +spl_pbuf_free (struct spl_pbuf *p) +{ + struct spl_pbuf *q; + u8_t count = 0; + + NSPOL_LOGINF (PBUF_DEBUG, "Freeing PBF %p", p); + + if (unlikely (p == NULL || p->type != SPL_PBUF_HUGE)) + { + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_LEVEL_SERIOUS, + "input param illegal]p=%p, type=%d", p, p ? p->type : -1); + return; + } + + (void) count; + + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + do + { + /* remember next pbuf in chain for next iteration */ + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "spl_pbuf_free: deallocating]buf=%p", (void *) p); + q = (struct spl_pbuf *) ADDR_SHTOL (p->next_a); + if (res_free (&p->res_chk)) + { + //NSPOL_LOGERR("res_free failed]p=%p", p); + } + + count++; + { + pbuf_set_recycle_flg (p, MBUF_UNUSED); /* release buf hold by app on abnormal exit */ + spl_mbuf_free ((char *) p - sizeof (struct common_mem_mbuf)); + p->res_chk.u8Reserve |= PBUF_FREE_FLAG; + } + + /* proceed to next pbuf */ + p = q; + } + while (p != NULL); + + /* return number of de-allocated pbufs */ + return; +} + +void +spl_pbuf_cat (struct spl_pbuf *h, struct spl_pbuf *t) +{ + struct spl_pbuf *p; + + if (h == NULL || t == NULL) + { + NSPOL_LOGERR ("pbuf_cat: h=NULL||t=NULL!!"); + return; + } + + for (p = h; p->next_a != 0; p = PTR_SHTOL (struct spl_pbuf *, p->next_a)) + { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + + if (0 != p->next_a) + { + NSPOL_LOGERR + ("pbuf_cat: p is not the last pbuf of the first chain, p->next_a != 0"); + return; + } + + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + + /* chain last pbuf of head (p) with first of tail (t) */ + p->next_a = (uint64_t) ADDR_LTOSH_EXT (t); + + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +err_t +spl_pbuf_copy (struct spl_pbuf * p_to, struct spl_pbuf * p_from) +{ + u32_t offset_to = 0; + u32_t offset_from = 0; + u32_t len = 0; + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, "pbuf_copy]p_to=%p,p_from=%p", + (void *) p_to, (void *) p_from); + + if (! + ((p_to != NULL) && (p_from != NULL) + && (p_to->tot_len >= p_from->tot_len))) + { + NSPOL_LOGERR ("pbuf_copy: target not big enough to hold source"); + return ERR_ARG; + } + + do + { + if (p_to == NULL) + { + NSPOL_LOGERR ("pbuf_copy: target pbuf not exist: p_to == NULL!!"); + return ERR_ARG; + } + + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) + { + + len = p_from->len - offset_from; + } + else + { + + len = p_to->len - offset_to; + } + + if (EOK != + MEMMOVE_S ((u8_t *) ADDR_SHTOL (p_to->payload_a) + offset_to, len, + (u8_t *) ADDR_SHTOL (p_from->payload_a) + offset_from, + len)) + { + NSPOL_LOGERR ("MEMMOVE_S failed"); + return ERR_MEM; + } + + offset_to += len; + offset_from += len; + if (offset_to > p_to->len) + { + NSPOL_LOGERR + ("pbuf_copy: target offset not match: offset_to > p_to->len."); + return ERR_VAL; + } + if (offset_to == p_to->len) + { + offset_to = 0; + p_to = (struct spl_pbuf *) ADDR_SHTOL (p_to->next_a); + } + + if (offset_from >= p_from->len) + { + /* on to next p_from (if any) */ + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_copy: source offset not match: offset_from >= p_from->len"); + offset_from = 0; + p_from = (struct spl_pbuf *) ADDR_SHTOL (p_from->next_a); + } + + if ((p_from != NULL) && (p_from->len == p_from->tot_len)) + { + if ((p_from->next_a != 0)) + { + NSPOL_LOGERR ("pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + + if ((p_to != NULL) && (p_to->len == p_to->tot_len)) + { + /* don't copy more than one packet! */ + if ((p_to->next_a != 0)) + { + NSPOL_LOGERR ("pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + } + while (p_from); + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_copy: end of chain reached."); + return ERR_OK; +} + +err_t +splpbuf_to_pbuf_copy (struct pbuf * p_to, struct spl_pbuf * p_from) +{ + u32_t offset_to = 0; + u32_t offset_from = 0; + u32_t len = 0; + + NSPOL_LOGINF (NETIF_DEBUG, "splpbuf_to_pbuf_copy"); + + if (! + ((p_to != NULL) && (p_from != NULL) + && (p_to->tot_len >= p_from->tot_len))) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target not big enough to hold source"); + return ERR_ARG; + } + NSPOL_LOGINF (PBUF_DEBUG, + "splpbuf_to_pbuf_copy]p_to=%p [type %d tot_len %d], p_from=%p [type %d tot_len %d]", + (void *) p_to, p_to->type, p_to->tot_len, (void *) p_from, + p_from->type, p_from->tot_len); + do + { + NSPOL_LOGINF (NETIF_DEBUG, "copying...."); + if (p_to == NULL) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target not big enough to hold source p_to len [%d] p_from len [%d]", + p_to->tot_len, p_from->tot_len); + return ERR_ARG; + } + + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) + { + + len = p_from->len - offset_from; + } + else + { + + len = p_to->len - offset_to; + } + + if (EOK != MEMMOVE_S ((u8_t *) p_to->payload + offset_to, + len, + (u8_t *) ADDR_SHTOL (p_from->payload_a) + + offset_from, len)) + { + NSPOL_LOGERR ("MEMMOVE_S failed"); + return ERR_MEM; + } + + offset_to += len; + offset_from += len; + if (offset_to > p_to->len) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target offset not match: offset_to > p_to->len."); + return ERR_VAL; + } + if (offset_to == p_to->len) + { + offset_to = 0; + p_to = p_to->next; + + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: p_to next %p", p_to); + } + + if (offset_from >= p_from->len) + { + /* on to next p_from (if any) */ + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: source offset not match: offset_from >= p_from->len"); + offset_from = 0; + p_from = (struct spl_pbuf *) ADDR_SHTOL (p_from->next_a); + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: pfrom next %p", p_from); + } + + if ((p_from != NULL) && (p_from->len == p_from->tot_len)) + { + if ((p_from->next_a != 0)) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + + if ((p_to != NULL) && (p_to->len == p_to->tot_len)) + { + /* don't copy more than one packet! */ + if ((p_to->next != NULL)) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + } + while (p_from); + + NSPOL_LOGDBG (NETIF_DEBUG, "splpbuf_to_pbuf_copy: end of chain reached."); + return ERR_OK; +} + +err_t +pbuf_to_splpbuf_copy (struct spl_pbuf * p_to, struct pbuf * p_from) +{ + int offset = 0; + void *data = NULL; + + do + { + data = (u8_t *) (p_to->payload_a) + offset; + memcpy (data, (u8_t *) p_from->payload, p_from->len); + offset = offset + p_from->len; + if (offset >= 2048) + { + NSPOL_LOGERR ("More thank 2K size"); + return ERR_MEM; + } + p_from = p_from->next; + } + while (p_from != NULL); + + return ERR_OK; +} + +struct pbuf * +spl_convert_spl_pbuf_to_pbuf (struct spl_pbuf *p_from) +{ + struct pbuf *p_to = NULL; + + p_to = pbuf_alloc (PBUF_RAW, p_from->tot_len, PBUF_POOL); + if (p_to) + { + splpbuf_to_pbuf_copy (p_to, p_from); + } + return p_to; +} + +spl_pbuf_layer +get_pbuf_layer_from_pbuf_payload (struct pbuf * buf) +{ + + struct eth_hdr *ethhdr; + spl_pbuf_layer layer = SPL_PBUF_TRANSPORT; + u16_t type; + + if (buf->len <= SIZEOF_ETH_HDR) + { + NSPOL_LOGINF (PBUF_DEBUG, + "get_pbuf_layer_from_payload failed. length is wrong"); + return layer; + } + ethhdr = (struct eth_hdr *) buf->payload; + type = spl_htons (ethhdr->type); + + NSPOL_LOGINF (PBUF_DEBUG, "packet type %x", type); + + switch (type) + { + case ETHTYPE_IP: + layer = SPL_PBUF_IP; + break; + case ETHTYPE_ARP: + layer = SPL_PBUF_LINK; + break; + default: + layer = SPL_PBUF_TRANSPORT; + break; + } + + return layer; +} + +void +print_pbuf_payload_info (struct pbuf *buf, bool send) +{ + + struct eth_hdr *ethhdr; + u16_t type; + + if (buf->len <= SIZEOF_ETH_HDR) + { + NSPOL_LOGINF (PBUF_DEBUG, + "get_pbuf_layer_from_payload failed. length is wrong"); + return; + } + ethhdr = (struct eth_hdr *) buf->payload; + type = spl_htons (ethhdr->type); + + if (send) + { + NSPOL_LOGINF (PBUF_DEBUG, "send packet start type %x len %d *****", + type, buf->len); + } + else + { + NSPOL_LOGINF (PBUF_DEBUG, + "receive packet start type %x len %d ########", type, + buf->len); + } + + switch (type) + { + case ETHTYPE_IP: + NSPOL_LOGINF (TCPIP_DEBUG, "ip packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + struct ip_hdr *ip = + (struct ip_hdr *) ((char *) buf->payload + SIZEOF_ETH_HDR); + NSPOL_LOGINF (PBUF_DEBUG, "ip packet src %x dest %x proto %d", ip->src, + ip->dest, ip->_proto); + break; + case ETHTYPE_ARP: + NSPOL_LOGINF (TCPIP_DEBUG, "arp packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + break; + default: + NSPOL_LOGINF (TCPIP_DEBUG, "other packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + break; + } + return; +} diff --git a/stacks/lwip_stack/lwip_src/core/spl_timers.c b/stacks/lwip_stack/lwip_src/core/spl_timers.c new file mode 100644 index 0000000..cfa130b --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/spl_timers.c @@ -0,0 +1,607 @@ +/* +* +* 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 "opt.h" +#include "nsfw_mem_api.h" +#include "def.h" +#include "sc_dpdk.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nstack_share_res.h" + +#include <time.h> +#include <signal.h> +#include <pthread.h> +#include <syscall.h> +#include "nsfw_ps_api.h" +#include "spl_timers.h" +#include "common_mem_api.h" + +extern sys_thread_t g_timerThread_id; + +/*Since the range of the dpdk read TSC value is u64_t, it changes*/ + +#ifndef typecheck +#define typecheck(type, x) \ +({ type __dummy; \ + typeof(x)__dummy2; \ + (void)(&__dummy == &__dummy2); \ + 1; \ + }) +#endif + +#ifndef time_after_eq +#define time_after_eq(a, b) \ +(typecheck(unsigned long, a) \ + && typecheck(unsigned long, b) \ + && ((long)(a) - (long)(b) >= 0)) +#endif + +#define MIN_TIME_PICE 50 +#define MICRO_PER_SECOND 1000 +#define NANO_PER_MICROSECOND 1000000 +#define NANO_PER_SECOND 1000000000 + +#define PTIMER_MSG_BUFFER_SIZE 4096 + +#define PTIMER_STATE_INACTIVE 0x00 +#define PTIMER_STATE_ENQUEUED 0x01 +#define gettid() syscall(__NR_gettid) + +#define TIMER_CONTEXT_NAME "TIMER_CONTEXT_NAME" + +static timer_t lazy_tim; +static timer_t lazy_tim_retry; +static struct ptimer_base ptimer; +static sys_sem_t ptimer_lock; + +extern void recycle_tmr (struct ptimer_node *tmo); + +extern nstack_tick_info_t g_nstack_timer_tick; + +/* + *************************** + * rb_tree wrapper function* + *************************** + */ +NSTACK_STATIC void +remove_ptimer (struct ptimer_node *tmo, struct ptimer_base *base) +{ + if (tmo == NULL) + { + NSPOL_LOGERR ("input parameter tmo is null"); + return; + } + if (!(tmo->state & PTIMER_STATE_ENQUEUED)) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "the timer state is: PTIMER_STATE_INACTIVE, no need to remove!"); + return; + } + + if (base->first == &tmo->node) + { + base->first = rb_next (&tmo->node); + } + + rb_erase (&tmo->node, &base->active); + + tmo->state = PTIMER_STATE_INACTIVE; +} + +NSTACK_STATIC struct ptimer_node * +search_ptimer (struct ptimer_msg *msg) +{ + if (msg == NULL) + { + NSPOL_LOGERR ("input parameter msg is null"); + return NULL; + } + if (msg->node) + { + return msg->node; + } + + return NULL; + +} + +err_t +del_ptimer (struct ptimer_msg * msg) +{ + struct ptimer_node *tmo; + + tmo = search_ptimer (msg); + if (tmo) + { + remove_ptimer (tmo, &ptimer); + NSPOL_LOGDBG (TIMERS_DEBUG, "del]thread=%u,ptimer_node=%p", tmo->index, + tmo); + return ERR_OK; + } + + NSPOL_LOGERR ("ptime_node not found!!"); + return ERR_VAL; +} + +/* + * Ptimer inserted into rb_tree + * @param node: the ptimer node pointer + * @param base: the ptimer root_base pointer + */ +NSTACK_STATIC void +enqueue_ptimer (struct ptimer_node *tmo, struct ptimer_base *base) +{ + struct rb_node **linknode; + struct rb_node *parent = NULL; + struct ptimer_node *entry; + int leftmost = 1; + if (tmo == NULL || base == NULL) + { + NSPOL_LOGERR ("input parameter is null"); + return; + } + + if ((tmo->state & PTIMER_STATE_ENQUEUED)) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "the timer state is: PTIMER_STATE_ENQUEUED"); + return; + } + + linknode = &base->active.rb_node; + while (*linknode) + { + parent = *linknode; + entry = rb_entry (parent, struct ptimer_node, node); + //XXX: do by the equal case is all of price of the large case + if (time_after_eq (entry->abs_nsec, tmo->abs_nsec)) + { + linknode = &(*linknode)->rb_left; + } + else + { + linknode = &(*linknode)->rb_right; + leftmost = 0; + } + } + + /* + * Insert the timer to the rb_tree and check whether it + * replaces the first pending timer + */ + if (leftmost) + { + base->first = &tmo->node; + } + + rb_link_node (&tmo->node, parent, linknode); + rb_insert_color (&tmo->node, &base->active); + NSPOL_LOGDBG (TIMERS_DEBUG, "enqueue]thread=%u,ptimer_node=%p", tmo->index, + tmo); + tmo->state |= PTIMER_STATE_ENQUEUED; +} + +void +launch_tmr (timer_t * tim, u64_t nsec) +{ + struct itimerspec vtim; + + vtim.it_value.tv_sec = (nsec) / NANO_PER_SECOND; + vtim.it_value.tv_nsec = (nsec) % NANO_PER_SECOND; + vtim.it_interval.tv_sec = 0; + vtim.it_interval.tv_nsec = 0; + + if (timer_settime (*tim, 0, &vtim, NULL) < 0) + { + NSPOL_LOGERR ("add_ptimer:timer_settime failed"); + } + +} + +/* + * add ptimer to rb_tree + * @param tmo: the ptimer node pointer + */ +void +add_ptimer (struct ptimer_node *tmo) +{ + if (tmo == NULL) + { + NSPOL_LOGERR ("input parameter is null"); + return; + } + enqueue_ptimer (tmo, &ptimer); + + if (ptimer.first == &tmo->node) + { + launch_tmr (&lazy_tim, tmo->info.msec * NANO_PER_MICROSECOND); + } +} + +#if 1 +/* + * cond signal ,send a ptimer message + * @param type: the message type + * @param handler: timeout handler + * @param node: the ptimer node pointer + */ +void +regedit_ptimer (enum msg_type Type, sys_timeout_handler handler, + struct ptimer_node *node) +{ + (void) handler; + (void) pthread_mutex_lock (&ptimer.lock); + if (ptimer.tail == NULL) + { + (void) pthread_mutex_unlock (&ptimer.lock); + NSPOL_LOGERR ("ptimer.tail is null"); + free (node); + node = NULL; + return; + } + ptimer.tail->msg_type = Type; + ptimer.tail->node = node; + ptimer.tail = ptimer.tail->next; + if (ptimer.head == ptimer.tail) + { + (void) pthread_mutex_unlock (&ptimer.lock); + NSPOL_LOGERR ("ptimer.head equal to ptimer.tail"); + return; + } + + (void) pthread_kill (g_timerThread_id, SIGRTMIN + 2); + + (void) pthread_mutex_unlock (&ptimer.lock); + return; +} +#endif +/* + * deal with the timeout signal + * + */ +void +deal_timeout_sig (void) +{ + struct ptimer_node *tmo; + struct timespec now; + unsigned long abs_nsec; + err_t err; + int retval; + if (ptimer.first == NULL) + { + return; + } + tmo = rb_entry (ptimer.first, struct ptimer_node, node); + retval = clock_gettime (CLOCK_MONOTONIC, &now); + if (0 != retval) + { + NSPOL_LOGERR ("clock_gettime failed]retval=%d,errno=%d", retval, errno); + } + abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec; + + // deal with all timeout point + while (time_after_eq (abs_nsec, tmo->abs_nsec)) + { + remove_ptimer (tmo, &ptimer); + + if (tmo->info.flags & PTIMER_ONESHOT) + { + } + else + { + //re-entry periodic ptimer + tmo->abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec + + tmo->info.msec * NANO_PER_MICROSECOND; + add_ptimer (tmo); + } + + //send timeout message + NSPOL_LOGDBG (INTERRUPT_DEBUG, + "ptimer happened to thread_index]index=%u", tmo->index); + if ((err = ltt_apimsg (tmo->info._phandle, (void *) tmo))) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "send timeout message failed!]errno=%d", err); + } + + if (ptimer.first == NULL) + { + NSPOL_LOGERR ("deal_timeout_sig: ptimer.first == NULL!!"); + return; + } + tmo = rb_entry (ptimer.first, struct ptimer_node, node); + } + + if (tmo->abs_nsec <= abs_nsec) + { + NSPOL_LOGERR ("tmo->abs_nsec is smaller than abs_nsec"); + return; + } + + NSPOL_LOGDBG (TIMERS_DEBUG, "TIMERSIGNAL : Launch timer for]time=%ul", + tmo->abs_nsec - abs_nsec); + launch_tmr (&lazy_tim, tmo->abs_nsec - abs_nsec); //timer interupted eveny 50ms instand by tmo->abs_nsec +} + +/* + * timeout signal handle function + * @param v: unused argument + */ +/*ptimer is already protected and used*/ + +NSTACK_STATIC void +timeout_sigaction (int sig) +{ + (void) sig; + if (!sys_arch_sem_trywait (&ptimer_lock)) + { + launch_tmr (&lazy_tim_retry, + (MIN_TIME_PICE / 5) * NANO_PER_MICROSECOND); + return; + } + + deal_timeout_sig (); + + sys_sem_signal (&ptimer_lock); + + return; +} + +/* + * initialize the ptimer buffer and timing mechanism + */ +err_t +init_ptimer (void) +{ + int i, retval; + struct sigevent timer_event; + struct sigevent timer_event1; + struct ptimer_msg *ptr; + + if (pthread_mutex_init (&ptimer.lock, NULL)) + { + NSPOL_LOGERR ("pthread_mutex_init failed"); + return ERR_MEM; + } + /*codex fix */ + if (ERR_MEM == sys_sem_new (&ptimer_lock, 1)) + { + NSPOL_LOGERR ("init_ptimer: sys_sem_new failure"); + return ERR_MEM; + } + + ptimer.active.rb_node = NULL; + ptimer.first = NULL; + + ptr = + (struct ptimer_msg *) malloc (PTIMER_MSG_BUFFER_SIZE * + sizeof (struct ptimer_msg)); + if (!ptr) + { + NSPOL_LOGERR ("init_ptimer: malloc ptimer buffer failed!"); + return ERR_MEM; + } + + int ret = + MEMSET_S (ptr, (PTIMER_MSG_BUFFER_SIZE * sizeof (struct ptimer_msg)), + 0, (PTIMER_MSG_BUFFER_SIZE * sizeof (struct ptimer_msg))); + if (EOK != ret) + { + free (ptr); + NSPOL_LOGERR ("init_ptimer: MEMSET_S ptimer buffer failed]ret=%d", ret); + return ERR_MEM; + } + + for (i = 0; i < PTIMER_MSG_BUFFER_SIZE - 1; i++) + { + ptr[i].next = &ptr[(i + 1)]; + ptr[(i + 1)].prev = &ptr[i]; + } + + ptr[i].next = &ptr[0]; + ptr[0].prev = &ptr[i]; + ptimer.head = ptimer.tail = &ptr[0]; + retval = + MEMSET_S (&timer_event, sizeof (struct sigevent), 0, + sizeof (struct sigevent)); + if (EOK != retval) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("MEMSET_S failed]ret=%d", retval); + return ERR_VAL; + } + timer_event.sigev_notify = SIGEV_SIGNAL; + timer_event.sigev_signo = SIGRTMIN; + timer_event.sigev_value.sival_ptr = (void *) &lazy_tim; + timer_event1 = timer_event; + timer_event1.sigev_value.sival_ptr = (void *) &lazy_tim_retry; + + if (timer_create (CLOCK_MONOTONIC, &timer_event, &lazy_tim) < 0) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("ptimer_init: timer_create failed!"); + return ERR_VAL; + } + + if (timer_create (CLOCK_MONOTONIC, &timer_event1, &lazy_tim_retry) < 0) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("ptimer_init: timer_create failed!"); + return ERR_VAL; + } + + return ERR_OK; +} + +NSTACK_STATIC err_t +process_timeout_msg (struct ptimer_msg * msg) +{ + struct ptimer_node *tmo = msg->node; + struct timespec now; + + switch (msg->msg_type) + { + case SYS_PTIMEROUT_MSG: + if (tmo) + { + int retval = clock_gettime (CLOCK_MONOTONIC, &now); + if (0 != retval) + { + NSPOL_LOGERR ("clock_gettime failed]retval=%d,errno=%d", retval, + errno); + } + tmo->abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec + + tmo->info.msec * NANO_PER_MICROSECOND; + add_ptimer (tmo); + } + else + { + NSPOL_LOGERR ("process_timeout_msg: rb_node is NULL!"); + return ERR_MEM; + } + + break; + case SYS_UNPTIMEROUT_MSG: + if (del_ptimer (msg) != ERR_OK) + { + NSPOL_LOGERR + ("process_timeout_msg: can not find the timeout event(oops)!"); + } + + break; + default: + NSPOL_LOGERR + ("process_timeout_msg: oops! lwip timeout_thread receive unacquainted message!"); + break; + } + + return ERR_OK; +} + +void +ptimer_thread (void *arg) +{ + LWIP_UNUSED_ARG (arg); + int sig, ret = -1; + sigset_t waitset; + sigset_t oset; + struct ptimer_msg *msg; + + if (0 != sigemptyset (&waitset)) + { + NSTCP_LOGERR ("sigemptyset function call error"); + return; + } + + if (0 != sigaddset (&waitset, SIGRTMIN)) + { + NSTCP_LOGERR ("sigaddset function call error"); + return; + } + + if (0 != sigaddset (&waitset, SIGRTMIN + 2)) + { + NSTCP_LOGERR ("sigaddset function call error"); + return; + } + + (void) pthread_sigmask (SIG_BLOCK, &waitset, &oset); + + (void) pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + (void) pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + NSPOL_LOGDBG (TIMERS_DEBUG, "ptimer: init done !"); + + if (!g_nstack_timer_tick.tick_ptr) + { + NSTCP_LOGERR ("g_nstack_timer_tick not inited"); + return; + } + (void) gettimeofday (&g_nstack_timer_tick.ref_time, NULL); + g_nstack_timer_tick.interval = 100; + *g_nstack_timer_tick.tick_ptr = 0; + g_nstack_timer_tick.ref_tick = 0; + while (1) + { + ret = sigwait (&waitset, &sig); + (void) nsfw_thread_chk (); // will only return TRUE, no need to check return value + if (ret != -1) + { + /* for timer expirt handle */ + if (SIGRTMIN == sig) + { + timeout_sigaction (sig); + continue; + } + } + else + { + continue; + } + + while (1) + { + (void) pthread_mutex_lock (&ptimer.lock); + if (ptimer.head == ptimer.tail) + { + (void) pthread_mutex_unlock (&ptimer.lock); + break; + } + + msg = ptimer.head; + ptimer.head = ptimer.head->next; + (void) pthread_mutex_unlock (&ptimer.lock); + + sys_arch_sem_wait (&ptimer_lock, 0); + + if (process_timeout_msg (msg) != ERR_OK) + { + NSPOL_LOGERR ("oops: ptimer_thread panic!"); + } + + sys_sem_signal (&ptimer_lock); + } + } +} + +void +timeout_phandler (void *act, void *arg) +{ + struct ptimer_node *tmo = arg; + if (act == NULL) + { + NSPOL_LOGERR ("input parameter arg is null"); + return; + } + + NSPOL_LOGINF (TIMERS_DEBUG, "Timer expire @timeout_phandler Handle %p", + tmo->info._phandle); + if (tmo->info.flags & PTIMER_ONESHOT) + { + sys_timeout_handler handle = act; + handle (tmo->info.ctx); + return; + } + else + { + NSPOL_LOGINF (TIMERS_DEBUG, + "Timer expire error @timeout_phandler Handle %p", + tmo->info._phandle); + } +} diff --git a/stacks/lwip_stack/lwip_src/core/unmatch_version.c b/stacks/lwip_stack/lwip_src/core/unmatch_version.c new file mode 100644 index 0000000..6c8cad3 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/unmatch_version.c @@ -0,0 +1,59 @@ +/* +* +* 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 "nstack_share_res.h" +#include "nstack_securec.h" + +char *g_nstack_ver_info = NULL; + +int +init_unmatch_version (void) +{ + int ret; + nsfw_mem_zone mzone; + + ret = + STRCPY_S (mzone.stname.aname, NSFW_MEM_NAME_LENGTH, NSTACK_VERSION_SHM); + if (EOK != ret) + { + NSPOL_LOGERR ("STRCPY_S fail]ret=%d", ret); + return -1; + } + mzone.stname.entype = NSFW_SHMEM; + mzone.isocket_id = -1; + mzone.length = + NSTACK_VERSION_LEN + MAX_UNMATCH_VER_CNT * sizeof (unmatch_ver_info_t); + mzone.ireserv = 0; + + char *version = (char *) nsfw_mem_zone_create (&mzone); + if (NULL == version) + { + NSPOL_LOGERR ("Failed to create unmatch_version memory"); + return -1; + } + + ret = STRCPY_S (version, NSTACK_VERSION_LEN, NSTACK_VERSION); + if (EOK != ret) + { + NSPOL_LOGERR ("STRCPY_S NSTACK_VERSION fail]ret=%d", ret); + return -1; + } + + g_nstack_ver_info = version; + + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/include/ip_module/config_common.h b/stacks/lwip_stack/lwip_src/include/ip_module/config_common.h new file mode 100644 index 0000000..0c88139 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ip_module/config_common.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. +*/ + +#ifndef _NSTACK_CONFIG_COMMON_H_ +#define _NSTACK_CONFIG_COMMON_H_ + +#include "ip_module_api.h" + +#define MAX_IP_MODULE_BUFF_SIZE 1024*1024 + +/* ip module config types */ +#define IP_MODULE_TYPE_IP "ip" +#define IP_MODULE_TYPE_NETWORK "network" +#define IP_MODULE_TYPE_PORT "port" +#define IP_MODULE_TYPE_SETLOG "setlog" +#define IP_MODULE_TYPE_SNAPSHOT "snapshot" +#define IP_MODULE_TYPE_SETTRACE "settrace" + +#define TCP_MODULE_TYPE_SET_OOS_LEN "ooslen" + +#define IP_MODULE_NAME "./nStackCtrl: " +#define IP_MODULE_INVALID_ARGUMENT_S "invalid argument -- \"%s\"\n" +#define IP_MODULE_MORE_OPTION "need more options -- " +#define IP_MODULE_LESS_OPTION "no need option -- " + +/* Error codes */ +#define IP_MODULE_OK 0 +#define IP_MODULE_DATA_ERROR 1 +#define IP_MODULE_DATA_NOT_EXIST 2 + +struct config_param +{ + int action; + char type[IP_MODULE_LENGTH_256]; + char name[IP_MODULE_LENGTH_256]; + char value[IP_MODULE_LENGTH_64]; + char container_id[IP_MODULE_LENGTH_256]; + int error; + + char error_desc[NSCRTL_ERRBUF_LEN]; + + u64 traceid; +}; + +struct config_data +{ + struct config_param param; + char json_buff[MAX_IP_MODULE_BUFF_SIZE - sizeof (struct config_param)]; +}; + +#endif diff --git a/src/adapt/nstack_rd_mng.h b/stacks/lwip_stack/lwip_src/include/ip_module/configuration_reader.h index f1fe7a3..779ace8 100644 --- a/src/adapt/nstack_rd_mng.h +++ b/stacks/lwip_stack/lwip_src/include/ip_module/configuration_reader.h @@ -14,14 +14,13 @@ * limitations under the License. */ -#ifndef __NSTACK_RD_MNG_H -#define __NSTACK_RD_MNG_H -#include <stdlib.h> -#include "nstack_rd_data.h" +#ifndef _CONFIGURATION_READER_H +#define _CONFIGURATION_READER_H +#include <semaphore.h> +#include "config_common.h" -int nstack_rd_mng_int (int flag); -int nstack_rd_ip_node_insert (char *name, rd_ip_data * data); -int nstack_rd_ip_node_delete (rd_ip_data * data); -int nstack_rd_ip_get (rd_route_data ** data, int *num); +struct config_data *get_config_data (); +int get_str_value (const char *arg); +int setlog_level_value (const char *param, const char *value); #endif diff --git a/stacks/lwip_stack/lwip_src/include/ip_module/container_ip.h b/stacks/lwip_stack/lwip_src/include/ip_module/container_ip.h new file mode 100644 index 0000000..e83c607 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ip_module/container_ip.h @@ -0,0 +1,39 @@ +/* +* +* 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 _CONTAINER_IP_H +#define _CONTAINER_IP_H +#include "ip_module_api.h" +#include "json.h" + +struct ip_action_param +{ + char container_id[IP_MODULE_LENGTH_256]; + char port_name[IP_MODULE_LENGTH_256]; +}; + +void free_container (struct container_ip *container, bool_t only_free); +struct container_port *parse_port_obj (struct json_object *port_obj); +struct container_ip *parse_container_ip_json (char *param); +int add_container (struct container_ip *container); +struct container_ip *get_container_by_container_id (char *container_id); + +int del_port (char *container_id, char *port_name); +struct container_port *get_port (char *container_id, char *port_name); +struct container_port *get_port_from_container (struct container_port *port); +int getIpCfgAll (char *jsonBuf, size_t size); + +#endif diff --git a/stacks/lwip_stack/lwip_src/include/ip_module/ip_module_api.h b/stacks/lwip_stack/lwip_src/include/ip_module/ip_module_api.h new file mode 100644 index 0000000..488e13e --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ip_module/ip_module_api.h @@ -0,0 +1,222 @@ +/* +* +* 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 _IP_MODULE_API_H_ +#define _IP_MODULE_API_H_ +#include "types.h" + +typedef int bool_t; +#define IP_MODULE_TRUE 1 +#define IP_MODULE_FALSE 0 +#define IP_MODULE_LENGTH_32 32 +#define IP_MODULE_LENGTH_64 64 +#define IP_MODULE_LENGTH_256 256 +#define IP_MODULE_LENGTH_1024 1024 +#define IP_MODULE_SUBNET_MASK_LEN IP_MODULE_LENGTH_32 +#define IP_MODULE_MAX_NAME_LEN IP_MODULE_LENGTH_256 +#define IP_MODULE_PORT_JSON_LEN (2048 * 2) +#define IP_MODULE_NETWORK_JSON_LEN (2048 * 2) +#define MAX_NETWORK_COUNT IP_MODULE_LENGTH_64 +#define MAX_NETWORK_IP_COUNT IP_MODULE_LENGTH_1024 +#define MAX_NETWORK_NUM (MAX_NETWORK_COUNT * 2) +COMPAT_PROTECT (MAX_NETWORK_NUM, 128); +#define MAX_PORT_NUM (MAX_NETWORK_IP_COUNT * 2) +COMPAT_PROTECT (MAX_PORT_NUM, 2048); +#define NSCRTL_ERRBUF_LEN IP_MODULE_LENGTH_256 + +#define INVALID_EXPIRE_TIME 0x7FFFFFFF +#define NSTACLCTRL_MAX_TRY_TIMES 60 + +/*sockaddr_un.sun_path is an array of 108 bytes*/ +#define IP_MODULE_MAX_PATH_LEN 108 + +typedef enum enumADERRCODE +{ + NSCRTL_OK = 0, + NSCRTL_ERR, + NSCRTL_RD_NOT_EXIST, + NSCRTL_RD_EXIST = 3, + NSCRTL_INPUT_ERR, + NSCRTL_STATUS_ERR, + NSCRTL_NETWORK_COUNT_EXCEED, + NSCRTL_IP_COUNT_EXCEED, + NSCRTL_FREE_ALL_PORT, //when all ports in container were deleted, need to free container. + + NSCRTL_MAX_ERR = 127 +} NSCRTL_ERR_CODE; + +#define NSOPR_SET_ERRINFO(_errno, fmt, ...) \ + {\ + struct config_data* cf_data = get_config_data(); \ + if (cf_data)\ + {\ + size_t len_error_desc = strlen(cf_data->param.error_desc); \ + cf_data->param.error = _errno; \ + if ((_errno != NSCRTL_OK) && (len_error_desc < NSCRTL_ERRBUF_LEN))\ + {\ + if (-1 == (SNPRINTF_S(cf_data->param.error_desc + len_error_desc, \ + NSCRTL_ERRBUF_LEN - len_error_desc, NSCRTL_ERRBUF_LEN - len_error_desc - 1, fmt, ## __VA_ARGS__)))\ + {\ + NSOPR_LOGERR("SNPRINTF_S failed]"); \ + } \ + } \ + } \ + } \ + +struct ref_nic +{ + struct ref_nic *next; + char nic_name[IP_MODULE_MAX_NAME_LEN]; +}; + +struct phy_net +{ + struct ref_nic *header; + char bond_name[IP_MODULE_MAX_NAME_LEN]; + int bond_mode; +}; + +struct container_port_ip_cidr +{ + struct container_port_ip_cidr *next; + unsigned int ip; + unsigned int mask_len; +}; + +struct container_multicast_id +{ + struct container_multicast_id *next; + unsigned int ip; +}; + +typedef struct +{ + char port_json[IP_MODULE_PORT_JSON_LEN]; +} port_buffer; + +struct container_port +{ + struct container_port *next; + struct container_port_ip_cidr *ip_cidr_list; + struct container_multicast_id *multicast_list; + char port_name[IP_MODULE_MAX_NAME_LEN]; + port_buffer *buffer; +}; + +#define get_port_json(obj) obj->buffer->port_json + +struct container_ip +{ + struct container_ip *next; + struct container_port *ports_list; + char container_id[IP_MODULE_MAX_NAME_LEN]; +}; + +struct container_list +{ + struct container_ip *header; +}; + +struct ip_subnet +{ + struct ip_subnet *next; + unsigned int subnet; + unsigned int mask_len; +}; + +typedef struct +{ + char network_json[IP_MODULE_NETWORK_JSON_LEN]; +} network_buffer; + +struct network_configuration +{ + struct network_configuration *next; + struct phy_net *phy_net; + struct ip_subnet *ip_subnet; + char network_name[IP_MODULE_MAX_NAME_LEN]; + char type_name[IP_MODULE_MAX_NAME_LEN]; + network_buffer *buffer; +}; + +#define get_network_json(obj) obj->buffer->network_json + +struct network_list +{ + struct network_configuration *header; +}; + +void ip_subnet_print (struct ip_subnet *subnet); +bool_t is_in_same_network (unsigned int src_ip, unsigned int dst_ip); +bool_t is_ip_match_netif (unsigned int ip, char *netif_name); +bool_t is_ip_exist (unsigned int ip); +struct network_configuration *get_network_list (); +inline struct network_configuration *get_network_by_ip_with_tree (unsigned int + ip); + +/* "type" option */ +typedef enum +{ + IP_MODULE_NETWORK, + IP_MODULE_IP, + IP_MODULE_NETWORK_ALL, + IP_MODULE_IP_ALL, + IP_MODULE_ALL, +} ip_module_type; + +/* "action" option */ +typedef enum +{ + IP_MODULE_OPERATE_NULL, + IP_MODULE_OPERATE_ADD, + IP_MODULE_OPERATE_DEL, + IP_MODULE_OPERATE_QUERY, + IP_MODULE_OPERATE_SET, + IP_MODULE_GET_VERSION, + IP_MODULE_QUERY_NET, + IP_MODULE_MAX, //new type should be added before IP_MODULE_MAX + IP_MODULE_BOTTOM = 0xFFFFFFFF +} ip_module_operate_type; + +typedef int (*post_to_fn) (void *arg, ip_module_type type, + ip_module_operate_type operate_type); +typedef int (*add_netif_ip_fn) (char *netif_name, unsigned int ip, + unsigned int mask); +typedef int (*del_netif_ip_fn) (char *netif_name, unsigned int ip); + +typedef struct +{ + post_to_fn post_to; + add_netif_ip_fn add_netif_ip; + del_netif_ip_fn del_netif_ip; +} output_api; + +void regist_output_api (output_api * api); +output_api *get_output_api (); +int init_configuration_reader (); +int process_post (void *arg, ip_module_type type, + ip_module_operate_type operate_type); +int process_configuration (void *arg, ip_module_type type, + ip_module_operate_type operate_type); + +port_buffer *malloc_port_buffer (); +void free_port_buffer (port_buffer * buffer); +network_buffer *malloc_network_buffer (); +void free_network_buffer (network_buffer * buffer); +int get_network_json_data (); +int get_ip_json_data (); + +#endif diff --git a/stacks/lwip_stack/lwip_src/include/ip_module/network.h b/stacks/lwip_stack/lwip_src/include/ip_module/network.h new file mode 100644 index 0000000..117b71c --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ip_module/network.h @@ -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. +*/ + +#ifndef _NETWORK_H +#define _NETWORK_H +#include "ip_module_api.h" + +void free_network_configuration (struct network_configuration *network, + bool_t only_free); +struct network_configuration *parse_network_obj (struct json_object + *network_obj); +struct network_configuration *parse_network_json (char *param, + struct network_configuration + *network_list); +int add_network_configuration (struct network_configuration + *network_configuration); +struct network_configuration *get_network_by_name (char *name); +struct network_configuration *get_network_by_nic_name (char *name); +int del_network_by_name (char *name); +int get_network_all (char *jsonBuf, size_t size); +int nic_already_init (const char *nic_name); + +#endif diff --git a/stacks/lwip_stack/lwip_src/include/ip_module/trp_rb_tree.h b/stacks/lwip_stack/lwip_src/include/ip_module/trp_rb_tree.h new file mode 100644 index 0000000..ef0ac37 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ip_module/trp_rb_tree.h @@ -0,0 +1,77 @@ +/* +* +* 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 __TRP_RB_TREE_H__ +#define __TRP_RB_TREE_H__ + +typedef void *trp_key_t; +typedef void *trp_data_t; + +#define RB_RED 0 +#define RB_BLACK 1 + +typedef int (*key_compare) (trp_key_t left, trp_key_t right); // return > 0 left > right, return 0 left = right, return < 0 left < right + +typedef struct trp_rb_node +{ + struct trp_rb_node *rb_parent; + struct trp_rb_node *rb_right; + struct trp_rb_node *rb_left; + key_compare key_compare_fn; + trp_key_t key; + trp_data_t data; + unsigned int color; +} trp_rb_node_t; + +typedef struct trp_rb_root +{ + struct trp_rb_node *rb_node; +} trp_rb_root_t; + +int trp_rb_insert (trp_key_t, trp_data_t, trp_rb_root_t *, key_compare); +int trp_rb_insert_allow_same_key (trp_key_t, trp_data_t, trp_rb_root_t *, + key_compare); +void trp_rb_erase (trp_key_t, trp_rb_root_t *, key_compare key_compare_fn); +void trp_rb_erase_with_data (trp_key_t key, trp_data_t data, + trp_rb_root_t * root, int count, + key_compare key_compare_fn); + +static inline trp_rb_node_t * +trp_rb_search (trp_key_t key, trp_rb_root_t * root, + key_compare key_compare_fn) +{ + trp_rb_node_t *node = root->rb_node; + int ret; + while (node) + { + ret = key_compare_fn (node->key, key); + if (0 < ret) + { + node = node->rb_left; + } + else if (0 > ret) + { + node = node->rb_right; + } + else + { + return node; + } + } + + return NULL; +} +#endif diff --git a/stacks/lwip_stack/lwip_src/include/ipv4/stackx/spl_ip_addr.h b/stacks/lwip_stack/lwip_src/include/ipv4/stackx/spl_ip_addr.h new file mode 100644 index 0000000..ae5c31f --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/ipv4/stackx/spl_ip_addr.h @@ -0,0 +1,162 @@ +/* +* +* 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 __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "spl_opt.h" +#include "spl_def.h" +#include "ip_module_api.h" +#include "stackx_ip_addr.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** ip_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip_addr_t as well as on ip_addr_p_t. */ +/* Forward declaration to not include netif.h */ +struct netif; +#if BYTE_ORDER == BIG_ENDIAN + +/** Set an IPaddress given by the four byte-parts */ +#define SPL_IP4_ADDR(ipaddr, a, b, c, d) \ + (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else + +/** Set an IPaddress given by the four byte-parts. + Little-endian version that prevents the use of htonl. */ +#define SPL_IP4_ADDR(ipaddr, a, b, c, d) \ + (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** memcpy-like copying of IPaddresses where addresses are known to be + * 16-bit-aligned if the port is correctly configured (so a port could define + * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ +#ifndef IPADDR2_COPY +#define IPADDR2_COPY(dest, src) MEMCPY_S(dest, sizeof(ip_addr_t), src, sizeof(ip_addr_t)) +#endif + +/** Copy IPaddress - faster than spl_ip_addr_set: no NULL check */ +#define spl_ip_addr_copy(dest, src) ((dest).addr = (src).addr) + +/** Safely copy one IPaddress to another (src may be NULL) */ +#define spl_ip_addr_set(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + (src)->addr)) + +/** Safely copy one IPaddress to another and change byte order + * from host- to network-order. */ +#define spl_ip_addr_set_hton(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + htonl((src)->addr))) + +/** Get the network address by combining host address with netmask */ +#define spl_ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) + +/** + * Determine if two address are on the same network. + * + * @arg addr1 IPaddress 1 + * @arg addr2 IPaddress 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define spl_ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) + +/* && ((dest)->addr & tmp->netmask.addr) == (tmp->ip_addr.addr & tmp->netmask.addr) */ +/* add "netif = netif->root; \"*/ +#define ip_net_netif_cmp( dest, netif) ({ \ + netif = netif->root; \ + struct netif* tmp = netif; \ + int find = 0; \ + while(tmp) \ + { \ + if (is_in_same_network((dest)->addr, tmp->ip_addr.addr)) \ + { \ + netif->ip_addr.addr = tmp->ip_addr.addr; \ + netif->netmask.addr = tmp->netmask.addr; \ + find = 1; \ + break; \ + } \ + if (netif->is_out) \ + { \ + break; \ + } \ + tmp = tmp->vnext; \ + } \ + (!!find); \ + }) + +/* Check if netif match dest , if not , find one and swap */ +/* add "netif = netif->root; \"*/ + +#define ip_addr_netif_cmp_and_swap( dest, pnetif) ({ \ + pnetif = pnetif->root; \ + struct netif* tmp = pnetif; \ + int find = 0; \ + while(tmp) \ + { \ + if ((dest)->addr == tmp->ip_addr.addr) \ + { \ + pnetif->ip_addr.addr = tmp->ip_addr.addr; \ + pnetif->netmask.addr = tmp->netmask.addr; \ + find = 1; \ + break; \ + } \ + if (pnetif->is_out) \ + { \ + break; \ + } \ + tmp = tmp->vnext; \ + } \ + (!!find); \ + }) + +#define ip_addr_netif_cmp( dest, pnetif) ({ \ + pnetif = pnetif->root; \ + struct netif* tmp = pnetif; \ + int find = 0; \ + while(tmp) \ + { \ + if ((dest)->addr == tmp->ip_addr.addr) \ + { \ + find = 1; \ + break; \ + } \ + tmp = tmp->vnext; \ + } \ + (!!find); \ + }) + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/netif/common.h b/stacks/lwip_stack/lwip_src/include/netif/common.h new file mode 100644 index 0000000..45e9c8f --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/netif/common.h @@ -0,0 +1,233 @@ +/* +* +* 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_H_ +#define _COMMON_H_ +#include <stddef.h> /* for size_t */ +#include "stackx_common.h" +#include "netif.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +//yyq + +/* define common names for structures shared between server and client */ + +#define MP_STACKX_INSTANCE_POLL_NAME "VppTCP_instance_poll" +#define MP_STACKX_PORT_ZONE "VppTCP_stackx_port_zone" +#define MP_STACKX_PORT_INFO "VppTCP_stackx_port_info" +#define MP_MEMPOLL_RX_NAME "VppTCP_MBUF_%u_%u_RX" +#define MP_MEMPOLL_RXMSG_NAME "VppTCP_MSG_%u_%u_RX" +#define MP_MEMPOLL_TX_NAME "VppTCP_MBUF_TX" +#define MP_MEMPOLL_SEG_NAME "VppTCP_MBUF_SEG" +#define MP_STACKX_MSG_NAME "VppTCP_msg" +#define MP_STACKX_RING_NAME "VppTCP_%u_ring" +#define MP_STACKX_LRING_NAME "VppTCP_%u_lring" + +#define MP_STACKX_BIT_SET_NAME "%s_bit_set" + +#define MP_STACKX_SOCKET_FREE_LIST_NAME "VppTCP_socket_list" + +#define MP_NETIF_LIST_NAME "VppTCP_Netif_list" + +/* + move sharemem create from App to nstackMain +advice rename app_tx_mbuf to VppTCP_APP_TXBUF_POOL +*/ +#define MP_STACKX_APP_TXBUF_POOL "app_tx_mbuf" + +#define MP_MEMPOLL_TCP_BUFF_NAME "VppTCP_MBUF_%u_TCP_BUFF" + +extern int spl_snprintf (char *buffer, int buflen, const char *format, ...); + +/*According to the number of network cards, the establishment of recv lring, + *each separate, each proc_id each NIC queue independent lring + */ +static inline const char * +get_mempoll_rx_name (unsigned proc_id, unsigned nic_id) +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) + * the id may reach 65535, need add more space*/ + static char buffer[sizeof (MP_MEMPOLL_RX_NAME) + 32]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, MP_MEMPOLL_RX_NAME, proc_id, nic_id); //???????????buffer?? + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_rxmsg_name (unsigned proc_id, unsigned nic_id) +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) + * the id may reach 65535, need add more space*/ + static char buffer[sizeof (MP_MEMPOLL_RXMSG_NAME) + 32]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, MP_MEMPOLL_RXMSG_NAME, proc_id, nic_id); //???????????buffer?? + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_ring_name (unsigned proc_id) +{ + static char buffer[sizeof (MP_STACKX_RING_NAME) + 16]; + + int retVal = + spl_snprintf (buffer, sizeof (buffer) - 1, MP_STACKX_RING_NAME, proc_id); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_lring_name (unsigned proc_id) +{ + static char buffer[sizeof (MP_STACKX_LRING_NAME) + 16]; + + int retVal = + spl_snprintf (buffer, sizeof (buffer) - 1, MP_STACKX_LRING_NAME, proc_id); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_msg_name () +{ + static char buffer[sizeof (MP_STACKX_MSG_NAME) + 16]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, MP_STACKX_MSG_NAME); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_tx_name () +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) */ + static char buffer[sizeof (MP_MEMPOLL_TX_NAME) + 16]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, MP_MEMPOLL_TX_NAME); //???????????buffer?? + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_mempoll_seg_name () +{ + /* buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) */ + static char buffer[sizeof (MP_MEMPOLL_SEG_NAME) + 16]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, MP_MEMPOLL_SEG_NAME); //???????????buffer?? + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_memStatusBitSet_name (const char *name, unsigned int num) +{ + static char buffer[64]; + + int retVal = + spl_snprintf (buffer, sizeof (buffer) - 1, MP_STACKX_BIT_SET_NAME "%d", + name, num); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_memNameWithProc (const char *name) +{ + static char buffer[64]; + + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, "%s", name); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +static inline const char * +get_memInstancePoll_name (unsigned int type) +{ + static char buffer[sizeof (MP_STACKX_INSTANCE_POLL_NAME) + 32]; + int retVal = spl_snprintf (buffer, sizeof (buffer) - 1, "%s" "%d", + MP_STACKX_INSTANCE_POLL_NAME, type); + if (-1 == retVal) + { + NSPOL_LOGERR ("spl_snprintf failed]"); + return NULL; + } + + return buffer; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/include/netif/kni_proc.h b/stacks/lwip_stack/lwip_src/include/netif/kni_proc.h new file mode 100644 index 0000000..bcf4129 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/netif/kni_proc.h @@ -0,0 +1,103 @@ +/* +* +* 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 _KNI_PROC_H_ +#define _KNI_PROC_H_ +#include <rte_kni.h> +#include <rte_mempool.h> +#include <rte_mbuf.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define KNI_MAX_KTHREAD 32 + +/* the kni is runned on the lcore from below on */ +#define DEFAULT_KNI_LCORE_BASE 24 + +/* Structure of kni para */ +struct disp_kni_para +{ + u8_t queue_id; + u8_t port_id; +}; + +/* + * Structure of port parameters + */ +struct kni_port_params +{ + uint8_t port_id; /* Port ID */ + unsigned lcore_rx; /* lcore ID for RX */ + unsigned lcore_tx; /* lcore ID for TX */ + uint32_t nb_lcore_k; /* Number of lcores for KNI multi kernel threads */ + uint32_t nb_kni; /* Number of KNI devices to be created */ + unsigned lcore_k[KNI_MAX_KTHREAD]; /* lcore ID list for kthreads */ + struct rte_kni *kni[KNI_MAX_KTHREAD]; /* KNI context pointers */ + struct rte_mempool *kni_pktmbuf_pool; + u8_t ip_reconfigured; +} __rte_cache_aligned; + +/* Structure type for storing kni interface specific stats */ +struct kni_interface_stats +{ + /* number of pkts received from NIC, and sent to KNI */ + uint64_t rx_packets; + + /* number of pkts received from NIC, but failed to send to KNI */ + uint64_t rx_dropped; + + /* number of pkts received from KNI, and sent to NIC */ + uint64_t tx_packets; + + /* number of pkts received from KNI, but failed to send to NIC */ + uint64_t tx_dropped; +}; + +/* External interface for initilizing KNI subsystem */ +int kni_proc_init (enum rte_proc_type_t proc_type, int proc_id, u32_t pmask, + struct kni_port_params **kni_para); + +int kni_proc_init_secondary (int proc_id, int port_id); +/* External interface for destroy KNI subsystem */ +void kni_proc_free (void); + +/* External interface for kni tx thread entry */ +void kni_tx_thread_cycle (void *arg); + +int kni_config_net (void); +void kni_handler_eth_operate_request (int port); + +/* External interface for commiting packet to kni device */ +void kni_dispatch_to_kernel (uint8_t port_id, + struct rte_mbuf *pkts_burst[], uint8_t nb_rx); + +/* the lcore kni tx/rx thread run on */ +unsigned kni_get_tx_lcore (uint8_t port_id); +unsigned kni_get_rx_lcore (uint8_t port_id); + +void init_kni (void); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /*#ifndef _KNI_PROC_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/netif/sc_dpdk.h b/stacks/lwip_stack/lwip_src/include/netif/sc_dpdk.h new file mode 100644 index 0000000..99c3bc6 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/netif/sc_dpdk.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 SC_DPDK_H_ +#define SC_DPDK_H_ + +#include <pbuf.h> +#include <sharedmemory.h> + +#include "lwip/etharp.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define NSTACK_CONFIG_SHM "nstack_config" + +#define MBUF_DATA_SIZE 2048 +#define MBUF_SIZE (MBUF_DATA_SIZE + sizeof(struct common_mem_mbuf) + COMMON_PKTMBUF_HEADROOM) + +extern int g_nstack_bind_cpu; + +inline uint16_t spl_mbuf_refcnt_update (void *mbuf, int16_t value); +struct stack_proc_content *get_stack_proc_content (); + +inline int spl_msg_malloc (data_com_msg ** p_msg_entry); +#define spl_msg_free(p_msg_entry) msg_free(p_msg_entry) +struct spl_pbuf *spl_mbuf_malloc (uint16_t len, spl_pbuf_type type, + u16_t * count); + +inline void spl_mbuf_free (void *mbuf); + +inline int spl_set_lcore_id (unsigned dest_lcore_id); + +static inline unsigned +spl_get_lcore_id () +{ + unsigned core_id = 0; + +#if (DPDK_MODULE != 1) +#ifdef HAL_LIB +#else + core_id = rte_lcore_id (); +#endif + if (core_id >= MAX_THREAD_NUM) + { + core_id = 0; + } +#endif + + return core_id; +} + +int set_share_config (); + +int init_instance (); + +void printmeminfo (); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#endif /* SERVER_DPDK_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/netif/sharedmemory.h b/stacks/lwip_stack/lwip_src/include/netif/sharedmemory.h new file mode 100644 index 0000000..0a92ea0 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/netif/sharedmemory.h @@ -0,0 +1,148 @@ +/* +* +* 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 SHAREDMEMORY_H_ +#define SHAREDMEMORY_H_ +#include "stackxopts.h" +#include <sys/types.h> +#include <semaphore.h> +//#include "stackx/raw.h" +#include "tcp.h" +#include "udp.h" +//#include "stackx/ip.h" +#include "spl_err.h" +#include "list.h" +#include "arch/queue.h" +#include "spl_opt.h" +#include "stackx/spl_ip_addr.h" + +#include "stackx/spl_api.h" +#include <arch/sys_arch.h> +#include "common_mem_api.h" +//#include "stackx/memp.h" +#include "stackx_instance.h" + +#include "hal_api.h" +#ifdef HAL_LIB +#else +#include "rte_ring.h" +#endif + +/** Description for a task waiting in select */ +struct stackx_select_cb +{ + /** Pointer to the next waiting task */ + union + { + struct stackx_select_cb *next; + PTR_ALIGN_TYPE next_a; + }; + + /** Pointer to the previous waiting task */ + union + { + struct stackx_select_cb *prev; + PTR_ALIGN_TYPE prev_a; + }; + + /** semaphore to wake up a task waiting for select */ + //sys_sem_t sem; + union + { + sys_sem_t_v1 sem; + PTR_ALIGN_TYPE sem_a; + }; + + /** readset passed to select */ + fd_set readset; + + /** writeset passed to select */ + fd_set writeset; + + /** unimplemented: exceptset passed to select */ + fd_set exceptset; + + /** don't signal the same semaphore twice: set to 1 when signalled */ + volatile int sem_signalled; + + uint8_t pad_64bit[4]; +}; +/** From epoll.h: Definition of struct stackx_sock and stackx_select_cb ---------End*/ + +enum tcp_run_type +{ + TCP_MUTIPL_INSTANCE = 0, + TCP_MASTER_WORKER, + TCP_DISTRIBUTOR_WORKER, + TCP_RUN_TO_COMPETE, + TCP_PROC_TYPE_END +}; + +enum proc_run_type +{ + PROC_MAIN_RUN_TYPE = 0, + PROC_BACKUP_RUN_TYPE, + PROC_RUN_TYPE_END +}; + +struct linux_port_info +{ + char if_name[HAL_MAX_NIC_NAME_LEN]; + char ip_addr_linux[18]; //uint32_t ip_addr_linux; + char mask_linux[18]; //uint32_t mask_linux; + char bcast_linux[18]; //uint32_t bcast_linux; + char mac_addr[20]; //struct ether_addr mac_addr; + hal_hdl_t hdl; +}; + +struct stackx_port_info +{ + struct stackx_port_info *next_use_port; + struct linux_port_info linux_ip; +}; + +struct stackx_port_zone +{ + unsigned int port_num; + unsigned int bonded_port_num; + struct stackx_port_info *stackx_one_port; +}; + +struct select_cb_entry +{ + struct stackx_select_cb select_cb; + + union + { + sem_t semForSelect; + ALIGN_TYPE pad_64bit[4]; + }; + + union + { + struct select_cb_entry *pre_empty_entry; + PTR_ALIGN_TYPE pre_empty_entry_a; + }; + + union + { + struct select_cb_entry *next_empty_entry; + PTR_ALIGN_TYPE next_empty_entry_a; + }; + +}; + +#endif /* SHAREDMEMORY_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/netif/spl_hal.h b/stacks/lwip_stack/lwip_src/include/netif/spl_hal.h new file mode 100644 index 0000000..ca56663 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/netif/spl_hal.h @@ -0,0 +1,114 @@ +/* +* +* 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 SPL_HAL_H_ +#define SPL_HAL_H_ + +#include "hal_api.h" +#include "netif.h" +#include "nsfw_maintain_api.h" +#include "stackx_spl_share.h" +#include "stackx_pbuf_comm.h" +#include "netifapi.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +int spl_hal_init (int argc, char *argv[]); +int spl_hal_port_init (); + +int spl_hal_stats_display (struct netif *pnetif, char *str, u32_t len, + char *json, u32_t json_len); + +err_t spl_hal_output (struct netif *netif, struct pbuf *buf); +void spl_hal_input (struct netif *netif, struct spl_pbuf **buf); + +inline u16_t spl_hal_recv (struct netif *netif, u8_t id); + +int spl_hal_tx_ip_cksum_enable (); +int spl_hal_tx_udp_cksum_enable (); +int spl_hal_tx_tcp_cksum_enable (); + +u32 spl_hal_is_nic_exist (const char *name); + +int spl_hal_is_bond_netif (struct netif *pnetif); + +static inline void +spl_do_dump (struct spl_pbuf *p, u16 direction) +{ + struct spl_pbuf *q = p; + while (q) + { + ntcpdump (q->payload, q->len, direction); + q = q->next; + } +} + +/* information of bond*/ +#define MAX_BOND_PORT_NUM 4 + +/* information of one bond port */ +struct bond_set +{ + char bond_port_name[HAL_MAX_NIC_NAME_LEN]; + char slave_ports[HAL_MAX_SLAVES_PER_BOND][HAL_MAX_NIC_NAME_LEN]; + u8_t slave_port_cnt; +}; + +#define NETIF_ETH_ADDR_LEN 6 + +/* information of all bond ports */ +struct bond_ports_info +{ + u8_t cnt; + struct bond_set ports[MAX_BOND_PORT_NUM]; +}; + +struct ether_addr +{ + u8_t addr_bytes[NETIF_ETH_ADDR_LEN]; + +}; + +struct netif *get_netif_by_ip (unsigned int ip); +struct netif *netif_check_broadcast_addr (spl_ip_addr_t * addr); +struct netifExt *getNetifExt (u16_t id); +int netifExt_add (struct netif *netif); + +int add_netif_ip (char *netif_name, unsigned int ip, unsigned int mask); +int del_netif_ip (char *netif_name, unsigned int ip); + +err_t spl_netifapi_netif_add (struct netif *pnetif, + spl_ip_addr_t * ipaddr, + spl_ip_addr_t * netmask, + spl_ip_addr_t * gw, + void *state, + netif_init_fn init, + netif_input_fn input, + netifapi_void_fn voidfunc); +struct netif *find_netif_by_if_name (char *if_name); +void ethernetif_packets_input (struct netif *pstnetif); +err_t ethernetif_init (struct netif *pnetif); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#endif /* SPL_HAL_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/internal_msg.h b/stacks/lwip_stack/lwip_src/include/stackx/internal_msg.h new file mode 100644 index 0000000..584ab06 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/internal_msg.h @@ -0,0 +1,90 @@ +/* +* +* 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 __internal_msg_h__ +#define __internal_msg_h__ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#include "nsfw_msg.h" +#include "netif.h" +#include "lwip/netifapi.h" +#include "ip_module_api.h" + +enum netif_msg_type +{ + NETIF_DO_ADD, + NETIF_MSG_API_MAX = MAX_MINOR_TYPE +}; + +/* NETIF_DO_ADD */ +typedef struct msg_add_netif_T +{ + void (*function) (struct msg_add_netif_T * m); + struct netif *netif; + spl_ip_addr_t *ipaddr; + spl_ip_addr_t *netmask; + spl_ip_addr_t *gw; + void *state; + netif_init_fn init; + netif_input_fn input; + netifapi_void_fn voidfunc; + /* no need to extend member */ +} msg_add_netif; + +typedef struct +{ + ip_module_type type; + ip_module_operate_type operate_type; + void *arg; +} msg_ip_module; + +typedef struct msg_internal_callback_T +{ + void (*function) (void *ctx); + void *ctx; +} msg_internal_callback; + +enum timer_msg_type +{ + TIMER_MSG_TIMEOUT, + TIMER_MSG_CLEAR, + TIMER_MSG_MAX = MAX_MINOR_TYPE +}; + +typedef struct msg_timer_T +{ + void *act; + void *arg; +} msg_timer; + +enum mt_msg_type +{ + MT_MSG_VER_MGR, + MT_MSG_MAX = MAX_MINOR_TYPE +}; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __internal_msg_h__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_api.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_api.h new file mode 100644 index 0000000..ea63e90 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_api.h @@ -0,0 +1,276 @@ +/* +* +* 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 __SPL_API_H__ +#define __SPL_API_H__ + +#include "opt.h" +#include "common_mem_base_type.h" +#include <stddef.h> /* for size_t */ +#include "arch/queue.h" +#include "arch/sys_arch.h" +#include "arch/atomic_32.h" +#include "stackx_common_opt.h" +#include "stackx_spl_share.h" + +/* From lwip */ +#include "api.h" +#include "sys.h" +#include "sys_arch.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define MAX_WAIT_TIMEOUT 0x7FFFFFFF + +/* Throughout this file, IPaddresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for struct netconn.flags (u8_t) */ + +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define SPL_NETCONN_FLAG_WRITE_DELAYED 0x01 + +/** Should this netconn avoid blocking? */ +#define SPL_NETCONN_FLAG_NON_BLOCKING 0x02 + +/** Was the last connect action a non-blocking one? */ +#define SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 + +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define SPL_NETCONN_FLAG_NO_AUTO_RECVED 0x08 + +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +// #define NETCONN_FLAG_CHECK_WRITESPACE 0x10 + +enum stackx_model +{ + SOCKET_STACKX = 0, + CALLBACK_STACKX +}; + +enum callback_type +{ + API_ACCEPT_EVENT = 0xF0, + API_RECV_EVENT, + API_SEND_EVENT, + API_CLOSE_EVENT +}; +#if 1 +/** Use to inform the callback function about changes */ +enum spl_netconn_evt +{ + SPL_NETCONN_EVT_RCVPLUS, + SPL_NETCONN_EVT_RCVMINUS, + SPL_NETCONN_EVT_SENDPLUS, + SPL_NETCONN_EVT_SENDMINUS, + SPL_NETCONN_EVT_ERROR, + SPL_NETCONN_EVT_HUP, + SPL_NETCONN_EVT_RDHUP, + SPL_NETCONN_EVT_AGAIN, + SPL_NETCONN_EVT_ACCEPT +}; +#endif +enum +{ + INET_ECN_NOT_ECT = 0, + INET_ECN_ECT_1 = 1, + INET_ECN_ECT_0 = 2, + INET_ECN_CE = 3, + INET_ECN_MASK = 3, +}; + +#define SPL_NETCONNTYPE_GROUP(t) (t & 0xF0) +#define SPL_NETCONNTYPE_DATAGRAM(t) (t & 0xE0) + +/* forward-declare some structs to avoid to include their headers */ +typedef struct common_pcb +{ + enum stackx_model model; + + int socket; + + /** type of the netconn (TCP, UDP or RAW) */ + enum spl_netconn_type type; + + /* share memory between sbr and stackx */ + spl_netconn_t *conn; + + u16 bind_thread_index; + u8 close_progress; + u8 recv_ring_not_empty; + + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. + Also used during connect and close. + */ + data_com_msg *current_msg; + + msg_write_buf *msg_head; + msg_write_buf *msg_tail; + + size_t write_offset; + + /** timeout to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; + + /* timeout to wait for send buffer writtable */ + int send_timeout; + + int sk_rcvlowat; + + //DFX stat for connection packet + /* dfx_conn_t dfx; */ + + /*store the hostpid info for release */ + uint32_t hostpid; + u8_t l4_tick; /* if is odd number, use l4 ring first */ + u8_t dataSentFlag; + + nsfw_res res_chk; +} common_pcb; + +/** A callback prototype to inform about events for a netconn */ +//typedef void (*netconn_callback)(struct spl_netconn *, enum netconn_evt, u16_t len); + +/* Though these callback pointers are not set and referenced in nStack Core, still +the padding is required since the structure will be used in netconn and it needs +padding across 32-bit and 64-bit architecture */ +typedef struct +{ + union + { + int (*accept_event) (struct spl_netconn * conn); + PTR_ALIGN_TYPE accept_event_a; + }; + + union + { + int (*recv_event) (struct spl_netconn * conn); + PTR_ALIGN_TYPE recv_event_a; + }; + union + { + int (*send_event) (struct spl_netconn * conn); + PTR_ALIGN_TYPE send_event_a; + }; + union + { + int (*close_event) (struct spl_netconn * conn); + PTR_ALIGN_TYPE close_event_a; + }; +} callback_funcation; + +union ring_addr_u +{ + void *ring_addr; + PTR_ALIGN_TYPE ring_addr_a; +}; + +struct mem_manage +{ + volatile uint32_t current_read; + volatile uint32_t current_write; + union ring_addr_u ring_addr[RECV_MAX_POOL]; + union ring_addr_u l4_ring; /* recv ring for l4 */ + //void *ring_addr[RECV_MAX_POOL]; +}; + +/* Pbuf free should be done in network stack */ +struct spl_netconn_recvbuf_recoder +{ + struct spl_pbuf *head; + struct spl_pbuf *tail; + int totalLen; +}; + +/** Register an Network connection event */ +void spl_event_callback (spl_netconn_t * conn, enum spl_netconn_evt evt, + int postFlag); + +#define SPL_API_EVENT(c, e, p) spl_event_callback(c, e, p) + +/** Set conn->last_err to err but don't overwrite fatal errors */ +#define SPL_NETCONN_SET_SAFE_ERR(conn, err) do { \ + SYS_ARCH_PROTECT(lev); \ + if (!ERR_IS_FATAL((conn)->last_err)) { \ + (conn)->last_err = err; \ + } \ + SYS_ARCH_UNPROTECT(lev); \ + } while (0); + +/** Set the blocking status of netconn calls (@todo: write/send is missing) */ +#define spl_netconn_set_nonblocking(conn, val) do { if (val) { \ + (conn)->flags |= SPL_NETCONN_FLAG_NON_BLOCKING; \ + } else { \ + (conn)->flags &= ~SPL_NETCONN_FLAG_NON_BLOCKING; }} while (0) + +/** Get the blocking status of netconn calls (@todo: write/send is missing) */ +#define spl_netconn_is_nonblocking(conn) (((conn)->flags & SPL_NETCONN_FLAG_NON_BLOCKING) != 0) + +/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define spl_netconn_set_noautorecved(conn, val) do { if (val) { \ + (conn)->flags |= SPL_NETCONN_FLAG_NO_AUTO_RECVED; \ + } else { \ + (conn)->flags &= ~SPL_NETCONN_FLAG_NO_AUTO_RECVED; }} while (0) + +/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define spl_netconn_get_noautorecved(conn) (((conn)->flags & SPL_NETCONN_FLAG_NO_AUTO_RECVED) != 0) + +/** Set the receive timeout in milliseconds */ +#define spl_netconn_set_recvtimeout(cpcb, timeout) ((cpcb)->recv_timeout = (timeout)) + +/** Get the receive timeout in milliseconds */ +#define spl_netconn_get_recvtimeout(cpcb) ((cpcb)->recv_timeout) + +/** Set the send timeout in milliseconds */ +#define spl_netconn_set_sendtimeout(cpcb, timeout) ((cpcb)->send_timeout = (timeout)) + +/** Get the send timeout in milliseconds */ +#define spl_netconn_get_sendtimeout(cpcb) ((cpcb)->send_timeout) + +#define spl_netconn_set_sendbufsize(conn, sendbufsize) ((conn)->send_bufsize = (sendbufsize)) + +/* "man 7 socket" information + SO_SNDBUF + Sets or _gets the maximum socket send buffer in bytes. The kernel doubles + this value (to allow space for bookkeeping overhead) when it is set using + setsockopt(2), and this doubled value is returned by getsockopt(2). +*/ +#define spl_netconn_get_sendbufsize(conn) (2 *((conn)->send_bufsize)) + +#define spl_netconn_set_reclowbufsize(cpcb, recvlowbufsize) ((cpcb)->sk_rcvlowat = ((recvlowbufsize) > 0) ? recvlowbufsize : 1) +#define spl_netconn_get_reclowbufsize(cpcb) ((cpcb)->sk_rcvlowat) + +extern int spl_post_msg (u16 mod, u16 maj, u16 min, u16 op, char *data, + u16 data_len, u32 src_pid); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_API_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_api_msg.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_api_msg.h new file mode 100644 index 0000000..94b681e --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_api_msg.h @@ -0,0 +1,129 @@ +/* +* +* 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 __LWIP_API_MSG_H__ +#define __LWIP_API_MSG_H__ + +#include <stddef.h> +#include <net/if.h> +#include <sys/ioctl.h> + +#include "nsfw_msg.h" +#include "spl_opt.h" +#include "spl_ip_addr.h" +#include "spl_err.h" +#include "spl_api.h" +//#include "sockets.h" +#include "stackx_spl_share.h" +#include "stackx_spl_msg.h" + +/* From lwip */ +#include "tcp.h" +#include "udp.h" +#include "sys.h" + +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* For the netconn API, these values are use as a bitmask! */ +#define NETCONN_SHUT_RD 1 +#define NETCONN_SHUT_WR 2 +#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) + +struct callback_fn +{ + tcp_sent_fn sent_fn; + tcp_recv_fn recv_fn; + tcp_connected_fn connected_fn; + tcp_poll_fn poll_fn; + tcp_err_fn err_fn; + tcp_err_fn close_fn; + tcp_accept_fn accept_fn; +}; + +#ifdef HAL_LIB +#else +typedef enum _mbuf_recyle_flg +{ + MBUF_UNUSED = 0, + MBUF_HLD_BY_APP = 1, + MBUF_HLD_BY_SPL = 2, +} mbuf_recycle_flg; +#endif + +err_t sp_enqueue (struct common_pcb *cpcb, void *p); +err_t accept_dequeue (spl_netconn_t * lconn, void **new_buf, + u32_t timeout /*miliseconds */ ); +err_t accept_enqueue (spl_netconn_t * conn, void *p); +void free_conn_by_spl (spl_netconn_t * conn); +void unlink_pcb (struct common_pcb *cpcb); +void do_try_delconn (void *close_data, u32 delay_sec); +void do_delconn (struct common_pcb *cpcb, msg_delete_netconn * msg); +void do_bind (struct common_pcb *cpcb, msg_bind * msg); +void do_pbuf_free (struct spl_pbuf *buf); +void do_connect (struct common_pcb *cpcb, msg_connect * msg); +void do_listen (struct common_pcb *cpcb, msg_listen * msg); +void do_send (struct common_pcb *cpcb, msg_send_buf * msg); +void do_recv (struct common_pcb *cpcb, msg_recv_buf * msg); +void do_write (struct common_pcb *cpcb, msg_write_buf * msg); +void do_getaddr (struct common_pcb *cpcb, msg_getaddrname * msg); +void do_close (struct common_pcb *cpcb, msg_close * msg); +void do_getsockopt_internal (struct common_pcb *cpcb, + msg_setgetsockopt * smsg); +void do_setsockopt_internal (struct common_pcb *cpcb, + msg_setgetsockopt * smsg); +void do_getsockname (struct common_pcb *cpcb, msg_getaddrname * amsg); +int netconn_drain (enum spl_netconn_type t, spl_netconn_t * conn); +int spl_pcb_new (msg_new_netconn * m); +void do_app_touch (msg_app_touch * smsg); +int do_close_finished (struct common_pcb *cpcb, u8_t close_finished, + u8_t shut, err_t err, int OpShutDown); +err_t do_writemore (struct spl_netconn *conn); +err_t do_close_internal (struct common_pcb *cpcb, int OpShutDown); + +u8 get_shut_op (data_com_msg * m); +int ks_to_stk_opt (int opt); +void update_tcp_state (spl_netconn_t * conn, enum tcp_state state); + +err_t spl_poll_tcp (void *arg, struct tcp_pcb *pcb); +err_t spl_recv_tcp (void *arg, struct tcp_pcb *pcb, struct pbuf *p, + err_t err); +err_t spl_sent_tcp (void *arg, struct tcp_pcb *pcb, u16_t len); +void spl_err_tcp (void *arg, err_t err); +err_t spl_tcp_recv_null (void *arg, struct tcp_pcb *pcb, struct pbuf *p, + err_t err); +err_t spl_do_connected (void *arg, struct tcp_pcb *pcb, err_t err); +err_t spl_accept_function (void *arg, struct tcp_pcb *newpcb, err_t err); + +struct common_pcb *alloc_common_pcb (); +void free_common_pcb (struct common_pcb *cpcb); +int common_pcb_init (struct common_pcb *cpcb); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_API_MSG_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_err.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_err.h new file mode 100644 index 0000000..a0188be --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_err.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. +*/ + +#ifndef __STACKX_ERR_H__ +#define __STACKX_ERR_H__ + +#include "spl_opt.h" +#include "lwip/arch.h" +#include "stackx_err.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +typedef s8_t err_t; + +/* Definitions for error constants. */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_ERR_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_instance.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_instance.h new file mode 100644 index 0000000..697c67d --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_instance.h @@ -0,0 +1,30 @@ +/* +* +* 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 _SPL_INSTANCE_H_ +#define _SPL_INSTANCE_H_ +#include "nsfw_msg_api.h" +#include "stackx_instance.h" + +extern stackx_instance *p_def_stack_instance; + +int spl_process (data_com_msg * m); + +void add_disp_netif (struct netif *netif); +void do_update_pcbstate (); +void init_stackx_lwip (); + +#endif /* _SPL_INSTANCE_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_netbuf.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_netbuf.h new file mode 100644 index 0000000..cd2e1bf --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_netbuf.h @@ -0,0 +1,52 @@ +/* +* +* 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 __LWIP_NETBUF_H__ +#define __LWIP_NETBUF_H__ + +#include "spl_opt.h" +#include "spl_pbuf.h" +#include "spl_ip_addr.h" +#include "common_mem_base_type.h" +#include "common_mem_pal.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_netbuf.h" +#include <sys/uio.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** This spl_netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 + +/** This spl_netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + +void spl_netbuf_delete (struct spl_netbuf *buf); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_NETBUF_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_pbuf.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_pbuf.h new file mode 100644 index 0000000..01fe242 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_pbuf.h @@ -0,0 +1,173 @@ +/* +* +* 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 __STACKX_PBUF_H__ +#define __STACKX_PBUF_H__ + +#include "cc.h" + +#include "common_mem_base_type.h" +#include "stackx_pbuf_comm.h" +#include "common_mem_mbuf.h" + +#ifdef HAL_LIB +#else +#include "common_pal_bitwide_adjust.h" +#endif + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +extern u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +/** indicates this pbuf is loop buf .*/ +#define PBUF_FLAG_LOOPBUF 0x08U + +#define PBUF_SET_LOOP_FLAG(buf) ((buf)->flags |= PBUF_FLAG_LOOPBUF) +#define PBUF_IS_LOOP_BUF(buf) ((buf)->flags & PBUF_FLAG_LOOPBUF) + +/*Add 1 parameter, the last one, indicating which dpdk_malloc + *should be allocated from the pool; non-PBUF_ALLOC type regardless of this parameter*/ +struct spl_pbuf *spl_pbuf_alloc_hugepage (spl_pbuf_layer l, u16_t length, + spl_pbuf_type type, + u16_t thread_index, void *net_conn); +struct pbuf *spl_convert_spl_pbuf_to_pbuf (struct spl_pbuf *p_from); +err_t pbuf_to_splpbuf_copy (struct spl_pbuf *p_to, struct pbuf *p_from); +err_t splpbuf_to_pbuf_copy (struct pbuf *p_to, struct spl_pbuf *p_from); +spl_pbuf_layer get_pbuf_layer_from_pbuf_payload (struct pbuf *buf); +void print_pbuf_payload_info (struct pbuf *buf, bool send); + +static inline u8_t +spl_pbuf_header (struct spl_pbuf *p, s16_t header_size_increment) +{ + u8_t pbuf_ret; + /* header max len is tcp len+ ip len: 0xf*4+PBUF_IP_HLEN */ + if (unlikely + (((header_size_increment) < 0 && (-(header_size_increment)) > p->len) + || (header_size_increment > 0 + && (header_size_increment) >= (0xf * 4 + SPL_PBUF_IP_HLEN)))) + { + pbuf_ret = 1; + } + else + { + p->payload_a = p->payload_a - (header_size_increment); + p->len += (header_size_increment); + p->tot_len += (header_size_increment); + pbuf_ret = 0; + } + return pbuf_ret; +} + +void spl_pbuf_realloc (struct spl_pbuf *p, u32_t size); + +void spl_pbuf_cat (struct spl_pbuf *head, struct spl_pbuf *tail); +void spl_pbuf_free (struct spl_pbuf *p); + +#define pbuf_free_safe(x)\ +{\ + spl_pbuf_free((x));\ + (x) = NULL;\ +} + +/** + * Count number of pbufs in a chain + * + * @param p first pbuf of chain + * @return the number of pbufs in a chain + */ +static inline u16_t +spl_pbuf_clen (struct spl_pbuf *p) +{ + u16_t len = 0; + while (p != NULL) + { + ++len; + p = (struct spl_pbuf *) ADDR_SHTOL (p->next_a); + } + return len; +} + +static inline u16_t +mbuf_count (struct spl_pbuf *p) +{ + u16_t count = 0; + struct spl_pbuf *buf = p; + struct common_mem_mbuf *mbuf; + while (buf) + { + mbuf = + (struct common_mem_mbuf *) ((char *) buf - + sizeof (struct common_mem_mbuf)); + while (mbuf) + { + count++; +#ifdef HAL_LIB +#else + mbuf = mbuf->next; +#endif + } + buf = (struct spl_pbuf *) ADDR_SHTOL (buf->next_a); //buf->next; + } + return count; +} + +static inline u16_t +mbuf_count_in_one_pbuf (struct spl_pbuf *p) +{ + + u16_t cnt = 0; + struct common_mem_mbuf *mbuf; + if (NULL == p) + { + NSPOL_LOGERR ("Invalid param : p(null) !"); + return 0; + } + + mbuf = + (struct common_mem_mbuf *) ((char *) p - sizeof (struct common_mem_mbuf)); + + /* no need to check mbuf itself */ +#ifdef HAL_LIB +#else + if (!mbuf->next) +#endif + return 1; + + while (mbuf) + { + ++cnt; +#ifdef HAL_LIB +#else + mbuf = mbuf->next; +#endif + } + + return cnt; +} + +inline int pbuf_internal_copy (struct spl_pbuf *dst, struct spl_pbuf *src); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_PBUF_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_sbr.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_sbr.h new file mode 100644 index 0000000..a4d6ccc --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_sbr.h @@ -0,0 +1,33 @@ +/* +* +* 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 _SPL_SBR_H_ +#define _SPL_SBR_H_ +#include "nsfw_msg_api.h" +#include "tcp.h" +#include "udp.h" +//#include "stackx/raw.h" +#define COMM_PRIVATE_PTR(m) \ + ((m->param.receiver) ? ((struct common_pcb *)m->param.comm_receiver) : 0) +#define TCP_PRIVATE_PTR(m) \ + ((m->param.receiver) ? (*(struct tcp_pcb **)m->param.receiver) : 0) +#define UDP_PRIVATE_PTR(m) \ + ((m->param.receiver) ? (*(struct udp_pcb **)m->param.receiver) : 0) +/*#define RAW_PRIVATE_PTR(m) \ + ((m->param.receiver) ? (*(void *)m->param.receiver) : 0) */ + +int spl_sbr_process (data_com_msg * m); +#endif /* _SPL_SBR_H_ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_sockets.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_sockets.h new file mode 100644 index 0000000..278bb02 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_sockets.h @@ -0,0 +1,252 @@ +/* +* +* 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 __STACKX_SOCKETS_H__ +#define __STACKX_SOCKETS_H__ + +#include <errno.h> +#include <stddef.h> /* for size_t */ +#include "arch/sys_arch.h" +#include "sys/socket.h" +#include <errno.h> +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#ifndef socklen_t +#define socklen_t u32_t +#endif + +#define SET_STACKP_ERRNO(err) (errno = (err)) //thread-local errno + +#ifndef set_errno +#define set_errno(err) SET_STACKP_ERRNO(err) +#endif + +#define sock_set_errno(sk, e) do { \ + (sk)->err = (e); \ + if ((sk)->err != 0) \ + set_errno((sk)->err); \ + } while (0) + +#ifndef __BITS_SOCKET_H +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info storing */ +#define SO_REUSEADDR 0x0002 +#endif + +#define SO_DONTROUTE 5 //0x0010 /* Unimplemented: just use interface addresses */ +#define SO_BROADCAST 6 //0x0020 /* permit to send and to receive broad cast messages*/ +#define SO_KEEPALIVE 9 //0x0008 gaussdb /* keep connections alive */ +#define SO_OOBINLINE 10 //0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_LINGER 13 //0x0080 /* linger on close if data present */ +#define SO_REUSEPORT 15 /* Unimplemented: allow local address & port reuse */ +#define SO_ACCEPTCONN 30 //0x0002 /* socket has had listen() */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ + +#define SO_DONTLINGER ((int)(~SO_LINGER)) + +/* + * Additional options, not kept in so_options. + */ +#define SO_TYPE 3 /* get socket type */ +#define SO_ERROR 4 +#define SO_SNDBUF 7 /* send buffer size */ +#define SO_RCVBUF 8 /* receive buffer size */ +#define SO_NO_CHECK 11 /* don't create UDP checksum */ +#define SO_RCVLOWAT 18 /* receive low-water mark */ +#define SO_SNDLOWAT 19 /* send low-water mark */ +#define SO_RCVTIMEO 20 /* receive timeout */ +#define SO_SNDTIMEO 21 /* Unimplemented: send timeout */ + +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 1 //0xfff + +#ifndef __BITS_SOCKET_H + +#define AF_UNSPEC 0 +#define PF_UNSPEC AF_UNSPEC +#define AF_INET 2 +#define PF_INET AF_INET + +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#define IPPROTO_UDPLITE 136 + +#define IPPROTO_IP 0 + +#define MSG_PEEK 0x02 +#define MSG_WAITALL 0x100 +#define MSG_OOB 0x01 +#define MSG_DONTWAIT 0x40 +#define MSG_MORE 0x8000 +#endif + +#define IP_TOS 1 +#define IP_TTL 2 + +#define RCV_WND 0x21 +#define RCV_ANN_WND 0x22 +#define INIT_CWND 0x23 +#define THRESHOLD_FACTOR 0x24 +#define TMR_INTERVAL 0x25 + +/* + * Options and types for UDP multicast traffic handling + */ +#ifndef __BITS_SOCKET_H +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 +#endif + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_LOWCOST 0x02 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_MINCOST IPTOS_LOWCOST +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_ROUTINE 0x00 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) + +#if !defined (FIONREAD) || !defined (FIONBIO) +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_INOUT (IOC_IN | IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */ + +#define _IO(x, y) (((x) << 8) | (y) |IOC_VOID ) + +#define _IOR(x, y, t) (IOC_OUT | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) + +#define _IOW(x, y, t) (IOC_IN | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) +#endif + +/*unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) +#define SIOCGHIWAT _IOR('s', 1, unsigned long) +#define SIOCSLOWAT _IOW('s', 2, unsigned long) +#define SIOCGLOWAT _IOR('s', 3, unsigned long) +#ifndef __BITS_SOCKET_H +#define SIOCATMARK _IOR('s', 7, unsigned long) +#endif +#endif + +/* commands for fnctl */ +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 0X800 /* nonblocking I/O */ +#endif +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK /* same as O_NONBLOCK, for compatibility */ +#endif + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0x80000 /* set close_on_exec */ +#endif +#ifndef __BITS_SOCKET_H +#define SOCK_CLOEXEC O_CLOEXEC +#endif +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 +#endif +#ifndef SHUT_RD +#define SHUT_RD 0 +#define SHUT_WR 1 +#define SHUT_RDWR 2 +#endif + +struct pollfd +{ + + int fd; /* file descriptor */ + short events; /* wait event */ + short revents; /* actual event happened */ +}; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_SOCKETS_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_tcpip.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_tcpip.h new file mode 100644 index 0000000..0f885d6 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_tcpip.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 __STACKX_TCPIP_H__ +#define __STACKX_TCPIP_H__ + +#include "spl_opt.h" +#include "stackx/spl_ip_addr.h" +#include "tcp.h" + +#define USEAGE_LOW 60 +#define USEAGE_HIGHT 80 +#define USEAGE_INVALID 0xFF + +/*** Put into stackx_instance ********* + +************************************/ +#include "stackx/spl_api_msg.h" +#include "netifapi.h" +#include "stackx/spl_pbuf.h" +#include "stackx/spl_api.h" +#include "sys.h" +#include "netif.h" +#include "ip_module_api.h" +#include "internal_msg.h" +#include "pbuf.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** Function prototype for send timeout message */ +err_t ltt_apimsg (sys_timeout_handler h, void *arg); + +/** Function prototype for the init_done function passed to tcpip_init */ +typedef void (*tcpip_init_done_fn) (void *arg); + +/** Function prototype for functions passed to tcpip_callback() */ +typedef void (*tcpip_callback_fn) (void *ctx); + +int init_by_main_thread (); +int init_by_tcpip_thread (); +err_t spl_tcpip_input (struct pbuf *p, struct netif *inp); + +int post_ip_module_msg (void *arg, ip_module_type type, + ip_module_operate_type operate_type); +int process_ip_module_msg (void *arg, ip_module_type type, + ip_module_operate_type operate_type); +int init_new_network_configuration (); + +#if STACKX_NETIF_API +err_t tcpip_netif_add (msg_add_netif * tmp); +#endif /* STACKX_NETIF_API */ + +err_t ltt_clearTmrmsg (void *pcb, void *arg); + +sys_mbox_t get_primary_box (); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_TCPIP_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/spl_timers.h b/stacks/lwip_stack/lwip_src/include/stackx/spl_timers.h new file mode 100644 index 0000000..4809b2b --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/spl_timers.h @@ -0,0 +1,108 @@ +/* +* +* 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 __SPL_TIMERS_H__ +#define __SPL_TIMERS_H__ + +#include "opt.h" +#include "common_mem_base_type.h" + +typedef void (*sys_timeout_handler) (void *arg); + +#include "rb_tree.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ + +/* + * ************************************************************************* + * PTIMER defined 2013/3/15 + * ************************************************************************* + */ +#define PTIMER_DEFAULT 0x00 /* periodic mode */ +#define PTIMER_ONESHOT 0x01 +#define PTIMER_USER_DEF 0x02 + +enum msg_type +{ + SYS_PTIMEROUT_MSG, + SYS_UNPTIMEROUT_MSG, +}; + +struct msg_context +{ + unsigned long msec; + union + { + sys_timeout_handler handle; + } action; +#define _act_category action.act_category +#define _phandle action.handle + u32_t flags; /* oneshot|user_def|... */ + void *ctx; /* pcb ptr */ +}; + +struct ptimer_node +{ + struct rb_node node; + unsigned long abs_nsec; + struct msg_context info; + unsigned long state; + u16_t index; /* store a lwip thread message box id */ +}; + +struct ptimer_msg +{ + enum msg_type msg_type; + struct ptimer_node *node; + struct ptimer_msg *next, *prev; +}; + +struct ptimer_base +{ + struct rb_root active; + struct rb_node *first; /* point the recently timeout */ + pthread_mutex_t lock; + pthread_cond_t cond; + struct ptimer_msg *head, *tail; +}; + +/* + * ***************************************************** + * ptimer E-N-D + * ***************************************************** + */ +void ptimer_thread (void *arg); +void timeout_phandler (void *act, void *arg); +void regedit_ptimer (enum msg_type type, sys_timeout_handler handler, + struct ptimer_node *node); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __LWIP_TIMERS_H__ */ diff --git a/stacks/lwip_stack/lwip_src/include/stackx/stackx_instance.h b/stacks/lwip_stack/lwip_src/include/stackx/stackx_instance.h new file mode 100644 index 0000000..679d2ac --- /dev/null +++ b/stacks/lwip_stack/lwip_src/include/stackx/stackx_instance.h @@ -0,0 +1,91 @@ +/* +* +* 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 __STACKX_INSTANCE_H__ +#define __STACKX_INSTANCE_H__ + +#include "stackx/spl_tcpip.h" +#include "netif.h" +#include "lwip/ip4_frag.h" +#include "stackx/spl_pbuf.h" +#include "arch/sys_arch.h" +#include "arch/queue.h" +#include "stackx_tx_box.h" +#include "nsfw_msg.h" +#include "stackx_app_res.h" +#include "ip_module_api.h" +#include "tcp.h" +#include "udp.h" + +#define PKT_BURST 32 + +#define TASK_BURST 16 + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define MAX_NETBUFS 1024*2 //define for C10M + +#define TOTAL_MSG_QUEUE_NUM (MSG_PRIO_QUEUE_NUM+1) /* three priority queue and one primary queue */ + +struct stackx_stat +{ + struct rti_queue primary_stat; //primary box stat + u64_t extend_member_bit; +}; + +struct stackx_stack +{ + struct queue primary_mbox; + struct queue priority_mbox[MSG_PRIO_QUEUE_NUM]; //0-highest; 1-medium; 2-lowest + //stackx_apis stackx_api; +}; + +struct disp_netif_list +{ + struct disp_netif_list *next; + struct netif *netif; +}; + +typedef struct stackx_instance +{ + uint16_t rss_queue_id; + + mpool_handle mp_tx; + //mring_handle mp_seg; + mring_handle cpcb_seg; + mring_handle lmsg_pool; + + struct stackx_stack lstack; + struct stackx_stat lstat; //point to p_stackx_table->lstat[i]; + + /** + * Header of the input packet currently being processed. + */ + /* global variables */ + struct disp_netif_list *netif_list; +} stackx_instance; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* __STACKX_INSTANCE_H__ */ diff --git a/stacks/lwip_stack/lwip_src/instance/spl_instance.c b/stacks/lwip_stack/lwip_src/instance/spl_instance.c new file mode 100644 index 0000000..69b9d82 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/instance/spl_instance.c @@ -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. +*/ + +#include "nsfw_msg_api.h" +#include "nsfw_init.h" +#include "stackx/spl_sbr.h" +#include "stackx/stackx_instance.h" + +stackx_instance *p_def_stack_instance = NULL; + +/** + * process message from other module, but the MT module message will be delayed + * to handle in the end of the loop to avoid to lose the message dequeued out. + * + * @param m the data_com_msg to handle + */ +int +spl_process (data_com_msg * m) +{ + return call_msg_fun (m); +} + +void +add_disp_netif (struct netif *netif) +{ + struct disp_netif_list *item = malloc (sizeof (struct disp_netif_list)); + if (!item) + { + NSPOL_LOGERR ("malloc failed"); + return; + } + + item->netif = netif; + item->next = p_def_stack_instance->netif_list; + p_def_stack_instance->netif_list = item; +} diff --git a/stacks/lwip_stack/lwip_src/ip_module/configuration_reader.c b/stacks/lwip_stack/lwip_src/ip_module/configuration_reader.c new file mode 100644 index 0000000..d5b228b --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/configuration_reader.c @@ -0,0 +1,1045 @@ +/* +* +* 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 <unistd.h> +#include <sys/wait.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <time.h> +#include <pthread.h> +#include <sys/types.h> +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include "configuration_reader.h" +#include "container_ip.h" +#include "network.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "json.h" +#include "spl_tcpip.h" + +#include <types.h> +#include <nsfw_mgr_com_api.h> +#include <nsfw_base_linux_api.h> +#include "nsfw_maintain_api.h" + +NSTACK_STATIC struct config_data g_ip_module_buff; +NSTACK_STATIC struct config_data *g_config_data; +NSTACK_STATIC char ip_module_unix_socket[IP_MODULE_MAX_PATH_LEN + 1]; +NSTACK_STATIC char ip_module_unix_socket_dir_path[IP_MODULE_MAX_PATH_LEN + 1]; +//static unsigned long int g_thread_id = 0; + +#define MAX_CONNECTION_NUMBER 5 +#define TCP_OOS_LEN_MAX 250 + +NSTACK_STATIC int read_configuration (); +NSTACK_STATIC int unix_socket_listen (const char *servername); +NSTACK_STATIC int process_query (); + +/***************************************************************************** +* Prototype : is_digit_str +* Description : check if a string contains only digit +* Input : char *input +* Output : 1 for yes, 0 for no +* Return Value : int +* Calls : +* Called By : get_main_pid +* +*****************************************************************************/ +NSTACK_STATIC int +is_digit_str (char *input) +{ + if (NULL == input || '\0' == input[0]) + { + return 0; + } + + while (*input) + { + if (*input > '9' || *input < '0') + { + return 0; + } + input++; + } + + return 1; +} + +/***************************************************************************** +* Prototype : process_query +* Description : ./nStackCtrl -a query +* Input : none +* Output : none +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC int +process_query () +{ + int retval; + + if (0 == g_config_data->param.type[0]) + { + return process_post (NULL, IP_MODULE_ALL, IP_MODULE_OPERATE_QUERY); + } + + /*name & p are freed inside process_post */ + if (0 == strcmp (g_config_data->param.type, IP_MODULE_TYPE_PORT)) + { + struct ip_action_param *p = malloc (sizeof (struct ip_action_param)); + if (p == NULL) + { + NSOPR_LOGERR ("name allocation failed!"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "mem alloc error!"); + return -1; + } + + retval = + MEMSET_S (p, sizeof (struct ip_action_param), 0, + sizeof (struct ip_action_param)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "MEMSET_S error!"); + free (p); + return -1; + } + + retval = + STRCPY_S (p->container_id, sizeof (p->container_id), + g_config_data->param.container_id); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (p); + return -1; + } + + retval = + STRCPY_S (p->port_name, sizeof (p->port_name), + g_config_data->param.name); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (p); + return -1; + } + + return process_post ((void *) p, IP_MODULE_IP, IP_MODULE_OPERATE_QUERY); + } + else if (0 == strcmp (g_config_data->param.type, IP_MODULE_TYPE_NETWORK)) + { + if (0 == g_config_data->param.name[0]) + { + return process_post (NULL, IP_MODULE_NETWORK_ALL, + IP_MODULE_OPERATE_QUERY); + } + else + { + char *name = malloc (sizeof (g_config_data->param.name)); + if (NULL == name) + { + NSOPR_LOGERR ("name allocation failed!"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "mem alloc error!"); + return -1; + } + + retval = + MEMSET_S (name, sizeof (g_config_data->param.name), 0, + sizeof (g_config_data->param.name)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "MEMSET_S error!"); + free (name); + return -1; + } + + retval = + STRCPY_S (name, sizeof (g_config_data->param.name), + g_config_data->param.name); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (name); + return -1; + } + + return process_post ((void *) name, IP_MODULE_NETWORK, + IP_MODULE_OPERATE_QUERY); + } + } + else if (0 == strcmp (g_config_data->param.type, IP_MODULE_TYPE_IP)) + { + if (0 == g_config_data->param.name[0]) + { + return process_post (NULL, IP_MODULE_IP_ALL, + IP_MODULE_OPERATE_QUERY); + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + } + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + } + + return -1; +} + +int +read_ipmoduleoperatesetnet_configuration () +{ + if (strcmp (g_config_data->param.type, IP_MODULE_TYPE_SETLOG) == 0) + { + if (NSCRTL_OK == + setlog_level_value (g_config_data->param.name, + g_config_data->param.value)) + { + NSOPR_LOGDBG ("set log level ok!"); + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + } + } + else if (strcmp (g_config_data->param.type, TCP_MODULE_TYPE_SET_OOS_LEN) == + 0) + { + if (is_digit_str (g_config_data->param.value) == 0) + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, + "Invalid value:value must be digital and smaller than %u]value=\"%s\"", + TCP_OOS_LEN_MAX, g_config_data->param.value); + return 0; + } + + unsigned int value_len = strlen (g_config_data->param.value); + if ((value_len >= 2) && (g_config_data->param.value[0] == '0')) + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, + "Invalid value:value cannot start with 0"); + return 0; + } + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + } + + return 0; +} + +/***************************************************************************** +* Prototype : read_version +* Description : Query Version by nStackCtrl +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +read_version () +{ + int retVal; + json_object *version = json_object_new_object (); + + if (NULL == version) + { + NSOPR_SET_ERRINFO (NSCRTL_ERR, "internal error for version=NULL!"); + return NSCRTL_ERR; + } + + json_object_object_add (version, "moudle", + json_object_new_string (NSTACK_GETVER_MODULE)); + json_object_object_add (version, "version", + json_object_new_string (NSTACK_GETVER_VERSION)); + json_object_object_add (version, "buildtime", + json_object_new_string (NSTACK_GETVER_BUILDTIME)); + + json_object *version_array = json_object_new_array (); + if (NULL == version_array) + { + json_object_put (version); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "internal error for version_array=NULL!"); + return NSCRTL_ERR; + } + + retVal = json_object_array_add (version_array, version); + + if (0 != retVal) + { + json_object_put (version_array); + json_object_put (version); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "internal error for json_object_array_add failed!"); + return NSCRTL_ERR; + } + + const char *str = json_object_to_json_string (version_array); + + if (NULL == str) + { + json_object_put (version_array); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "internal error for str=NULL!"); + return NSCRTL_ERR; + } + + size_t str_len = strlen (str); + if (str_len >= sizeof (get_config_data ()->json_buff)) + { + json_object_put (version_array); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "internal error!"); + return NSCRTL_ERR; + } + + retVal = + STRNCPY_S (get_config_data ()->json_buff, + sizeof (get_config_data ()->json_buff), str, str_len); + if (EOK != retVal) + { + json_object_put (version_array); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRNCPY_S error!"); + return NSCRTL_ERR; + } + + json_object_put (version_array); + return NSCRTL_OK; +} + +void +reset_config_data (void) +{ + int retval = MEMSET_S (g_config_data, sizeof (struct config_data), 0, + sizeof (struct config_data)); + if (EOK != retval) + { + printf ("MEMSET_S failed]retval=%d.\n", retval); + exit (1); + } +} + +int +get_network_json_data () +{ + STRCPY_S (g_config_data->param.type, sizeof (g_config_data->param.type), + "network"); + g_config_data->param.action = IP_MODULE_OPERATE_ADD; + + char *tmp_config_path; + tmp_config_path = realpath ("./network_data_tonStack.json", NULL); + if (!tmp_config_path) + { + exit (1); + } + + int fp = open (tmp_config_path, O_RDONLY); + if (-1 == fp) + { + free (tmp_config_path); + NSTCP_LOGINF ("network file open failed.\n"); + exit (1); + } + free (tmp_config_path); + + int nread = read (fp, g_config_data->json_buff, + sizeof (g_config_data->json_buff) - 1); + if (nread <= 0) + { + close (fp); + NSTCP_LOGINF ("read failed %d.\n", nread); + exit (1); + } + + /* though MEMSET_S is done above, MEMSET_S can be removed */ + g_config_data->json_buff[nread] = '\0'; + close (fp); + + struct network_configuration *network = NULL; + struct network_configuration *tmp = NULL; + + /* input shouldnot be same with return */ + network = parse_network_json (g_config_data->json_buff, NULL); + if (!network) + { + NSTCP_LOGINF ("Invalid network data!"); + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "Invalid network data!"); + return -1; + } + + /* run process_post for each network, not only the head node */ + while (network) + { + tmp = network; + network = network->next; + int retval = + add_network_configuration ((struct network_configuration *) tmp); + + /* When network exceeds max number, just log warning at operation.log */ + if (retval == NSCRTL_NETWORK_COUNT_EXCEED) + { + NSTCP_LOGINF + ("Warning!! Network count exceed max allowed number]max=%d", + MAX_NETWORK_COUNT); + } + else + { + + NSTCP_LOGINF ("add_network_configuration %d", retval); + NSOPR_SET_ERRINFO (retval, "add_network_configuration return %d", + retval); + } + + if (!retval) + { + /*init DPDK eth */ + if ((retval = init_new_network_configuration ()) != ERR_OK) + { + NSTCP_LOGINF ("process_configuration failed! %d", retval); + free_network_configuration ((struct network_configuration *) + tmp, IP_MODULE_TRUE); + NSOPR_SET_ERRINFO (retval, + "init_new_network_configuration return %d", + retval); + return -1; + } + } + } + NSTCP_LOGINF ("Get_network_json_data done!"); + + return 0; +} + +int +get_ip_json_data () +{ + NSTCP_LOGINF ("get_ip_json_data start!"); + + STRCPY_S (g_config_data->param.type, sizeof (g_config_data->param.type), + "ip"); + g_config_data->param.action = IP_MODULE_OPERATE_ADD; + + char *tmp_config_path; + tmp_config_path = realpath ("./ip_data.json", NULL); + if (!tmp_config_path) + { + exit (1); + } + + int fp = open (tmp_config_path, O_RDONLY); + if (-1 == fp) + { + free (tmp_config_path); + NSTCP_LOGINF ("network file open failed\n"); + exit (1); + } + free (tmp_config_path); + + int nread = read (fp, g_config_data->json_buff, + sizeof (g_config_data->json_buff) - 1); + if (nread <= 0) + { + close (fp); + NSTCP_LOGINF ("read failed %d.\n", nread); + exit (1); + } + + /* though MEMSET_S is done above, MEMSET_S can be removed */ + g_config_data->json_buff[nread] = '\0'; + close (fp); + + struct container_ip *container = + parse_container_ip_json (g_config_data->json_buff); + if (container) + { + int retval = add_container (container); + + NSTCP_LOGINF ("add_container %d", retval); + NSOPR_SET_ERRINFO (retval, "add_container return %d", retval); + } + else + { + NSTCP_LOGINF ("Invalid IP config data!"); + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "Invalid IP config data!"); + return -1; + } + NSTCP_LOGINF ("get_ip_json_data done!"); + + return 0; +} + +int +read_ipmoduleoperateadd_configuration () +{ + struct network_configuration *tmp = NULL; + if (strcmp (g_config_data->param.type, IP_MODULE_TYPE_IP) == 0) + { + struct container_ip *container = + parse_container_ip_json (g_config_data->json_buff); + if (container) + { + return process_post ((void *) container, IP_MODULE_IP, + IP_MODULE_OPERATE_ADD); + } + else + { + NSOPR_LOGERR ("Invalid IP config data!"); + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "Invalid IP config data!"); + return -1; + } + } + else if (strcmp (g_config_data->param.type, IP_MODULE_TYPE_NETWORK) == 0) + { + struct network_configuration *network = NULL; + + //Read network.json + + /* input shouldnot be same with return */ + network = parse_network_json (g_config_data->json_buff, NULL); + if (!network) + { + NSOPR_LOGERR ("Invalid network data!"); + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "Invalid network data!"); + return -1; + } + + /* run process_post for each network, not only the head node */ + while (network) + { + tmp = network; + network = network->next; + int ret = process_post ((void *) tmp, IP_MODULE_NETWORK, + IP_MODULE_OPERATE_ADD); + if (ret == -1) + { + NSOPR_LOGERR ("process_configuration failed!"); + return -1; + } + } + return 0; + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + return -1; + } +} + +int +read_ipmoduleoperatedel_configuration () +{ + int retval; + + if (strcmp (g_config_data->param.type, IP_MODULE_TYPE_IP) == 0) + { + struct ip_action_param *p = malloc (sizeof (struct ip_action_param)); + if (NULL == p) + { + NSOPR_LOGERR ("ip_action_param allocation failed!"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "mem alloc error!"); + return -1; + } + + retval = + MEMSET_S (p, sizeof (struct ip_action_param), 0, + sizeof (struct ip_action_param)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "MEMSET_S error!"); + free (p); + return -1; + } + + retval = + STRCPY_S (p->container_id, sizeof (p->container_id), + g_config_data->param.container_id); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (p); + return -1; + } + + retval = + STRCPY_S (p->port_name, sizeof (p->port_name), + g_config_data->param.name); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (p); + return -1; + } + + return process_post ((void *) p, IP_MODULE_IP, IP_MODULE_OPERATE_DEL); + } + else if (strcmp (g_config_data->param.type, IP_MODULE_TYPE_NETWORK) == 0) + { + char *name = malloc (sizeof (g_config_data->param.name)); + if (name == NULL) + { + NSOPR_LOGERR ("name allocation failed!"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "mem alloc error!"); + return -1; + } + + retval = + MEMSET_S (name, sizeof (g_config_data->param.name), 0, + sizeof (g_config_data->param.name)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "MEMSET_S error!"); + free (name); + return -1; + } + + retval = + STRCPY_S (name, sizeof (g_config_data->param.name), + g_config_data->param.name); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, "STRCPY_S error!"); + free (name); + return -1; + } + + return process_post ((void *) name, IP_MODULE_NETWORK, + IP_MODULE_OPERATE_DEL); + } + else + { + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + return -1; + } +} + +NSTACK_STATIC int +read_configuration () +{ + int retval = -1; + //u64 traceid = 0; + + /* initialise default memory */ + g_config_data->param.error = NSCRTL_OK; + + /* Make sure error_desc is inited to null string */ + g_config_data->param.error_desc[0] = '\0'; + + //traceid = g_config_data->param.traceid; + + NSOPR_LOGINF + ("g_config_data]type=%s,name=%s,value=%s,container_id=%s,action=%d,Json_buf=%s, traceid=%llu", + g_config_data->param.type, g_config_data->param.name, + g_config_data->param.value, g_config_data->param.container_id, + g_config_data->param.action, g_config_data->json_buff, + g_config_data->param.traceid); + + retval = + MEMSET_S (g_config_data->param.error_desc, + sizeof (g_config_data->param.error_desc), 0, + sizeof (g_config_data->param.error_desc)); + if (0 != retval) + { + NSOPR_SET_ERRINFO (NSCRTL_ERR, "ERR:internal error, MEMSET_S failed]"); + return -1; + } + + switch (g_config_data->param.action) + { + case IP_MODULE_OPERATE_DEL: + { + retval = read_ipmoduleoperatedel_configuration (); + break; + } + case IP_MODULE_OPERATE_QUERY: + { + retval = process_query (); + break; + } + case IP_MODULE_OPERATE_ADD: + { + retval = read_ipmoduleoperateadd_configuration (); + break; + } + case IP_MODULE_OPERATE_SET: + retval = read_ipmoduleoperatesetnet_configuration (); + break; + case IP_MODULE_GET_VERSION: + { + retval = read_version (); + break; + } + + default: + { + retval = -1; //here, must set retval to -1 + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "input error!"); + break; + } + } + + return retval; +} + +NSTACK_STATIC int +unix_socket_listen (const char *servername) +{ + int fd, retval; + unsigned int len; + struct stat st; + struct sockaddr_un un; + + if (stat (ip_module_unix_socket_dir_path, &st) == 0) + { + NSOPR_LOGDBG (" /directory is present"); + } + else + { + NSOPR_LOGERR (" /var/run/nStack/ directory is not present "); + return (-1); + } + + if ((fd = nsfw_base_socket (AF_UNIX, SOCK_STREAM, 0)) < 0) + { + return -1; + } + + retval = unlink (servername); /* in case it already exists */ + if (0 != retval) + { + NSOPR_LOGWAR ("unlink failed]retval=%d,errno=%d", retval, errno); + } + + retval = MEMSET_S (&un, sizeof (un), 0, sizeof (un)); + if (EOK != retval) + { + (void) nsfw_base_close (fd); + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + return -1; + } + + un.sun_family = AF_UNIX; + retval = STRCPY_S (un.sun_path, sizeof (un.sun_path), servername); + if (EOK != retval) + { + (void) nsfw_base_close (fd); + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + return -1; + } + + len = + (unsigned int) (offsetof (struct sockaddr_un, sun_path) + + strlen (servername)); + + if (nsfw_base_bind (fd, (struct sockaddr *) &un, len) < 0) + { + (void) nsfw_base_close (fd); + return -1; + } + else + { + if (nsfw_base_listen (fd, MAX_CONNECTION_NUMBER) < 0) + { + (void) nsfw_base_close (fd); + return -1; + } + else + { + return fd; + } + } +} + +/***************************************************************************** +* Prototype : read_fn +* Description : process new ip module msg +* Input : i32 fd +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +void +read_fn (i32 fd) +{ + ssize_t size; + ssize_t offset = 0; + size_t left = MAX_IP_MODULE_BUFF_SIZE; + while (left > 0) + { + size = nsfw_base_recv (fd, (char *) g_config_data + offset, left, 0); + if (size > 0) + { + offset += size; + left -= (size_t) size; + } + else + { + NSOPR_LOGERR ("Error when recieving]errno=%d,err_string=%s", errno, + strerror (errno)); + break; + } + } + + if (left != 0) + { + (void) nsfw_base_close (fd); + return; + } + + const char *old_hbt_cnt = "6"; + const char *new_hbt_cnt = "60"; + nsfw_set_soft_para (NSFW_PROC_MASTER, NSFW_HBT_COUNT_PARAM, + (void *) new_hbt_cnt, sizeof (u16)); + (void) read_configuration (); // if it returns -1, the err desc info will be wrote to g_config_data, so no need to check return value. + nsfw_set_soft_para (NSFW_PROC_MASTER, NSFW_HBT_COUNT_PARAM, + (void *) old_hbt_cnt, sizeof (u16)); + + offset = 0; + left = MAX_IP_MODULE_BUFF_SIZE; + while (left > 0) + { + size = + nsfw_base_send (fd, (char *) g_config_data + offset, left, + MSG_NOSIGNAL); + + if (size > 0) + { + offset += size; + left -= (size_t) size; + } + else + { + NSOPR_LOGERR ("Error when Sending data]errno=%d", errno); + break; + } + } + + (void) nsfw_base_close (fd); + return; +} + +/***************************************************************************** +* Prototype : ip_module_new_msg +* Description : recv new config message +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +ip_module_new_msg (i32 epfd, i32 fd, u32 events) +{ + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + { + nsfw_mgr_unreg_sock_fun (fd); + (void) nsfw_base_close (fd); + return TRUE; + } + + nsfw_mgr_unreg_sock_fun (fd); + read_fn (fd); + return TRUE; +} + +int +init_ip_module_unix_socket_path () +{ + const char *directory = "/var/log/nStack"; + const char *home_dir = getenv ("HOME"); + + if (getuid () != 0 && home_dir != NULL) + directory = home_dir; + + if (STRCPY_S + (ip_module_unix_socket_dir_path, IP_MODULE_MAX_PATH_LEN, directory) < 0) + { + NSOPR_LOGERR ("STRCPY_S fail]"); + return -1; + } + + if (STRCAT_S + (ip_module_unix_socket_dir_path, IP_MODULE_MAX_PATH_LEN, + "/ip_module") < 0) + { + NSOPR_LOGERR ("STRCAT_S fail]"); + return -1; + } + + if (STRCPY_S + (ip_module_unix_socket, IP_MODULE_MAX_PATH_LEN, + ip_module_unix_socket_dir_path) < 0) + { + NSOPR_LOGERR ("STRCPY_S fail]"); + return -1; + } + + if (STRCAT_S + (ip_module_unix_socket, IP_MODULE_MAX_PATH_LEN, + "/ip_module_unix_sock") < 0) + { + NSOPR_LOGERR ("STRCAT_S fail]"); + return -1; + } + + NSOPR_LOGINF ("ip_module_unix_socket=%s", ip_module_unix_socket); + NSOPR_LOGINF ("ip_module_unix_socket_dir_path=%s", + ip_module_unix_socket_dir_path); + return 0; +} + +/***************************************************************************** +* Prototype : ip_module_new_connection +* Description : recv new connect for network config +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +ip_module_new_connection (i32 epfd, i32 fd, u32 events) +{ + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + { + (void) nsfw_base_close (fd); + NSFW_LOGINF ("listen disconnect!]epfd=%d,listen=%d,event=0x%x", epfd, + fd, events); + nsfw_mgr_unreg_sock_fun (fd); + + if (init_ip_module_unix_socket_path () < 0) + { + NSFW_LOGERR ("Error when init path]epfd=%d,listen_fd=%d,event=0x%x", + epfd, fd, events); + return FALSE; + } + + i32 listen_fd = unix_socket_listen (ip_module_unix_socket); + if (listen_fd < 0) + { + NSFW_LOGERR ("get listen_fd faied!]epfd=%d,listen_fd=%d,event=0x%x", + epfd, fd, events); + return FALSE; + } + + if (FALSE == + nsfw_mgr_reg_sock_fun (listen_fd, ip_module_new_connection)) + { + (void) nsfw_base_close (listen_fd); + return FALSE; + } + return TRUE; + } + + struct sockaddr in_addr; + socklen_t in_len; + int infd; + in_len = sizeof in_addr; + + while (1) + { + infd = nsfw_base_accept (fd, &in_addr, &in_len); + if (infd == -1) + { + break; + } + + if (FALSE == nsfw_mgr_reg_sock_fun (infd, ip_module_new_msg)) + { + NSFW_LOGINF ("accept new fd but reg failed]new_mgr_fd=%d", infd); + return FALSE; + } + NSFW_LOGINF ("accept new fd]new_mgr_fd=%d", infd); + } + + return TRUE; +} + +int +init_configuration_reader () +{ + int error_number = 0; + INITPOL_LOGINF ("RTP", "init_configuration_reader", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_START); + g_config_data = &g_ip_module_buff; + + if (init_ip_module_unix_socket_path () < 0) + { + INITPOL_LOGERR ("RTP", "init_configuration_reader", + "Error when init path", LOG_INVALID_VALUE, + MODULE_INIT_FAIL); + return -1; + } + + i32 listen_fd = unix_socket_listen (ip_module_unix_socket); + if (listen_fd < 0) + { + error_number = errno; + INITPOL_LOGERR ("RTP", "init_configuration_reader", + "when listening ip_module_unix_socket", error_number, + MODULE_INIT_FAIL); + return -1; + } + + NSOPR_LOGINF ("start mgr_com module!]listern_fd=%d", listen_fd); + + if (FALSE == nsfw_mgr_reg_sock_fun (listen_fd, ip_module_new_connection)) + { + (void) nsfw_base_close (listen_fd); + NSOPR_LOGERR ("nsfw_mgr_reg_sock_fun failed]listen_fd=%d", listen_fd); + return -1; + } + + INITPOL_LOGINF ("RTP", "init_configuration_reader", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); + return 0; +} + +struct config_data * +get_config_data () +{ + return g_config_data; +} diff --git a/stacks/lwip_stack/lwip_src/ip_module/container_ip.c b/stacks/lwip_stack/lwip_src/ip_module/container_ip.c new file mode 100644 index 0000000..decc52c --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/container_ip.c @@ -0,0 +1,1132 @@ +/* +* +* 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 <sys/stat.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> +#include "lwip/inet.h" +#include "trp_rb_tree.h" +#include "container_ip.h" +#include "network.h" +#include "netif.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "config_common.h" +#include "igmp.h" +#include "spl_def.h" +#include "stackx_ip_addr.h" +#include "hal_api.h" +#include "spl_hal.h" + +struct container_list g_container_list = { 0 }; +static trp_rb_root_t g_container_ip_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock +static trp_rb_root_t g_container_multicast_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock + +static void free_container_port (struct container_port *port, + bool_t only_free); + +/*unsigned int value is typecasted into void * pointer and passed as argument to +this function. so the value can never be > 0xFFFFFFFF. so can suppress the warning*/ + +static int +ip_compare (trp_key_t left, trp_key_t right) +{ + //return (int)((unsigned long)left - (unsigned long)right); + + if (left > right) + { + return 1; + } + else if (left < right) + { + return -1; + } + else + { + return 0; + } +} + +NSTACK_STATIC bool_t +is_container_ok (struct container_ip * container) +{ + if (!container->ports_list) + { + return 0; + } + + return 1; +} + +NSTACK_STATIC void +add_port (struct container_ip *container, struct container_port *port) +{ + if (port->ip_cidr_list) + { + port->next = container->ports_list; + container->ports_list = port; + } + else + { + free_container_port (port, IP_MODULE_TRUE); + } +} + +static void +add_ip_cidr (struct container_port *port, + struct container_port_ip_cidr *ip_cidr) +{ + if (!ip_cidr) + { + return; + } + + ip_cidr->next = port->ip_cidr_list; + port->ip_cidr_list = ip_cidr; + return; +} + +NSTACK_STATIC void +add_multilcast_ip (struct container_port *port, + struct container_multicast_id *muticastIP) +{ + if (!muticastIP) + { + return; + } + + muticastIP->next = port->multicast_list; + port->multicast_list = muticastIP; + return; +} + +NSTACK_STATIC void +free_container_port_ip_cidr (struct container_port_ip_cidr *ip_cidr, + bool_t only_free) +{ + output_api *api = get_output_api (); + struct container_port_ip_cidr *ip_cidr_tmp = NULL; + + while (ip_cidr) + { + ip_cidr_tmp = ip_cidr; + ip_cidr = ip_cidr_tmp->next; + if (!only_free) + { + if (api->del_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr_tmp->ip); + if (network) + { + if (network->phy_net->bond_name[0] != 0) + { + (void) api->del_netif_ip (network->phy_net->bond_name, ip_cidr_tmp->ip); //fails only when netif_name not exist, no side effect so don't check return value. + } + else + { + (void) api->del_netif_ip (network->phy_net-> + header->nic_name, + ip_cidr_tmp->ip); + } + } + else + { + NSOPR_LOGERR ("can't find network by]IP=%u", + ip_cidr_tmp->ip); + } + } + + trp_rb_erase ((void *) (u64_t) ip_cidr_tmp->ip, + &g_container_ip_root, ip_compare); + } + + free (ip_cidr_tmp); + ip_cidr_tmp = NULL; + } +} + +static void +free_container_multicast (struct container_multicast_id *multicast, + bool_t only_free) +{ + struct container_multicast_id *tmp = NULL; + + while (multicast) + { + tmp = multicast; + multicast = multicast->next; + if (!only_free) + { + trp_rb_erase ((void *) (u64_t) tmp->ip, &g_container_multicast_root, + ip_compare); + } + + free (tmp); + tmp = NULL; + } +} + +static void +free_container_port (struct container_port *port, bool_t only_free) +{ + struct container_port *port_tmp = NULL; + struct container_port *port_curr = port; + + while (port_curr) + { + port_tmp = port_curr; + port_curr = port_tmp->next; + + free_container_multicast (port_tmp->multicast_list, only_free); + free_container_port_ip_cidr (port_tmp->ip_cidr_list, only_free); + + if (port_tmp->buffer) + { + free_port_buffer (port_tmp->buffer); + port_tmp->buffer = NULL; + } + + free (port_tmp); + port_tmp = NULL; + } +} + +void +free_container (struct container_ip *container, bool_t only_free) +{ + struct container_ip *container_tmp = NULL; + struct container_ip *container_curr = container; + + while (container_curr) + { + container_tmp = container_curr; + container_curr = container_tmp->next; + if (container_tmp->ports_list) + { + free_container_port (container_tmp->ports_list, only_free); + } + + free (container_tmp); + container_tmp = NULL; + } +} + +struct container_port * +parse_port_obj (struct json_object *port_obj) +{ + int retval; + struct json_object *port_name_obj = NULL; + struct json_object *ip_cidr_list_obj = NULL; + struct json_object *mcIDObj = NULL; + + if (!port_obj) + { + NSOPR_LOGERR ("port_obj is null"); + return NULL; + } + + struct container_port *port = malloc (sizeof (struct container_port)); + if (!port) + { + NSOPR_LOGERR ("malloc failed"); + return NULL; + } + + retval = + MEMSET_S (port, sizeof (struct container_port), 0, + sizeof (struct container_port)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port); + return NULL; + } + + json_object_object_get_ex (port_obj, "port_name", &port_name_obj); + if (port_name_obj) + { + const char *port_name = json_object_get_string (port_name_obj); + if ((NULL == port_name) + || (strlen (port_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("port name is not ok"); + goto RETURN_ERROR; + } + + retval = + STRCPY_S (port->port_name, sizeof (port->port_name), port_name); + + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + + json_object_object_get_ex (port_obj, "ip_cidr", &ip_cidr_list_obj); + if (ip_cidr_list_obj) + { + int j; + int ip_cidr_num = json_object_array_length (ip_cidr_list_obj); + for (j = 0; j < ip_cidr_num; ++j) + { + struct json_object *ip_cidr_obj = + json_object_array_get_idx (ip_cidr_list_obj, j); + if (ip_cidr_obj) + { + char tmp[IP_MODULE_LENGTH_32] = { 0 }; + struct container_port_ip_cidr *port_ip_cidr = + malloc (sizeof (struct container_port_ip_cidr)); + if (NULL == port_ip_cidr) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retval = + MEMSET_S (port_ip_cidr, + sizeof (struct container_port_ip_cidr), 0, + sizeof (struct container_port_ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *ip_cidr = json_object_get_string (ip_cidr_obj); + if ((NULL == ip_cidr) || (ip_cidr[0] == 0)) + { + NSOPR_LOGERR ("ip_cidr is not ok"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *sub = strstr (ip_cidr, "/"); + if ((NULL == sub) + || (sizeof (tmp) - 1 < (unsigned int) (sub - ip_cidr)) + || (strlen (sub) > sizeof (tmp) - 1)) + { + NSOPR_LOGERR + ("Error : Ipaddress notation must be in ip cidr notation!"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + retval = + STRNCPY_S (tmp, sizeof (tmp), ip_cidr, + (size_t) (sub - ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRNCPY_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + struct in_addr addr; + int iRet; + retval = MEMSET_S (&addr, sizeof (addr), 0, sizeof (addr)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + iRet = spl_inet_aton (tmp, &addr); + if (0 == iRet) + { + NSOPR_LOGERR ("spl_inet_aton failed"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->ip = addr.s_addr; + iRet = atoi (sub + 1); + if ((iRet <= 0) || (iRet > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("IP mask length is not correct"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->mask_len = (unsigned int) iRet; + add_ip_cidr (port, port_ip_cidr); + } + } + } + + json_object_object_get_ex (port_obj, "multicast_id", &mcIDObj); + if (mcIDObj) + { + int j; + int arrLen = json_object_array_length (mcIDObj); + if (0 == arrLen) + { + NSOPR_LOGERR ("arrLen is 0"); + goto RETURN_ERROR; + } + + for (j = 0; j < arrLen; ++j) + { + struct json_object *elemObj = + json_object_array_get_idx (mcIDObj, j); + + if (elemObj) + { + struct json_object *tObj = NULL; + const char *tStr; + int ret; + struct in_addr addr; + + struct container_multicast_id *mcID = + malloc (sizeof (struct container_multicast_id)); + if (NULL == mcID) + { + NSOPR_LOGERR ("Can't alloc container multicast id"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (elemObj, "group_ip", &tObj); + if (NULL == tObj) + { + NSOPR_LOGERR ("No group_IP"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + tStr = json_object_get_string (tObj); + if (NULL == tStr) + { + NSOPR_LOGERR ("Get Multiple cast group IP Failed"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + ret = spl_inet_aton (tStr, &addr); + if (0 == ret) + { + NSOPR_LOGERR ("Parse group IP Failed"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + mcID->ip = addr.s_addr; + add_multilcast_ip (port, mcID); + } + } + } + + const char *port_json = json_object_get_string (port_obj); + if ((NULL == port_json) || (0 == strlen (port_json))) + { + NSOPR_LOGERR ("json_object_get_string failed"); + goto RETURN_ERROR; + } + + port->buffer = malloc_port_buffer (); + if (!port->buffer) + { + goto RETURN_ERROR; + } + + retval = + STRCPY_S (get_port_json (port), IP_MODULE_PORT_JSON_LEN, port_json); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + return port; +RETURN_ERROR: + free_container_port (port, IP_MODULE_TRUE); + return NULL; +} + +struct container_ip * +parse_container_ip_json (char *param) +{ + int retval; + struct json_object *obj = json_tokener_parse (param); + struct json_object *container_id_obj = NULL; + struct json_object *ports_list_obj = NULL; + + if (!obj) + { + return NULL; + } + + struct container_ip *container = malloc (sizeof (struct container_ip)); + if (container == NULL) + { + json_object_put (obj); + return NULL; + } + + retval = + MEMSET_S (container, sizeof (struct container_ip), 0, + sizeof (struct container_ip)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + json_object_object_get_ex (obj, "containerID", &container_id_obj); + if (container_id_obj) + { + const char *container_id = json_object_get_string (container_id_obj); + if ((container_id == NULL) || (container_id[0] == 0) + || (strlen (container_id) >= IP_MODULE_MAX_NAME_LEN)) + { + goto RETURN_ERROR; + } + + retval = + MEMSET_S (container->container_id, sizeof (container->container_id), + 0, sizeof (container->container_id)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + retval = + STRCPY_S (container->container_id, sizeof (container->container_id), + container_id); + + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + else + { + /* this mandatory parameter */ + goto RETURN_ERROR; + } + + json_object_object_get_ex (obj, "ports_list", &ports_list_obj); + if (ports_list_obj) + { + int i; + int port_num = json_object_array_length (ports_list_obj); + + if (port_num == 0) + { + /* this mandatory parameter */ + goto RETURN_ERROR; + } + + for (i = 0; i < port_num; i++) + { + struct json_object *port_obj = + json_object_array_get_idx (ports_list_obj, i); + struct container_port *port = parse_port_obj (port_obj); + if (!port) + { + goto RETURN_ERROR; + } + + add_port (container, port); + } + } + else + { + /* mandatory parameter */ + goto RETURN_ERROR; + } + + /* Check if this function is required, or needs more check inside this function, + as some of them are alraedy validated + */ + if (!is_container_ok (container)) + { + goto RETURN_ERROR; + } + + json_object_put (obj); + return container; + +RETURN_ERROR: + json_object_put (obj); + free_container (container, IP_MODULE_TRUE); + return NULL; +} + +bool_t +is_ip_match_netif (unsigned int ip, char *netif_name) +{ + if (!netif_name) + { + return 0; + } + + if (trp_rb_search ((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip); + if (network && network->phy_net && network->phy_net->header) + { + if (0 == + strncmp (netif_name, network->phy_net->header->nic_name, + HAL_MAX_NIC_NAME_LEN)) + { + return 1; + } + } + } + + return 0; +} + +inline bool_t +is_ip_exist (unsigned int ip) +{ + if (trp_rb_search ((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + return 1; + } + + return 0; +} + +int +validate_addcontainerconfig (struct container_ip *container) +{ + struct container_port *port; + struct container_ip *old = + get_container_by_container_id (container->container_id); + struct container_port *tmp = container->ports_list; + + if (old) + { + struct container_port *last = NULL; + + while (tmp) + { + if (get_port (container->container_id, tmp->port_name)) + { + NSOPR_LOGERR ("port=%s already exists!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + + (void) last; + } + + /* check if port_name duplicates in one json configuration */ + tmp = container->ports_list; + while (tmp) + { + if (get_port_from_container (tmp)) + { + NSOPR_LOGERR ("port=%s duplicates!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + tmp = tmp->next; + } + + bool_t is_nstack_dpdk_port; + struct container_port **ref = &container->ports_list; + while ((port = *ref)) + { + is_nstack_dpdk_port = 1; + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr->ip); + if (network && (0 == strcmp (network->type_name, "nstack-dpdk"))) + { + struct netif *pnetif; + if (get_netif_by_ip (ip_cidr->ip)) + { + NSOPR_LOGERR ("ip exists]IP=0x%08x", ip_cidr->ip); + return NSCRTL_RD_EXIST; + } + + if (network->phy_net->bond_name[0] != 0) + { + pnetif = + find_netif_by_if_name (network->phy_net->bond_name); + } + else + { + pnetif = + find_netif_by_if_name (network->phy_net-> + header->nic_name); + } + + if (!pnetif) + { + NSOPR_LOGERR ("can't find netif, network json:%s", + get_network_json (network)); + return NSCRTL_ERR; + } + + if (0 == port->port_name[0]) + { + NSOPR_LOGINF + ("ip=0x%08x is in nstack dpdk network, but port_name is null, json:%s", + ip_cidr->ip, get_port_json (port)); + is_nstack_dpdk_port = 0; + break; + } + } + else + { + NSOPR_LOGINF ("port %s is not in nstack dpdk network, json:%s", + port->port_name, get_port_json (port)); + is_nstack_dpdk_port = 0; + break; + } + + ip_cidr = ip_cidr->next; + } + + /* only use nstack dpdk port */ + if (is_nstack_dpdk_port) + { + ref = &port->next; + } + else + { + *ref = port->next; + port->next = NULL; + free_container_port (port, IP_MODULE_TRUE); + } + } + + return (!container->ports_list) ? NSCRTL_FREE_ALL_PORT : NSCRTL_OK; +} + +/* get the num of IPs in a container , which in a certain subnet */ +extern struct network_list g_network_list; +extern inline int is_in_subnet (unsigned int ip, struct ip_subnet *subnet); +NSTACK_STATIC inline int get_network_ip_count + (struct container_ip *container, struct ip_subnet *subnet) +{ + int ip_count = 0; + struct container_port *port_list = NULL; + struct container_ip *ci = container; + + while (ci) + { + port_list = ci->ports_list; + while (port_list) + { + struct container_port_ip_cidr *ip_list = port_list->ip_cidr_list; + while (ip_list) + { + if (!is_in_subnet (ip_list->ip, subnet)) + { + ip_count++; + } + + ip_list = ip_list->next; + } + + port_list = port_list->next; + } + + ci = ci->next; + } + + return ip_count; +} + +int +check_ip_count (struct container_ip *container) +{ + int cur_count = 0; + int new_count = 0; + + if (NULL == container) + { + return 1; + } + + struct network_configuration *network = g_network_list.header; + while (network) + { + cur_count = + get_network_ip_count (g_container_list.header, network->ip_subnet); + new_count = get_network_ip_count (container, network->ip_subnet); + + if ((cur_count > MAX_NETWORK_IP_COUNT) + || (new_count > MAX_NETWORK_IP_COUNT) + || (cur_count + new_count > MAX_NETWORK_IP_COUNT)) + { + NSOPR_LOGERR + ("reach ip addr max count]network=%s, max=%d, current=%d, new=%d.", + network->network_name, MAX_NETWORK_IP_COUNT, cur_count, + new_count); + return 0; + } + + network = network->next; + } + + return 1; +} + +int +match_groupaddr (struct container_multicast_id *multi_list, + spl_ip_addr_t * groupaddr) +{ + struct container_multicast_id *group_info = multi_list; + + while (group_info) + { + if (group_info->ip == groupaddr->addr) + { + return 1; + } + + group_info = group_info->next; + } + + return 0; +} + +int +add_container (struct container_ip *container) +{ + int retVal = 0; + + /* need to check if any of the netif operation failed, then we should return fail */ + retVal = validate_addcontainerconfig (container); + if (retVal != NSCRTL_OK) + { + free_container (container, IP_MODULE_TRUE); + return (NSCRTL_FREE_ALL_PORT == retVal) ? NSCRTL_OK : retVal; + } + + /* control max network and ipaddress count */ + if (!check_ip_count (container)) + { + free_container (container, IP_MODULE_TRUE); + return NSCRTL_IP_COUNT_EXCEED; + } + + struct container_port *last = NULL; + struct container_ip *old = + get_container_by_container_id (container->container_id); + if (old) + { + struct container_port *tmp = container->ports_list; + while (tmp) + { + /* here we don't need to check "if tmp->port_name == NULL", as validate_addcontainerconfig() has done this. */ + if (get_port (container->container_id, tmp->port_name)) + { + free_container (container, IP_MODULE_TRUE); + NSOPR_LOGERR ("port exist!"); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + } + else + { + container->next = g_container_list.header; + g_container_list.header = container; + } + + output_api *api = get_output_api (); + struct container_port *port = container->ports_list; + while (port) + { + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + if (api->add_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr->ip); + if (network) + { + unsigned int mask = ~0; + mask = + (mask << (IP_MODULE_SUBNET_MASK_LEN - ip_cidr->mask_len)); + mask = spl_htonl (mask); + if (network->phy_net->bond_name[0] != 0) + { + (void) api->add_netif_ip (network->phy_net->bond_name, ip_cidr->ip, mask); //no need to check return value, validate_addcontainerconfig() has been checked parameters. + } + else + { + (void) api->add_netif_ip (network->phy_net-> + header->nic_name, ip_cidr->ip, + mask); + } + } + else + { + NSOPR_LOGERR ("can't find network by]IP=%u,port_name=%s", + ip_cidr->ip, port->port_name); + } + } + + retVal = + trp_rb_insert ((void *) (u64_t) ip_cidr->ip, (void *) port, + &g_container_ip_root, ip_compare); + + if (0 != retVal) + { + NSOPR_LOGERR ("trp_rb_insert failed]ip_cidr->ip=%u", + ip_cidr->ip); + } + + ip_cidr = ip_cidr->next; + } + port = port->next; + } + + if (old) + { + if (last) + { + last->next = old->ports_list; + old->ports_list = container->ports_list; + } + + container->ports_list = NULL; + free_container (container, IP_MODULE_FALSE); + } + + return NSCRTL_OK; +} + +struct container_ip * +get_container_by_container_id (char *container_id) +{ + if (NULL == container_id) + { + NSOPR_LOGERR ("Param input container ID is NULL"); + return NULL; + } + + struct container_ip *container = g_container_list.header; + while (container) + { + if (0 == strcmp (container->container_id, container_id)) + { + return container; + } + + container = container->next; + } + + return NULL; +} + +/***************************************************************************** +* Prototype : getIpCfgAll +* Description : Get All ip configurations +* Input : char * +* size_t +* Output : char * patern:[***,***,***] +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +getIpCfgAll (char *jsonBuf, size_t size) +{ + int retval; + + if (NULL == jsonBuf) + { + return NSCRTL_ERR; + } + + if (size < 2) + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + char bfirstData = 1; + *jsonBuf = '['; + jsonBuf = jsonBuf + 1; + + /*need another two char to keep [and ] */ + size_t len = size - 2; + size_t strsize = 0; + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + while (container) + { + port = container->ports_list; + while (port) + { + if (NULL == port->buffer) + { + port = port->next; + continue; + } + + strsize = strlen (get_port_json (port)) + 1; + + /*always reserve 1 char */ + if ((strsize > 0) && (strsize < len)) + { + if (bfirstData) + { + bfirstData = 0; + } + else + { + *jsonBuf = ','; + jsonBuf = jsonBuf + 1; + len = len - 1; + } + + retval = STRCPY_S (jsonBuf, len, get_port_json (port)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + return NSCRTL_ERR; + } + + len = len - strlen (get_port_json (port)); + jsonBuf = jsonBuf + strlen (get_port_json (port)); + } + else + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + port = port->next; + } + + container = container->next; + } + + *jsonBuf = ']'; + return 0; +} + +int +del_port (char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_port **ref = NULL; + struct container_ip *container = NULL; + struct container_ip **container_ref = &g_container_list.header; + + while ((container = *container_ref)) + { + NSOPR_LOGDBG ("container->container_id=%s,container_id=%p", + container->container_id, container_id); + if (strcmp (container->container_id, container_id) == 0) + { + ref = &container->ports_list; + while ((port = *ref)) + { + if (strcmp (port_name, port->port_name) == 0) + { + *ref = port->next; + port->next = NULL; + free_container_port (port, IP_MODULE_FALSE); + return 0; + } + + ref = &port->next; + } + + break; + } + + container_ref = &container->next; + } + + return NSCRTL_RD_NOT_EXIST; +} + +struct container_port * +get_port (char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + + while (container) + { + if (strcmp (container->container_id, container_id) == 0) + { + port = container->ports_list; + while (port) + { + if (strcmp (port_name, port->port_name) == 0) + { + return port; + } + + port = port->next; + } + } + + container = container->next; + } + + return NULL; +} + +struct container_port * +get_port_from_container (struct container_port *port) +{ + char *port_name = port->port_name; + struct container_port *tmp = port->next; + + while (tmp) + { + if (strcmp (port_name, tmp->port_name) == 0) + { + return tmp; + } + + tmp = tmp->next; + } + + return NULL; +} diff --git a/stacks/lwip_stack/lwip_src/ip_module/ip_module_api.c b/stacks/lwip_stack/lwip_src/ip_module/ip_module_api.c new file mode 100644 index 0000000..0ae61ed --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/ip_module_api.c @@ -0,0 +1,347 @@ +/* +* +* 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 <string.h> +#include "inet.h" +#include "spl_ip_addr.h" +#include "ip_module_api.h" +#include "container_ip.h" +#include "network.h" +#include "config_common.h" +#include "configuration_reader.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "spl_hal.h" +#include "stackx_spl_share.h" +#include "stackx/spl_api.h" +#include "stackx_common.h" +#include "spl_tcpip.h" + +static output_api g_output_api = { 0 }; + +void +regist_output_api (output_api * api) +{ + if (NULL == api) + { + NSOPR_LOGERR ("error!!!param api==NULL]"); + return; + } + + g_output_api = *api; +} + +output_api * +get_output_api () +{ + return &g_output_api; +} + +int +process_post (void *arg, ip_module_type Type, + ip_module_operate_type operate_type) +{ + /* only when add network, in other words: + only when (IP_MODULE_NETWORK == Type) && (IP_MODULE_OPERATE_ADD == operate_type), + process_configuration() is called in read_fn thread itself. + other cases, will post_to tcpip_thread to handle them. + + tips: when add network, it need to post msg(add netif) to tcpip thread and wait a sem, + but after the msg is handled by tcpip thread, the sem could be post. + so adding netword is handled in read_fn thread, can't be moved to tcpip thread. + + But we should know, many global and static variables maybe not safe(netif,sc_dpdk etc.), + because they can be visited by multi-thread. */ + if ((IP_MODULE_NETWORK == Type) && (IP_MODULE_OPERATE_ADD == operate_type)) + { + return process_configuration (arg, Type, operate_type); + } + + if (g_output_api.post_to) + { + int retval = g_output_api.post_to (arg, Type, operate_type); + if ((post_ip_module_msg == g_output_api.post_to) && (retval != ERR_OK) + && (arg != NULL)) + { + if ((IP_MODULE_IP == Type) + && (IP_MODULE_OPERATE_ADD == operate_type)) + { + free_container ((struct container_ip *) arg, IP_MODULE_TRUE); + } + else + { + free (arg); + } + + arg = NULL; + NSOPR_LOGERR ("post failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_INPUT_ERR, "process_post failed!"); + } + + return retval; + } + else + { + NSOPR_LOGERR ("g_output_api.post_to==NULL"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "ERR:internal error, g_output_api.post_to==NULL]"); + return -1; + } +} + +/* arg can be NULL, no need check */ +int +process_configuration (void *arg, ip_module_type Type, + ip_module_operate_type operate_type) +{ + NSOPR_LOGINF ("precoess begin]arg=%p,action=%d,type=%d", arg, operate_type, + Type); + int retval = 0; + + switch (Type) + { + case IP_MODULE_NETWORK: + switch (operate_type) + { + case IP_MODULE_OPERATE_ADD: + retval = + add_network_configuration ((struct network_configuration *) arg); + + /* When network exceeds max number, just log warning at operation.log */ + if (retval == NSCRTL_NETWORK_COUNT_EXCEED) + { + NSOPR_LOGWAR + ("Warning!! Network count exceed max allowed number]max=%d", + MAX_NETWORK_COUNT); + } + else + { + NSOPR_SET_ERRINFO (retval, + "add_network_configuration return %d", + retval); + } + + if (!retval) + { + /*init DPDK eth */ + if ((retval = init_new_network_configuration ()) != ERR_OK) + { + free_network_configuration ((struct network_configuration *) + arg, IP_MODULE_TRUE); + NSOPR_SET_ERRINFO (retval, + "init_new_network_configuration return %d", + retval); + } + } + break; + case IP_MODULE_OPERATE_DEL: + { + retval = del_network_by_name ((char *) arg); + NSOPR_SET_ERRINFO (retval, "del_network_by_name return %d", + retval); + free (arg); + arg = NULL; + } + break; + case IP_MODULE_OPERATE_QUERY: + { + struct network_configuration *network = + get_network_by_name ((char *) arg); + if (!network) + { + retval = NSCRTL_RD_NOT_EXIST; + NSOPR_SET_ERRINFO (retval, "get_network_by_name return %d", + retval); + } + else + { + if (strlen (get_network_json (network)) > + sizeof (get_config_data ()->json_buff) - 1) + { + NSOPR_LOGERR + ("length of network->network_json too big]len=%u", + strlen (get_network_json (network))); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "ERR:internal error, buf is not enough]"); + retval = NSCRTL_ERR; + } + + retval = + STRCPY_S (get_config_data ()->json_buff, + sizeof (get_config_data ()->json_buff), + get_network_json (network)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "ERR:internal error, STRCPY_S failed]ret=%d", + retval); + retval = NSCRTL_ERR; + } + + } + + free (arg); + arg = NULL; + } + break; + default: + break; + } + + break; + case IP_MODULE_IP: + switch (operate_type) + { + case IP_MODULE_OPERATE_ADD: + retval = add_container ((struct container_ip *) arg); + NSOPR_SET_ERRINFO (retval, "add_container return %d", retval); + break; + case IP_MODULE_OPERATE_DEL: + { + struct ip_action_param *p = (struct ip_action_param *) arg; + retval = del_port (p->container_id, p->port_name); + NSOPR_SET_ERRINFO (retval, "del_port return %d", retval); + free (arg); + arg = NULL; + } + break; + case IP_MODULE_OPERATE_QUERY: + { + struct ip_action_param *p = (struct ip_action_param *) arg; + struct container_port *port = + get_port (p->container_id, p->port_name); + if (!port) + { + retval = NSCRTL_RD_NOT_EXIST; + NSOPR_SET_ERRINFO (retval, "get_port return %d", retval); + } + else + { + if (strlen (get_port_json (port)) > + sizeof (get_config_data ()->json_buff) - 1) + { + NSOPR_LOGERR + ("length of network->network_json too big]len=%u", + strlen (get_port_json (port))); + retval = NSCRTL_ERR; + } + + retval = + STRCPY_S (get_config_data ()->json_buff, + sizeof (get_config_data ()->json_buff), + get_port_json (port)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + retval = NSCRTL_ERR; + } + + } + + free (arg); + arg = NULL; + } + break; + default: + break; + } + + break; + case IP_MODULE_NETWORK_ALL: + if (operate_type == IP_MODULE_OPERATE_QUERY) + { + retval = + get_network_all (get_config_data ()->json_buff, + sizeof (get_config_data ()->json_buff)); + NSOPR_SET_ERRINFO (retval, "get_network_all return %d", retval); + } + + break; + + case IP_MODULE_IP_ALL: + if (operate_type == IP_MODULE_OPERATE_QUERY) + { + retval = + getIpCfgAll (get_config_data ()->json_buff, + sizeof (get_config_data ()->json_buff)); + NSOPR_SET_ERRINFO (retval, "getIpCfgAll return %d", retval); + } + + break; + + case IP_MODULE_ALL: + if (operate_type == IP_MODULE_OPERATE_QUERY) + { + NSOPR_LOGERR + ("---------- IP_MODULE_ALL query is not implemented --------------"); + NSOPR_SET_ERRINFO (NSCRTL_ERR, + "ERR:This query interface is not implemented. ErrCode:%d", + NSCRTL_ERR); + } + + break; + + default: + break; + } + + NSOPR_LOGINF ("process finished]result=%d", retval); + + return retval; +} + +void +ip_subnet_print (struct ip_subnet *subnet) +{ + spl_ip_addr_t ipAddr; + + if (subnet == NULL) + { + return; + } + + ipAddr.addr = spl_htonl (subnet->subnet); + NSPOL_LOGINF (IP_DEBUG, "]\t Subnet=%s/%u", spl_inet_ntoa (ipAddr), + subnet->mask_len); +} + +port_buffer * +malloc_port_buffer () +{ + port_buffer *buffer = malloc (sizeof (port_buffer)); + return buffer; +} + +void +free_port_buffer (port_buffer * buffer) +{ + free (buffer); +} + +network_buffer * +malloc_network_buffer () +{ + network_buffer *buffer = malloc (sizeof (network_buffer)); + return buffer; +} + +void +free_network_buffer (network_buffer * buffer) +{ + free (buffer); +} diff --git a/stacks/lwip_stack/lwip_src/ip_module/network.c b/stacks/lwip_stack/lwip_src/ip_module/network.c new file mode 100644 index 0000000..ef0d9a7 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/network.c @@ -0,0 +1,1067 @@ +/* +* +* 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 <stdio.h> +#include <sys/socket.h> +#include <string.h> +#include "json.h" +#include "trp_rb_tree.h" +#include "network.h" +#include "nstack_log.h" +#include "config_common.h" +#include "stackx_spl_share.h" +#include "stackx/spl_api.h" +#include "sharedmemory.h" +#include "nstack_securec.h" +#include "spl_hal.h" +#include "inet.h" + +struct network_list g_network_list = { 0 }; + +extern struct stackx_port_zone *p_stackx_port_zone; +extern u32 spl_hal_is_nic_exist (const char *name); + +static bool_t +is_phy_net_ok (struct phy_net *pst_phy_net) +{ + if (!pst_phy_net || !pst_phy_net->header) + { + NSOPR_LOGERR ("phy_net is not ok"); + return 0; + } + + return 1; +} + +static bool_t +is_network_configuration_ok (struct network_configuration *network) +{ + while (network) + { + if (!is_phy_net_ok (network->phy_net)) + { + return 0; + } + + network = network->next; + } + + return 1; +} + +static void +add_ref_nic (struct phy_net *pst_phy_net, struct ref_nic *pst_ref_nic) +{ + pst_ref_nic->next = pst_phy_net->header; + pst_phy_net->header = pst_ref_nic; +} + +static void +free_ref_nic (struct ref_nic *pst_ref_nic) +{ + struct ref_nic *nic = pst_ref_nic; + struct ref_nic *tmp = NULL; + + while (nic) + { + tmp = nic; + nic = tmp->next; + free (tmp); + } +} + +static void +free_phy_net (struct phy_net *pst_phy_net) +{ + if (pst_phy_net) + { + free_ref_nic (pst_phy_net->header); + free (pst_phy_net); + } +} + +static void +free_ip_subnet (struct ip_subnet *subnet, bool_t only_free) +{ + struct ip_subnet *tmp = NULL; + + while (subnet) + { + tmp = subnet; + subnet = subnet->next; + free (tmp); + } +} + +void +free_network_configuration (struct network_configuration *network, + bool_t only_free) +{ + if (network) + { + free_ip_subnet (network->ip_subnet, only_free); + free_phy_net (network->phy_net); + + if (network->buffer) + { + free_network_buffer (network->buffer); + network->buffer = NULL; + } + + free (network); + } +} + +inline int +is_in_subnet (unsigned int ip, struct ip_subnet *subnet) +{ + unsigned int mask = ~0; + unsigned int seg_ip, seg; + + mask = mask << (IP_MODULE_SUBNET_MASK_LEN - subnet->mask_len); + + seg_ip = ip & mask; + seg = subnet->subnet & mask; + + return seg_ip != seg ? 1 : 0; +} + +inline struct network_configuration * +get_network_by_ip_with_tree (unsigned int ip) +{ + unsigned int h_ip = spl_ntohl (ip); + struct network_configuration *p = g_network_list.header; + + while (p) + { + if (!is_in_subnet (h_ip, p->ip_subnet)) + { + return p; + } + + p = p->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_name (char *name) +{ + struct network_configuration *network = g_network_list.header; + + while (network) + { + if (strcasecmp (name, network->network_name) == 0) + { + return network; + } + + network = network->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_nic_name (char *name) +{ + if (NULL == name) + { + return NULL; + } + + struct ref_nic *refnic = NULL; + struct phy_net *phynet = NULL; + struct network_configuration *network = g_network_list.header; + while (network) + { + phynet = network->phy_net; + if (phynet) + { + if ((phynet->bond_mode != -1) + && strcmp (name, phynet->bond_name) == 0) + { + return network; + } + + refnic = phynet->header; + while (refnic) + { + if (strcmp (name, refnic->nic_name) == 0) + { + return network; + } + + refnic = refnic->next; + } + } + + network = network->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_name_from_json (struct network_configuration *network) +{ + char *name = network->network_name; + struct network_configuration *tmp = network->next; + + while (tmp) + { + if (strcasecmp (name, tmp->network_name) == 0) + { + return tmp; + } + + tmp = tmp->next; + } + + return NULL; +} + +NSTACK_STATIC inline int +get_network_count () +{ + int count = 0; + struct network_configuration *network = g_network_list.header; + + while (network) + { + count++; + network = network->next; + } + + return count; +} + +int +get_network_all (char *jsonBuf, size_t size) +{ + if (NULL == jsonBuf) + { + return NSCRTL_ERR; + } + + if (size < 2) + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + int retVal; + char bfirstData = 1; + *jsonBuf = '['; + jsonBuf = jsonBuf + 1; + + size_t len = size - 2; // strlen("[]") + size_t strsize = 0; + struct network_configuration *network = g_network_list.header; + while (network) + { + if (NULL == network->buffer) + { + network = network->next; + continue; + } + + if (bfirstData) + { + bfirstData = 0; + } + else + { + *jsonBuf = ','; + jsonBuf = jsonBuf + 1; + len = len - 1; + } + + strsize = strlen (get_network_json (network)) + 1; + if ((strsize > 0) && (strsize < len)) + { + retVal = STRCPY_S (jsonBuf, len, get_network_json (network)); + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return NSCRTL_STATUS_ERR; + } + + len = len - strlen (get_network_json (network)); + jsonBuf = jsonBuf + strlen (get_network_json (network)); + } + else + { + NSOPR_LOGERR ("get all network cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + network = network->next; + } + + *jsonBuf = ']'; + return 0; +} + +int +nic_already_bind (const char *nic_name) +{ + struct ref_nic *pnic = NULL; + struct network_configuration *pnetwork = g_network_list.header; + + while (pnetwork) + { + pnic = pnetwork->phy_net->header; + while (pnic) + { + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + + pnic = pnic->next; + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +int +nic_already_init (const char *nic_name) +{ + unsigned int i; + + for (i = 0; i < p_stackx_port_zone->port_num; i++) + { + if (0 == + strcmp (p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name, + nic_name)) + { + return 1; + } + } + + return 0; +} + +extern struct stackx_port_info *head_used_port_list; +int +bonded_nic_already_bind (struct network_configuration *pnetwork, + const char *nic_name) +{ + struct stackx_port_info *p_port_list = head_used_port_list; + + while (p_port_list) + { + if (0 == strcmp (p_port_list->linux_ip.if_name, nic_name)) + { + return 1; + } + + p_port_list = p_port_list->next_use_port; + } + + struct ref_nic *pnic = NULL; + + while (pnetwork) + { + if (pnetwork->phy_net->bond_mode == -1) + { + pnic = pnetwork->phy_net->header; + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +extern struct bond_ports_info bond_ports_array; +int +nic_already_bond (struct network_configuration *pnetwork, + const char *nic_name) +{ + u8_t i, j; + struct bond_set *s; + + for (i = 0; i < bond_ports_array.cnt; i++) + { + s = &bond_ports_array.ports[i]; + for (j = 0; j < s->slave_port_cnt; j++) + { + if (strcmp (s->slave_ports[j], nic_name) == 0) + { + return 1; + } + } + } + + struct ref_nic *pnic = NULL; + + while (pnetwork) + { + if (pnetwork->phy_net->bond_mode != -1) + { + pnic = pnetwork->phy_net->header; + while (pnic) + { + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + + pnic = pnic->next; + } + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +/* add network to list in descending sort */ +void +add_network_to_list (struct network_configuration *network) +{ + struct network_configuration *curr = g_network_list.header; + struct network_configuration *prev = NULL; + + network->next = NULL; + + while (curr) + { + if (network->ip_subnet->mask_len >= curr->ip_subnet->mask_len) + { + break; + } + + prev = curr; + curr = curr->next; + } + + if (NULL == prev) + { + network->next = curr; + g_network_list.header = network; + } + else + { + network->next = prev->next; + prev->next = network; + } +} + +int +add_network_configuration (struct network_configuration + *pst_network_configuration) +{ + struct network_configuration *tmp = pst_network_configuration; + struct ref_nic *pheader; + + if (tmp) + { + if (get_network_by_name (tmp->network_name) + || get_network_by_name_from_json (tmp)) + { + NSOPR_LOGERR ("network exists or duplicates]network_name=%s", + tmp->network_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_RD_EXIST; + } + + if (strcasecmp ("nstack-dpdk", tmp->type_name) != 0) + { + NSOPR_LOGWAR ("illegal network type]type_name=%s", tmp->type_name); + } + + /* control max network and ipaddress count */ + if (get_network_count () >= MAX_NETWORK_COUNT) + { + NSOPR_LOGERR ("network reach]max_count=%d", MAX_NETWORK_COUNT); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_NETWORK_COUNT_EXCEED; + } + + /* If nic is not existed or not initiated, return error */ + pheader = tmp->phy_net->header; + while (pheader) + { + if (!spl_hal_is_nic_exist (pheader->nic_name) + && !nic_already_init (pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s not exist Error! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_RD_NOT_EXIST; + } + + pheader = pheader->next; + } + + /* if a bonded nic has been inited in a non-bond network, return error */ + if (tmp->phy_net->bond_mode != -1) + { + pheader = tmp->phy_net->header; + while (pheader) + { + if (bonded_nic_already_bind + (pst_network_configuration, pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s already bind! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_INPUT_ERR; + } + + pheader = pheader->next; + } + } + + /* if a non-bond nic has been inited in a bonded network, return error */ + if (tmp->phy_net->bond_mode == -1) + { + pheader = tmp->phy_net->header; + while (pheader) + { + if (nic_already_bond + (pst_network_configuration, pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s already bind! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_INPUT_ERR; + } + + pheader = pheader->next; + } + } + } + else + { + NSOPR_LOGERR ("Invalid network configuration!"); + return NSCRTL_INPUT_ERR; + } + + /*looping through each node has move to read_ipmoduleoperateadd_configuration */ + ip_subnet_print (tmp->ip_subnet); + add_network_to_list (tmp); + + return NSCRTL_OK; +} + +struct network_configuration * +parse_network_obj (struct json_object *network_obj) +{ + int retVal; + struct network_configuration *pst_network_configuration = NULL; + struct json_object *network_name_obj = NULL, *args_obj = NULL, *phy_obj = + NULL, *type_name_obj = NULL; + struct json_object *ref_nic_list_obj = NULL, *bond_mode_obj = + NULL, *bond_name_obj = NULL, *ipam_obj = NULL; + struct json_object *subnet_obj = NULL; + + if (!network_obj) + { + NSOPR_LOGERR ("network_obj is null"); + goto RETURN_ERROR; + } + + pst_network_configuration = malloc (sizeof (struct network_configuration)); + if (NULL == pst_network_configuration) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_network_configuration, + sizeof (struct network_configuration), 0, + sizeof (struct network_configuration)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "name", &network_name_obj); + if (network_name_obj) + { + const char *network_name = json_object_get_string (network_name_obj); + if ((NULL == network_name) || (network_name[0] == 0) + || (strlen (network_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("network_name is not ok"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_network_configuration->network_name, + sizeof (pst_network_configuration->network_name), + network_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("name is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "type", &type_name_obj); + if (type_name_obj) + { + const char *type_name = json_object_get_string (type_name_obj); + if ((NULL == type_name) || (type_name[0] == 0) + || (strlen (type_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("type parse error"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_network_configuration->type_name, + sizeof (pst_network_configuration->type_name), type_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retVal); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("type is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "args", &args_obj); + if (args_obj) + { + json_object_object_get_ex (args_obj, "phynet", &phy_obj); + if (phy_obj) + { + struct phy_net *pst_phy_net = malloc (sizeof (struct phy_net)); + if (NULL == pst_phy_net) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_phy_net, sizeof (struct phy_net), 0, + sizeof (struct phy_net)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + json_object_object_get_ex (phy_obj, "ref_nic", &ref_nic_list_obj); + if (ref_nic_list_obj) + { + int j; + int ref_nic_num = json_object_array_length (ref_nic_list_obj); + if (0 == ref_nic_num) + { + NSOPR_LOGERR ("ref_nic is empty"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + for (j = ref_nic_num - 1; j >= 0; j--) + { + struct json_object *ref_nic_obj = + json_object_array_get_idx (ref_nic_list_obj, j); + if (ref_nic_obj) + { + const char *nic_name = + json_object_get_string (ref_nic_obj); + if ((NULL == nic_name) || (nic_name[0] == 0) + || (strlen (nic_name) >= HAL_MAX_NIC_NAME_LEN)) + { + NSOPR_LOGERR ("nic_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + struct ref_nic *pst_ref_nic = + malloc (sizeof (struct ref_nic)); + if (NULL == pst_ref_nic) + { + NSOPR_LOGERR ("malloc failed"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_ref_nic, sizeof (struct ref_nic), 0, + sizeof (struct ref_nic)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + free (pst_ref_nic); + pst_ref_nic = NULL; + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_ref_nic->nic_name, + sizeof (pst_ref_nic->nic_name), nic_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + free (pst_ref_nic); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + add_ref_nic (pst_phy_net, pst_ref_nic); + } + } + } + else + { + NSOPR_LOGERR ("ref_nic is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + json_object_object_get_ex (phy_obj, "bond_mode", &bond_mode_obj); + if (bond_mode_obj) + { + pst_phy_net->bond_mode = json_object_get_int (bond_mode_obj); + if (pst_phy_net->bond_mode != -1) + { + json_object_object_get_ex (phy_obj, "bond_name", + &bond_name_obj); + if (bond_name_obj) + { + const char *bond_name = + json_object_get_string (bond_name_obj); + if ((NULL == bond_name) + || (strlen (bond_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("bond_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_phy_net->bond_name, + sizeof (pst_phy_net->bond_name), 0, + sizeof (pst_phy_net->bond_name)); + + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + STRNCPY_S (pst_phy_net->bond_name, + sizeof (pst_phy_net->bond_name), bond_name, + strlen (bond_name)); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRNCPY_S failed]retVal=%d", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("bond_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + } + } + else + { + pst_phy_net->bond_mode = -1; + } + + pst_network_configuration->phy_net = pst_phy_net; + } + else + { + NSOPR_LOGERR ("phy_net is not ok"); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("args is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "ipam", &ipam_obj); + if (ipam_obj) + { + json_object_object_get_ex (ipam_obj, "subnet", &subnet_obj); + if (subnet_obj) + { + int iRet; + char tmp[IP_MODULE_LENGTH_32] = { 0 }; + const char *subnet = json_object_get_string (subnet_obj); + struct in_addr addr; + + retVal = MEMSET_S (&addr, sizeof (addr), 0, sizeof (addr)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + if ((NULL == subnet) || (subnet[0] == 0) + || (strlen (subnet) > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + const char *sub = strstr (subnet, "/"); + if ((NULL == sub) + || (sizeof (tmp) - 1 <= (unsigned int) (sub - subnet)) + || (strlen (sub) >= sizeof (tmp) - 1)) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + iRet = + STRNCPY_S (tmp, sizeof (tmp), subnet, (size_t) (sub - subnet)); + if (EOK != iRet) + { + NSOPR_LOGERR ("STRNCPY_S failed]ret=%d", iRet); + goto RETURN_ERROR; + } + + iRet = spl_inet_aton (tmp, &addr); + if (0 == iRet) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet = + (struct ip_subnet *) malloc (sizeof (struct ip_subnet)); + if (!pst_network_configuration->ip_subnet) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_network_configuration->ip_subnet, + sizeof (struct ip_subnet), 0, + sizeof (struct ip_subnet)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet->next = NULL; + pst_network_configuration->ip_subnet->subnet = + spl_ntohl (addr.s_addr); + + iRet = atoi (sub + 1); + if ((iRet < 0) || (iRet > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("mask is not ok"); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet->mask_len = + (unsigned int) iRet; + } + else + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("ipam is not ok"); + goto RETURN_ERROR; + } + + const char *network_json = json_object_get_string (network_obj); + if ((NULL == network_json) || (network_json[0] == 0)) + { + NSOPR_LOGERR ("json_object_get_string failed"); + goto RETURN_ERROR; + } + + pst_network_configuration->buffer = malloc_network_buffer (); + if (!pst_network_configuration->buffer) + { + NSOPR_LOGERR ("malloc_network_buffer failed"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (get_network_json (pst_network_configuration), + IP_MODULE_NETWORK_JSON_LEN, network_json); + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + return pst_network_configuration; + +RETURN_ERROR: + if (pst_network_configuration) + { + free_network_configuration (pst_network_configuration, IP_MODULE_TRUE); + pst_network_configuration = NULL; + } + + return NULL; +} + +struct network_configuration * +parse_network_json (char *param, struct network_configuration *pnetwork_list) +{ + struct json_object *obj = json_tokener_parse (param); + struct network_configuration *pst_network_configuration = NULL; + + if (!obj) + { + NSOPR_LOGERR ("parse error"); + return NULL; + } + + int network_num = json_object_array_length (obj); + if (0 == network_num) + { + json_object_put (obj); + return NULL; + } + + int i; + for (i = 0; i < network_num; i++) + { + struct json_object *network_obj = json_object_array_get_idx (obj, i); + if (network_obj) + { + pst_network_configuration = parse_network_obj (network_obj); + if (!pst_network_configuration) + { + NSOPR_LOGERR ("parse_network_obj error"); + goto RETURN_ERROR; + } + + pst_network_configuration->next = pnetwork_list; + pnetwork_list = pst_network_configuration; + pst_network_configuration = NULL; + } + else + { + NSOPR_LOGERR ("network_obj is NULL"); + goto RETURN_ERROR; + } + } + + if (pnetwork_list) + { + if (!is_network_configuration_ok (pnetwork_list)) + { + NSOPR_LOGERR ("network_configuration is not ok"); + goto RETURN_ERROR; + } + } + + json_object_put (obj); + return pnetwork_list; + +RETURN_ERROR: + free_network_configuration (pnetwork_list, IP_MODULE_TRUE); + json_object_put (obj); + return NULL; +} + +int +del_network_by_name (char *name) +{ + struct network_configuration *network = NULL; + struct network_configuration **ref = &g_network_list.header; + + while ((network = *ref)) + { + if (strcasecmp (name, network->network_name) == 0) + { + *ref = network->next; + network->next = NULL; + + free_network_configuration (network, IP_MODULE_FALSE); + return 0; + } + + ref = &network->next; + } + + return NSCRTL_RD_NOT_EXIST; +} + +int +is_in_same_network (unsigned int src_ip, unsigned int dst_ip) +{ + if (src_ip == dst_ip) + { + return 1; + } + + struct network_configuration *src = get_network_by_ip_with_tree (src_ip); + struct network_configuration *dst = get_network_by_ip_with_tree (dst_ip); + if (src && (src == dst)) + { + return 1; + } + + return 0; +} + +struct network_configuration * +get_network_list () +{ + return g_network_list.header; +} diff --git a/stacks/lwip_stack/lwip_src/ip_module/trp_rb_tree.c b/stacks/lwip_stack/lwip_src/ip_module/trp_rb_tree.c new file mode 100644 index 0000000..1990f52 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/trp_rb_tree.c @@ -0,0 +1,563 @@ +/* +* +* 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "trp_rb_tree.h" + +NSTACK_STATIC void +__rb_rotate_left (struct trp_rb_node *X, struct trp_rb_root *root) +{ + /************************** + * rotate Node X to left * + **************************/ + + struct trp_rb_node *Y = X->rb_right; + + /* estblish X->Right link */ + X->rb_right = Y->rb_left; + if (Y->rb_left != NULL) + Y->rb_left->rb_parent = X; + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + if (X->rb_parent) + { + if (X == X->rb_parent->rb_left) + X->rb_parent->rb_left = Y; + else + X->rb_parent->rb_right = Y; + } + else + { + root->rb_node = Y; + } + + /* link X and Y */ + Y->rb_left = X; + X->rb_parent = Y; + + return; +} + +NSTACK_STATIC void +__rb_rotate_right (struct trp_rb_node *X, struct trp_rb_root *root) +{ + /**************************** + * rotate Node X to right * + ****************************/ + + struct trp_rb_node *Y = X->rb_left; + + /* estblish X->Left link */ + X->rb_left = Y->rb_right; + if (Y->rb_right != NULL) + Y->rb_right->rb_parent = X; + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + if (X->rb_parent) + { + if (X == X->rb_parent->rb_right) + X->rb_parent->rb_right = Y; + else + X->rb_parent->rb_left = Y; + } + else + { + root->rb_node = Y; + } + + /* link X and Y */ + Y->rb_right = X; + X->rb_parent = Y; + + return; +} + +/* X, Y are for application */ +NSTACK_STATIC void +__rb_erase_color (struct trp_rb_node *X, struct trp_rb_node *Parent, + struct trp_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after deleting node X * + *************************************/ + + while (X != root->rb_node && (!X || X->color == RB_BLACK)) + { + + if (Parent == NULL) + { + break; + } + + if (X == Parent->rb_left) + { + struct trp_rb_node *W = Parent->rb_right; + if (W->color == RB_RED) + { + W->color = RB_BLACK; + Parent->color = RB_RED; /* Parent != NIL? */ + __rb_rotate_left (Parent, root); + W = Parent->rb_right; + } + + if ((!W->rb_left || W->rb_left->color == RB_BLACK) + && (!W->rb_right || W->rb_right->color == RB_BLACK)) + { + W->color = RB_RED; + X = Parent; + Parent = X->rb_parent; + } + else + { + if (!W->rb_right || W->rb_right->color == RB_BLACK) + { + if (W->rb_left != NULL) + W->rb_left->color = RB_BLACK; + W->color = RB_RED; + __rb_rotate_right (W, root); + W = Parent->rb_right; + } + + W->color = Parent->color; + Parent->color = RB_BLACK; + if (W->rb_right->color != RB_BLACK) + { + W->rb_right->color = RB_BLACK; + } + __rb_rotate_left (Parent, root); + X = root->rb_node; + break; + } + } + else + { + + struct trp_rb_node *W = Parent->rb_left; + if (W->color == RB_RED) + { + W->color = RB_BLACK; + Parent->color = RB_RED; /* Parent != NIL? */ + __rb_rotate_right (Parent, root); + W = Parent->rb_left; + } + + if ((!W->rb_left || (W->rb_left->color == RB_BLACK)) + && (!W->rb_right || (W->rb_right->color == RB_BLACK))) + { + W->color = RB_RED; + X = Parent; + Parent = X->rb_parent; + } + else + { + if (!W->rb_left || (W->rb_left->color == RB_BLACK)) + { + if (W->rb_right != NULL) + W->rb_right->color = RB_BLACK; + W->color = RB_RED; + __rb_rotate_left (W, root); + W = Parent->rb_left; + } + + W->color = Parent->color; + Parent->color = RB_BLACK; + if (W->rb_left->color != RB_BLACK) + { + W->rb_left->color = RB_BLACK; + } + __rb_rotate_right (Parent, root); + X = root->rb_node; + break; + } + } + } + + if (X) + { + X->color = RB_BLACK; + } + + return; +} + +static void +rb_insert_color (struct trp_rb_node *X, struct trp_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after inserting node X * + *************************************/ + + /* check red-black properties */ + while (X != root->rb_node && X->rb_parent->color == RB_RED) + { + /* we have a violation */ + if (X->rb_parent == X->rb_parent->rb_parent->rb_left) + { + struct trp_rb_node *Y = X->rb_parent->rb_parent->rb_right; + if (Y && Y->color == RB_RED) + { + + /* uncle is red */ + X->rb_parent->color = RB_BLACK; + Y->color = RB_BLACK; + X->rb_parent->rb_parent->color = RB_RED; + X = X->rb_parent->rb_parent; + } + else + { + + /* uncle is black */ + if (X == X->rb_parent->rb_right) + { + /* make X a left child */ + X = X->rb_parent; + __rb_rotate_left (X, root); + } + + /* recolor and rotate */ + X->rb_parent->color = RB_BLACK; + X->rb_parent->rb_parent->color = RB_RED; + __rb_rotate_right (X->rb_parent->rb_parent, root); + } + } + else + { + + /* miror image of above code */ + struct trp_rb_node *Y = X->rb_parent->rb_parent->rb_left; + if (Y && (Y->color == RB_RED)) + { + + /* uncle is red */ + X->rb_parent->color = RB_BLACK; + Y->color = RB_BLACK; + X->rb_parent->rb_parent->color = RB_RED; + X = X->rb_parent->rb_parent; + } + else + { + + /* uncle is black */ + if (X == X->rb_parent->rb_left) + { + X = X->rb_parent; + __rb_rotate_right (X, root); + } + X->rb_parent->color = RB_BLACK; + X->rb_parent->rb_parent->color = RB_RED; + __rb_rotate_left (X->rb_parent->rb_parent, root); + } + } + } + + root->rb_node->color = RB_BLACK; + + return; +} + +static void +rb_erase (struct trp_rb_node *node, struct trp_rb_root *root) +{ + struct trp_rb_node *child, *parent; + unsigned int color; + + if (!node->rb_left) + { + child = node->rb_right; + } + else if (!node->rb_right) + { + child = node->rb_left; + } + else + { + struct trp_rb_node *old = node, *left; + + node = node->rb_right; + while ((left = node->rb_left) != NULL) + { + node = left; + } + + if (old->rb_parent) + { + if (old->rb_parent->rb_left == old) + { + old->rb_parent->rb_left = node; + } + else + { + old->rb_parent->rb_right = node; + } + } + else + { + root->rb_node = node; + } + + child = node->rb_right; + parent = node->rb_parent; + color = node->color; + + if (parent == old) + { + parent = node; + } + else + { + if (child) + { + child->rb_parent = parent; + } + + parent->rb_left = child; + + node->rb_right = old->rb_right; + old->rb_right->rb_parent = node; + } + + node->color = old->color; + node->rb_parent = old->rb_parent; + node->rb_left = old->rb_left; + old->rb_left->rb_parent = node; + + if (color == RB_BLACK) + { + __rb_erase_color (child, parent, root); + } + + return; + + } + + parent = node->rb_parent; + color = node->color; + + if (child) + { + child->rb_parent = parent; + } + + if (parent) + { + if (parent->rb_left == node) + { + parent->rb_left = child; + } + else + { + parent->rb_right = child; + } + } + else + { + root->rb_node = child; + } + + if (color == RB_BLACK) + { + __rb_erase_color (child, parent, root); + } + + return; +} + +NSTACK_STATIC trp_rb_node_t * +rb_new_node (trp_key_t key, trp_data_t data, + trp_rb_node_t * parent /*, key_compare key_compare_fn */ ) +{ + trp_rb_node_t *node = (trp_rb_node_t *) malloc (sizeof (trp_rb_node_t)); + if (!node) + { + return NULL; + } + node->key = key; + node->data = data; + node->rb_parent = parent; + node->rb_left = node->rb_right = NULL; + node->color = RB_RED; + /*node->key_compare_fn = key_compare_fn; */ + return node; +} + +int +trp_rb_insert (trp_key_t key, trp_data_t data, trp_rb_root_t * root, + key_compare key_compare_fn) +{ + trp_rb_node_t *node = root->rb_node, *parent = NULL; + int ret = 0; /* CID 24640 */ + while (node) + { + parent = node; + ret = key_compare_fn (node->key, key); + if (0 < ret) + { + node = node->rb_left; + } + else if (0 > ret) + { + node = node->rb_right; + } + else + { + return -1; + } + } + + node = rb_new_node (key, data, parent /*, key_compare_fn */ ); + if (!node) + { + return -1; + } + + if (parent) + { + if (ret > 0) + { + parent->rb_left = node; + } + else + { + parent->rb_right = node; + } + } + else + { + root->rb_node = node; + } + + rb_insert_color (node, root); + return 0; +} + +int +trp_rb_insert_allow_same_key (trp_key_t key, trp_data_t data, + trp_rb_root_t * root, + key_compare key_compare_fn) +{ + trp_rb_node_t *node = root->rb_node, *parent = NULL; + int ret = 0; /*CID 24638 */ + while (node) + { + parent = node; + ret = key_compare_fn (node->key, key); + if (0 < ret) + { + node = node->rb_left; + } + else + { + node = node->rb_right; + } + } + + node = rb_new_node (key, data, parent /*, key_compare_fn */ ); + if (!node) + { + return -1; + } + + if (parent) + { + if (ret > 0) + { + parent->rb_left = node; + } + else + { + parent->rb_right = node; + } + } + else + { + root->rb_node = node; + } + + rb_insert_color (node, root); + return 0; +} + +NSTACK_STATIC trp_rb_node_t * +trp_rb_search_inorder (trp_key_t key, trp_data_t data, + trp_rb_node_t * node, int *count, + key_compare key_compare_fn) +{ + if (!node) + { + return NULL; + } + + int ret = key_compare_fn (node->key, key);; + if (0 == ret && data == node->data) + { + return node; + } + + if ((NULL == count) || (0 >= --(*count))) + { + return NULL; + } + + trp_rb_node_t *ret_node = + trp_rb_search_inorder (key, data, node->rb_left, count, key_compare_fn); + if (ret_node) + { + return ret_node; + } + + ret_node = + trp_rb_search_inorder (key, data, node->rb_right, count, key_compare_fn); + return ret_node; +} + +void +trp_rb_erase_with_data (trp_key_t key, trp_data_t data, trp_rb_root_t * root, + int count, key_compare key_compare_fn) +{ + trp_rb_node_t *node; + /* recursion operation need depth protect */ + if (! + (node = + trp_rb_search_inorder (key, data, root->rb_node, &count, + key_compare_fn))) + { + return; + } + + rb_erase (node, root); + free (node); + node = NULL; +} + +void +trp_rb_erase (trp_key_t key, trp_rb_root_t * root, key_compare key_compare_fn) +{ + trp_rb_node_t *node; + if (!(node = trp_rb_search (key, root, key_compare_fn))) + { + return; + } + + rb_erase (node, root); + free (node); + node = NULL; +} diff --git a/stacks/lwip_stack/lwip_src/netif/ethernetif.c b/stacks/lwip_stack/lwip_src/netif/ethernetif.c new file mode 100644 index 0000000..6a3e810 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/netif/ethernetif.c @@ -0,0 +1,167 @@ +/* +* +* 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 "spl_opt.h" + +#include "spl_def.h" +#include "mem.h" +#include "stackx/spl_pbuf.h" +//#include <stackx/stats.h> +//#include "sockets.h" +#include <netinet/in.h> + +#include "stackx_spl_share.h" +#include "stackx/spl_api.h" +#include "lwip/etharp.h" + +#include <sc_dpdk.h> +#include "sc_dpdk.h" + +#include "cpuid.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "spl_hal.h" +#include "hal_api.h" + +#include "sys.h" + +#define IFNAME0 'e' +#define IFNAME1 'n' + +struct ethernetif +{ + struct eth_addr *ethaddr; + +}; + +#if (DPDK_MODULE != 1) +NSTACK_STATIC void +low_level_init (struct netif *pnetif) +{ + struct ether_addr eth_addr; + + struct netifExt *pnetifExt = NULL; + NSPOL_LOGINF (NETIF_DEBUG, "low_level_init \n"); + + pnetifExt = getNetifExt (pnetif->num); + if (NULL == pnetifExt) + return; + + hal_get_macaddr (pnetifExt->hdl, ð_addr); + NSPOL_LOGINF (SC_DPDK_INFO, + "low_level_init: Port %s, MAC : %02X:%02X:%02X:%02X:%02X:%02X", + pnetifExt->if_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]); + + pnetif->hwaddr_len = 6; + pnetif->hwaddr[0] = eth_addr.addr_bytes[0]; //0x00; + pnetif->hwaddr[1] = eth_addr.addr_bytes[1]; //0x1b; + pnetif->hwaddr[2] = eth_addr.addr_bytes[2]; //0x21; + pnetif->hwaddr[3] = eth_addr.addr_bytes[3]; //0x6b; + pnetif->hwaddr[4] = eth_addr.addr_bytes[4]; //0x24; + pnetif->hwaddr[5] = eth_addr.addr_bytes[5]; //0x40; + pnetif->mtu = SPL_FRAME_MTU; + + /* don't set SPL_NETIF_FLAG_ETHARP if this device is not an ethernet one */ + pnetif->flags = + NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + pnetif->flags |= NETIF_FLAG_IGMP; + +} +#endif + +#if (DPDK_MODULE != 1) + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to spl_netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if privatedata couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init (struct netif * pnetif) +{ + struct ethernetif *eth_netif; + + if (NULL == pnetif) + { + NSPOL_LOGERR ("netif=NULL"); + return ERR_VAL; + } + NSPOL_LOGINF (NETIF_DEBUG, "ethernetif_init \n"); + + eth_netif = (struct ethernetif *) malloc (sizeof (struct ethernetif)); + if (eth_netif == NULL) + { + NSPOL_LOGERR ("ethernetif_init: out of memory"); + return ERR_MEM; + } + + pnetif->state = eth_netif; + pnetif->name[0] = IFNAME0; + pnetif->name[1] = IFNAME1; + + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + pnetif->output = etharp_output; + pnetif->linkoutput = spl_hal_output; + + eth_netif->ethaddr = (struct eth_addr *) &(pnetif->hwaddr[0]); + + // Add extra netif information here + if (0 != netifExt_add (pnetif)) + { + return ERR_VAL; + } + + /* initialize the hardware */ + low_level_init (pnetif); + NSPOL_LOGINF (NETIF_DEBUG, + "ethernetif_init complete ifname [%c][%c][%d] \n", + pnetif->name[0], pnetif->name[1], pnetif->num); + + return ERR_OK; +} + +void +ethernetif_packets_input (struct netif *pstnetif) +{ + struct spl_pbuf *p = NULL; + spl_hal_input (pstnetif, &p); + + /* no packet could be read, silently ignore this */ + if (p != NULL + && pstnetif->input (spl_convert_spl_pbuf_to_pbuf (p), + pstnetif) != ERR_OK) + { + NSPOL_LOGERR ("netif->input failed]p=%p, netif=%p", p, pstnetif); + } + + /* Free the spl pbuf */ + spl_pbuf_free (p); +} +#endif +//#endif /* 0 */ diff --git a/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c b/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c new file mode 100644 index 0000000..95f3eec --- /dev/null +++ b/stacks/lwip_stack/lwip_src/netif/sc_dpdk.c @@ -0,0 +1,574 @@ +/* +* +* 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 "sc_dpdk.h" +#include "common_mem_mbuf.h" +#include "netif/common.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_msg_api.h" +#include "nsfw_maintain_api.h" +#include "nsfw_recycle_api.h" +#include "stackx_app_res.h" +#include "stackx_pbuf.h" +#ifdef SYS_MEM_RES_STAT +#include "memp.h" +#endif +#include "spl_instance.h" +#ifdef HAL_LIB +#else +#include "rte_memzone.h" +#endif + +#define SPL_MEM_MODULE "spl_mem_module" + +#define TMR_TICK_LENGTH TCP_TMR_INTERVAL /* define the tick length */ + +u32_t uStackArgIndex = 0; +int stackx_core_mask = 40; + +int g_nstack_bind_cpu = 0; +int g_tcpip_thread_sleep_time = 0; + +extern int sbr_create_tx_pool (); +extern int stackx_stat_zone_create (); + +#define GLOBAL_STACK_CORE_ARG "-c" +#define GLOBAL_STACK_CORE_BINE "-bind_cpu" + +u32 g_type; +struct memory_statics memory_used_size[80]; + +void +printmeminfo () +{ + unsigned int i = 0; + long size = 0; + + NSPOL_LOGDBG (SC_DPDK_INFO, + "*************************************************************"); + for (i = 0; i < g_type; i++) + { + NSPOL_LOGDBG (SC_DPDK_INFO, "%s : %ld", memory_used_size[i].name, + memory_used_size[i].size); + size += memory_used_size[i].size; + } + + size += (g_type * sizeof (struct common_mem_memzone)); + NSPOL_LOGDBG (SC_DPDK_INFO, "total size %ld", size); + NSPOL_LOGDBG (SC_DPDK_INFO, + "*************************************************************"); +} + +void +print_call_stack () +{ +} + +/* Parse the argument given in the command line of the application */ +void +smp_parse_stack_args (int argc, char **argv) +{ + int i = 0; + + const unsigned int global_core_length = 2; //GLOBAL_STACK_CORE_ARG "-c" string length is 2 + + for (i = uStackArgIndex + 1; i < argc; i++) + { + if ((i + 1) < argc) + { + if (strncmp (argv[i], "-sleep", 6) == 0) //compare "-sleep" string, length is 6 + { + g_tcpip_thread_sleep_time = atoi (argv[++i]); + NSPOL_LOGDBG (SC_DPDK_INFO, "g_tcpip_thread_sleep_time=%d", + g_tcpip_thread_sleep_time); + continue; + } + + if (strncmp (argv[i], GLOBAL_STACK_CORE_ARG, global_core_length) == + 0) + { + stackx_core_mask = atoi (argv[++i]); + if (stackx_core_mask < 1) + { + NSPOL_LOGDBG (SC_DPDK_INFO, + "Invalid Args:core_mask can't be less than 1,input value is:%s", + argv[i]); + } + + continue; + } + + if (strncmp + (argv[i], GLOBAL_STACK_CORE_BINE, + sizeof (GLOBAL_STACK_CORE_BINE)) == 0) + { + if (argv[++i]) + { + g_nstack_bind_cpu = atoi (argv[i]); + } + + if (g_nstack_bind_cpu < 0) + { + g_nstack_bind_cpu = 0; + } + + continue; + } + } + else + { + NSPOL_LOGDBG (SC_DPDK_INFO, "Invalid args:%s miss value ", argv[i]); //now ,only support this format ,others maybe supported in future + } + } + + return; +} + +mpool_handle +create_tx_mbuf_pool () +{ + mpool_handle mbf_pool_handle = NULL; + + nsfw_mem_mbfpool mbuf_pool; + + mbuf_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbuf_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_tx_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbuf_pool.usnum = TX_MBUF_POOL_SIZE - 1; + mbuf_pool.uscash_size = 0; + mbuf_pool.uspriv_size = 0; + mbuf_pool.usdata_room = TX_MBUF_MAX_LEN; + mbuf_pool.isocket_id = SOCKET_ID_ANY; + mbuf_pool.enmptype = NSFW_MRING_SPSC; + mbf_pool_handle = nsfw_mem_mbfmp_create (&mbuf_pool); + if (NULL == mbf_pool_handle) + { + NSPOL_LOGERR ("create_tx_mbuf_pool failed]name=%s, num=%u, room=%u", + mbuf_pool.stname.aname, mbuf_pool.usnum, + mbuf_pool.usdata_room); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "tx_mempool_malloc=%p, num=%u, room=%u, total_mem=%d", + mbf_pool_handle, TX_MBUF_POOL_SIZE, mbuf_pool.usdata_room, + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + DPDK_MEMORY_COUNT ((get_mempoll_tx_name ()), + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + MEM_STAT (SPL_MEM_MODULE, "spl_mbuf_pool", NSFW_SHMEM, + nsfw_mem_get_len (mbf_pool_handle, NSFW_MEM_MBUF)); + + return mbf_pool_handle; +} + +mring_handle +create_segment_pool () +{ + nsfw_mem_sppool seg_pool; + seg_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (seg_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_seg_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + seg_pool.usnum = 16; + seg_pool.useltsize = sizeof (struct common_pcb); + seg_pool.isocket_id = SOCKET_ID_ANY; + seg_pool.enmptype = NSFW_MRING_SPSC; + + mring_handle seg_mp_handle = nsfw_mem_sp_create (&seg_pool); + if (NULL == seg_mp_handle) + { + NSPOL_LOGERR + ("create_segment_pool common failed]name=%s, num=%u, size=%u", + seg_pool.stname.aname, SPL_MEMP_NUM_TCP_SEG, seg_pool.useltsize); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "common seg_mempool_malloc=%p, num=%u, size=%u, total_mem=%d", + seg_mp_handle, SPL_MEMP_NUM_TCP_SEG, seg_pool.useltsize, + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + DPDK_MEMORY_COUNT ((get_mempoll_seg_name ()), + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + MEM_STAT (SPL_MEM_MODULE, "spl_seg_pool", NSFW_SHMEM, + nsfw_mem_get_len (seg_mp_handle, NSFW_MEM_SPOOL)); + return seg_mp_handle; +} + +mring_handle +create_msg_pool () +{ + nsfw_mem_sppool msg_pool; + msg_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (msg_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_msg_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf fail"); + return NULL; + } + + msg_pool.usnum = TX_MSG_POOL_SIZE; + msg_pool.useltsize = sizeof (data_com_msg); + msg_pool.isocket_id = SOCKET_ID_ANY; + msg_pool.enmptype = NSFW_MRING_MPMC; + mring_handle msg_mp_handle = nsfw_mem_sp_create (&msg_pool); + + if (NULL == msg_mp_handle) + { + NSPOL_LOGERR ("create_msg_pool failed]name=%s, num=%u, size=%u", + msg_pool.stname.aname, TX_MSG_POOL_SIZE, + msg_pool.useltsize); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "msg_pool_malloc=%p, num=%u, size=%u, total_mem=%d", + msg_mp_handle, TX_MSG_POOL_SIZE, msg_pool.useltsize, + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + DPDK_MEMORY_COUNT ((get_mempoll_msg_name ()), + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + MEM_STAT (SPL_MEM_MODULE, "spl_msg_pool", NSFW_SHMEM, + nsfw_mem_get_len (msg_mp_handle, NSFW_MEM_SPOOL)); + return msg_mp_handle; +} + +mring_handle +create_primary_box () +{ + nsfw_mem_mring mbox_pool; + mbox_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbox_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_stackx_ring_name ()); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbox_pool.usnum = MBOX_RING_SIZE - 1; + mbox_pool.isocket_id = SOCKET_ID_ANY; + mbox_pool.enmptype = NSFW_MRING_MPSC; + mring_handle mbox_handle = nsfw_mem_ring_create (&mbox_pool); + if (NULL == mbox_handle) + { + NSPOL_LOGERR ("create_primary_mbox failed]name=%s, num=%u", + mbox_pool.stname.aname, mbox_pool.usnum + 1); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "primary_mbox_malloc=%p, num=%u, total_mem=%d", + mbox_handle, MBOX_RING_SIZE, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + DPDK_MEMORY_COUNT ((get_stackx_ring_name ()), + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + MEM_STAT (SPL_MEM_MODULE, "primary_mbox_ring", NSFW_SHMEM, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + return mbox_handle; +} + +mring_handle +create_priority_box (u32 prio) +{ + nsfw_mem_mring mbox_pool; + mbox_pool.stname.entype = NSFW_SHMEM; + int retval = + spl_snprintf (mbox_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_stackx_priority_ring_name (prio)); + if (retval < 0) + { + NSPOL_LOGERR ("spl_snprintf failed"); + return NULL; + } + + mbox_pool.usnum = MBOX_RING_SIZE - 1; + mbox_pool.isocket_id = SOCKET_ID_ANY; + mbox_pool.enmptype = NSFW_MRING_MPSC; + mring_handle mbox_handle = nsfw_mem_ring_create (&mbox_pool); + if (NULL == mbox_handle) + { + NSPOL_LOGERR ("Create priority mbox fail]name=%s, num=%u", + mbox_pool.stname.aname, mbox_pool.usnum + 1); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "prio=%u, mbox=%p, num=%u, total_mem=%d", prio, + mbox_handle, MBOX_RING_SIZE, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + DPDK_MEMORY_COUNT ((get_stackx_priority_ring_name (prio)), + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + MEM_STAT (SPL_MEM_MODULE, mbox_pool.stname.aname, NSFW_SHMEM, + (nsfw_mem_get_len (mbox_handle, NSFW_MEM_RING))); + return mbox_handle; + +} + +int +init_instance () +{ + int ret; + p_def_stack_instance = + (stackx_instance *) malloc (sizeof (stackx_instance)); + if (NULL == p_def_stack_instance) + { + NSPOL_LOGERR ("malloc failed"); + return -1; + } + + ret = MEMSET_S (p_def_stack_instance, sizeof (stackx_instance), 0, + sizeof (stackx_instance)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + + p_def_stack_instance->rss_queue_id = 0; + p_def_stack_instance->netif_list = NULL; + p_def_stack_instance->mp_tx = create_tx_mbuf_pool (); + if (!p_def_stack_instance->mp_tx) + { + return -1; + } + + (void) spl_reg_res_tx_mgr (p_def_stack_instance->mp_tx); // will only return 0, no need to check return value + + /* Modified above code to hold common_pcb */ + p_def_stack_instance->cpcb_seg = create_segment_pool (); + if (!p_def_stack_instance->cpcb_seg) + { + return -1; + } + + p_def_stack_instance->lmsg_pool = create_msg_pool (); + if (!p_def_stack_instance->lmsg_pool) + { + return -1; + } + + mring_handle mbox_array[SPL_MSG_BOX_NUM] = { NULL }; + p_def_stack_instance->lstack.primary_mbox.llring = create_primary_box (); + if (!p_def_stack_instance->lstack.primary_mbox.llring) + { + return -1; + } + mbox_array[0] = p_def_stack_instance->lstack.primary_mbox.llring; + + u32 m = 0; + while (m < MSG_PRIO_QUEUE_NUM) + { + p_def_stack_instance->lstack.priority_mbox[m].llring = + create_priority_box (m); + if (!p_def_stack_instance->lstack.priority_mbox[m].llring) + { + return -1; + } + mbox_array[m + 1] = + p_def_stack_instance->lstack.priority_mbox[m].llring; + m++; + } + + (void) spl_add_mbox (mbox_array, SPL_MSG_BOX_NUM); + + g_nsfw_rti_primary_stat = &p_def_stack_instance->lstat.primary_stat; //save to g_nsfw_rti_primary_stat(this is a SH addr) + return 0; +} + +void +spl_free_msgs_in_box (mring_handle r) +{ + i32 count = 0, i = 0; + + void **msgs = NULL; + data_com_msg *m = NULL; + + while ((count = nsfw_mem_ring_dequeuev (r, msgs, 32)) > 0) + { + /* drop all of them */ + if (msgs == NULL) + break; + + for (i = 0; i < count; i++) + { + m = (data_com_msg *) msgs[i]; + if (m->param.op_type == MSG_ASYN_POST) + ASYNC_MSG_FREE (m); + else + SYNC_MSG_ACK (m); + } + } +} + +inline int +spl_msg_malloc (data_com_msg ** p_msg_entry) +{ + mring_handle msg_pool = NULL; + int rslt; + stackx_instance *instance = p_def_stack_instance; + msg_pool = instance->lmsg_pool; + if (!msg_pool) + { + NSPOL_LOGERR ("msg_pool is NULL"); + return -1; + } + + rslt = nsfw_mem_ring_dequeue (msg_pool, (void **) p_msg_entry); + if ((rslt == 0) || (*p_msg_entry == NULL)) + { + NSPOL_LOGERR ("failed to get msg from ring"); + return -1; + } + + res_alloc (&(*p_msg_entry)->param.res_chk); + + (*p_msg_entry)->param.msg_from = msg_pool; + (*p_msg_entry)->param.err = ERR_OK; + return 0; +} + +struct spl_pbuf * +spl_mbuf_malloc (uint16_t len, spl_pbuf_type Type, u16_t * count) +{ + struct common_mem_mbuf *mbuf = NULL; + struct common_mem_mbuf *mbuf_first = NULL; + struct common_mem_mbuf *mbuf_tail = NULL; + struct spl_pbuf *buf = NULL; + struct spl_pbuf *first = NULL; + struct spl_pbuf *tail = NULL; + + mpool_handle mp = NULL; + + mp = p_def_stack_instance->mp_tx; + if (mp == NULL) + { + return NULL; /*if mp is NULL when init app will Inform */ + } + + while (len > 0) + { + mbuf = (struct common_mem_mbuf *) nsfw_mem_mbf_alloc (mp, NSFW_SHMEM); + if (unlikely (mbuf == NULL)) + { + if (mbuf_first != NULL) + { + if (res_free + (& + (((struct spl_pbuf *) ((char *) mbuf_first + + sizeof (struct + common_mem_mbuf)))->res_chk))) + { + NSPOL_LOGERR ("res_free failed"); + } + spl_mbuf_free (mbuf_first); + } + + return NULL; + } + + uint16_t alloc = TX_MBUF_MAX_LEN; + if (len < TX_MBUF_MAX_LEN) + { + alloc = len; + } + + (*count)++; + mbuf->data_len = alloc; + mbuf->next = NULL; + buf = + (struct spl_pbuf *) ((char *) mbuf + sizeof (struct common_mem_mbuf)); + res_alloc (&buf->res_chk); + + buf->next_a = 0; + buf->payload_a = ADDR_LTOSH_EXT (common_pktmbuf_mtod (mbuf, void *)); + buf->tot_len = len; + buf->len = alloc; + buf->type = Type; + buf->flags = 0; + + buf->freeNext = NULL; + + buf->conn_a = 0; + + if (first == NULL) + { + first = buf; + mbuf_first = mbuf; + tail = buf; + mbuf_tail = mbuf; + mbuf_first->nb_segs = 1; + mbuf_first->pkt_len = alloc; + } + else + { + /* Already there is a check for the return value of rtp_pktmbuf_alloc, + hence not an issue */ + + tail->next_a = ADDR_LTOSH_EXT (buf); + tail = buf; +#ifdef HAL_LIB +#else + mbuf_tail->next = mbuf; +#endif + mbuf_tail = mbuf; + + mbuf_first->pkt_len = (mbuf_first->pkt_len + mbuf->data_len); + mbuf_first->nb_segs++; + + } + + len -= alloc; + } + + return first; +} + +/* + * Ring distribution function: protocol stack once a packet processing, so there is no use of bulk package + * @param buf pbuf means * @param packet_inport the packet from which the port to enter, for the configuration table with the ip comparison + * @ Protocol stack add location: ip.c-> ip_input () -> (if (netif == NULL) branch) + * @ Return value: 0 for the send into * 0 for the transmission failed: send the original failure 1, + * err = -20 did not match to the client, err = -1Ring full, overflow, will release the package +*/ + +inline void +spl_mbuf_free (void *mbuf) +{ + (void) nsfw_mem_mbf_free ((mbuf_handle) mbuf, NSFW_SHMEM); +} + +inline uint16_t +spl_mbuf_refcnt_update (void *mbuf, int16_t value) +{ + common_mbuf_refcnt_set ((struct common_mem_mbuf *) mbuf, + common_mbuf_refcnt_read ((struct common_mem_mbuf *) + mbuf) + value); + return 1; +} diff --git a/stacks/lwip_stack/lwip_src/netif/spl_hal.c b/stacks/lwip_stack/lwip_src/netif/spl_hal.c new file mode 100644 index 0000000..c7cfca1 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/netif/spl_hal.c @@ -0,0 +1,1755 @@ +/* +* +* 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_arch.h" +#include "netif.h" +#include "spl_sockets.h" +//#include <netinet/in.h> + +#include "stackx_spl_share.h" +#include "stackx_pbuf.h" +#include "spl_api.h" +#include "sharedmemory.h" +//#include "nettool.h" +#include "lwip/etharp.h" +#include "ip_module_api.h" +#include "sc_dpdk.h" +#include "nstack_log.h" +#include "common.h" +#include "nstack_securec.h" +//#include "ip.h" +#include "configuration_reader.h" +#include "spl_hal.h" +#include "nsfw_maintain_api.h" +#include "stackx_common.h" +#include "spl_instance.h" +#include <netinet/in.h> +#include "prot/tcp.h" + +extern u32_t g_mbuf_size[MAX_THREAD_NUM]; +extern u32_t uStackArgIndex; +extern void smp_parse_stack_args (int argc, char **argv); +extern void spl_do_dump (struct spl_pbuf *p, u16 direction); + +#define SPL_HAL_SEND_TRY 100000 + +#define SPL_HAL_MODULE "SPL_HAL_MODULE" +extern u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +/* structure to store the rx and tx packets. Put two per cache line as ports + * used in pairs */ +struct port_stats +{ + unsigned rx; + unsigned tx; + unsigned drop; + u64_t rx_size; + u64_t tx_size; + u64_t recv_last_cycles; + u64_t send_last_cycles; +} __attribute__ ((aligned (COMMON_CACHE_LINE_SIZE / 2))); + +struct port_capa +{ + u32_t tx_ipv4_cksum_offload; + u32_t tx_udp_cksum_offload; + u32_t tx_tcp_cksum_offload; +}; + +struct rx_pkts +{ + u16_t num; + u16_t index; + struct common_mem_mbuf *pkts[PKT_BURST]; +}; + +struct tx_pkts +{ + u16_t num; + struct common_mem_mbuf *pkts[PKT_BURST]; +}; + +struct port_pkts +{ + struct rx_pkts rx; + struct tx_pkts tx; +}; + +struct psd_header +{ + u32_t src_addr; /* IPaddress of source host. */ + u32_t dst_addr; /* IPaddress of destination host(s). */ + u8_t zero; /* zero. */ + u8_t proto; /* L4 protocol type. */ + u16_t len; /* L4 length. */ +} __attribute__ ((__packed__)); + +NSTACK_STATIC unsigned num_ports_NIC = 0; +NSTACK_STATIC unsigned num_ports_NIC_start = 0; + +struct stackx_port_info *head_used_port_list; +struct stackx_port_zone *p_stackx_port_zone = NULL; + +struct bond_ports_info bond_ports_array = {.cnt = 0 }; + +static u8_t bond_ports_array_cnt_start = 0; + +static struct port_capa spl_hal_capa = { 0 }; + +static struct port_pkts spl_hal_pkts[HAL_MAX_NIC_NUM]; + +NSTACK_STATIC inline u16_t +get_ipv4_16b_sum (u16_t * ptr16, u32_t nr) +{ + u32_t sum = 0; + + while (nr > 1) + { + sum += *ptr16; + nr -= sizeof (u16_t); + ptr16++; + + if (sum > UINT16_MAX) + { + sum -= UINT16_MAX; + } + } + + /* If length is in odd bytes */ + if (nr) + { + sum += *((u8_t *) ptr16); + } + + sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff); + sum &= 0x0ffff; + return (u16_t) sum; +} + +NSTACK_STATIC inline u16_t +get_ipv4_bswap16 (u16_t x) +{ + return (u16_t) (((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8)); +} + +NSTACK_STATIC inline u16_t +get_ipv4_psd_sum (struct ip_hdr * iphdr, u64_t ol_flags) +{ + struct psd_header psd_hdr; + + psd_hdr.src_addr = iphdr->src.addr; + psd_hdr.dst_addr = iphdr->dest.addr; + psd_hdr.zero = 0; + psd_hdr.proto = iphdr->_proto; + + if (ol_flags & PKT_TX_TCP_SEG) + { + psd_hdr.len = 0; + } + else + { + psd_hdr.len = get_ipv4_bswap16 ((get_ipv4_bswap16 (iphdr->_len) + - sizeof (struct ip_hdr))); + } + + return get_ipv4_16b_sum ((u16_t *) & psd_hdr, sizeof (struct psd_header)); +} + +/* should be called after head_used_port_list is initialized */ +NSTACK_STATIC hal_hdl_t +get_port_hdl_by_name (const char *name) +{ + unsigned int i = 0; + struct stackx_port_info *p = p_stackx_port_zone->stackx_one_port; + + while (i < p_stackx_port_zone->port_num) + { + if (!strncasecmp (p->linux_ip.if_name, name, strlen (name))) + { + return p->linux_ip.hdl; + } + + p = &p_stackx_port_zone->stackx_one_port[++i]; + } + + NSPOL_LOGERR ("failed to find port id]name=%s", name); + return hal_get_invalid_hdl (); +} + +NSTACK_STATIC struct stackx_port_info * +get_port_info_by_name (const char *name) +{ + struct stackx_port_info *p = p_stackx_port_zone->stackx_one_port; + unsigned int i = 0; + + while (i < p_stackx_port_zone->port_num) + { + if (!strncasecmp (p->linux_ip.if_name, name, strlen (name))) + { + return p; + } + + p = &p_stackx_port_zone->stackx_one_port[++i]; + } + + return NULL; +} + +NSTACK_STATIC int +del_port_in_port_list (const char *name) +{ + struct stackx_port_info *inf = head_used_port_list; + struct stackx_port_info *prev = NULL; + + while (inf) + { + if (!strncasecmp (inf->linux_ip.if_name, name, strlen (name))) + { + if (prev != NULL) + { + prev->next_use_port = inf->next_use_port; + } + else + { + head_used_port_list = inf->next_use_port; + } + + break; + } + + prev = inf; + inf = inf->next_use_port; + } + + return 0; +} + +extern void create_netif (struct stackx_port_info *p_port_info); + +NSTACK_STATIC int +add_port_in_port_list (struct stackx_port_info *p) +{ + char *name; + struct stackx_port_info *inf = head_used_port_list; + struct stackx_port_info *prev = NULL; + + name = p->linux_ip.if_name; + + while (inf) + { + if (!strncasecmp (inf->linux_ip.if_name, name, strlen (name))) + { + NSPOL_LOGERR ("ERROR: add an existing port!"); + return -1; + } + + prev = inf; + inf = inf->next_use_port; + } + + if (prev == NULL) + { + head_used_port_list = p; + } + else + { + prev->next_use_port = p; + } + + p->next_use_port = NULL; + create_netif (p); + return 0; +} + +/* Queries the link status of a port and prints it to screen */ +NSTACK_STATIC void +report_port_link_status (struct stackx_port_info *p) +{ + /* get link status */ + u32 status; + + status = hal_link_status (p->linux_ip.hdl); + + if (status) + { + NSPOL_LOGINF (SC_DPDK_INFO, "Port=%s: Link Up", p->linux_ip.if_name); + } + else + { + NSPOL_LOGINF (SC_DPDK_INFO, "Port=%s: Link Down", p->linux_ip.if_name); + } +} + +int +spl_hal_ether_etoa (const unsigned char *e, int e_len, char *a, int a_len) +{ + char *c = a; + int i; + int retVal; + + if (!e || !a || e_len < 0) + return -1; + + if (e_len > NETIF_ETH_ADDR_LEN) + e_len = NETIF_ETH_ADDR_LEN; + + if (a_len < e_len * 3) + return -1; + + for (i = 0; i < e_len; i++) + { + if (i) + { + *c++ = ':'; + } + retVal = SPRINTF_S (c, a_len - (c - a), "%02x", e[i] & 0xff); + if (-1 == retVal) + { + NSPOL_LOGERR ("SPRINTF_S failed]ret=%d.", retVal); + return -1; + } + c = c + retVal; + } + + return 0; +} + +NSTACK_STATIC inline void +spl_hal_buf_convert (struct common_mem_mbuf *mbuf, struct spl_pbuf **buf) +{ + struct common_mem_mbuf *before = NULL; + struct spl_pbuf *last = NULL; + struct spl_pbuf *first = NULL; + struct spl_pbuf *tmp = NULL; + + while (mbuf != NULL) + { + //dpdk 2.1 + tmp = + (struct spl_pbuf *) ((char *) mbuf + sizeof (struct common_mem_mbuf)); + res_alloc (&tmp->res_chk); + tmp->payload = common_pktmbuf_mtod (mbuf, void *); + tmp->tot_len = mbuf->pkt_len; + tmp->len = mbuf->data_len; + tmp->type = SPL_PBUF_HUGE; + tmp->proto_type = SPL_PBUF_PROTO_NONE; + tmp->next = NULL; + tmp->flags = 0; + + if (first == NULL) + { + first = tmp; + last = first; + } + else + { + /* Always the "if(first == NULL)" code segment is executed and then + "else" segment code is executed, so the "last" variable is not + NULL always when "else" case is executed */ + last->next = tmp; + last = tmp; + } + + before = mbuf; + mbuf = mbuf->next; + + before->next = NULL; + } + + *buf = first; +} + +NSTACK_STATIC int +spl_hal_port_zone_init () +{ + int retVal; + nsfw_mem_zone create_port_zone; + nsfw_mem_zone create_port_info; + struct stackx_port_info *mz_port_info; + INITPOL_LOGINF ("RTP", "spl_hal_port_zone_init", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_START); + + if ((CUR_CFG_HAL_PORT_NUM < 1) + || (SIZE_MAX / sizeof (struct stackx_port_info) < CUR_CFG_HAL_PORT_NUM)) + { + NSPOL_LOGERR ("malloc parameter incorrect]max_linux_port=%u", + CUR_CFG_HAL_PORT_NUM); + return -1; + } + + if (spl_snprintf + (create_port_zone.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + MP_STACKX_PORT_ZONE) < 0) + { + NSPOL_LOGERR ("spl_snprintf fail"); + + return -1; + } + + create_port_zone.stname.entype = NSFW_SHMEM; + create_port_zone.isocket_id = SOCKET_ID_ANY; + create_port_zone.length = sizeof (struct stackx_port_zone); + create_port_zone.ireserv = 0; + p_stackx_port_zone = + (struct stackx_port_zone *) nsfw_mem_zone_create (&create_port_zone); + + if (NULL == p_stackx_port_zone) + { + INITPOL_LOGERR ("RTP", "spl_hal_port_zone_init", + "Cannot create memory zone for MP_STACKX_PORT_ZONE information", + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + common_exit (EXIT_FAILURE, + "Cannot create memory zone for MP_STACKX_PORT_ZONE information"); + } + + retVal = + MEMSET_S (p_stackx_port_zone, sizeof (struct stackx_port_zone), 0, + sizeof (struct stackx_port_zone)); + + if (EOK != retVal) + { + INITPOL_LOGERR ("RTP", "spl_hal_port_zone_init", "MEMSET_S return fail", + retVal, MODULE_INIT_FAIL); + nsfw_mem_zone_release (&create_port_zone.stname); + return -1; + } + + if (spl_snprintf + (create_port_info.stname.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + MP_STACKX_PORT_INFO) < 0) + { + NSPOL_LOGERR ("VSNPRINTF_S fail"); + return -1; + } + + create_port_info.stname.entype = NSFW_SHMEM; + create_port_info.isocket_id = SOCKET_ID_ANY; + create_port_info.length = + CUR_CFG_HAL_PORT_NUM * sizeof (struct stackx_port_info); + create_port_info.ireserv = 0; + mz_port_info = + (struct stackx_port_info *) nsfw_mem_zone_create (&create_port_info); + + if (NULL == mz_port_info) + { + INITPOL_LOGERR ("RTP", "spl_hal_port_zone_init", + "Cannot create memory zone for MP_STACKX_PORT_INFO information", + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + common_exit (EXIT_FAILURE, + "Cannot create memory zone for MP_STACKX_PORT_INFO information"); + } + + retVal = + MEMSET_S (mz_port_info, create_port_info.length, 0, + create_port_info.length); + + if (EOK != retVal) + { + INITPOL_LOGERR ("RTP", "spl_hal_port_zone_init", "MEMSET_S return fail", + retVal, MODULE_INIT_FAIL); + nsfw_mem_zone_release (&create_port_info.stname); + nsfw_mem_zone_release (&create_port_zone.stname); + return -1; + } + + MEM_STAT (SPL_HAL_MODULE, create_port_zone.stname.aname, NSFW_SHMEM, + create_port_info.length); + + p_stackx_port_zone->stackx_one_port = mz_port_info; + + INITPOL_LOGINF ("RTP", "spl_hal_port_zone_init", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); + + return 0; +} + +int +spl_hal_init (int argc, char *argv[]) +{ + int retval = -1; + int idx_init; + + NSPOL_LOGINF (SC_DPDK_INFO, "spl_hal_init start"); + + /* Get nstack args */ + smp_parse_stack_args (argc, argv); + + if (0 == uStackArgIndex) + { + NSPOL_LOGERR ("uStackArgIndex is 0, can lead to long loop]"); + return retval; + } + + /* Init DPDK */ + argc = uStackArgIndex--; + INITPOL_LOGINF ("RTP", "hal_init_global", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_START); + + for (idx_init = 0; idx_init < argc; idx_init++) + { + NSPOL_LOGINF (SC_DPDK_INFO, + "hal_init_global]idx_init=%d,argv[idx_init]=%s", idx_init, + argv[idx_init]); + } + + retval = hal_init_global (argc, argv); + + if (0 != retval) + { + NSPOL_LOGERR ("call hal_init_global fail]retval = %d", retval); + return -1; + } + + retval = hal_init_local (); + + if (0 != retval) + { + NSPOL_LOGERR ("call hal_init_local fail]retval = %d", retval); + return -1; + } + + retval = spl_hal_port_zone_init (); + if (0 != retval) + { + NSPOL_LOGERR ("call hal_init_local fail]retval = %d", retval); + return -1; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "Finished Process Init"); + + return 0; + +} + +static inline int +spl_hal_rx_mbuf_free (void *data, void *arg) +{ + struct spl_pbuf *tmp = NULL; + struct common_mem_mbuf *mbuf = (struct common_mem_mbuf *) data; + (void) arg; + + tmp = (struct spl_pbuf *) ((char *) mbuf + sizeof (struct common_mem_mbuf)); + if (tmp->res_chk.alloc_flag == TRUE) + return 1; + + if (common_mbuf_refcnt_read (mbuf) == 0) + return 1; + + NSPOL_LOGDBG (SC_DPDK_INFO, "rx_pool init in fault case: free mbuf=%p", + mbuf); + spl_mbuf_free (mbuf); + return 0; +} + +struct common_mem_mempool * +spl_hal_rx_pool_create (int nic_id, int queue_id, int start_type) +{ + int retval; + struct common_mem_mempool *mp; + nsfw_mem_mbfpool create_mbuf_pool; + nsfw_mem_name lookup_mbuf_pool; + struct common_mem_ring *ring; + + if (start_type == 1) + { + create_mbuf_pool.stname.entype = NSFW_SHMEM; + create_mbuf_pool.uscash_size = 0; + create_mbuf_pool.uspriv_size = 0; + create_mbuf_pool.isocket_id = SOCKET_ID_ANY; + create_mbuf_pool.enmptype = NSFW_MRING_SPSC; + + retval = + spl_snprintf (create_mbuf_pool.stname.aname, NSFW_MEM_NAME_LENGTH - 1, + "%s", get_mempoll_rx_name (queue_id, nic_id)); + + if (-1 == retval) + { + NSPOL_LOGERR ("spl_snprintf fail"); + return NULL; + } + + create_mbuf_pool.usnum = RX_MBUF_POOL_SIZE - 1; + /*performance, rx buf cap is special, ((size - HEADROOM) >> 10) <<10, see ixgbe_dev_rx_init; + if want cap size == TX_MBUF_MAX_LEN, must let data_root=TX_MBUF_MAX_LEN+COMMON_PKTMBUF_HEADROOM and + TX_MBUF_MAX_LEN must N*1024; + */ + create_mbuf_pool.usdata_room = + TX_MBUF_MAX_LEN + COMMON_PKTMBUF_HEADROOM; + + NSPOL_LOGDBG (SC_DPDK_INFO, "hal_rx_pool.usnum=%u, usdata_room=%u", + create_mbuf_pool.usnum, create_mbuf_pool.usdata_room); + + mp = + (struct common_mem_mempool *) + nsfw_mem_mbfmp_create (&create_mbuf_pool); + + if (mp == NULL) + { + NSPOL_LOGERR ("nsfw_mem_mbfmp_create fail"); + return NULL; + } + + MEM_STAT (SPL_HAL_MODULE, create_mbuf_pool.stname.aname, NSFW_SHMEM, + nsfw_mem_get_len (mp, NSFW_MEM_MBUF)); + NSPOL_LOGDBG (SC_DPDK_INFO, "create:thread=%d,nic_id=%d,mp=%p,size=%d", + queue_id, nic_id, mp, nsfw_mem_get_len (mp, + NSFW_MEM_MBUF)); + + char rx_msg_arr_name[NSFW_MEM_NAME_LENGTH]; + data_com_msg *rx_msg_array = NULL; + retval = spl_snprintf (rx_msg_arr_name, NSFW_MEM_NAME_LENGTH, "%s", + get_mempoll_rxmsg_name (queue_id, nic_id)); + + if (-1 != retval) + { + rx_msg_array = (data_com_msg *) sbr_create_mzone (rx_msg_arr_name, + (size_t) + sizeof + (data_com_msg) * + RX_MBUF_POOL_SIZE); + } + + if (!rx_msg_array) + { + NSSBR_LOGERR + ("Create rx_msg_array zone fail]name=%s, num=%u, size=%zu", + rx_msg_arr_name, RX_MBUF_POOL_SIZE, + (size_t) sizeof (data_com_msg) * RX_MBUF_POOL_SIZE); + } + else + { + /*bind msg to pbuf */ + MEM_STAT (SPL_HAL_MODULE, rx_msg_arr_name, NSFW_SHMEM, + (size_t) sizeof (data_com_msg) * RX_MBUF_POOL_SIZE); + NSSBR_LOGINF + ("Create rx_msg_array zone ok]name=%s, ptr=%p, num=%u, size=%zu", + rx_msg_arr_name, rx_msg_array, RX_MBUF_POOL_SIZE, + sizeof (data_com_msg) * RX_MBUF_POOL_SIZE); + + struct common_mem_mbuf *mbuf = NULL; + struct spl_pbuf *buf = NULL; + u32 loop = 0; + + for (; loop < RX_MBUF_POOL_SIZE; loop++) + { + mbuf = nsfw_mem_mbf_alloc (mp, NSFW_SHMEM); + + if (!mbuf) + { + /* alloc failed , still can work, no prebind success just not so faster */ + NSSBR_LOGERR + ("nsfw_mem_mbf_alloc failed,this can not happen"); + break; + } + + buf = + (struct spl_pbuf *) ((char *) mbuf + + sizeof (struct common_mem_mbuf)); + sys_sem_init (&rx_msg_array[loop].param.op_completed); + rx_msg_array[loop].param.msg_from = NULL; + buf->msg = (void *) &rx_msg_array[loop]; + (void) res_free (&buf->res_chk); //no need to check return value, as it will do free operation depends on alloc_flag + + if (nsfw_mem_mbf_free (mbuf, NSFW_SHMEM) < 0) + { + /* free failed , still can work, no prebind work just not so faster */ + NSSBR_LOGERR + ("nsfw_mem_mbf_free failed,this can not happen"); + break; + } + } + + } + + } + else + { + retval = + spl_snprintf (lookup_mbuf_pool.aname, NSFW_MEM_NAME_LENGTH - 1, "%s", + get_mempoll_rx_name (queue_id, nic_id)); + + if (-1 == retval) + { + NSPOL_LOGERR ("spl_snprintf fail"); + return NULL; + } + + lookup_mbuf_pool.entype = NSFW_SHMEM; + lookup_mbuf_pool.enowner = NSFW_PROC_MAIN; + mp = + (struct common_mem_mempool *) + nsfw_mem_mbfmp_lookup (&lookup_mbuf_pool); + + if (mp == NULL) + { + NSPOL_LOGERR ("nsfw_mem_mbfmp_lookup fail, name=%s, try to create", + lookup_mbuf_pool.aname); + return spl_hal_rx_pool_create (nic_id, queue_id, 1); + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "lookup:thread=%d,nic_id=%d,mp=%p,size=%d", + queue_id, nic_id, mp, nsfw_mem_get_len (mp, + NSFW_MEM_MBUF)); + + /*We have to recycle RX mbufs hold by DPDK when fault recovering of upgrading nstack */ + if (start_type == 3 || start_type == 2) + { + ring = (struct common_mem_ring *) (mp->pool_data); + NSPOL_LOGINF (SC_DPDK_INFO, + "BEFORE clear rx_mpool]prod.head=%u, prod.tail=%u, " + "cons.head=%u, cons.tail=%u", ring->prod.head, + ring->prod.tail, ring->cons.head, ring->cons.tail); + + if (nsfw_mem_mbuf_iterator (mp, 0, mp->size, + spl_hal_rx_mbuf_free, NULL) < 0) + { + NSPOL_LOGERR ("nsfw_mem_mbuf_iterator return fail"); + return NULL; + } + + NSPOL_LOGINF (SC_DPDK_INFO, + "AFTER clear rx_mpool]prod.head=%u, prod.tail=%u, " + "cons.head=%u, cons.tail=%u", ring->prod.head, + ring->prod.tail, ring->cons.head, ring->cons.tail); + } + + } + + return mp; + +} + +int +spl_hal_bond_config (struct network_configuration *network) +{ + struct phy_net *phynet = network->phy_net; + struct ref_nic *phead = phynet->header; + static u8_t bond_index = 0; /* for auto-generating bond_name */ + unsigned int check_bond = 0, check_name; + int retVal; + u8_t j, k, idx = 0; + + /* get bond info from network configuration */ + if (phynet->bond_mode != -1 && bond_ports_array.cnt < MAX_BOND_PORT_NUM) + { + struct ref_nic *phead_bond = phead; + char *name = phynet->bond_name; + struct bond_set *s = &bond_ports_array.ports[bond_ports_array.cnt]; + + while (phead_bond != NULL) + { + /* check slave name, repeated slave nic cannot be added to bond set. */ + check_name = 0; + + for (j = 0; j < idx; j++) + { + if (strcmp (s->slave_ports[j], phead_bond->nic_name) == 0) + { + check_name = 1; + break; + } + } + + if (check_name) + { + break; + } + + /* if this nic has been added to a bond_set, ignore it */ + check_bond = 0; + + for (k = 0; k < bond_ports_array.cnt && !check_bond; k++) + { + for (j = 0; + j < bond_ports_array.ports[k].slave_port_cnt + && !check_bond; j++) + { + if (strcmp + (bond_ports_array.ports[k].slave_ports[j], + phead_bond->nic_name) == 0) + { + check_bond = 1; + + if (name[0] == 0) + { + retVal = + STRNCPY_S (name, IP_MODULE_MAX_NAME_LEN, + bond_ports_array. + ports[k].bond_port_name, + strlen (bond_ports_array. + ports[k].bond_port_name)); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRNCPY_S failed]ret=%d.", + retVal); + return -1; + } + } + + if (strcmp + (name, + bond_ports_array.ports[k].bond_port_name) != 0) + { + NSOPR_SET_ERRINFO (-1, "%s init failed!\n", name); + NSPOL_LOGERR + ("%s init failed! %s in both %s and %s", name, + phead_bond->nic_name, name, + bond_ports_array.ports[k].bond_port_name); + return -1; + } + } + } + } + + if (check_bond == 1) + { + break; + } + + /* copy slave ports name to bond array */ + retVal = + STRNCPY_S (s->slave_ports[idx], HAL_MAX_NIC_NAME_LEN, + phead_bond->nic_name, strlen (phead_bond->nic_name)); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRNCPY_S failed]ret=%d.", retVal); + return -1; + } + + idx++; + phead_bond = phead_bond->next; + + if (idx >= HAL_MAX_SLAVES_PER_BOND) + { + break; + } + } + + if (check_bond == 0) + { + if (name[0] == 0) + { + /* if bond_name is a empty string, generate a new bond name */ + retVal = + SPRINTF_S (name, HAL_MAX_NIC_NAME_LEN, "bond%u_auto", + bond_index++); + + if (-1 == retVal) + { + NSPOL_LOGERR ("SPRINTF_S failed]ret=%d.", retVal); + return -1; + } + } + + /* copy bond_name to bond array */ + retVal = + STRNCPY_S (s->bond_port_name, HAL_MAX_NIC_NAME_LEN, name, + strlen (name)); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRNCPY_S failed]ret=%d.", retVal); + return -1; + } + + s->slave_port_cnt = idx; + bond_ports_array.cnt++; + NSPOL_LOGINF (SC_DPDK_INFO, + "bond_ports_array.cnt=%u,slave_port_cnt=%u", + bond_ports_array.cnt, s->slave_port_cnt); + } + } + + return 0; +} + +int +spl_hal_port_config (unsigned int *port_num) +{ + int retVal; + unsigned int check; + struct phy_net *phynet; + + struct network_configuration *network = get_network_list (); + + if (!network) + { + NSPOL_LOGERR ("fail to get_provider_node"); + return -1; + } + + unsigned int port_index = p_stackx_port_zone->port_num; + + while (network && (phynet = network->phy_net)) + { + struct ref_nic *phead = phynet->header; + NSPOL_LOGINF (SC_DPDK_INFO, "network=%p,network_name=%s", network, + network->network_name); + + if (spl_hal_bond_config (network) < 0) + { + NSPOL_LOGERR ("spl_hal_bond_config fail."); + return -1; + } + + while (phead != NULL) + { + /* check if the NIC is inited */ + for (check = 0; check < port_index; ++check) + { + if (strcmp + (p_stackx_port_zone->stackx_one_port[check]. + linux_ip.if_name, phead->nic_name) == 0) + { + break; + } + } + + if (check != port_index) + { + phead = phead->next; + continue; + } + + /* check if the number of VF exceeds MAX_VF_NUM */ + if (port_index >= MAX_VF_NUM + p_stackx_port_zone->bonded_port_num) + { + NSOPR_SET_ERRINFO (-1, "Support Only %d VF. %s init failed!\n", + MAX_VF_NUM, phead->nic_name); + NSPOL_LOGERR ("Support Only %d VF. %s init failed!", MAX_VF_NUM, + phead->nic_name); + NSOPR_SET_ERRINFO (-1, "Add network %s failed!\n", + network->network_name); + break; + } + + if (strlen (phead->nic_name) >= + sizeof (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name) - 1 + || strlen (phead->nic_name) <= 3) + { + NSPOL_LOGERR ("Invalid configuration"); + return -1; + } + + retVal = + STRCPY_S (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name, + sizeof (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name), + phead->nic_name); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "if_name %s", + p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.if_name); + retVal = + STRCPY_S (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.ip_addr_linux, + sizeof (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + ip_addr_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + retVal = + STRCPY_S (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.mask_linux, + sizeof (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + mask_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + retVal = + STRCPY_S (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip.bcast_linux, + sizeof (p_stackx_port_zone-> + stackx_one_port[port_index].linux_ip. + bcast_linux), "0.0.0.0"); + + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return -1; + } + + ++port_index; + NSPOL_LOGINF (SC_DPDK_INFO, "port_index=%u", port_index); + + if (CUR_CFG_HAL_PORT_NUM <= port_index + bond_ports_array.cnt) + { + // TODO: Invalid configuration received, return immediately + NSPOL_LOGERR + ("Insufficient nStack configuration when compared to configuration from network.json"); + return -1; + } + + /* [TA33636] [2017-04-11] Do not need provider.json */ + if (phynet->bond_mode == + -1 /*&& strncmp(network->network_name, "provider", 8) != 0 */ ) + { + break; + } + else + { + phead = phead->next; + } + } + + network = network->next; + } + + *port_num = port_index; + + return ERR_OK; +} + +void +spl_hal_capa_init () +{ + u32_t ipv4_cksum_offload = 1; + u32_t udp_cksum_offload = 1; + u32_t tcp_cksum_offload = 1; + hal_netif_capa_t info = { 0 }; + struct stackx_port_info *p_port_info = head_used_port_list; + + while (p_port_info) + { + hal_get_capability (p_port_info->linux_ip.hdl, &info); + + if ((info.tx_offload_capa & HAL_ETH_TX_OFFLOAD_IPV4_CKSUM) == 0) + { + ipv4_cksum_offload = 0; + + NSPOL_LOGDBG (SC_DPDK_INFO, "Port %s TX_OFFLOAD_IPV4_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + if ((info.tx_offload_capa & HAL_ETH_TX_OFFLOAD_UDP_CKSUM) == 0) + { + udp_cksum_offload = 0; + + NSPOL_LOGDBG (SC_DPDK_INFO, "Port %s TX_OFFLOAD_UDP_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + if ((info.tx_offload_capa & HAL_ETH_TX_OFFLOAD_TCP_CKSUM) == 0) + { + tcp_cksum_offload = 0; + + NSPOL_LOGDBG (SC_DPDK_INFO, "Port %s TX_OFFLOAD_TCP_CKSUM Disable", + p_port_info->linux_ip.if_name); + } + + p_port_info = p_port_info->next_use_port; + } + + spl_hal_capa.tx_ipv4_cksum_offload = ipv4_cksum_offload; + spl_hal_capa.tx_udp_cksum_offload = udp_cksum_offload; + spl_hal_capa.tx_tcp_cksum_offload = tcp_cksum_offload; + + NSPOL_LOGINF (SC_DPDK_INFO, + "ipv4_cksum_offload(%u),udp_cksum_offload(%u),tcp_cksum_offload(%u)", + ipv4_cksum_offload, udp_cksum_offload, tcp_cksum_offload); + +} + +NSTACK_STATIC void +spl_hal_bond_info_init (hal_hdl_t hdl, struct bond_set *s, + struct stackx_port_info *p) +{ +#define MAX_MAC_STR_LEN 20 + char mac_string[MAX_MAC_STR_LEN]; + int retVal; + struct ether_addr addr; + + p->linux_ip.hdl = hdl; + + struct stackx_port_info *slave_port; + slave_port = get_port_info_by_name (s->slave_ports[0]); + + if (slave_port == NULL) + { + NSPOL_LOGERR ("get_port_info_by_name failed]bond_port_name=%s", + s->bond_port_name); + return; + } + + /* check the lenght of bond_port_name */ + retVal = + STRCPY_S (p->linux_ip.if_name, sizeof (p->linux_ip.if_name), + s->bond_port_name); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return; + } + + hal_get_macaddr (hdl, &addr); + retVal = + spl_hal_ether_etoa (addr.addr_bytes, sizeof (addr.addr_bytes), mac_string, + sizeof (mac_string)); + if (retVal < 0) + { + NSPOL_LOGERR ("spl_hal_ether_etoa failed]ret=%d", retVal); + return; + } + + retVal = + STRCPY_S (p->linux_ip.mac_addr, sizeof (p->linux_ip.mac_addr), + mac_string); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + STRCPY_S (p->linux_ip.ip_addr_linux, sizeof (p->linux_ip.ip_addr_linux), + slave_port->linux_ip.ip_addr_linux); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + STRCPY_S (p->linux_ip.mask_linux, sizeof (p->linux_ip.mask_linux), + slave_port->linux_ip.mask_linux); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return; + } + + retVal = + STRCPY_S (p->linux_ip.bcast_linux, sizeof (p->linux_ip.bcast_linux), + slave_port->linux_ip.bcast_linux); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return; + } + + NSPOL_LOGINF (SC_DPDK_INFO, "===== the bond port info ======"); + NSPOL_LOGINF (SC_DPDK_INFO, "bond port name=%s", p->linux_ip.if_name); + NSPOL_LOGINF (SC_DPDK_INFO, "bond port mac=%s", p->linux_ip.mac_addr); + NSPOL_LOGINF (SC_DPDK_INFO, "bond port ip=%s", p->linux_ip.ip_addr_linux); + NSPOL_LOGINF (SC_DPDK_INFO, "bond port netmask=%s", p->linux_ip.mask_linux); + NSPOL_LOGINF (SC_DPDK_INFO, "bond port broad_cast addr=%s", + p->linux_ip.bcast_linux); + +} + +NSTACK_STATIC int +spl_hal_bond_start (void) +{ + u8_t i, j = 0; + struct stackx_port_info *bond_port = NULL; + hal_hdl_t hdl; + hal_hdl_t slave_hdl[HAL_MAX_SLAVES_PER_BOND]; + + NSPOL_LOGINF (SC_DPDK_INFO, "bond_ports_array.cnt=%u", + bond_ports_array.cnt); + + for (i = bond_ports_array_cnt_start; i < bond_ports_array.cnt; i++) + { + struct bond_set *s = &bond_ports_array.ports[i]; + NSPOL_LOGINF (SC_DPDK_INFO, "i=%u,bond_port_name=%s", i, + s->bond_port_name); + + u8_t slave_num = 0; + for (j = 0; j < s->slave_port_cnt; j++) + { + NSPOL_LOGINF (SC_DPDK_INFO, "s->slave_ports[%u]=%s", j, + s->slave_ports[j]); + hdl = get_port_hdl_by_name (s->slave_ports[j]); + + if (!hal_is_valid (hdl)) + { + continue; + } + + slave_hdl[slave_num++] = hdl; + + /* here we didn't release the port mem allocated in p_stackx_port_zone */ + del_port_in_port_list (s->slave_ports[j]); + } + + hdl = hal_bond (s->bond_port_name, slave_num, slave_hdl); + + if (!hal_is_valid (hdl)) + { + NSPOL_LOGERR ("hal_bond fail: bond_name =%s", s->bond_port_name); + return -1; + } + + bond_port = + &p_stackx_port_zone->stackx_one_port[p_stackx_port_zone->port_num]; + num_ports_NIC++; + p_stackx_port_zone->port_num++; + p_stackx_port_zone->bonded_port_num++; + + spl_hal_bond_info_init (hdl, s, bond_port); + add_port_in_port_list (bond_port); + + } + + bond_ports_array_cnt_start = bond_ports_array.cnt; + return 0; +} + +/* + * Initialises a given port using global settings and with the rx buffers + * coming from the mbuf_pool passed as parameter + */ + +NSTACK_STATIC inline int +spl_hal_port_start (uint16_t nic_id, struct stackx_port_info *p_port_info, + u16_t num_queues) +{ + u16_t num_queues_request, q; + hal_hdl_t hdl; + struct common_mem_mempool *mp; + hal_netif_config_t conf; +#define MAX_MAC_STR_LEN 20 + char mac_string[MAX_MAC_STR_LEN]; + int retVal; + struct ether_addr addr; + + // change the queues number per configuration. + // even we only receive packets from one rx queue when dispatch mode is on, the tx queue + // shoule set to the queues number requested. + num_queues_request = num_queues; + if (num_queues_request > HAL_ETH_MAX_QUEUE_NUM) + { + NSPOL_LOGERR + ("no enougth queue num for thread!]num_queues_request=%u,MAX_QUEUE_NUM=%u", + num_queues_request, HAL_ETH_MAX_QUEUE_NUM); + return -1; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "# Initialising index=%s... ", + p_port_info->linux_ip.if_name); + /* used to have fflush,no use code ,remove it. */ + + conf.bit.hw_vlan_filter = 1; + conf.bit.hw_vlan_strip = 1; + + conf.rx.queue_num = num_queues_request; + conf.tx.queue_num = num_queues_request; + + for (q = 0; q < num_queues_request; q++) + { + mp = + (struct common_mem_mempool *) spl_hal_rx_pool_create (nic_id, q, 1); + + if (mp == NULL) + { + NSPOL_LOGERR + ("spl_hal_rx_pool_create fail]mp=NULL,nic_id=%u,if_name=%s", + nic_id, p_port_info->linux_ip.if_name); + return -1; + } + + (void) spl_reg_res_txrx_mgr ((mpool_handle *) mp); // will only return 0, no need to check return value + conf.rx.ring_pool[q] = mp; + conf.rx.ring_size[q] = HAL_RX_RING_SIZE; + conf.tx.ring_size[q] = HAL_TX_RING_SIZE; + } + + hdl = hal_create (p_port_info->linux_ip.if_name, &conf); + + if (!hal_is_valid (hdl)) + { + NSPOL_LOGERR ("hal_create fail]if_name =%s", + p_port_info->linux_ip.if_name); + return -1; + } + + p_port_info->linux_ip.hdl = hdl; + + /* add mac address */ + hal_get_macaddr (hdl, &addr); + retVal = + spl_hal_ether_etoa (addr.addr_bytes, sizeof (addr.addr_bytes), mac_string, + sizeof (mac_string)); + if (retVal < 0) + { + NSPOL_LOGERR ("spl_hal_ether_etoa failed]ret=%d", retVal); + return -1; + } + + retVal = + STRCPY_S (p_port_info->linux_ip.mac_addr, + sizeof (p_port_info->linux_ip.mac_addr), mac_string); + if (EOK != retVal) + { + NSPOL_LOGERR ("STRCPY_S failed]ret=%d", retVal); + return -1; + } + + return 0; +} + +NSTACK_STATIC int +spl_hal_port_setup () +{ + unsigned int i; + struct stackx_port_info *p_port_info = NULL; + + INITPOL_LOGINF ("RTP", "spl_hal_port_setup", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_START); + + for (i = num_ports_NIC_start; i < num_ports_NIC; i++) + { + p_port_info = &(p_stackx_port_zone->stackx_one_port[i]); + + if (spl_hal_port_start (i, p_port_info, (u16_t) 1) < 0) + { + NSPOL_LOGERR ("Error initialising]nic_id=%u", i); + + INITPOL_LOGERR ("RTP", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + + return -1; + } + else + { + report_port_link_status (p_port_info); + add_port_in_port_list (p_port_info); + } + } + + if (spl_hal_bond_start () < 0) + { + NSPOL_LOGERR ("bond port init failed!"); + + INITPOL_LOGERR ("RTP", "spl_hal_port_setup", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + + return -1; + } + + spl_hal_capa_init (); + + INITPOL_LOGINF ("RTP", "spl_hal_port_setup", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_SUCCESS); + + return 0; + +} + +int +spl_hal_port_init () +{ + int retval; + unsigned int i, port_num = 0; + + int port_num_start = p_stackx_port_zone->port_num; + num_ports_NIC_start = num_ports_NIC; + + //Read network info + INITPOL_LOGINF ("IP", "spl_hal_port_config", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_START); + retval = spl_hal_port_config (&port_num); + + if (retval != ERR_OK) + { + INITPOL_LOGERR ("IP", "spl_hal_port_config", NULL_STRING, + LOG_INVALID_VALUE, MODULE_INIT_FAIL); + return -1; + } + + p_stackx_port_zone->port_num = port_num; + + NSPOL_LOGINF (SC_DPDK_INFO, "port_num=%u", port_num); + INITPOL_LOGINF ("IP", "spl_hal_port_config", NULL_STRING, LOG_INVALID_VALUE, + MODULE_INIT_SUCCESS); + + if (port_num_start == p_stackx_port_zone->port_num) + { + NSPOL_LOGERR ("No new NIC find."); + return 0; + } + + //Get ports num + for (i = port_num_start; i < p_stackx_port_zone->port_num; i++) + { + if (p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name[0] != 0) + { + /* right now hard coded, */ + int eth_num = + atoi (p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name + + 3); + + num_ports_NIC++; + + NSPOL_LOGDBG (SC_DPDK_INFO, "port_mask=%d ,eth_name=%s", eth_num, + p_stackx_port_zone->stackx_one_port[i]. + linux_ip.if_name); + } + } + + if (num_ports_NIC > HAL_MAX_NIC_NUM) + { + NSPOL_LOGERR ("just support one eth"); + common_exit (EXIT_FAILURE, "just surport one eth"); + } + + if (num_ports_NIC == num_ports_NIC_start) + { + NSPOL_LOGERR ("No new NIC find."); + return 0; + } + + retval = spl_hal_port_setup (); + + if (retval == -1) + { + return -1; + } + + NSPOL_LOGDBG (SC_DPDK_INFO, "Finished Process Init."); + + return 1; +} + +inline NSTACK_STATIC void +spl_hal_send (struct netif *pnetif) +{ + u16_t i, sent = 0; + struct netifExt *pnetifExt = NULL; + u16_t netif_id = pnetif->num; + u16_t tx_num = spl_hal_pkts[netif_id].tx.num; + struct common_mem_mbuf **tx_ptks = spl_hal_pkts[netif_id].tx.pkts; + + for (i = 0; i < tx_num; i++) + { + (void) + res_free (& + (((struct spl_pbuf *) (((char *) tx_ptks[i]) + + sizeof (struct + common_mem_mbuf)))->res_chk)); + } + + int _retry = 0; + + pnetifExt = getNetifExt (pnetif->num); + if (NULL == pnetifExt) + return; + + do + { + sent += + hal_send_packet (pnetifExt->hdl, 0, (hal_mbuf_t **) & (tx_ptks[sent]), + tx_num - sent); + _retry++; + + if (_retry > SPL_HAL_SEND_TRY) + { + NSPOL_LOGERR ("send loop %d times but dpdk send data fail ", + SPL_HAL_SEND_TRY); + break; + } + } + while (unlikely (sent != tx_num)); + + if (unlikely (sent != tx_num)) + { + for (i = sent; i < tx_num; i++) + { + (void) nsfw_mem_mbf_free ((mbuf_handle) (tx_ptks[i]), NSFW_SHMEM); + } + } + for (i = 0; i < tx_num; i++) + { + /* set dpdk_send flag */ + ((struct spl_pbuf *) (((char *) tx_ptks[i]) + + sizeof (struct common_mem_mbuf)))-> + res_chk.u8Reserve |= DPDK_SEND_FLAG; + } + + spl_hal_pkts[netif_id].tx.num = 0; + +} + +inline u16_t +spl_hal_recv (struct netif *pnetif, u8_t id) +{ + u16_t netif_id, rx_c = 0; + struct netifExt *pnetifExt = NULL; + + netif_id = pnetif->num; + + pnetifExt = getNetifExt (pnetif->num); + if (NULL == pnetifExt) + return 0; + + rx_c = + hal_recv_packet (pnetifExt->hdl, 0, + (hal_mbuf_t **) spl_hal_pkts[netif_id].rx.pkts, + PKT_BURST); + + if (rx_c <= 0) + { + return 0; + } + + spl_hal_pkts[netif_id].rx.num = rx_c; + spl_hal_pkts[netif_id].rx.index = 0; + + return rx_c; +} + +/*needflush set 1 has pbuf release problem, ref maybe set 0 before release*/ +NSTACK_STATIC inline void +spl_hal_set_cksum (struct spl_pbuf *buf, struct common_mem_mbuf *mbuf) +{ + + //need to be careful, special when small packet oversize + if (buf->tot_len > mbuf->pkt_len) + { + NSPOL_LOGWAR (SC_DPDK_INFO, + "small packet OVERSIZE]pbuf_len=%u,mbuf_len=%u", buf->len, + mbuf->pkt_len); + mbuf->pkt_len = buf->len; + } + + if (!spl_hal_tx_ip_cksum_enable () || !spl_hal_tx_tcp_cksum_enable () + || !spl_hal_tx_udp_cksum_enable ()) + { + struct tcp_hdr *t_hdr; + struct udp_hdr *u_hdr; + u16_t flag_offset; + u64_t ol_flags = (mbuf->ol_flags); //& (~PKT_TX_L4_MASK)); + + struct eth_hdr *ethhdr = (struct eth_hdr *) ((char *) buf->payload); + + if (ethhdr->type == 8) + { + struct ip_hdr *iphdr = + (struct ip_hdr *) ((char *) buf->payload + + sizeof (struct eth_hdr)); + + if (!spl_hal_tx_ip_cksum_enable ()) + { + ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM; + iphdr->_chksum = 0; + } + + flag_offset = spl_ntohs (iphdr->_offset); + + /*ip frag, only the first packet has udp or tcp head */ + if (0 == (flag_offset & IP_OFFMASK)) + { + switch (iphdr->_proto) + { + case IPPROTO_TCP: + if (!spl_hal_tx_tcp_cksum_enable ()) + { + t_hdr = + (struct tcp_hdr *) ((char *) buf->payload + + sizeof (struct eth_hdr) + + sizeof (struct ip_hdr)); + t_hdr->chksum = get_ipv4_psd_sum (iphdr, ol_flags); + ol_flags |= PKT_TX_TCP_CKSUM; + } + + break; + + case IPPROTO_UDP: + { + if ((mbuf->ol_flags & PKT_TX_UDP_CKSUM) == + PKT_TX_UDP_CKSUM) + { + u_hdr = (struct udp_hdr *) ((char *) buf->payload + sizeof (struct eth_hdr) + sizeof (struct ip_hdr)); //l2_len + l3_len); + u_hdr->chksum = + get_ipv4_psd_sum (iphdr, mbuf->ol_flags); + } + } + + break; + + default: + + break; + } + } + mbuf->l2_len = sizeof (struct eth_hdr); //l2_len; + mbuf->l3_len = sizeof (struct ip_hdr); + mbuf->ol_flags = ol_flags; + } + } +} + +/*needflush set 1 has pbuf release problem, ref maybe set 0 before release*/ +err_t +spl_hal_output (struct netif *pnetif, struct pbuf *buf) +{ + u16_t netif_id, idx; + struct common_mem_mbuf *mbuf; + struct spl_pbuf *spbuf = NULL; + //spl_pbuf_layer layer = SPL_PBUF_TRANSPORT; + //u16_t offset; + + if (!p_def_stack_instance) + { + NSPOL_LOGERR ("p_def_stack_instance is NULL"); + return -1; + } + + u16_t proc_id = spl_get_lcore_id (); + + NSPOL_LOGINF (SC_DPDK_INFO, "spl_hal_output. len %d totlen %d", buf->len, + buf->tot_len); + print_pbuf_payload_info (buf, true); + + if (buf->tot_len > DEF_MBUF_DATA_SIZE) + { + NSPOL_LOGINF (TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); + return ERR_MEM; + + } + spbuf = spl_pbuf_alloc_hugepage (SPL_PBUF_RAW, + buf->tot_len, + SPL_PBUF_HUGE, proc_id, NULL); + + if (!spbuf) + { + NSPOL_LOGINF (TCP_DEBUG, "spl_pbuf_alloc_hugepage Failed!!!"); + return ERR_MEM; + } + + if (ERR_OK != pbuf_to_splpbuf_copy (spbuf, buf)) + { + NSPOL_LOGERR ("pbuf to splpbuf copy failed"); + return -1; + } + + mbuf = + (struct common_mem_mbuf *) ((char *) spbuf - + sizeof (struct common_mem_mbuf)); + + if (spbuf->tot_len > mbuf->pkt_len) + { + NSPOL_LOGWAR (SC_DPDK_INFO, + "small packet OVERSIZE]pbuf_len=%u,mbuf_len=%u", + spbuf->len, mbuf->pkt_len); + mbuf->pkt_len = spbuf->len; + } + + spl_hal_set_cksum (spbuf, mbuf); + + netif_id = pnetif->num; + idx = spl_hal_pkts[netif_id].tx.num++; + spl_hal_pkts[netif_id].tx.pkts[idx] = mbuf; + spl_do_dump (spbuf, DUMP_SEND); + spl_hal_send (pnetif); + + return 0; +} + +void +spl_hal_input (struct netif *pnetif, struct spl_pbuf **buf) +{ + u16_t netif_id; + + struct common_mem_mbuf *mbuf; + + netif_id = pnetif->num; + + if (likely + (spl_hal_pkts[netif_id].rx.num > spl_hal_pkts[netif_id].rx.index)) + { + mbuf = spl_hal_pkts[netif_id].rx.pkts[spl_hal_pkts[netif_id].rx.index]; + spl_hal_pkts[netif_id].rx.index++; + spl_hal_buf_convert (mbuf, buf); + spl_do_dump (*buf, DUMP_RECV); + } + else + { + NSPOL_LOGERR + ("recv from spl_dev has a problem]pnetif=%p, num=%u, index=%u", + pnetif, spl_hal_pkts[netif_id].rx.num, + spl_hal_pkts[netif_id].rx.index); + *buf = NULL; + } + return; +} + +int +spl_hal_tx_ip_cksum_enable () +{ + return !spl_hal_capa.tx_ipv4_cksum_offload; +} + +int +spl_hal_tx_udp_cksum_enable () +{ + return !spl_hal_capa.tx_udp_cksum_offload; +} + +int +spl_hal_tx_tcp_cksum_enable () +{ + return !spl_hal_capa.tx_tcp_cksum_offload; +} + +u32 +spl_hal_is_nic_exist (const char *name) +{ + return hal_is_nic_exist (name); +} + +int +spl_hal_is_bond_netif (struct netif *pnetif) +{ + int i; + struct bond_set *s; + struct netifExt *pnetifExt = NULL; + + pnetifExt = getNetifExt (pnetif->num); + if (NULL == pnetifExt) + return 0; + + for (i = 0; i < bond_ports_array.cnt; i++) + { + s = &bond_ports_array.ports[i]; + if (!strncmp + (pnetifExt->if_name, s->bond_port_name, HAL_MAX_NIC_NAME_LEN)) + { + return 1; + } + } + + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/recycle/stackx_recycle.c b/stacks/lwip_stack/lwip_src/recycle/stackx_recycle.c new file mode 100644 index 0000000..addc0e6 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/recycle/stackx_recycle.c @@ -0,0 +1,676 @@ +/* +* +* 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 "stackx_spl_share.h" +#include "nsfw_recycle_api.h" +#include "nstack_log.h" +#include "nsfw_msg_api.h" +#include "stackx_socket.h" +#include "stackx_spl_msg.h" +#include "stackx_app_res.h" +#include "common.h" +#include "sc_dpdk.h" +#include "nsfw_mt_config.h" +#include "spl_instance.h" + +#define SS_DELAY_CLOSE_SEC 5 + +extern struct stackx_port_zone *p_stackx_port_zone; + +/***************************************************************************** +* Prototype : sbr_recycle_rx_mbuf +* Description : iterator and free rx mbufs with pid flags, when the app + with certain pid is no longer exist +* Input : void *data +* void *arg +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_recycle_rx_mbuf (void *data, void *arg) +{ + u32 *recycle_flg; + pid_t *pid = (pid_t *) arg; + struct common_mem_mbuf *m_buf = (struct common_mem_mbuf *) data; +#ifdef HAL_LIB +#else + recycle_flg = + (u32 *) ((char *) (m_buf->buf_addr) + RTE_PKTMBUF_HEADROOM - + sizeof (u32)); +#endif + if (m_buf->refcnt > 0 && *recycle_flg == *pid) + { + NSSBR_LOGDBG ("free rx mbuf hold by app], mbuf=%p", m_buf); + *recycle_flg = MBUF_UNUSED; + spl_mbuf_free (m_buf); + } + return 0; +} + +/***************************************************************************** +* Prototype : sbr_recycle_rx_pool +* Description : recycle rx mbufs hold by app when app crahes +* Input : pid_t pid +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC int +sbr_recycle_rx_pool (pid_t pid) +{ + static struct common_mem_mempool *rx_pool[MAX_VF_NUM * 2][MAX_THREAD_NUM] = + { {0} }; + struct common_mem_mempool *mp; + nsfw_mem_name lookup_mbuf_pool; + u32 nic_id, queue_id = 0; + int retval; + struct common_mem_ring *ring; + + for (nic_id = 0; + nic_id < p_stackx_port_zone->port_num && nic_id < MAX_VF_NUM * 2; + nic_id++) + { + mp = rx_pool[nic_id][queue_id]; + if (mp == NULL) + { + retval = + spl_snprintf (lookup_mbuf_pool.aname, NSFW_MEM_NAME_LENGTH - 1, + "%s", get_mempoll_rx_name (queue_id, nic_id)); + if (-1 == retval) + { + NSPOL_LOGERR ("spl_snprintf fail"); + break; + } + + lookup_mbuf_pool.entype = NSFW_SHMEM; + lookup_mbuf_pool.enowner = NSFW_PROC_MAIN; + mp = + (struct common_mem_mempool *) + nsfw_mem_mbfmp_lookup (&lookup_mbuf_pool); + if (mp == NULL) + break; + rx_pool[nic_id][queue_id] = mp; + } + if (nsfw_mem_mbuf_iterator + (mp, 0, mp->size, sbr_recycle_rx_mbuf, (void *) &pid) < 0) + { + NSSBR_LOGERR ("nsfw_mem_mbuf_iterator return fail"); + return -1; + } + ring = (struct common_mem_ring *) (mp->pool_data); + NSSBR_LOGINF + ("after recycling rx pbuf hold by app]ring=%p,prod.head=%u,prod.tail=%u," + "cons.head=%u,cons.tail=%u.", ring, ring->prod.head, ring->prod.tail, + ring->cons.head, ring->cons.tail); + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_recycle_rx_pool +* Description : recycle stackx tx mbufs hold by app when app crahes +* Input : pid_t pid +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC int +sbr_recycle_tx_pool (pid_t pid) +{ + struct common_mem_mempool *mp; + struct common_mem_ring *ring; + + /* Try to free all the RX mbufs which are holded in stackx TX pool */ + mp = (struct common_mem_mempool *) p_def_stack_instance->mp_tx; + if (mp == NULL) + return -1; + + if (nsfw_mem_mbuf_iterator + (mp, 0, mp->size, sbr_recycle_rx_mbuf, (void *) &pid) < 0) + { + NSSBR_LOGERR ("nsfw_mem_mbuf_iterator return fail"); + return -1; + } + ring = (struct common_mem_ring *) (mp->pool_data); + NSSBR_LOGINF + ("after recycling stackx tx pbuf hold by app]ring=%p,prod.head=%u,prod.tail=%u," + "cons.head=%u,cons.tail=%u.", ring, ring->prod.head, ring->prod.tail, + ring->cons.head, ring->cons.tail); + + return 0; +} + +/***************************************************************************** +* Prototype : ss_free_del_conn_msg +* Description : free msg +* Input : msg_delete_netconn *dmsg +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_free_del_conn_msg (msg_delete_netconn * dmsg) +{ + data_com_msg *msg = (data_com_msg *) ((char *) dmsg - MAX_MSG_PARAM_SIZE); + + if (MSG_ASYN_POST == msg->param.op_type) /* should check type for linger */ + { + msg_free (msg); + } +} + +extern int nsep_recycle_ep (u32 pid); + +/***************************************************************************** +* Prototype : ss_recycle_done +* Description : recycle done,need recycle ep and rx pool +* Input : pid_t pid +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_recycle_done (pid_t pid) +{ + spl_free_tx_pool (pid); + spl_recycle_msg_pool (pid); + (void) sbr_recycle_rx_pool (pid); + (void) sbr_recycle_tx_pool (pid); + (void) nsep_recycle_ep (pid); + (void) nsfw_recycle_obj_end (pid); +} + +/***************************************************************************** +* Prototype : ss_notify_omc +* Description : try to notify omc +* Input : spl_netconn_t** conn_array +* u32 conn_num +* u8 notify_omc +* pid_t pid +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_notify_omc (spl_netconn_t ** conn_array, u32 conn_num, u8 notify_omc, + pid_t pid) +{ + if (notify_omc) + { + u32 i; + for (i = 0; i < conn_num; ++i) + { + struct spl_netconn *conn = conn_array[i]; + if (ss_is_pid_exist (conn, pid)) + { + NSSBR_LOGINF ("there are still conn at work]pid=%d", pid); + break; + } + + msg_delete_netconn *delay_msg = conn->recycle.delay_msg; + if (delay_msg && (delay_msg->pid == pid)) + { + delay_msg->notify_omc = notify_omc; + NSSBR_LOGINF ("there are still conn at delay]pid=%d", pid); + break; + } + } + + if (conn_num == i) + { + NSSBR_LOGINF ("recycle done,notify omc]pid=%d", pid); + ss_recycle_done (pid); + } + } +} + +extern void do_pbuf_free (struct spl_pbuf *buf); + +static void +ss_recycle_fd_share (sbr_fd_share * fd_share) +{ + /* to free pbufs which are attached to sbr_fd_share */ + if (fd_share->recoder.head) + { + struct spl_pbuf *buf = fd_share->recoder.head; + fd_share->recoder.head = NULL; + fd_share->recoder.tail = NULL; + fd_share->recoder.totalLen = 0; + do_pbuf_free (buf); + } +} + +extern void nsep_recycle_epfd (void *epinfo, u32 pid); +extern void tcp_free_accept_ring (spl_netconn_t * conn); +extern void free_conn_by_spl (spl_netconn_t * conn); +extern void tcp_drop_conn (spl_netconn_t * conn); + +/***************************************************************************** +* Prototype : ss_close_conn_now +* Description : close netconn now +* Input : spl_netconn_t *conn +* msg_delete_netconn *dmsg +* pid_t pid +* ss_close_conn_fun close_conn +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_close_conn_now (spl_netconn_t * conn, msg_delete_netconn * dmsg, pid_t pid, + ss_close_conn_fun close_conn) +{ + spl_netconn_t **conn_array = conn->recycle.group->conn_array; + u32 conn_num = conn->recycle.group->conn_num; + u8 notify_omc = dmsg->notify_omc; + + close_conn (dmsg, 0); + + nsep_recycle_epfd (conn->epInfo, pid); + conn->epInfo = NULL; /*must be set to NULL */ + + u32 i; + if (conn->recycle.is_listen_conn) + { + /* drop the conn inside the accept ring */ + tcp_free_accept_ring (conn); + + /* app coredump and accept_from not changed, need recyle */ + for (i = 0; i < conn_num; ++i) + { + struct spl_netconn *accept_conn = conn_array[i]; + if ((accept_conn->recycle.accept_from == conn) + && ss_is_pid_array_empty (accept_conn)) + { + NSSBR_LOGINF + ("recycle lost conn]listen_conn=%p,listen_private_data=%p,accept_conn=%p,accept_private_data=%p,pid=%d", + conn, conn->private_data, accept_conn, + accept_conn->private_data, pid); + data_com_msg *msg = + (data_com_msg *) ((char *) dmsg - MAX_MSG_PARAM_SIZE); + msg->param.receiver = ss_get_recv_obj (accept_conn); + dmsg->buf = NULL; + dmsg->time_started = sys_now (); + dmsg->shut = 0; + dmsg->conn = accept_conn; + close_conn (dmsg, 0); + + nsep_recycle_epfd (accept_conn->epInfo, pid); + accept_conn->epInfo = NULL; /*must be set to NULL */ + + /* lost conn need drop first, can't just free conn */ + tcp_drop_conn (accept_conn); + } + } + } + + if (SS_DELAY_STOPPED == conn->recycle.delay_flag) + { + sbr_fd_share *fd_share = + (sbr_fd_share *) ((char *) conn + SS_NETCONN_SIZE); + ss_recycle_fd_share (fd_share); + free_conn_by_spl (conn); + } + + ss_free_del_conn_msg (dmsg); + ss_notify_omc (conn_array, conn_num, notify_omc, pid); +} + +/***************************************************************************** +* Prototype : ss_close_conn_delay +* Description : delay to close conn +* Input : spl_netconn_t *conn +* pid_t pid +* msg_delete_netconn *dmsg +* ss_close_conn_fun close_conn +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_close_conn_delay (spl_netconn_t * conn, pid_t pid, + msg_delete_netconn * dmsg, ss_close_conn_fun close_conn) +{ + NSSBR_LOGINF + ("ref > 0 and pid array is empty, start delay closing conn]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + close_conn (dmsg, SS_DELAY_CLOSE_SEC); +} + +/***************************************************************************** +* Prototype : ss_process_delay_up +* Description : delay is up +* Input : spl_netconn_t *conn +* pid_t pid +* msg_delete_netconn *dmsg +* ss_close_conn_fun close_conn +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +ss_process_delay_up (spl_netconn_t * conn, pid_t pid, + msg_delete_netconn * dmsg, ss_close_conn_fun close_conn) +{ + spl_netconn_t **conn_array = conn->recycle.group->conn_array; + u32 conn_num = conn->recycle.group->conn_num; + u8 notify_omc = dmsg->notify_omc; + + if (SS_DELAY_STARTED == conn->recycle.delay_flag) + { + if (ss_is_pid_array_empty (conn)) + { + NSSBR_LOGINF + ("delay time is up,close conn now]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + conn->recycle.delay_flag = SS_DELAY_STOPPED; + conn->recycle.delay_msg = NULL; + ss_close_conn_now (conn, dmsg, pid, close_conn); + return; + } + else + { + NSSBR_LOGINF + ("stop delay closing conn,conn still working]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + conn->recycle.delay_flag = SS_DELAY_STOPPED; + conn->recycle.delay_msg = NULL; + ss_free_del_conn_msg (dmsg); + ss_notify_omc (conn_array, conn_num, notify_omc, pid); + return; + } + } + else if (SS_DELAY_AGAIN == conn->recycle.delay_flag) + { + if (ss_is_pid_array_empty (conn)) + { + NSSBR_LOGINF + ("delay time is up,but need delay again]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + conn->recycle.delay_flag = SS_DELAY_STARTED; + ss_close_conn_delay (conn, pid, dmsg, close_conn); + return; + } + else + { + NSSBR_LOGINF + ("stop delay closing conn,conn still working]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + conn->recycle.delay_flag = SS_DELAY_STOPPED; + conn->recycle.delay_msg = NULL; + ss_free_del_conn_msg (dmsg); + ss_notify_omc (conn_array, conn_num, notify_omc, pid); + return; + } + } + else if (SS_DELAY_STOPPING == conn->recycle.delay_flag) + { + NSSBR_LOGINF + ("the conn has been closed,free conn]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + conn->recycle.delay_flag = SS_DELAY_STOPPED; + conn->recycle.delay_msg = NULL; + free_conn_by_spl (conn); + ss_free_del_conn_msg (dmsg); + ss_notify_omc (conn_array, conn_num, notify_omc, pid); + return; + } + else + { + NSSBR_LOGERR ("this can not happen]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + } +} + +/***************************************************************************** +* Prototype : ss_recycle_conn +* Description : recycle conn +* Input : void *close_data +* ss_close_conn_fun close_conn +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +ss_recycle_conn (void *close_data, ss_close_conn_fun close_conn) +{ + msg_delete_netconn *dmsg = (msg_delete_netconn *) close_data; + spl_netconn_t *conn = dmsg->conn; + pid_t pid = dmsg->pid; + u8 notify_omc = dmsg->notify_omc; + struct spl_netconn **conn_array = conn->recycle.group->conn_array; + u32 conn_num = conn->recycle.group->conn_num; + + int ret = ss_del_pid (conn, pid); + if (0 == ret) + { + i32 ref = ss_dec_fork_ref (conn); + if (0 == ref) + { + if (conn->recycle.delay_flag != SS_DELAY_STOPPED) + { + conn->recycle.delay_flag = SS_DELAY_STOPPING; + NSSBR_LOGINF + ("stop delay closing conn,close conn now]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + } + else + { + NSSBR_LOGINF ("close conn now]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + } + + ss_close_conn_now (conn, dmsg, pid, close_conn); + return 0; + } + else + { + if (ss_is_pid_array_empty (conn)) + { + if (SS_DELAY_STOPPED == conn->recycle.delay_flag) /* only start one delay */ + { + conn->recycle.delay_flag = SS_DELAY_STARTED; + conn->recycle.delay_msg = close_data; + ss_close_conn_delay (conn, pid, dmsg, close_conn); + return 0; + } + else if (SS_DELAY_STARTED == conn->recycle.delay_flag) + { + conn->recycle.delay_flag = SS_DELAY_AGAIN; + NSSBR_LOGINF + ("ref > 0 and pid array is empty, delay again]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + } + } + } + } + else + { + if (conn->recycle.delay_msg && (conn->recycle.delay_msg == close_data)) /* only the stater can process */ + { + ss_process_delay_up (conn, pid, dmsg, close_conn); + return 0; + } + } + + NSSBR_LOGINF ("go to notify omc]conn=%p,pid=%d,private_data=%p", conn, pid, + conn->private_data); + ss_free_del_conn_msg (dmsg); + ss_notify_omc (conn_array, conn_num, notify_omc, pid); + return 0; +} + +/***************************************************************************** +* Prototype : sbr_handle_recycle_conn +* Description : post msg to spl +* Input : spl_netconn_t* conn +* pid_t pid +* u8 notify_omc +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_handle_recycle_conn (spl_netconn_t * conn, pid_t pid, u8 notify_omc) +{ + data_com_msg *m = msg_malloc (ss_get_msg_pool (conn)); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]conn=%p,pid=%d,private_data=%p", conn, + pid, conn->private_data); + return -1; + } + + NSSBR_LOGINF ("recycle conn]conn=%p,pid=%d,private_data=%p", conn, pid, + conn->private_data); + + m->param.module_type = MSG_MODULE_SBR; + m->param.major_type = SPL_TCPIP_NEW_MSG_API; + m->param.minor_type = SPL_API_DO_DELCON; + m->param.err = 0; + m->param.op_type = MSG_ASYN_POST; + sys_sem_init (&m->param.op_completed); + m->param.receiver = ss_get_recv_obj (conn); + m->param.extend_member_bit = 0; + + msg_delete_netconn *p = (msg_delete_netconn *) m->buffer; + p->extend_member_bit = 0; + p->time_started = sys_now (); + p->shut = 0; + p->pid = pid; + p->conn = conn; + p->notify_omc = notify_omc; + p->msg_box_ref = SPL_MSG_BOX_NUM; + p->buf = NULL; + + /* to ensure that the last deal with SPL_API_DO_DELCON message */ + int i; + for (i = 0; i < SPL_MSG_BOX_NUM; ++i) + { + if (msg_post_with_lock_rel + (m, + ss_get_instance_msg_box (ss_get_bind_thread_index (conn), i)) < 0) + { + msg_free (m); + NSSBR_LOGERR ("post msg failed]conn=%p,pid=%d,private_data=%p", + conn, pid, conn->private_data); + return -1; + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_recycle_fd_share +* Description : recycle sbr_fd_share +* Input : sbr_fd_share* fd_share +* pid_t pid +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +sbr_recycle_fd_share (sbr_fd_share * fd_share, pid_t pid) +{ + if (fd_share->common_lock.locked == pid) + { + common_spinlock_unlock (&fd_share->common_lock); + } + + if (fd_share->recv_lock.locked == pid) + { + common_spinlock_unlock (&fd_share->recv_lock); + } +} + +/***************************************************************************** +* Prototype : sbr_recycle_conn +* Description : recycle api,called by recycle module +* Input : u32 exit_pid +* void *pdata +* u16 rec_type +* Output : None +* Return Value : nsfw_rcc_stat +* Calls : +* Called By : +* +*****************************************************************************/ +nsfw_rcc_stat +sbr_recycle_conn (u32 exit_pid, void *pdata, u16 rec_type) +{ + NSSBR_LOGINF ("start recycle]pid=%d", exit_pid); + + if (0 == exit_pid) + { + NSSBR_LOGERR ("pid is not ok]pid=%d", exit_pid); + return NSFW_RCC_CONTINUE; + } + + spl_netconn_t **conn_array = spl_get_conn_array (exit_pid); + if (!conn_array) + { + NSSBR_LOGERR ("conn_array is NULL]pid=%d", exit_pid); + return NSFW_RCC_CONTINUE; + } + + u32 num = spl_get_conn_num (); + spl_netconn_t *conn; + sbr_fd_share *fd_share; + u32 i; + for (i = 0; i < num; ++i) + { + conn = conn_array[i]; + if (ss_is_pid_exist (conn, exit_pid)) + { + fd_share = (sbr_fd_share *) ((char *) conn + SS_NETCONN_SIZE); + sbr_recycle_fd_share (fd_share, exit_pid); + sbr_handle_recycle_conn (conn, exit_pid, FALSE); + } + } + + sbr_handle_recycle_conn (conn_array[0], exit_pid, TRUE); + return NSFW_RCC_SUSPEND; +} + +REGIST_RECYCLE_OBJ_FUN (NSFW_REC_SBR_SOCKET, sbr_recycle_conn) diff --git a/stacks/lwip_stack/lwip_src/socket/CMakeLists.txt b/stacks/lwip_stack/lwip_src/socket/CMakeLists.txt new file mode 100644 index 0000000..e7915d2 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/CMakeLists.txt @@ -0,0 +1,76 @@ +######################################################################### +# +# 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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIE -pie -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") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack -mcmodel=medium") + +SET(ADAPT_DIRECTORIES "${PROJECT_SOURCE_DIR}/src/adapt/") +#SET(DMM_API "${PROJECT_SOURCE_DIR}/src/nSocket/include/") + +ADD_DEFINITIONS(-D_GNU_SOURCE -D_FORTIFY_SOURCE=2) +ADD_DEFINITIONS(-DDPDK_MODULE=0) +if(WITH_HAL_LIB) +SET(RTP_CONFIG ${CMAKE_CURRENT_LIST_DIR}/../../../src/include/rtp_config.h) +else() + SET(PAL_H_DIRECTORIES "/usr/include/dpdk/") + SET(RTP_CONFIG ${PROJECT_SOURCE_DIR}/../../src/framework/common/base/include/common/common_sys_config.h) + INCLUDE_DIRECTORIES( + ${PAL_H_DIRECTORIES} + ${ADAPT_DIRECTORIES} +# ${DMM_API} + ) +endif() +SET(COMPLE_CONFIG ${CMAKE_CURRENT_LIST_DIR}/../../src/include/compile_config.h) +#SET(MGR_COM ${PROJECT_SOURCE_DIR}/src/framework/ipc/mgr_com/mgr_com.h) +SET(MGR_COM ${CMAKE_CURRENT_LIST_DIR}/../../src/include/mgr_com.h) +ADD_DEFINITIONS(-include ${RTP_CONFIG}) +ADD_DEFINITIONS(-include ${COMPLE_CONFIG}) +ADD_DEFINITIONS(-include ${MGR_COM}) +if(WITH_SECUREC_LIB) +LINK_LIBRARIES(pthread rt securec) +else() +LINK_LIBRARIES(pthread rt) +endif() +LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../../../../thirdparty/json/json-c-0.12.1/ + ${CMAKE_CURRENT_LIST_DIR}/../../../../thirdparty/glog/glog-0.3.4/src/ + ${CMAKE_CURRENT_LIST_DIR}/../../src/include/ +# ${PROJECT_SOURCE_DIR}/src/framework/include/ +# ${PROJECT_SOURCE_DIR}/src/framework/common/include/ +# ${ADAPT_DIRECTORIES} +# ${DMM_API} +) + +FILE(GLOB COMMON ../common/*.c) +FILE(GLOB SOCKET ./*.c) +ADD_LIBRARY(socket STATIC ${COMMON} ${SOCKET}) +ADD_DEPENDENCIES(socket JSON GLOG DPDK) +TARGET_INCLUDE_DIRECTORIES( + socket + PRIVATE + ../common/ + ./ + ${CMAKE_CURRENT_LIST_DIR}/../../src/sbr/ + ${CMAKE_CURRENT_LIST_DIR}/../../src/include/ +# ${PROJECT_SOURCE_DIR}/src/framework/include/ +# ${PROJECT_SOURCE_DIR}/src/framework/common/include/ +# ${ADAPT_DIRECTORIES} +# ${DMM_API} +) diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_cfg.h b/stacks/lwip_stack/lwip_src/socket/stackx_cfg.h new file mode 100644 index 0000000..4f4749d --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_cfg.h @@ -0,0 +1,54 @@ +/* +* +* 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 STACKX_CONTAINER_CFG_H +#define STACKX_CONTAINER_CFG_H +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define SBR_MAX_CFG_PATH_LEN 256 +#define SBR_MAX_CONTAINER_IP_NUM 1024 +#define SBR_MAX_CFG_FILE_SIZE (1 * 1024 * 1024) + +typedef struct +{ + u32 ip; + u32 mask_len; +} sbr_container_ip; + +typedef struct +{ + sbr_container_ip ip_array[SBR_MAX_CONTAINER_IP_NUM]; + u32 ip_num; +} sbr_container_ip_group; + +extern sbr_container_ip_group g_container_ip_group; + +int sbr_init_cfg (); +int sbr_get_src_ip (u32 dst_ip, u32 * src_ip); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_container_cfg.c b/stacks/lwip_stack/lwip_src/socket/stackx_container_cfg.c new file mode 100644 index 0000000..b6580ed --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_container_cfg.c @@ -0,0 +1,332 @@ +/* +* +* 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 <sys/stat.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include "stackx_cfg.h" +#include "json.h" +#include "nstack_log.h" +#include "spl_def.h" +#include "nstack_securec.h" +#include "stackx_ip_addr.h" + +sbr_container_ip_group g_container_ip_group; + +/***************************************************************************** +* Prototype : sbr_parse_container_ip_json +* Description : parse port json +* Input : char* param +* Output : None +* Return Value : static void +* Calls : +* Called By : +* +*****************************************************************************/ +static void +sbr_parse_container_ip_json (char *param) +{ + int retval; + struct json_object *obj = json_tokener_parse (param); + struct json_object *container_id_obj = NULL; + struct json_object *ports_list_obj = NULL; + struct json_object *ip_cidr_list_obj = NULL; + + if (!obj) + { + NSSBR_LOGERR ("json_tokener_parse failed"); + return; + } + + json_object_object_get_ex (obj, "containerID", &container_id_obj); + if (!container_id_obj) + { + NSSBR_LOGERR ("can't get containerID"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (obj, "ports_list", &ports_list_obj); + if (ports_list_obj) + { + int i; + int port_num = json_object_array_length (ports_list_obj); + + if (0 == port_num) + { + NSSBR_LOGERR ("port num is 0"); + goto RETURN_ERROR; + } + + for (i = 0; i < port_num; i++) + { + struct json_object *port_obj = + json_object_array_get_idx (ports_list_obj, i); + json_object_object_get_ex (port_obj, "ip_cidr", &ip_cidr_list_obj); + if (ip_cidr_list_obj) + { + int j; + int ip_cidr_num = json_object_array_length (ip_cidr_list_obj); + for (j = 0; j < ip_cidr_num; ++j) + { + struct json_object *ip_cidr_obj = + json_object_array_get_idx (ip_cidr_list_obj, j); + if (ip_cidr_obj) + { + char tmp[32] = { 0 }; + const char *ip_cidr = + json_object_get_string (ip_cidr_obj); + if ((NULL == ip_cidr) || (ip_cidr[0] == 0)) + { + NSSBR_LOGERR ("ip is empty"); + goto RETURN_ERROR; + } + + const char *sub = strstr (ip_cidr, "/"); + if ((NULL == sub) + || (sizeof (tmp) - 1 < + (unsigned int) (sub - ip_cidr)) + || (strlen (sub) > sizeof (tmp) - 1)) + { + NSSBR_LOGERR ("ip format is not ok"); + goto RETURN_ERROR; + } + + retval = + STRNCPY_S (tmp, sizeof (tmp), ip_cidr, + (size_t) (sub - ip_cidr)); + if (EOK != retval) + { + NSSBR_LOGERR ("STRNCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + struct in_addr addr; + retval = + MEMSET_S (&addr, sizeof (addr), 0, sizeof (addr)); + if (EOK != retval) + { + NSSBR_LOGERR ("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + retval = spl_inet_aton (tmp, &addr); + if (0 == retval) + { + NSSBR_LOGERR ("spl_inet_aton failed]ret=%d", + retval); + goto RETURN_ERROR; + } + + g_container_ip_group. + ip_array[g_container_ip_group.ip_num].ip = + addr.s_addr; + int mask_len = atoi (sub + 1); + if ((mask_len <= 0) || (mask_len > 32)) + { + NSSBR_LOGERR ("mask len is not ok"); + goto RETURN_ERROR; + } + + g_container_ip_group. + ip_array[g_container_ip_group.ip_num].mask_len = + (u32) mask_len; + g_container_ip_group.ip_num++; + + if (g_container_ip_group.ip_num >= + SBR_MAX_CONTAINER_IP_NUM) + { + NSSBR_LOGWAR ("container ip num is full]ip_num=%u", + g_container_ip_group.ip_num); + goto RETURN_OK; + } + } + } + } + } + } + else + { + NSSBR_LOGERR ("can't get ports_list"); + goto RETURN_ERROR; + } + +RETURN_OK: + json_object_put (obj); + NSSBR_LOGINF ("container ip num is %u", g_container_ip_group.ip_num); + u32 idx; + for (idx = 0; idx < g_container_ip_group.ip_num; ++idx) + { + NSSBR_LOGDBG ("container ip=0x%08x", + g_container_ip_group.ip_array[idx].ip); + } + return; + +RETURN_ERROR: + json_object_put (obj); + if (MEMSET_S + (&g_container_ip_group, sizeof (sbr_container_ip_group), 0, + sizeof (sbr_container_ip_group)) != EOK) + { + NSSBR_LOGERR ("MEMSET_S failed"); + } +} + +/***************************************************************************** +* Prototype : sbr_get_cfg_path +* Description : get cfg path +* Input : None +* Output : None +* Return Value : NSTACK_STATIC const char* +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC const char * +sbr_get_cfg_path () +{ + static char cfg_file[SBR_MAX_CFG_PATH_LEN] = "/canal/output/portinfo.json"; + return cfg_file; +} + +/***************************************************************************** +* Prototype : sbr_init_cfg +* Description : init cfg from file +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_init_cfg () +{ + int ret; + off_t file_len = 0; + off_t buff_len = 0; + char *buff = NULL; + const char *cfg_file = sbr_get_cfg_path (); /* no need check ret */ + + int fp = open (cfg_file, O_RDONLY); + + if (fp < 0) + { + NSSBR_LOGWAR ("failed to open file]file name=%s", cfg_file); + goto RETURN_ERROR; + } + + file_len = lseek (fp, 0, SEEK_END); + if (file_len <= 0) + { + NSSBR_LOGWAR ("failed to get file len]file name=%s", cfg_file); + goto RETURN_ERROR; + } + + if (file_len > SBR_MAX_CFG_FILE_SIZE) + { + NSSBR_LOGWAR + ("file len is too big]file len=%d, max len=%d, file name=%s", + file_len, SBR_MAX_CFG_FILE_SIZE, cfg_file); + goto RETURN_ERROR; + } + + ret = lseek (fp, 0, SEEK_SET); + if (ret < 0) + { + NSSBR_LOGWAR ("seek to start failed]file name=%s", cfg_file); + goto RETURN_ERROR; + } + + buff_len = file_len + 1; + buff = (char *) malloc (buff_len); + if (!buff) + { + NSSBR_LOGWAR ("malloc buff failed]buff_len=%d", buff_len); + goto RETURN_ERROR; + } + + ret = MEMSET_S (buff, buff_len, 0, buff_len); + if (EOK != ret) + { + NSSBR_LOGWAR ("MEMSET_S failed]ret=%d.", ret); + goto RETURN_ERROR; + } + + ret = read (fp, buff, buff_len - 1); + if (ret <= 0) + { + NSSBR_LOGWAR ("read failed]ret=%d", ret); + goto RETURN_ERROR; + } + + sbr_parse_container_ip_json (buff); + close (fp); + free (buff); + return 0; + +RETURN_ERROR: + if (fp >= 0) + { + close (fp); + } + + if (buff) + { + free (buff); + } + + return -1; +} + +/***************************************************************************** +* Prototype : sbr_get_src_ip +* Description : get src ip from cfg +* Input : u32 dst_ip +* u32* src_ip +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_get_src_ip (u32 dst_ip, u32 * src_ip) +{ + if (!src_ip) + { + NSSBR_LOGERR ("src_ip is NULL"); + return -1; + } + + u32 i; + for (i = 0; i < g_container_ip_group.ip_num; ++i) + { + unsigned int mask = ~0; + mask = (mask << (32 - g_container_ip_group.ip_array[i].mask_len)); + mask = htonl (mask); + if ((dst_ip & mask) == (g_container_ip_group.ip_array[i].ip & mask)) + { + *src_ip = g_container_ip_group.ip_array[i].ip; + NSSBR_LOGDBG ("find src ip]container_ip=0x%08x,dest_ip=0x%08x", + *src_ip, dst_ip); + return 0; + } + } + + NSSBR_LOGDBG ("can't find src ip]dest_ip=0x%08x", dst_ip); + return -1; +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c new file mode 100644 index 0000000..0223ac9 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c @@ -0,0 +1,150 @@ +/* +* +* 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 "stackx_epoll_api.h" +#include "stackx_spl_share.h" +#include "common_pal_bitwide_adjust.h" +#include "nstack_dmm_adpt.h" +#include "nstack_dmm_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +void +epoll_triggle_event_from_api (sbr_socket_t * sock, int op) +{ + struct spl_netconn *conn = sbr_get_conn (sock); + void *epInfo = ADDR_SHTOL (conn->epInfo); + //NSPOL_LOGDBG(SOCKETS_DEBUG, "enter]fd=%d,op=%d", sock, op); + switch (op) + { + case EPOLL_API_OP_RECV: + break; + case EPOLL_API_OP_SEND: + if (conn->epoll_flag && epInfo) + { + nstack_event_callback (epInfo, EPOLLOUT); + } + break; + case EPOLL_API_OP_STACK_RECV: + if (conn->epoll_flag && epInfo) + { + nstack_event_callback (epInfo, EPOLLIN); + } + break; + default: + break; + } + return; +} + +/* + * This function will be registed to application + * The context will be in the application + */ +unsigned int +stackx_eventpoll_triggle (sbr_socket_t * sock, int triggle_ops, + struct epoll_event *pevent, void *pdata) +{ + struct spl_netconn *conn = sbr_get_conn (sock); + unsigned int events = 0; + if (!conn) + { + NSPOL_LOGINF (SOCKETS_DEBUG, "get socket failed]fd=%d", sock->fd); + return -1; + } + + NSPOL_LOGINF (SOCKETS_DEBUG, + "]fd=%d,triggle_ops=%d conn=%p event:%d pdata=%p", sock->fd, + triggle_ops, conn, pevent->events, pdata); + /* + * sock->epoll_flag must be set before sock->rcvevent check. + * Consider this Scenario : 1) network stack has got one packet, but event_callback not called yet + * 2) Do epoll ctl add, then stackx triggle will check event, it will get 0 + * 3) network stack call event_callback , it will check epoll_flag + * So, if epoll_flag not set before sock->rcvent check, neither of network stack and stackx triggle + * will add this event to epoll. because : for network stack, event_callback check epoll_flag fail + * for stackx triggle, event check fail. + */ + if (nstack_ep_triggle_add == triggle_ops) + { + /*log info */ + conn->epInfo = pdata; + __sync_fetch_and_add (&conn->epoll_flag, 1); + } + + if ((pevent->events & EPOLLIN) + && + (!((conn->rcvevent == 0) && (sbr_get_fd_share (sock)->lastdata == 0) + && (sbr_get_fd_share (sock)->lastoffset == 0)))) + events |= EPOLLIN; + if ((pevent->events & EPOLLOUT) && conn->sendevent) + events |= EPOLLOUT; + if (conn->errevent) + events |= pevent->events & (conn->errevent); + + switch (triggle_ops) + { + case nstack_ep_triggle_add: + break; + case nstack_ep_triggle_mod: + break; + case nstack_ep_triggle_del: + if (conn->epoll_flag > 0) + { + __sync_fetch_and_sub (&conn->epoll_flag, 1); + } + events = 0; + break; + default: + return -1; + } + return events; +} + +/* + * This function will be registed to application + * The context will be in the application + * RETURN VALUE : Event exists in current protocol + */ +unsigned int +stackx_eventpoll_getEvt (sbr_socket_t * sock, unsigned int events) +{ + struct spl_netconn *conn = sbr_get_conn (sock); + unsigned int tevent = 0; + if ((events & EPOLLIN) + && + (!((conn->rcvevent == 0) && (sbr_get_fd_share (sock)->lastdata == 0) + && (sbr_get_fd_share (sock)->lastoffset == 0)))) + { + tevent |= EPOLLIN; + } + + if ((events & EPOLLOUT) && conn->sendevent) + { + tevent |= EPOLLOUT; + } + return tevent; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* _cplusplus */ diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.h b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.h new file mode 100644 index 0000000..59a1d21 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.h @@ -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. +*/ + +#ifndef STACKX_EPOLL_API_H +#define STACKX_EPOLL_API_H +#include "stackx_socket.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +typedef enum +{ + EPOLL_API_OP_RECV, + EPOLL_API_OP_SEND, + EPOLL_API_OP_STACK_RECV +} EPOLL_TRIGGLE_EVENT_API_OPS_T; + +extern void epoll_triggle_event_from_api (sbr_socket_t * sock, int op); +extern unsigned int stackx_eventpoll_getEvt (sbr_socket_t * sock, + unsigned int events); +extern unsigned int stackx_eventpoll_triggle (sbr_socket_t * sock, + int triggle_ops, + struct epoll_event *pevent, + void *pdata); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_event.c b/stacks/lwip_stack/lwip_src/socket/stackx_event.c new file mode 100644 index 0000000..93e47a3 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_event.c @@ -0,0 +1,29 @@ +/* +* +* 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 "stackx_spl_share.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_event.h" +#include <netinet/in.h> + +#define FREE_FD_SET(readfd, writefd, exceptfd) {\ + if(readfd)\ + free(readfd);\ + if(writefd)\ + free(writefd);\ + if(exceptfd)\ + free(exceptfd);\ +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_event.h b/stacks/lwip_stack/lwip_src/socket/stackx_event.h new file mode 100644 index 0000000..f95b370 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_event.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 __STACKX_EVENT_H__ +#define __STACKX_EVENT_H__ + +#include <sys/types.h> +#include <sys/time.h> +#include <stdio.h> +#include <unistd.h> +#include "stackx_socket.h" +#include "nstack_securec.h" +#include "sbr_res_mgr.h" +#include "sbr_index_ring.h" +#define NSTACK_SETSIZE SBR_MAX_FD_NUM + +typedef struct +{ + unsigned char fds_bits[(NSTACK_SETSIZE + 7) / 8]; +} __attribute__ ((packed)) nstack_fd_set; + +#define NSTACK_FD_SET(n, p) ((p)->fds_bits[(n)/8]|=1U<<((n)&0x07)) +#define NSTACK_FD_ISSET(n,p) (((p)->fds_bits[(n)/8]&(1U<<((n)&0x07)))?1:0) +#define NSTACK_FD_CLR(n,p) ((p)->fds_bits[(n)/8]&=~(1U<<((n)&0x07))) +#define NSTACK_FD_ZERO(p) (MEMSET_S((void *)(p), sizeof(*(p)),0,sizeof(*(p)))) +#define NSTACK_FD_OR(p1 ,p2) {\ + int i;\ + for(i = 0; i < (NSTACK_SETSIZE+7)/8; i++){\ + (p1)->fds_bits[i] |= (p2)->fds_bits[i];\ + }\ +} + +#endif /* __STACKX_EVENT_H__ */ diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_macro.h b/stacks/lwip_stack/lwip_src/socket/stackx_macro.h new file mode 100644 index 0000000..96a0b91 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_macro.h @@ -0,0 +1,24 @@ +/* +* +* 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 STACKX_MACRO_H +#define STACKX_MACRO_H + +#ifndef SBR_USE_LOCK +#define SBR_USE_LOCK +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.c b/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.c new file mode 100644 index 0000000..6fcde44 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.c @@ -0,0 +1,775 @@ +/* +* +* 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 "stackx_msg_handler.h" +#include "stackx_spl_share.h" +#include "stackx_spl_msg.h" +#include "nsfw_msg_api.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_res_mgr.h" +#include "stackx_prot_com.h" +#include "nstack_securec.h" +//#include "stackx_dfx_api.h" + +#define SBR_MSG_MALLOC(sk) msg_malloc(ss_get_msg_pool(sbr_get_conn(sk))) +#define SBR_MSG_FREE(msg) msg_free(msg) + +#define SBR_MSG_POST(msg, ring) \ + do { \ + if (MSG_ASYN_POST == msg->param.op_type)\ + {\ + if (msg_post(msg, ring) < 0)\ + {\ + SBR_MSG_FREE(msg); \ + NSSBR_LOGERR("msg_post failed]major=%u,minor=%u,type=%u", \ + msg->param.major_type, msg->param.minor_type, msg->param.op_type); \ + }\ + } \ + else \ + {\ + if (msg_post(msg, ring) < 0)\ + {\ + msg->param.err = ECONNABORTED; \ + NSSBR_LOGERR("msg_post_with_ref failed]major=%u,minor=%u,type=%u", \ + msg->param.major_type, msg->param.minor_type, msg->param.op_type); \ + }\ + } \ + } while (0) + +#define SBR_MSG_POST_RET(msg, ring, ret) \ + do { \ + if (MSG_ASYN_POST == msg->param.op_type)\ + {\ + if ((ret = msg_post(msg, ring)) < 0)\ + {\ + SBR_MSG_FREE(msg); \ + NSSBR_LOGERR("msg_post failed]major=%u,minor=%u,type=%u", \ + msg->param.major_type, msg->param.minor_type, msg->param.op_type); \ + }\ + } \ + else \ + {\ + if ((ret = msg_post(msg, ring)) < 0)\ + {\ + msg->param.err = ECONNABORTED; \ + NSSBR_LOGERR("msg_post_with_ref failed]major=%u,minor=%u,type=%u", \ + msg->param.major_type, msg->param.minor_type, msg->param.op_type); \ + }\ + } \ + } while (0) + +NSTACK_STATIC inline void +_sbr_construct_msg (data_com_msg * m, u16 major_type, u16 minor_type, + u16 type, sbr_socket_t * sk) +{ + m->param.module_type = MSG_MODULE_SBR; + m->param.major_type = major_type; + m->param.minor_type = minor_type; + m->param.err = 0; + m->param.op_type = type; + sys_sem_init (&m->param.op_completed); + m->param.receiver = ss_get_recv_obj (sbr_get_conn (sk)); + m->param.comm_receiver = ss_get_comm_private_data (sbr_get_conn (sk)); + m->param.extend_member_bit = 0; +} + +#define sbr_construct_msg(m, major_type, minor_type, type, sk) { \ + _sbr_construct_msg(m, major_type, minor_type, type, sk); \ + NSSBR_LOGINF("fd=%d,conn=%p,private_data=%p", sk->fd, sbr_get_conn(sk), ss_get_private_data(sbr_get_conn(sk))); \ + } + +#define sbr_construct_msg_dbg(m, major_type, minor_type, type, sk) { \ + _sbr_construct_msg(m, major_type, minor_type, type, sk); \ + NSSBR_LOGDBG("fd=%d,conn=%p,private_data=%p", sk->fd, sbr_get_conn(sk), ss_get_private_data(sbr_get_conn(sk))); \ + } + +/***************************************************************************** +* Prototype : sbr_attach_msg +* Description : use buf's msg first +* Input : sbr_socket_t * sk +* struct pbuf* buf +* Output : None +* Return Value : static inline data_com_msg* +* Calls : +* Called By : +* +*****************************************************************************/ +static inline data_com_msg * +sbr_attach_msg (sbr_socket_t * sk, struct spl_pbuf *buf) +{ + data_com_msg *m = NULL; + if (!sk) + { + return m; + } + + if (buf && buf->msg) + { + m = (data_com_msg *) ADDR_SHTOL (buf->msg); + } + else + { + m = SBR_MSG_MALLOC (sk); + } + + return m; +} + +/***************************************************************************** +* Prototype : sbr_handle_socket +* Description : create socket +* Input : sbr_socket_t * sk +* netconn_type_t type +* u8 proto +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_socket (sbr_socket_t * sk, spl_netconn_type_t type, u8 proto) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_NEWCONN, + MSG_SYN_POST, sk); + msg_new_netconn *p = (msg_new_netconn *) m->buffer; + p->conn = (spl_netconn_t *) ADDR_LTOSH (sbr_get_conn (sk)); + p->type = type; + p->proto = proto; + p->socket = sk->fd; + p->extend_member_bit = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + int err = sbr_spl_err_to_errno (m->param.err); + SBR_MSG_FREE (m); + if (err != 0) + { + NSSBR_LOGERR ("handle socket failed]fd=%d,type=%d,proto=%u,err=%d", + sk->fd, type, proto, err); + sbr_set_sk_errno (sk, err); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_handle_bind +* Description : bind +* Input : sbr_socket_t * sk +* spl_ip_addr_t * addr +* u16 port +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_bind (sbr_socket_t * sk, spl_ip_addr_t * addr, u16 port) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_BIND, MSG_SYN_POST, + sk); + msg_bind *p = (msg_bind *) m->buffer; + p->ipaddr = *addr; + p->port = port; + p->extend_member_bit = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + int err = sbr_spl_err_to_errno (m->param.err); + SBR_MSG_FREE (m); + if (err != 0) + { + NSSBR_LOGERR ("handle bind failed]fd=%d,err=%d", sk->fd, err); + sbr_set_sk_errno (sk, err); + return -1; + } + + return 0; +} + +int +sbr_handle_listen (sbr_socket_t * sk, int backlog) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_LISTEN, + MSG_SYN_POST, sk); + msg_listen *p = (msg_listen *) m->buffer; + p->conn_pool = sbr_get_conn_pool (); + p->backlog = backlog; + p->extend_member_bit = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + int err = sbr_spl_err_to_errno (m->param.err); + SBR_MSG_FREE (m); + if (err != 0) + { + NSSBR_LOGERR ("handle listen failed]fd=%d,err=%d", sk->fd, err); + sbr_set_sk_errno (sk, err); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_handle_connect +* Description : connect +* Input : sbr_socket_t * sk +* spl_ip_addr_t * addr +* u16 port +* spl_ip_addr_t* local_ip +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_connect (sbr_socket_t * sk, spl_ip_addr_t * addr, u16 port, + spl_ip_addr_t * local_ip) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_CONNECT, + MSG_SYN_POST, sk); + msg_connect *p = (msg_connect *) m->buffer; + p->local_ip = *local_ip; + p->ipaddr = *addr; + p->port = port; + p->extend_member_bit = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + int err = sbr_spl_err_to_errno (m->param.err); + SBR_MSG_FREE (m); + if (err != 0) + { + NSSBR_LOGERR ("handle connect failed]fd=%d,err=%d", sk->fd, err); + sbr_set_sk_errno (sk, err); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_handle_get_name +* Description : get name +* Input : sbr_socket_t * sk +* struct sockaddr * name +* socklen_t * namelen +* u8 cmd +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_get_name (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen, u8 cmd) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_GETSOCK_NAME, + MSG_SYN_POST, sk); + msg_getaddrname *p = (msg_getaddrname *) m->buffer; + p->cmd = cmd; + p->extend_member_bit = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + int err = sbr_spl_err_to_errno (m->param.err); + if (err != 0) + { + NSSBR_LOGERR ("handle get name failed]fd=%d,err=%d", sk->fd, err); + goto error; + } + else + { + if (*namelen > sizeof (p->sock_addr)) + { + *namelen = sizeof (p->sock_addr); + } + + int ret = MEMCPY_S (name, *namelen, &p->sock_addr, *namelen); + if (0 != ret) + { + NSSBR_LOGERR ("MEMCPY_S failed]fd=%d,ret=%d", sk->fd, ret); + err = EINVAL; + goto error; + } + + *namelen = sizeof (p->sock_addr); + } + + SBR_MSG_FREE (m); + return 0; + +error: + sbr_set_sk_errno (sk, err); + SBR_MSG_FREE (m); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_handle_setsockopt +* Description : msg box will changed in IP_TOS +* Input : sbr_socket_t * sk +* int level +* int optname +* const void *optval +* socklen_t optlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_setsockopt (sbr_socket_t * sk, int level, int optname, + const void *optval, socklen_t optlen) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_SET_SOCK_OPT, + MSG_SYN_POST, sk); + msg_setgetsockopt *p = (msg_setgetsockopt *) m->buffer; + p->extend_member_bit = 0; + p->level = level; + p->optname = optname; + p->msg_box = NULL; /* init the value to avoid unexpected consequences */ + + if (optlen > sizeof (p->optval)) + { + optlen = sizeof (p->optval); + } + + p->optlen = optlen; + int err; + int ret = MEMCPY_S (&p->optval, sizeof (p->optval), optval, optlen); + if (0 != ret) + { + NSSBR_LOGERR ("MEMCPY_S failed]fd=%d,ret=%d", sk->fd, ret); + err = EINVAL; + goto error; + } + + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + err = sbr_spl_err_to_errno (m->param.err); + if (err != 0) + { + NSSBR_LOGERR ("handle setsockopt failed]fd=%d,err=%d", sk->fd, err); + goto error; + } + + if (IPPROTO_IP == level && IP_TOS == optname && p->msg_box) + { + ss_set_msg_box (sbr_get_conn (sk), + (mring_handle) ADDR_SHTOL (p->msg_box)); + } + + SBR_MSG_FREE (m); + return 0; + +error: + sbr_set_sk_errno (sk, err); + SBR_MSG_FREE (m); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_handle_getsockopt +* Description : get sockopt +* Input : sbr_socket_t * sk +* int level +* int optname +* void *optval +* socklen_t* optlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_getsockopt (sbr_socket_t * sk, int level, int optname, + void *optval, socklen_t * optlen) +{ + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_GET_SOCK_OPT, + MSG_SYN_POST, sk); + msg_setgetsockopt *p = (msg_setgetsockopt *) m->buffer; + p->extend_member_bit = 0; + p->level = level; + p->optname = optname; + + if (*optlen > sizeof (p->optval)) + { + *optlen = sizeof (p->optval); + } + + p->optlen = *optlen; + int err; + int ret = MEMCPY_S (&p->optval, sizeof (p->optval), optval, *optlen); + if (0 != ret) + { + NSSBR_LOGERR ("MEMCPY_S failed]fd=%d,ret=%d", sk->fd, ret); + err = EINVAL; + goto error; + } + + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + + err = sbr_spl_err_to_errno (m->param.err); + if (err != 0) + { + NSSBR_LOGERR ("handle getsockopt failed]fd=%d,err=%d", sk->fd, err); + goto error; + } + + ret = MEMCPY_S (optval, *optlen, &p->optval.int_optval, *optlen); + if (0 != ret) + { + NSSBR_LOGERR ("MEMCPY_S failed]fd=%d,ret=%d", sk->fd, ret); + err = EINVAL; + goto error; + } + + SBR_MSG_FREE (m); + return 0; + +error: + sbr_set_sk_errno (sk, err); + SBR_MSG_FREE (m); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_handle_close +* Description : need care msg_box_ref,make sure to finalize this message +* Input : sbr_socket_t * sk +* u8 how +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_close (sbr_socket_t * sk, u8 how) +{ + data_com_msg *m = sbr_attach_msg (sk, + (struct spl_pbuf *) + ADDR_SHTOL (sbr_get_fd_share + (sk)->recoder.head)); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_DELCON, + MSG_ASYN_POST, sk); + msg_delete_netconn *p = (msg_delete_netconn *) m->buffer; + p->extend_member_bit = 0; + p->buf = NULL; + p->time_started = sys_now (); + p->shut = how; + p->pid = get_sys_pid (); + p->conn = (spl_netconn_t *) ADDR_LTOSH (sbr_get_conn (sk)); + p->notify_omc = FALSE; + p->msg_box_ref = SPL_MSG_BOX_NUM; + + /* to ensure that the last deal with SPL_API_DO_DELCON message */ + int i; + for (i = 0; i < SPL_MSG_BOX_NUM; ++i) + { + SBR_MSG_POST (m, + ss_get_instance_msg_box (ss_get_bind_thread_index + (sbr_get_conn (sk)), i)); + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_handle_udp_send +* Description : udp send +* Input : sbr_socket_t * sk +* struct netbuf *buf +* spl_ip_addr_t* local_ip +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_udp_send (sbr_socket_t * sk, struct spl_netbuf *buf, + spl_ip_addr_t * local_ip) +{ + data_com_msg *m = + sbr_attach_msg (sk, (struct spl_pbuf *) ADDR_SHTOL (buf->p)); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg_dbg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_SEND, + MSG_ASYN_POST, sk); + msg_send_buf *p = (msg_send_buf *) m->buffer; + p->local_ip.addr = local_ip->addr; + int ret = MEMCPY_S (&p->addr, sizeof (spl_ip_addr_t), &buf->addr, + sizeof (spl_ip_addr_t)); + if (ret != 0) + { + NSSBR_LOGERR ("MEMCPY_S failed]fd=%d,ret=%d", sk->fd, ret); + sbr_set_sk_io_errno (sk, EINVAL); + SBR_MSG_FREE (m); + return -1; + } + + p->p = buf->p; + p->port = buf->port; + p->extend_member_bit = 0; + SBR_MSG_POST_RET (m, sbr_get_msg_box (sk), ret); + + if (0 == ret) + { + return 0; + } + else + { + NSSBR_LOGERR ("post msg failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EAGAIN); + return -1; + } +} + +/***************************************************************************** +* Prototype : sbr_handle_free_recv_buf +* Description : free recv buf,can't free buf in app +* Input : sbr_socket_t * sk +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +sbr_handle_free_recv_buf (sbr_socket_t * sk) +{ + data_com_msg *m = sbr_attach_msg (sk, + (struct spl_pbuf *) + ADDR_SHTOL (sbr_get_fd_share + (sk)->recoder.head)); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + return; + } + + sbr_construct_msg_dbg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_PBUF_FREE, + MSG_ASYN_POST, sk); + msg_free_buf *p = (msg_free_buf *) m->buffer; + p->extend_member_bit = 0; + p->buf = sbr_get_fd_share (sk)->recoder.head; + sbr_get_fd_share (sk)->recoder.head = NULL; + sbr_get_fd_share (sk)->recoder.tail = NULL; + sbr_get_fd_share (sk)->recoder.totalLen = 0; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); +} + +void +sbr_handle_free_send_buf (sbr_socket_t * sk, struct spl_pbuf *buf) +{ + if (buf != NULL) + { + data_com_msg *m = sbr_attach_msg (sk, buf); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + return; + } + + sbr_construct_msg_dbg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_PBUF_FREE, + MSG_ASYN_POST, sk); + msg_free_buf *p = (msg_free_buf *) m->buffer; + p->extend_member_bit = 0; + p->buf = (struct spl_pbuf *) ADDR_LTOSH (buf); + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + } +} + +/***************************************************************************** +* Prototype : sbr_handle_shutdown +* Description : shut down +* Input : sbr_socket_t * sk +* u8 how +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_handle_shutdown (sbr_socket_t * sk, u8 how) +{ + int err; + data_com_msg *m = SBR_MSG_MALLOC (sk); + + if (!m) + { + NSSBR_LOGERR ("malloc msg failed]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_CLOSE, MSG_SYN_POST, + sk); + msg_close *p = (msg_close *) m->buffer; + p->extend_member_bit = 0; + p->time_started = sys_now (); + p->shut = how; + SBR_MSG_POST (m, sbr_get_msg_box (sk)); + err = sbr_spl_err_to_errno (m->param.err); + SBR_MSG_FREE (m); + if (err != 0) + { + NSSBR_LOGERR ("handle getsockopt failed]fd=%d,err=%d", sk->fd, err); + sbr_set_sk_errno (sk, err); + return -1; + } + + return 0; +} + +void +sbr_handle_tcp_recv (sbr_socket_t * sk, u32 len, struct spl_pbuf *buf) +{ + data_com_msg *m = sbr_attach_msg (sk, buf); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + return; + } + + sbr_construct_msg_dbg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_RECV, + MSG_ASYN_POST, sk); + msg_recv_buf *p = (msg_recv_buf *) m->buffer; + p->extend_member_bit = 0; + p->len = len; + p->p = (struct spl_pbuf *) ADDR_LTOSH (buf); + SBR_MSG_POST (m, sbr_get_msg_box (sk)); +} + +int +sbr_handle_tcp_send (sbr_socket_t * sk, size_t size, struct spl_pbuf *buf, + u8 api_flag) +{ + int ret; + data_com_msg *m = sbr_attach_msg (sk, buf); + + if (!m) + { + NSSBR_LOGERR ("attach msg failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, ENOMEM); + return -1; + } + + sbr_construct_msg_dbg (m, SPL_TCPIP_NEW_MSG_API, SPL_API_DO_WRITE, + MSG_ASYN_POST, sk); + msg_write_buf *p = (msg_write_buf *) m->buffer; + p->extend_member_bit = 0; + p->len = size; + p->p = (struct spl_pbuf *) ADDR_LTOSH (buf); + p->apiflags = api_flag; + SBR_MSG_POST_RET (m, sbr_get_msg_box (sk), ret); + + if (0 == ret) + { + return 0; + } + else + { + NSSBR_LOGERR ("post msg failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EAGAIN); + return -1; + } +} + +/* need delete sbr_handle_app_touch */ +void +sbr_handle_app_touch (void) +{ +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.h b/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.h new file mode 100644 index 0000000..a52d026 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_msg_handler.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 STACKX_MSG_HANDLER_H +#define STACKX_MSG_HANDLER_H +#include "stackx_socket.h" +#include "stackx_ip_addr.h" +#include "stackx_netbuf.h" +#include "stackx_spl_share.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define SBR_GET_SOCK_NAME 1 +#define SBR_GET_PEER_NAME 0 + +int sbr_handle_socket (sbr_socket_t * sk, spl_netconn_type_t type, u8 proto); + +int sbr_handle_bind (sbr_socket_t * sk, spl_ip_addr_t * addr, u16 port); + +int sbr_handle_listen (sbr_socket_t * sk, int backlog); + +int sbr_handle_connect (sbr_socket_t * sk, spl_ip_addr_t * addr, u16 port, + spl_ip_addr_t * local_ip); + +int sbr_handle_get_name (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen, u8 cmd); + +int sbr_handle_setsockopt (sbr_socket_t * sk, int level, int optname, + const void *optval, socklen_t optlen); + +int sbr_handle_getsockopt (sbr_socket_t * sk, int level, int optname, + void *optval, socklen_t * optlen); + +int sbr_handle_close (sbr_socket_t * sk, u8 how); + +int sbr_handle_udp_send (sbr_socket_t * sk, struct spl_netbuf *buf, + spl_ip_addr_t * local_ip); + +void sbr_handle_free_recv_buf (sbr_socket_t * sk); + +void sbr_handle_free_send_buf (sbr_socket_t * sk, struct spl_pbuf *buf); + +int sbr_handle_shutdown (sbr_socket_t * sk, u8 how); + +void sbr_handle_tcp_recv (sbr_socket_t * sk, u32 len, struct spl_pbuf *buf); + +int sbr_handle_tcp_send (sbr_socket_t * sk, size_t size, struct spl_pbuf *buf, + u8 api_flag); + +int sbr_handle_custom_send (sbr_socket_t * sk, struct spl_pbuf *buf, + spl_ip_addr_t * src, spl_ip_addr_t * dst, u8 tos); + +int sbr_handle_custom_close (sbr_socket_t * sk, spl_ip_addr_t * addr); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c new file mode 100644 index 0000000..292c17a --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c @@ -0,0 +1,679 @@ +/* +* +* 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 <string.h> +#include <time.h> +#include "stackx_msg_handler.h" +#include "stackx_prot_com.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_err.h" +#include "nstack_securec.h" +#include "nsfw_rti.h" +//#include "stackx_custom.h" + +#define FAST_SLEEP_TIME 10000 +#define FAST_RETRY_COUNT 100 +#define MAX_WAIT_TIMEOUT 0x7FFFFFFF + +/***************************************************************************** +* Prototype : sbr_getsockopt_sol_socket +* Description : get sol socket +* Input : sbr_socket_t * sk +* int optname +* void * optval +* socklen_t optlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_getsockopt_sol_socket (sbr_socket_t * sk, int optname, void *optval, + socklen_t optlen) +{ + int err = 0; + + switch (optname) + { + case SO_ERROR: + { + if (optlen < sizeof (int)) + { + return EINVAL; + } + + /* only overwrite ERR_OK or tempoary errors */ + err = sbr_get_sk_errno (sk); + + if ((0 == err) || (EINPROGRESS == err)) + { + err = + sbr_spl_err_to_errno (ss_get_last_errno (sbr_get_conn (sk))); + sbr_set_sk_errno (sk, err); + } + else + { + sbr_set_sk_errno (sk, 0); + } + + *(int *) optval = sbr_get_sk_errno (sk); + + return 0; + } + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_RCVBUF: + case SO_SNDBUF: + case SO_REUSEADDR: + if (optlen < sizeof (int)) + { + err = EINVAL; + } + + break; + case SO_RCVTIMEO: + case SO_SNDTIMEO: + if (optlen < sizeof (struct timeval)) + { + err = EINVAL; + } + + break; + case SO_LINGER: + if (optlen < sizeof (struct linger)) + { + err = EINVAL; + } + + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +/***************************************************************************** +* Prototype : sbr_getsockopt_ipproto_ip +* Description : get ipproto ip +* Input : int optname +* void * optval +* socklen_t optlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_getsockopt_ipproto_ip (int optname, void *optval, socklen_t optlen) +{ + int err = 0; + + switch (optname) + { + case IP_TOS: + if (optlen < sizeof (u8)) + { + err = EINVAL; + } + + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +/***************************************************************************** +* Prototype : sbr_pick_timeout +* Description : pick time +* Input : const void * optval +* socklen_t optlen +* i32* timeout +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_pick_timeout (const void *optval, socklen_t optlen, i32 * timeout) +{ + if (optlen < sizeof (struct timeval)) + { + return EINVAL; + } + + struct timeval *time_val = (struct timeval *) optval; + if ((time_val->tv_usec < 0) || (time_val->tv_usec > USEC_TO_SEC)) + { + return EDOM; + } + else + { + if (time_val->tv_sec < 0) + { + *timeout = 0; + } + else + { + *timeout = MAX_WAIT_TIMEOUT; + if ((time_val->tv_sec != 0) || (time_val->tv_usec != 0)) + { + if (time_val->tv_sec < ((MAX_WAIT_TIMEOUT / 1000) - 1)) + { + *timeout = + time_val->tv_sec * 1000 + time_val->tv_usec / 1000; + } + } + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_setsockopt_sol_socket +* Description : set sol socket +* Input : sbr_socket_t * sk +* int optname +* const void * optval +* socklen_t optlen +* netconn_type_t type +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_setsockopt_sol_socket (sbr_socket_t * sk, int optname, const void *optval, + socklen_t optlen, spl_netconn_type_t type) +{ + int err = 0; + + switch (optname) + { + case SO_REUSEADDR: + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_RCVBUF: + case SO_SNDBUF: + if (optlen < sizeof (int)) + { + err = EINVAL; + } + + break; + case SO_RCVTIMEO: + err = + sbr_pick_timeout (optval, optlen, + &sbr_get_fd_share (sk)->recv_timeout); + break; + case SO_SNDTIMEO: + err = + sbr_pick_timeout (optval, optlen, + &sbr_get_fd_share (sk)->send_timeout); + break; + case SO_LINGER: + if (optlen < sizeof (struct linger)) + { + err = EINVAL; + } + + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +/***************************************************************************** +* Prototype : sbr_setsockopt_ipproto_ip +* Description : set ipproto ip +* Input : int optname +* const void * optval +* socklen_t optlen +* netconn_type_t type +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_setsockopt_ipproto_ip (int optname, const void *optval, socklen_t optlen, + spl_netconn_type_t type) +{ + int err = 0; + + switch (optname) + { + case IP_TOS: + if (optlen < sizeof (u8)) + { + err = EINVAL; + } + + break; + case IP_MULTICAST_TTL: + if (optlen < sizeof (u8)) + { + err = EINVAL; + break; + } + + if (type != SPL_NETCONN_UDP) + { + err = EAFNOSUPPORT; + break; + } + + break; + case IP_MULTICAST_IF: + if (optlen < sizeof (struct in_addr)) + { + err = EINVAL; + break; + } + + if (type != SPL_NETCONN_UDP) + { + err = EAFNOSUPPORT; + break; + } + + break; + case IP_MULTICAST_LOOP: + if (optlen < sizeof (u8)) + { + err = EINVAL; + break; + } + + if (type != SPL_NETCONN_UDP) + { + err = EAFNOSUPPORT; + break; + } + + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +/***************************************************************************** +* Prototype : sbr_dequeue_buf +* Description : dequeue buf +* Input : sbr_socket_t * sk +* void **buf +* i32 timeout +* u8 use_l4_ring +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_dequeue_buf (sbr_socket_t * sk, void **buf, i32 timeout) +{ + mring_handle ring = ss_get_recv_ring (sbr_get_conn (sk)); + + struct timespec start, end; + long timediff; + long timediff_sec; + long timeout_sec = (long) (timeout / 1000); + unsigned int retry_count = 0; + + if (timeout > 0) + { + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &start))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + } + + if (!ss_recv_ring_valid (sbr_get_conn (sk))) + { + NSSBR_LOGDBG ("ring is invalid]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, ENOTCONN); + return -1; + } + + int dequeue_ret = 0; + pid_t pid = get_sys_pid (); + + while (1) + { + if (ss_is_shut_rd (sbr_get_conn (sk))) + { + NSSBR_LOGDBG ("is shut rd]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + + dequeue_ret = nsfw_mem_ring_dequeue (ring, buf); + if (1 == dequeue_ret) + { + pbuf_set_recycle_flg ((struct spl_pbuf *) *buf, pid); /*release buf hold by app on abnormal exit */ + return 0; + } + else if (0 == dequeue_ret) + { + /*If the peer reset connect, try to receive data only once */ + if (ss_can_not_recv (sbr_get_conn (sk))) + { + NS_LOG_CTRL (LOG_CTRL_RECV_QUEUE_FULL, LOGSBR, "NSSBR", + NSLOG_WAR, "try to fetch one more time]fd=%d", + sk->fd); + /** + * l4_ring will not be processed here as can_not_recv flag is + * set by TCP only. + */ + if (1 == nsfw_mem_ring_dequeue (ring, buf)) + { + pbuf_set_recycle_flg ((struct spl_pbuf *) *buf, pid); + return 0; + } + + sbr_set_sk_io_errno (sk, ENOTCONN); + return -1; + } + + int err = ss_get_last_errno (sbr_get_conn (sk)); + if (SPL_ERR_IS_FATAL (err) || err == ERR_TIMEOUT) /* have to handle ERR_TIMEOUT here, when TCP keepalive timeout. */ + { + NS_LOG_CTRL (LOG_CTRL_RECV_QUEUE_FULL, LOGSBR, "NSSBR", + NSLOG_ERR, "connection fatal error!err=%d", err); + + /* l4_ring need to be handled in the future */ + if (1 == nsfw_mem_ring_dequeue (ring, buf)) + { + pbuf_set_recycle_flg ((struct spl_pbuf *) *buf, pid); + return 0; + } + + sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err)); + return -1; + } + + if (0 > timeout) + { + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + return -1; + } + + if (retry_count < FAST_RETRY_COUNT) + { + sys_sleep_ns (0, FAST_SLEEP_TIME); + retry_count++; + } + else + { + sys_sleep_ns (0, sbr_get_fd_share (sk)->block_polling_time); + } + + if (timeout > 0) + { + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &end))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + timediff_sec = end.tv_sec - start.tv_sec; + if (timediff_sec >= timeout_sec) + { + timediff = end.tv_nsec > start.tv_nsec ? + (timediff_sec * 1000) + (end.tv_nsec - + start.tv_nsec) / + USEC_TO_SEC : (timediff_sec * 1000) - + ((start.tv_nsec - end.tv_nsec) / USEC_TO_SEC); + if (timediff > timeout) + { + NSSBR_LOGDBG ("recv timeout]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + return -1; + } + } + } + } + else + { + NSSBR_LOGERR ("dequeue failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + } +} + +int +sbr_com_peak (sbr_socket_t * sk) +{ + NSSBR_LOGERR ("not implement]fd=%d", sk->fd); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_com_try_lock_recv +* Description : try lock recv +* Input : sbr_socket_t * sk +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_com_try_lock_recv (sbr_socket_t * sk) +{ +#ifdef SBR_USE_LOCK + return common_spinlock_try_lock_with_pid (&sbr_get_fd_share (sk)->recv_lock, + get_sys_pid ()); +#else + return 1; +#endif +} + +/***************************************************************************** +* Prototype : sbr_com_lock_common +* Description : lock common +* Input : sbr_socket_t * sk +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +sbr_com_lock_common (sbr_socket_t * sk) +{ +#ifdef SBR_USE_LOCK + while (!common_spinlock_try_lock_with_pid + (&sbr_get_fd_share (sk)->common_lock, get_sys_pid ())) + { + sys_sleep_ns (0, 0); + } +#endif + +} + +void +sbr_com_fork_parent (sbr_socket_t * sk, pid_t p) +{ + i32 ref = ss_inc_fork_ref (sbr_get_conn (sk)); + NSSBR_LOGINF ("inc fork ref] fd=%d, p=%d, ref=%d, conn=%p, private_data=%p", + sk->fd, p, ref, sbr_get_conn (sk), + sbr_get_conn (sk)->private_data); +} + +void +sbr_com_fork_child (sbr_socket_t * sk, pid_t p, pid_t c) +{ + if (ss_add_pid (sbr_get_conn (sk), c) != 0) + { + NSSBR_LOGERR + ("add pid failed] fd=%d, p=%d, c=%d, ref=%d, conn=%p, private_data=%p", + sk->fd, p, c, ss_get_fork_ref (sbr_get_conn (sk)), sbr_get_conn (sk), + sbr_get_conn (sk)->private_data); + } + else + { + NSSBR_LOGINF + ("add pid ok] fd=%d, p=%d, c=%d, ref=%d, conn=%p, private_data=%p", + sk->fd, p, c, ss_get_fork_ref (sbr_get_conn (sk)), sbr_get_conn (sk), + sbr_get_conn (sk)->private_data); + } +} + +/***************************************************************************** +* Prototype : sbr_com_unlock_common +* Description : unlock common +* Input : sbr_socket_t * sk +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +sbr_com_unlock_common (sbr_socket_t * sk) +{ +#ifdef SBR_USE_LOCK + common_spinlock_unlock (&sbr_get_fd_share (sk)->common_lock); +#endif +} + +/***************************************************************************** +* Prototype : sbr_com_free_recv_buf +* Description : free recv buf,can't free buf in app +* Input : sbr_socket_t * sk +* struct spl_pbuf *p +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +sbr_com_free_recv_buf (sbr_socket_t * sk, struct spl_pbuf *p) +{ + struct spl_pbuf *p_orig = p; + if (p) + { + p->freeNext = NULL; + p = (struct spl_pbuf *) ADDR_LTOSH (p); + + if (sbr_get_fd_share (sk)->recoder.totalLen > 0) + { + ((struct spl_pbuf *) + ADDR_SHTOL (sbr_get_fd_share (sk)->recoder.tail))->freeNext = p; + sbr_get_fd_share (sk)->recoder.tail = p; + } + else + { + sbr_get_fd_share (sk)->recoder.head = p; + sbr_get_fd_share (sk)->recoder.tail = p; + } + + sbr_get_fd_share (sk)->recoder.totalLen++; + } + + /* send MSG only if it's a big packet or number of packets larger than 32 */ + if ((p_orig && p_orig->tot_len > MAX_RECV_FREE_LEN) || + (sbr_get_fd_share (sk)->recoder.totalLen >= MAX_RECV_FREE_BUF)) + { + sbr_handle_free_recv_buf (sk); + } + +} + +/***************************************************************************** +* Prototype : sbr_get_sockaddr_and_len +* Description : get addr and len +* Input : u16 port +* spl_ip_addr_t * ipaddr +* struct sockaddr * addr +* socklen_t * addrlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_get_sockaddr_and_len (u16 port, spl_ip_addr_t * ipaddr, + struct sockaddr *addr, socklen_t * addrlen) +{ + int ret; + struct sockaddr_in sin; + + ret = MEMSET_S (&sin, sizeof (sin), 0, sizeof (sin)); + if (0 != ret) + { + NSSBR_LOGERR ("MEMSET_S failed]ret=%d.", ret); + return -1; + } + + sin.sin_family = AF_INET; + sin.sin_port = htons (port); + inet_addr_from_ipaddr (&sin.sin_addr, ipaddr); + if (*addrlen > sizeof (struct sockaddr)) + { + *addrlen = sizeof (struct sockaddr); + } + + if (*addrlen > 0) + { + ret = MEMCPY_S (addr, sizeof (struct sockaddr), &sin, *addrlen); + if (0 != ret) + { + NSSBR_LOGERR ("MEMCPY_S failed]ret=%d", ret); + + return -1; + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_com_set_app_info +* Description : set app info to netconn +* Input : sbr_socket_t * sk +* void* appinfo +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +sbr_com_set_app_info (sbr_socket_t * sk, void *appinfo) +{ + return; +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h new file mode 100644 index 0000000..1be44cb --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h @@ -0,0 +1,162 @@ +/* +* +* 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 STACKX_PROT_COM_H +#define STACKX_PROT_COM_H +#include "stackx_socket.h" +#include "stackx_ip_addr.h" +#include "stackx_res_mgr.h" +#include "stackx_pbuf.h" +#include "stackx_macro.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define MAX_RECV_FREE_BUF 32 +#define MAX_RECV_FREE_LEN (SPL_FRAME_MTU - SPL_IP_HLEN) +#define USEC_TO_SEC 1000000 + +#ifndef NSTACK_SOCKOPT_CHECK +#define NSTACK_SOCKOPT_CHECK +/* setsockopt level type*/ +enum +{ + NSTACK_SOCKOPT = 0xff02 +}; +/*setsockopt optname type*/ +enum +{ + NSTACK_SEM_SLEEP = 0X001 +}; +#endif + +#define sbr_malloc_tx_pbuf(len, offset) sbr_malloc_pbuf(sbr_get_tx_pool(), len, TX_MBUF_MAX_LEN, offset) + +static inline int +sbr_spl_err_to_errno (i32 err) +{ + static int table[] = { + 0, /* ERR_OK 0 No error, everything OK. */ + ENOMEM, /* ERR_MEM -1 Out of memory error. */ + ENOBUFS, /* ERR_BUF -2 Buffer error. */ + ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + EINVAL, /* ERR_VAL -6 Illegal value. */ + EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ + EISCONN, /* ERR_ISCONN -9 Already connected. */ + ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + ECONNRESET, /* ERR_RST -11 Connection reset. */ + ENOTCONN, /* ERR_CLSD -12 Connection closed. */ + ENOTCONN, /* ERR_CONN -13 Not connected. */ + EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ + EALREADY, /*ERR_ALREADY -16 previous connect attemt has not yet completed */ + EPROTOTYPE, /*ERR_PROTOTYPE -17 prototype error or some other generic error. + the operation is not allowed on current socket */ + EINVAL, /* ERR_CALLBACK -18 callback error */ + EADDRNOTAVAIL, /* ERR_CANTASSIGNADDR -19 Cannot assign requested address */ + EIO, /* ERR_CONTAINER_ID -20 Illegal container id */ + ENOTSOCK, /*ERR_NOTSOCK -21 not a socket */ + -1, /* ERR_CLOSE_WAIT -22 closed in established state */ + EPROTONOSUPPORT, /* ERR_EPROTONOSUPPORT -23 Protocol not supported */ + ECONNABORTED /* ERR_FAULTRECOVERY -24 SPL just recovered from a fatal fault */ + }; + + if (((-(err)) >= 0) + && (-(err)) < (i32) (sizeof (table) / sizeof (table[0]))) + { + return table[-(err)]; + } + else + { + return EIO; + } +} + +int sbr_getsockopt_sol_socket (sbr_socket_t * sk, int optname, void *optval, + socklen_t optlen); +int sbr_getsockopt_ipproto_ip (int optname, void *optval, socklen_t optlen); +int sbr_setsockopt_sol_socket (sbr_socket_t * sk, int optname, + const void *optval, socklen_t optlen, + spl_netconn_type_t type); +int sbr_setsockopt_ipproto_ip (int optname, const void *optval, + socklen_t optlen, spl_netconn_type_t type); +int sbr_dequeue_buf (sbr_socket_t * sk, void **buf, i32 timeout); +int sbr_com_peak (sbr_socket_t * sk); +int sbr_com_try_lock_recv (sbr_socket_t * sk); +/***************************************************************************** +* Prototype : sbr_com_lock_recv +* Description : lock recv +* Input : sbr_socket_t * sk +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +sbr_com_lock_recv (sbr_socket_t * sk) +{ +#ifdef SBR_USE_LOCK + while (!common_spinlock_try_lock_with_pid + (&sbr_get_fd_share (sk)->recv_lock, get_sys_pid ())) + { + sys_sleep_ns (0, 0); + } +#endif + +} + +/***************************************************************************** +* Prototype : sbr_com_unlock_recv +* Description : unlock recv +* Input : sbr_socket_t * sk +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +sbr_com_unlock_recv (sbr_socket_t * sk) +{ +#ifdef SBR_USE_LOCK + common_spinlock_unlock (&sbr_get_fd_share (sk)->recv_lock); +#endif +} + +void sbr_com_lock_common (sbr_socket_t * sk); +void sbr_com_unlock_common (sbr_socket_t * sk); +void sbr_com_free_recv_buf (sbr_socket_t * sk, struct spl_pbuf *p); +int sbr_get_sockaddr_and_len (u16 port, spl_ip_addr_t * ip_addr, + struct sockaddr *addr, socklen_t * addrlen); +void sbr_com_set_app_info (sbr_socket_t * sk, void *appinfo); + +void sbr_com_fork_parent (sbr_socket_t * sk, pid_t p); +void sbr_com_fork_child (sbr_socket_t * sk, pid_t p, pid_t c); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c b/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c new file mode 100644 index 0000000..920d73d --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c @@ -0,0 +1,113 @@ +/* +* +* 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 "sbr_protocol_api.h" +#include "stackx_epoll_api.h" +#include "stackx_socket.h" +#include "stackx_res_mgr.h" +#include "stackx_common_opt.h" +#include "common_mem_api.h" +#include "stackx_event.h" + +extern sbr_fdopt tcp_fdopt; +extern sbr_fdopt udp_fdopt; +extern sbr_fdopt raw_fdopt; +extern sbr_fdopt custom_fdopt; + +/***************************************************************************** +* Prototype : sbr_init_protocol +* Description : init protocol +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_init_protocol () +{ + return sbr_init_stackx (); +} + +/***************************************************************************** +* Prototype : sbr_fork_protocol +* Description : init protocol +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_fork_protocol () +{ + pid_t pid = updata_sys_pid (); + + NSSBR_LOGINF ("update pid in child]pid=%d", pid); + return sbr_fork_stackx (); +} + +/***************************************************************************** +* Prototype : sbr_get_fdopt +* Description : get fdopt by domain type protocol +* Input : int domain +* int type +* int protocol +* Output : None +* Return Value : sbr_fdopt* +* Calls : +* Called By : +* +*****************************************************************************/ +sbr_fdopt * +sbr_get_fdopt (int domain, int type, int protocol) +{ + if (domain != AF_INET) + { + NSSBR_LOGERR ("domain is not AF_INET]domain=%d", domain); + sbr_set_errno (EAFNOSUPPORT); + return NULL; + } + + sbr_fdopt *fdopt = NULL; + + switch (type & (~(O_NONBLOCK | SOCK_CLOEXEC))) + { + case SOCK_DGRAM: + fdopt = &udp_fdopt; + break; + case SOCK_STREAM: + fdopt = &tcp_fdopt; + break; + + default: + NSSBR_LOGDBG ("type is unknown]type=%d", type); + sbr_set_errno (ESOCKTNOSUPPORT); + return NULL; + } + + return fdopt; +} + +/* app send its version info to nStackMain */ +extern void sbr_handle_app_touch (void); +void +sbr_app_touch_in (void) +{ + sbr_handle_app_touch (); +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c new file mode 100644 index 0000000..f3cb5b5 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c @@ -0,0 +1,279 @@ +/* +* +* 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 "stackx_res_mgr.h" +#include "stackx_common.h" +#include "nstack_securec.h" +#include "nsfw_msg.h" +#include "stackx_common.h" +#include "nsfw_mgr_com_api.h" +#include "stackx_cfg.h" +#include "nsfw_maintain_api.h" +//#include "stackx_dfx_api.h" +#include "stackx_app_res.h" + +sbr_share_group g_share_group = { 0 }; + +#define SLOW_SLEEP_TIME 500000 + +NSTACK_STATIC inline void +sbr_reset_fd_share (sbr_fd_share * fd_share) +{ + common_mem_spinlock_init (&fd_share->recv_lock); + common_mem_spinlock_init (&fd_share->common_lock); + fd_share->err = 0; + fd_share->lastoffset = 0; + fd_share->lastdata = NULL; + fd_share->recoder.head = NULL; + fd_share->recoder.tail = NULL; + fd_share->recoder.totalLen = 0; + fd_share->recv_timeout = 0; + fd_share->send_timeout = 0; + fd_share->rcvlowat = 1; + fd_share->block_polling_time = SLOW_SLEEP_TIME; +} + +/***************************************************************************** +* Prototype : sbr_init_tx_pool +* Description : get tx buf pool +* Input : None +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC int +sbr_init_tx_pool () +{ + mpool_handle pool[1]; + pool[0] = NULL; + + (void) sbr_malloc_tx_pool (get_sys_pid (), pool, 1); + if (pool[0]) + { + g_share_group.tx_pool = pool[0]; + return 0; + } + + return -1; +} + +/***************************************************************************** +* Prototype : sbr_init_app_res +* Description : get msg, conn pool +* Input : None +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +NSTACK_STATIC int +sbr_init_app_res () +{ + g_share_group.conn_pool = sbr_get_instance_conn_pool (0); + if (!g_share_group.conn_pool) + { + return -1; + } + + return 0; +} + +/*=========== get share config for app =============*/ +NSTACK_STATIC inline int +get_share_config () +{ + static nsfw_mem_name g_cfg_mem_info = + { NSFW_SHMEM, NSFW_PROC_MAIN, NSTACK_SHARE_CONFIG }; + + mzone_handle base_cfg_mem = nsfw_mem_zone_lookup (&g_cfg_mem_info); + if (NULL == base_cfg_mem) + { + NSSOC_LOGERR ("get config share mem failed."); + return -1; + } + + if (get_share_cfg_from_mem (base_cfg_mem) < 0) + { + NSSOC_LOGERR ("get share config failed."); + return -1; + } + + NSSOC_LOGDBG ("get share config success."); + return 0; +} + +int +nstack_set_share_config () +{ + return 0; +} + +/***************************************************************************** +* Prototype : sbr_init_stackx +* Description : init stackx res +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_init_stackx () +{ + sbr_init_cfg (); + if (get_share_config () < 0) + { + NSSBR_LOGERR ("get_share_config failed"); + return -1; + } + + if (sbr_attach_group_array () != 0) + { + NSSBR_LOGERR ("sbr_attach_group_array failed"); + return -1; + } + + NSSBR_LOGDBG ("sbr_attach_group_array ok"); + + if (sbr_init_tx_pool () != 0) + { + NSSBR_LOGERR ("init tx pool failed"); + return -1; + } + + NSSBR_LOGDBG ("init tx pool ok"); + + if (sbr_init_app_res () != 0) + { + NSSBR_LOGERR ("sbr_init_app_res failed"); + return -1; + } + + NSSBR_LOGDBG ("sbr_init_app_res ok"); + NSSBR_LOGDBG ("sbr_init_stackx ok"); + return 0; +} + +/***************************************************************************** +* Prototype : sbr_fork_stackx +* Description : init stackx res +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_fork_stackx () +{ + + if (sbr_attach_group_array () != 0) + { + NSSBR_LOGERR ("sbr_attach_group_array failed"); + return -1; + } + + NSSBR_LOGDBG ("sbr_attach_group_array ok"); + + if (sbr_init_tx_pool () != 0) + { + NSSBR_LOGERR ("init tx pool failed"); + return -1; + } + + NSSBR_LOGDBG ("init tx pool ok"); + NSSBR_LOGDBG ("sbr_fork_stackx ok"); + return 0; +} + +/***************************************************************************** +* Prototype : sbr_malloc_conn_for_sk +* Description : malloc netconn for sk,need add pid +* Input : sbr_socket_t* sk +* netconn_type_t type +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_malloc_conn_for_sk (sbr_socket_t * sk, spl_netconn_type_t type) +{ + spl_netconn_t *conn = ss_malloc_conn_app (g_share_group.conn_pool, type); + + if (!conn) + { + NSSBR_LOGERR ("malloc conn failed]fd=%d", sk->fd); + sbr_set_errno (ENOBUFS); + return -1; + } + + NSSBR_LOGINF ("malloc conn ok]fd=%d,conn=%p", sk->fd, conn); + + u16 thread_index = 0; + ss_set_bind_thread_index (conn, thread_index); + ss_set_msg_box (conn, ss_get_instance_msg_box (thread_index, 0)); + + sbr_fd_share *fd_share = (sbr_fd_share *) ((char *) conn + SS_NETCONN_SIZE); + sbr_reset_fd_share (fd_share); + + sk->stack_obj = (void *) conn; + sk->sk_obj = (void *) fd_share; + return 0; +} + +int +sbr_init_conn_for_accept (sbr_socket_t * sk, spl_netconn_t * conn) +{ + if (!conn) + { + sbr_set_sk_errno (sk, ENOBUFS); + return -1; + } + + NSSBR_LOGINF ("accept conn ok]fd=%d,conn=%p,private_data=%p", sk->fd, conn, + conn->private_data); + + if (ss_add_pid (conn, get_sys_pid ()) < 0) + { + NSSBR_LOGERR ("ss_add_pid failed]fd=%d", sk->fd); + } + + ss_set_accept_from (conn, NULL); /* need clear flag */ + + sbr_fd_share *fd_share = (sbr_fd_share *) ((char *) conn + SS_NETCONN_SIZE); + sbr_reset_fd_share (fd_share); + + sk->stack_obj = (void *) conn; + sk->sk_obj = (void *) fd_share; + + return 0; +} + +void +sbr_free_conn_from_sk (sbr_socket_t * sk) +{ + ss_free_conn (sbr_get_conn (sk)); + sk->stack_obj = NULL; + sk->sk_obj = NULL; + NSSBR_LOGDBG ("free conn ok]fd=%d", sk->fd); +} diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h new file mode 100644 index 0000000..73cec7f --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.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 STACKX_RES_MGR_H +#define STACKX_RES_MGR_H +#include "stackx_socket.h" +#include "stackx_ip_tos.h" +#include "stackx_tx_box.h" +#include "stackx_app_res.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +typedef struct +{ + mring_handle conn_pool; + mpool_handle tx_pool; +} sbr_share_group; + +extern sbr_share_group g_share_group; + +static inline mpool_handle +sbr_get_tx_pool () +{ + return g_share_group.tx_pool; +} + +static inline mring_handle +sbr_get_conn_pool () +{ + return (mring_handle) ADDR_LTOSH (g_share_group.conn_pool); +} + +static inline mring_handle +sbr_get_spl_msg_box (sbr_socket_t * sk, u8 tos) +{ + return + ss_get_instance_msg_box (ss_get_bind_thread_index (sbr_get_conn (sk)), + stackx_get_prio (tos)); +} + +int sbr_init_stackx (); +int sbr_fork_stackx (); +int sbr_malloc_conn_for_sk (sbr_socket_t * sk, spl_netconn_type_t type); +int sbr_init_conn_for_accept (sbr_socket_t * sk, spl_netconn_t * conn); +void sbr_free_conn_from_sk (sbr_socket_t * sk); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_socket.h b/stacks/lwip_stack/lwip_src/socket/stackx_socket.h new file mode 100644 index 0000000..e344535 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_socket.h @@ -0,0 +1,141 @@ +/* +* +* 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 STACKX_SOCKET_H +#define STACKX_SOCKET_H +#include "sbr_protocol_api.h" +#include "stackx_spl_share.h" +#include "nstack_log.h" +#include "stackx_pbuf.h" +#include "common_mem_spinlock.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +typedef struct +{ + PRIMARY_ADDR struct spl_pbuf *head; + PRIMARY_ADDR struct spl_pbuf *tail; + int totalLen; +} sbr_recvbuf_recoder; + +/* need fork and recycle */ +typedef struct +{ + common_mem_spinlock_t recv_lock; + common_mem_spinlock_t common_lock; + PRIMARY_ADDR void *lastdata; + u32 lastoffset; + sbr_recvbuf_recoder recoder; + i32 recv_timeout; + i32 send_timeout; + i32 rcvlowat; + int err; + u64 block_polling_time; + i64 extend_member_bit; +} sbr_fd_share; + +/* check sbr_fd_share size */ +SIZE_OF_TYPE_NOT_LARGER_THAN (sbr_fd_share, SBR_FD_SIZE); + +#define sbr_get_fd_share(sk) ((sbr_fd_share*)sk->sk_obj) + +#define sbr_get_conn(sk) ((spl_netconn_t*)sk->stack_obj) + +#define sbr_get_msg_box(sk) ss_get_msg_box(sbr_get_conn(sk)) + +/***************************************************************************** +* Prototype : sbr_set_sk_errno +* Description : set errno for sk +* Input : sbr_socket_t * sk +* int err +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +sbr_set_sk_errno (sbr_socket_t * sk, int err) +{ + sbr_get_fd_share (sk)->err = err; + if (err != 0) + { + if (sbr_get_conn (sk)) + { + NSSBR_LOGERR ("fd=%d,errno=%d,conn=%p,private_data=%p", sk->fd, err, + sbr_get_conn (sk), + ss_get_private_data (sbr_get_conn (sk))); + } + + sbr_set_errno (err); + } +} + +/***************************************************************************** +* Prototype : sbr_set_sk_io_errno +* Description : set errno for sk in send/recv func, in case of too many logs +* Input : sbr_socket_t * sk +* int err +* Output : None +* Return Value : static inline void +* Calls : +* Called By : +* +*****************************************************************************/ +static inline void +sbr_set_sk_io_errno (sbr_socket_t * sk, int err) +{ + sbr_get_fd_share (sk)->err = err; + if (err != 0) + { + if (sbr_get_conn (sk)) + { + NSSBR_LOGDBG ("fd=%d,errno=%d,conn=%p,private_data=%p", sk->fd, err, + sbr_get_conn (sk), + ss_get_private_data (sbr_get_conn (sk))); + } + + sbr_set_errno (err); + } +} + +/***************************************************************************** +* Prototype : sbr_get_sk_errno +* Description : get sk's errno +* Input : sbr_socket_t * sk +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_get_sk_errno (sbr_socket_t * sk) +{ + return sbr_get_fd_share (sk)->err; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c b/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c new file mode 100644 index 0000000..3225c2f --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c @@ -0,0 +1,1698 @@ +/* +* +* 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 "stackx_prot_com.h" +#include "stackx_msg_handler.h" +#include "stackx_pbuf.h" +#include "stackx_epoll_api.h" +#include "nstack_securec.h" +#include "common_pal_bitwide_adjust.h" +#include "common_mem_mbuf.h" +#include "stackx_spl_share.h" +#include "stackx_err.h" +#include "stackx_cfg.h" +#include "spl_opt.h" +//#include "stackx_tcp_sctl.h" +#include "stackx_tcp_opt.h" +//#include "stackx_dfx_api.h" +#include "stackx_spl_msg.h" +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif + +static void +sbr_tcp_init_conn (spl_netconn_t * conn) +{ + conn->tcp_sndbuf = CONN_TCP_MEM_DEF_LINE; + conn->conn_pool = sbr_get_conn_pool (); +} + +/* need close after accept failed */ +static void +sbr_tcp_accept_failed (sbr_socket_t * sk) +{ + (void) sbr_handle_close (sk, 0); + sk->stack_obj = NULL; + sk->sk_obj = NULL; +} + +NSTACK_STATIC int +sbr_tcp_socket (sbr_socket_t * sk, int domain, int type, int protocol) +{ + int err = 0; + + if (sbr_malloc_conn_for_sk (sk, SPL_NETCONN_TCP) != 0) + { + return -1; + } + + sbr_tcp_init_conn (sbr_get_conn (sk)); + + err = sbr_handle_socket (sk, SPL_NETCONN_TCP, 0); + if (0 == err) + { + /* Prevent automatic window updates, we do this on our own! */ + ss_set_noautorecved_flag (sbr_get_conn (sk), 1); + + ss_set_nonblock_flag (sbr_get_conn (sk), (type & O_NONBLOCK)); + + ss_add_recv_event (sbr_get_conn (sk)); + + ss_set_send_event (sbr_get_conn (sk), 1); + + NSSBR_LOGINF ("add write and read events]fd=%d", sk->fd); + + return 0; + } + else + { + sbr_free_conn_from_sk (sk); + return err; + } +} + +NSTACK_STATIC int +sbr_tcp_bind (sbr_socket_t * sk, const struct sockaddr *name, + socklen_t namelen) +{ + const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; + NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, + spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), + sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); + spl_ip_addr_t local_addr; + inet_addr_to_ipaddr (&local_addr, &addr_in->sin_addr); + u16 local_port = addr_in->sin_port; + return sbr_handle_bind (sk, &local_addr, ntohs (local_port)); +} + +NSTACK_STATIC int +sbr_tcp_listen (sbr_socket_t * sk, int backlog) +{ + ss_set_is_listen_conn (sbr_get_conn (sk), 1); + return sbr_handle_listen (sk, backlog); +} + +static inline int +sbr_tcp_recv_is_timeout (sbr_socket_t * sk, struct timespec *starttm) +{ + struct timespec currtm; + i64 timediff_ms, timediff_sec; + i64 timeout_thr_ms, timeout_thr_sec; + + timeout_thr_ms = sbr_get_fd_share (sk)->recv_timeout; + if (0 == timeout_thr_ms) + { + return ERR_OK; + } + + timeout_thr_sec = (i64) (timeout_thr_ms / 1000); + + /* Handle system time change side-effects */ + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &currtm))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + + timediff_sec = currtm.tv_sec - starttm->tv_sec; + if (timediff_sec >= timeout_thr_sec) + { + timediff_ms = currtm.tv_nsec > starttm->tv_nsec ? + (timediff_sec * 1000) + (currtm.tv_nsec - + starttm->tv_nsec) / + USEC_TO_SEC : (timediff_sec * 1000) - + ((starttm->tv_nsec - currtm.tv_nsec) / USEC_TO_SEC); + + /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value + will be negetive if still 0.5 ms is not elapsed. this is intended and we should + not typecast to any unsigned type during this below if check */ + if (timediff_ms > timeout_thr_ms) + { + sbr_set_sk_errno (sk, ETIMEDOUT); + return ETIMEDOUT; + } + } + + return ERR_OK; +} + +static inline int +sbr_tcp_wait_new_conn (sbr_socket_t * sk, void **new_buf) +{ + int ret = 0; + int elem_num; + u32 timeout_thr_sec; + struct timespec starttm = { 0, 0 }; + unsigned int retry_count = 0; + mring_handle ring = NULL; + +#define FAST_SLEEP_TIME 10000 +#define SLOW_SLEEP_TIME 500000 +#define FAST_RETRY_COUNT 100 + + ring = ss_get_recv_ring (sbr_get_conn (sk)); //clear codeDEX warning , CID:24284 + timeout_thr_sec = sbr_get_fd_share (sk)->recv_timeout / 1000; + if (0 != timeout_thr_sec) + { + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + } + + while (1) + { + if (ss_is_shut_rd (sbr_get_conn (sk))) + { + sbr_set_sk_errno (sk, EINVAL); + ret = EINVAL; + break; + } + + elem_num = nsfw_mem_ring_dequeue (ring, new_buf); + if (1 == elem_num) + { + break; + } + else if (0 == elem_num) + { + ret = sbr_tcp_recv_is_timeout (sk, &starttm); + if (0 != ret) + { + break; + } + + /* reduce CPU usage in blocking mode- Begin */ + if (retry_count < FAST_RETRY_COUNT) + { + sys_sleep_ns (0, FAST_SLEEP_TIME); + retry_count++; + } + else + { + sys_sleep_ns (0, sbr_get_fd_share (sk)->block_polling_time); + } + + continue; + } + else + { + sbr_set_sk_errno (sk, EINVAL); + ret = EINVAL; + break; + } + } + + return ret; +} + +NSTACK_STATIC inline int +sbr_tcp_get_sockaddr (sbr_socket_t * sk, struct sockaddr *addr, + socklen_t * addrlen) +{ + int ret; + spl_netconn_t *conn = sbr_get_conn (sk); + + ret = (addr + && addrlen) ? sbr_get_sockaddr_and_len (ss_get_remote_port (conn), + ss_get_remote_ip (conn), + addr, addrlen) : 0; + if (0 != ret) + { + sbr_set_sk_io_errno (sk, EINVAL); + NSSBR_LOGERR ("sbr_tcp_get_sockaddr]fd=%d", sk->fd); + return -1; + } + + return 0; +} + +static int +sbr_tcp_accept_socket (sbr_socket_t * sk, sbr_socket_t * new_sk, + struct sockaddr *addr, socklen_t * addrlen) +{ + int err; + spl_netconn_t *newconn = NULL; + + err = sbr_tcp_wait_new_conn (sk, (void **) &newconn); + if (ERR_OK != err) + { + return err; + } + + err = sbr_init_conn_for_accept (new_sk, newconn); + if (ERR_OK != err) + { + /*When conn is null, return err; then do not need to free conn */ + return err; + } + + err = sbr_tcp_get_sockaddr (new_sk, addr, addrlen); + if (ERR_OK != err) + { + NSSBR_LOGERR ("sbr_get_sockaddr_and_socklen]ret=%d.", err); + sbr_tcp_accept_failed (new_sk); + return -1; + } + + NSSBR_LOGINF + ("return]listen fd=%d,listen conn=%p,listen private_data=%p,accept fd=%d,accept conn=%p,accept private_data=%p", + sk->fd, sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk)), + new_sk->fd, sbr_get_conn (new_sk), + ss_get_private_data (sbr_get_conn (new_sk))); + + //ip_addr_info_print(SOCKETS_DEBUG, &sbr_get_conn(new_sk)->share_remote_ip); + + /* test_epollCtl_003_001: Accept a conn. Add epoll_ctl with IN event and + send a msg from peer. The event will be given once epoll_wait is called. + Now, modify to IN|OUT. Calling epoll_event should return immediately since + the socket is writable. Currently, returns 0 events. + This issue is fixed here + */ + + /* Prevent automatic window updates, we do this on our own! */ + ss_set_noautorecved_flag (sbr_get_conn (new_sk), 1); + + ss_set_send_event (sbr_get_conn (new_sk), 1); + + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +} + +NSTACK_STATIC int +sbr_tcp_accept (sbr_socket_t * sk, sbr_socket_t * new_sk, + struct sockaddr *addr, socklen_t * addrlen) +{ + int err; + + /* If conn is not in listen state then return failure with error code: EINVAL(22) */ + if (!ss_is_listen_state (sbr_get_conn (sk))) + { + NSSBR_LOGERR ("fd is not listening for connections]fd=%d,err=%d", + sk->fd, EINVAL); + sbr_set_sk_errno (sk, EINVAL); + + return -1; + } + + if (ss_is_nonblock_flag (sbr_get_conn (sk)) + && (0 >= ss_get_recv_event (sbr_get_conn (sk)))) + { + NSSBR_LOGERR ("fd is nonblocking and rcvevent<=0]fd=%d,err=%d", sk->fd, + EWOULDBLOCK); + sbr_set_sk_errno (sk, EWOULDBLOCK); + + return -1; + } + + err = ss_get_last_errno (sbr_get_conn (sk)); + if (SPL_ERR_IS_FATAL (err)) + { + /* don't recv on fatal errors: this might block the application task + waiting on acceptmbox forever! */ + sbr_set_sk_errno (sk, sbr_spl_err_to_errno (err)); + + return -1; + } + + /* wait for a new connection */ + err = sbr_tcp_accept_socket (sk, new_sk, addr, addrlen); + if (ERR_OK != err) + { + NSSBR_LOGERR ("sbr_tcp_accept_socket failed]fd=%d,err=%d", sk->fd, err); + + return -1; + } + + /* Prevent automatic window updates, we do this on our own! */ + ss_sub_recv_event (sbr_get_conn (sk)); + + sbr_set_sk_errno (sk, ERR_OK); + + /* test_epollCtl_003_001: Accept a conn. Add epoll_ctl with IN event and + send a msg from peer. The event will be given once epoll_wait is called. + Now, modify to IN|OUT. Calling epoll_event should return immediately since + the socket is writable. Currently, returns 0 events. + This issue is fixed here + */ + + ss_set_send_event (sbr_get_conn (new_sk), 1); + + return new_sk->fd; +} + +NSTACK_STATIC int +sbr_tcp_accept4 (sbr_socket_t * sk, sbr_socket_t * new_sk, + struct sockaddr *addr, socklen_t * addrlen, int flags) +{ + int fd = sbr_tcp_accept (sk, new_sk, addr, addrlen); + + if (0 > fd) + { + return fd; + } + + if (flags & O_NONBLOCK) + { + int opts = new_sk->fdopt->fcntl (new_sk, F_GETFL, 0); + if (opts < 0) + { + NSSBR_LOGERR ("sbr_tcp_fcntl(sock,GETFL)"); + sbr_tcp_accept_failed (new_sk); + return -1; + } + + opts = opts | O_NONBLOCK; + + if (new_sk->fdopt->fcntl (new_sk, F_SETFL, opts) < 0) + + { + NSSBR_LOGERR ("sbr_tcp_fcntl(sock,F_SETFL,opts)"); + sbr_tcp_accept_failed (new_sk); + return -1; + } + } + + return new_sk->fd; +} + +NSTACK_STATIC int +sbr_tcp_connect (sbr_socket_t * sk, const struct sockaddr *name, + socklen_t namelen) +{ + const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; + + NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, + spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), + sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); + spl_ip_addr_t remote_addr; + + inet_addr_to_ipaddr (&remote_addr, &addr_in->sin_addr); + u16 remote_port = addr_in->sin_port; + + spl_ip_addr_t local_addr; + if (IPADDR_ANY == ss_get_local_ip (sbr_get_conn (sk))->addr) + { + if (sbr_get_src_ip (remote_addr.addr, &local_addr.addr) != 0) + { + sbr_set_sk_errno (sk, EHOSTUNREACH); + NSSBR_LOGERR ("get src ip failed]fd=%d", sk->fd); + return -1; + } + } + + if (sbr_handle_connect (sk, &remote_addr, ntohs (remote_port), &local_addr) + != 0) + { + NSSBR_LOGERR ("fail]fd=%d", sk->fd); + return -1; + } + + if (ss_is_shut_rd (sbr_get_conn (sk))) + { + NSSBR_LOGERR ("shut_rd]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ECONNRESET); + return -1; + } + + NSSBR_LOGINF ("succeeded]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ERR_OK); + + return 0; +} + +static u8 netconn_shutdown_opt[] = { + SPL_NETCONN_SHUT_RD, + SPL_NETCONN_SHUT_WR, + SPL_NETCONN_SHUT_RDWR +}; + +NSTACK_STATIC int +sbr_tcp_shutdown (sbr_socket_t * sk, int how) +{ + err_t err; + + if (ss_is_listen_state (sbr_get_conn (sk))) + { + return 0; + } + + ss_set_shut_status (sbr_get_conn (sk), how); + + err = sbr_handle_shutdown (sk, netconn_shutdown_opt[how]); + + return (err == ERR_OK ? 0 : -1); +} + +NSTACK_STATIC int +sbr_tcp_getsockname (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen) +{ + + NSSBR_LOGINF ("sockname]fd=%d,tcp_state=%d", sk->fd, + ss_get_tcp_state (sbr_get_conn (sk))); + + return sbr_handle_get_name (sk, name, namelen, SBR_GET_SOCK_NAME); +} + +NSTACK_STATIC int +sbr_tcp_getpeername (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen) +{ + + if (SPL_CLOSED == ss_get_tcp_state (sbr_get_conn (sk))) + { + NSSBR_LOGERR ("connection not exist]fd=%d", sk->fd); + sbr_set_sk_errno (sk, ENOTCONN); + return -1; + } + + NSSBR_LOGINF ("peername]fd=%d,tcp_state=%d", sk->fd, + ss_get_tcp_state (sbr_get_conn (sk))); + + return sbr_handle_get_name (sk, name, namelen, SBR_GET_PEER_NAME); +} + +static int +sbr_getsockopt_ipproto_tcp (int optname, void *optval, socklen_t optlen) +{ + int err = ERR_OK; + + switch (optname) + { + case SPL_TCP_NODELAY: + break; + case SPL_TCP_KEEPIDLE: + case SPL_TCP_KEEPINTVL: + case SPL_TCP_KEEPCNT: + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +NSTACK_STATIC int inline +sbr_tcp_set_sockopt_err (sbr_socket_t * sk, int err) +{ + if (ENOPROTOOPT == err) + { + return 0; + } + else + { + sbr_set_sk_errno (sk, err); + return -1; + } +} + +NSTACK_STATIC int inline +sbr_tcp_get_sockopt_err (sbr_socket_t * sk, int err) +{ + sbr_set_sk_errno (sk, err); + return -1; +} + +NSTACK_STATIC int +sbr_tcp_getsockopt (sbr_socket_t * sk, int level, int optname, void *optval, + socklen_t * optlen) +{ + int err = 0; + + switch (level) + { + case SOL_SOCKET: + err = sbr_getsockopt_sol_socket (sk, optname, optval, *optlen); + break; + + case IPPROTO_IP: + err = sbr_getsockopt_ipproto_ip (optname, optval, *optlen); + break; + + case IPPROTO_TCP: + err = sbr_getsockopt_ipproto_tcp (optname, optval, *optlen); + break; + + case NSTACK_SOCKOPT: + if ((optname == NSTACK_SEM_SLEEP) || (*optlen < sizeof (u32_t))) + { + *(u32_t *) optval = + sbr_get_fd_share (sk)->block_polling_time / 1000; + NSSOC_LOGINF + ("tcp get recv sleep time success, usleep time = %d,fd = %d", + sbr_get_fd_share (sk)->block_polling_time, sk->fd); + return ERR_OK; + } + else + { + NSSOC_LOGINF ("get recv sleep time failed, fd = %d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + default: + err = ENOPROTOOPT; + break; + } + + if (0 != err) + { + NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, + optname, err); + /* for option not support ,getsockopt() should return fail */ + return sbr_tcp_get_sockopt_err (sk, err); + } + + return sbr_handle_getsockopt (sk, level, optname, optval, optlen); +} + +int +sbr_setsockopt_ipproto_tcp (int optname, socklen_t optlen) +{ + int err = 0; + + if (optlen < sizeof (int)) + { + return EINVAL; + } + + switch (optname) + { + case SPL_TCP_KEEPIDLE: + case SPL_TCP_KEEPINTVL: + case SPL_TCP_KEEPCNT: + break; + default: + err = ENOPROTOOPT; + break; + } + + return err; +} + +NSTACK_STATIC int +sbr_tcp_setsockopt (sbr_socket_t * sk, int level, int optname, + const void *optval, socklen_t optlen) +{ + int err = 0; + + switch (level) + { + case SOL_SOCKET: + err = + sbr_setsockopt_sol_socket (sk, optname, optval, optlen, + SPL_NETCONN_TCP); + break; + case IPPROTO_IP: + err = + sbr_setsockopt_ipproto_ip (optname, optval, optlen, SPL_NETCONN_TCP); + break; + case IPPROTO_TCP: + err = sbr_setsockopt_ipproto_tcp (optname, optlen); + break; + case NSTACK_SOCKOPT: + { + u32_t sleep_time = *(u32_t *) optval; + /*sleep time should less than 1s */ + if ((optname == NSTACK_SEM_SLEEP) && (optlen >= sizeof (u32_t)) + && (sleep_time < 1000000)) + { + sbr_get_fd_share (sk)->block_polling_time = sleep_time * 1000; + NSSOC_LOGINF + ("tcp set recv sleep time success, usleep time = %d,fd = %d", + sbr_get_fd_share (sk)->block_polling_time, sk->fd); + return ERR_OK; + } + else + { + NSSOC_LOGINF ("set recv sleep time failed, fd = %d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + } + + default: + err = ENOPROTOOPT; + break; + } + + if (0 != err) + { + NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, + optname, err); + + return sbr_tcp_set_sockopt_err (sk, err); + } + + return sbr_handle_setsockopt (sk, level, optname, optval, optlen); +} + +static inline u16 +sbr_tcp_mbuf_count (struct spl_pbuf *p) +{ + u16 count = 0; + struct spl_pbuf *buf = p; + struct common_mem_mbuf *mbuf; + + while (buf) + { + mbuf = + (struct common_mem_mbuf *) ((char *) buf - + sizeof (struct common_mem_mbuf)); + while (mbuf) + { + count++; +#ifdef HAL_LIB +#else + mbuf = mbuf->next; +#endif + } + + buf = (struct spl_pbuf *) ADDR_SHTOL (buf->next_a); + } + + return count; +} + +static inline void +sbr_tcp_free_recvbuf (sbr_socket_t * sk, struct spl_pbuf *p) +{ + int len; + + if (ss_is_noautorecved_flag (sbr_get_conn (sk))) + { + len = sbr_tcp_mbuf_count (p); + sbr_handle_tcp_recv (sk, len, p); + } +} + +static inline void +sbr_tcp_recv_no_peak (sbr_socket_t * sk, struct spl_pbuf *buf, u32 buflen, + u32 copylen) +{ + if ((buflen - copylen) > 0) + { + sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf); + sbr_get_fd_share (sk)->lastoffset += copylen; + } + else + { + sbr_get_fd_share (sk)->lastdata = 0; + sbr_get_fd_share (sk)->lastoffset = 0; + sbr_tcp_free_recvbuf (sk, buf); + } +} + +static inline int +sbr_tcp_recv_from_ring (sbr_socket_t * sk, struct spl_pbuf **buf, i32 timeout) +{ + int err; + spl_netconn_t *conn = sbr_get_conn (sk); + + err = ss_get_last_errno (conn); + if (SPL_ERR_IS_FATAL (err)) + { + /* don't recv on fatal errors: this might block the application task + waiting on recvmbox forever! */ + + /* @todo: this does not allow us to fetch data that has been put into recvmbox + before the fatal error occurred - is that a problem? */ + NSSBR_LOGDBG ("last err when recv:]=%d", err); + if (ERR_CLSD != err) + { + sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err)); + return -1; + } + } + + *buf = NULL; + if (0 != sbr_dequeue_buf (sk, (void **) buf, timeout)) + { + return -1; + } + + ss_sub_recv_avail (sbr_get_conn (sk), (*buf)->tot_len); + + ss_sub_recv_event (sbr_get_conn (sk)); + + return 0; +} + +static inline int +sbr_tcp_recv_state_check (sbr_socket_t * sk) +{ + + spl_tcp_state_t state = ss_get_tcp_state (sbr_get_conn (sk)); + + NSSBR_LOGDBG ("tcp state when recv:]=%d", state); + + //close_wait state also can recive data + //no connect cannot recive data + if (SPL_ESTABLISHED > state) + { + if (SPL_SHUT_WR != ss_get_shut_status (sbr_get_conn (sk))) + { + /* after all data retrnasmission, connection is active */ + /* patch solution as last_err is not maintained properly */ + if ((SPL_CLOSED == state) + && (ERR_TIMEOUT == ss_get_last_errno (sbr_get_conn (sk)))) + { + sbr_set_sk_io_errno (sk, ETIMEDOUT); + } + else if ((SPL_CLOSED == state) + && (ERR_RST == ss_get_last_errno (sbr_get_conn (sk)))) + { + sbr_set_sk_io_errno (sk, ECONNRESET); + } + else + { + sbr_set_sk_io_errno (sk, ENOTCONN); + } + + return -1; + } + } + + return 0; +} + +NSTACK_STATIC int +sbr_tcp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t * fromlen) +{ + struct spl_pbuf *p; + u32 buflen; + u32 copylen; + u32 off = 0; + u8 done = 0; + int para_len = len; + int retval = 0; + + sbr_com_lock_recv (sk); + NSSOC_LOGINF ("recv start, fd = %d last data %p flags to be set %d", sk->fd, + ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata), MSG_DONTWAIT); + + if (0 != sbr_tcp_recv_state_check (sk)) + { + retval = -1; + goto sbr_tcp_recvfrom_exit; + } + + do + { + if (sbr_get_fd_share (sk)->lastdata) + { + p = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + } + else + { + if ((flags & MSG_DONTWAIT) + || ss_is_nonblock_flag (sbr_get_conn (sk))) + { + NSSOC_LOGINF ("call ss_get_recv_event"); + if (0 >= ss_get_recv_event (sbr_get_conn (sk))) + { + NSSOC_LOGINF ("no recv event]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + retval = -1; + goto sbr_tcp_recvfrom_exit; + } + } + + if (0 != + sbr_tcp_recv_from_ring (sk, &p, + sbr_get_fd_share (sk)->recv_timeout)) + { + /* already received data, return that */ + if (off > 0) + { + sbr_set_sk_io_errno (sk, ERR_OK); + retval = off; + goto sbr_tcp_recvfrom_exit; + } + + /* we tell the user the connection is closed by returning zero */ + if (sbr_get_sk_errno (sk) == ENOTCONN) + { + retval = 0; + goto sbr_tcp_recvfrom_exit; + } + + retval = -1; + goto sbr_tcp_recvfrom_exit; + } + + sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (p); + } + + buflen = p->tot_len - sbr_get_fd_share (sk)->lastoffset; + copylen = len > buflen ? buflen : len; + + if ((copylen > 0) + && 0 == spl_pbuf_copy_partial (p, (u8 *) mem + off, copylen, + sbr_get_fd_share (sk)->lastoffset)) + { + NSSBR_LOGERR ("copy failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EFAULT); + retval = -1; + goto sbr_tcp_recvfrom_exit; + } + + off += copylen; + + len -= copylen; + + if ((len == 0) || (ss_get_recv_event (sbr_get_conn (sk)) <= 0) + || ((flags & MSG_PEEK) != 0)) + { + if ((off >= sbr_get_fd_share (sk)->rcvlowat) + || (para_len <= sbr_get_fd_share (sk)->rcvlowat)) + { + done = 1; + } + } + + if (done) + { + if (sbr_tcp_get_sockaddr (sk, from, fromlen) != 0) + { + retval = -1; + goto sbr_tcp_recvfrom_exit; + } + } + + /* If this is a TCP socket, check if there is data left in the buffer, + If so, it should be saved in the sock structure for next time around. */ + if (!(flags & MSG_PEEK)) + { + sbr_tcp_recv_no_peak (sk, p, buflen, copylen); + } + } + while (!done); + + retval = off; + + NSSOC_LOGINF ("recv done, fd = %d last data %p", sk->fd); +sbr_tcp_recvfrom_exit: + + NSSOC_LOGINF ("recv exit, fd = %d last data %p", sk->fd); + sbr_com_unlock_recv (sk); + return retval; +} + +/***************************************************************************** +* Prototype : sbr_tcp_recvdata +* Description : recvdata +* Input : sbr_socket_t* sk +* const struct iovec* iov +* int iovcnt +* int flags +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_tcp_recvdata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) +{ + int max = SBR_MAX_INTEGER; + int len = 0; + int ret = 0; + int i = 0; + + do + { + len += ret; + + if (!iov[i].iov_base || (0 == iov[i].iov_len)) + { + ret = 0; + continue; + } + + ret = sbr_tcp_recvfrom (sk, (char *) iov[i].iov_base, iov[i].iov_len, 0, + NULL, NULL); + } + while ((ret == (int) iov[i].iov_len) && (iovcnt > (++i)) + && (max - len - ret > (int) iov[i].iov_len)); + + if (len == 0) + { + return ret; + } + else + { + return (ret == -1 ? len : len + ret); + } +} + +/***************************************************************************** +* Prototype : sbr_tcp_readv +* Description : readv +* Input : sbr_socket_t* sk +* const struct iovec* iov +* int iovcnt +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_tcp_readv (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) +{ + return sbr_tcp_recvdata (sk, iov, iovcnt); +} + +/***************************************************************************** +* Prototype : sbr_tcp_recvmsg +* Description : recvmsg,unsupport flags +* Input : sbr_socket_t* sk +* struct msghdr* msg +* int flags +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_tcp_recvmsg (sbr_socket_t * sk, struct msghdr *msg, int flags) +{ + if (sbr_tcp_get_sockaddr + (sk, (struct sockaddr *) msg->msg_name, &msg->msg_namelen) != 0) + { + return -1; + } + + return sbr_tcp_recvdata (sk, msg->msg_iov, msg->msg_iovlen); +} + +static int +sbr_tcp_send_is_timeout (sbr_socket_t * sk, struct timespec *starttm) +{ + struct timespec currtm; + i64 timediff_ms, timediff_sec; + i64 timeout_thr_ms, timeout_thr_sec; + + timeout_thr_ms = sbr_get_fd_share (sk)->send_timeout; + if (0 == timeout_thr_ms) + { + return 0; + } + + /* it is possible that starttm don't be inited, + if send_timeout is change when this write function is running */ + timeout_thr_sec = (timeout_thr_ms + 240) >> 10; + + /* Handle system time change side-effects */ + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &currtm))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + + timediff_sec = currtm.tv_sec - starttm->tv_sec; + if (timediff_sec >= timeout_thr_sec) + { + timediff_ms = currtm.tv_nsec > starttm->tv_nsec ? + (timediff_sec * 1000) + (currtm.tv_nsec - + starttm->tv_nsec) / + USEC_TO_SEC : (timediff_sec * 1000) - + ((starttm->tv_nsec - currtm.tv_nsec) / USEC_TO_SEC); + + /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value + will be negetive if still 0.5 ms is not elapsed. this is intended and we should + not typecast to any unsigned type during this below if check */ + if (timediff_ms > timeout_thr_ms) + { + return 1; + } + } + + return 0; +} + +static inline int +sbr_tcp_write_is_wait (sbr_socket_t * sk, struct timespec *starttm, + int noneblockFlg) +{ + if (noneblockFlg || sbr_tcp_send_is_timeout (sk, starttm)) + { + return 0; + } + else + { + return 1; + } +} + +static struct spl_pbuf * +sbr_tcp_write_alloc_buf (sbr_socket_t * sk, size_t seglen, u8 api_flag, + struct timespec *starttm, u8 * errno_flag) +{ + spl_netconn_t *conn = sbr_get_conn (sk); + + struct spl_pbuf *curr_buf = NULL; + size_t head_len = SPL_TCP_HLEN + SPL_PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN; + int noneblockFlg = (api_flag & SPL_NETCONN_DONTBLOCK) + || ss_is_nonblock_flag (sbr_get_conn (sk)); + + do + { + /* When packages are lost more than TCP_MAXRTX times, + * conn will be closed and pcb will be removed. */ + if (ss_get_tcp_state (conn) == SPL_CLOSED) + { + NSSBR_LOGERR ("pcb SPL_CLOSED]conn=%p", conn); + sbr_set_sk_io_errno (sk, ECONNABORTED); + /* Must set errno_flag when set errno, to avoid errnno overwritten by sbr_tcp_write */ + *errno_flag = 1; + return NULL; + } + + curr_buf = sbr_malloc_tx_pbuf (seglen + head_len, head_len); + if (NULL == curr_buf) + { + if (!sbr_tcp_write_is_wait (sk, starttm, noneblockFlg)) + { + return NULL; + } + + int err = ss_get_last_errno (sbr_get_conn (sk)); + if (SPL_ERR_IS_FATAL (err)) + { + NSSBR_LOGERR ("connection fatal error!err=%d", err); + sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err)); + *errno_flag = 1; + return NULL; + } + + sched_yield (); + } + } + while (curr_buf == NULL); + + return curr_buf; +} + +static inline void +sbr_tcp_write_rel_buf (sbr_socket_t * sk, struct spl_pbuf *buf, + u32 thread_index) +{ + if (buf != NULL) + { + sbr_handle_free_send_buf (sk, buf); + } +} + +static inline int +sbr_tcp_write_fill_buf (const void *data, size_t * pos, + struct spl_pbuf *seg_buf, size_t seglen, + size_t optlen) +{ + size_t start = *pos; + size_t copy = seglen; + struct spl_pbuf *first = seg_buf; + + while ((0 < copy) && (NULL != first)) + { + char *dst_ptr = PTR_SHTOL (char *, first->payload_a) + optlen; + + if (NULL == + common_memcpy (dst_ptr, (u8_t *) data + start, first->len - optlen)) + { + NSSBR_LOGERR ("common_memcpy error]dst=%p,src=%p,len=%u", + dst_ptr, (u8_t *) data + start, first->len); + return -1; + } + + start += (first->len - optlen); + copy -= (first->len - optlen); + first = ADDR_SHTOL (first->next_a); + } + + (*pos) = start; + + return 0; +} + +static inline int +sbr_tcp_writev_fill_buf (const struct iovec *iov, size_t * iov_pos, + int *iov_var, size_t * pos, struct spl_pbuf *seg_buf, + size_t seglen, size_t optlen) +{ + size_t valid_copy_len; + size_t iov_data_left; + + size_t copy = seglen; + size_t start = *pos; + size_t current_iov_pos = *iov_pos; + int current_iov_var = *iov_var; + + u32 pbuf_offset = optlen; + u32 pbuf_data_len; + struct spl_pbuf *first = seg_buf; + + while ((0 < copy) && (NULL != first)) + { + iov_data_left = iov[current_iov_var].iov_len - current_iov_pos; + if (seglen == copy) + { + pbuf_offset = optlen; + } + + pbuf_data_len = first->len - pbuf_offset; + valid_copy_len = + (iov_data_left > pbuf_data_len ? pbuf_data_len : iov_data_left); + if (NULL == + common_memcpy ((char *) ADDR_SHTOL (first->payload_a) + pbuf_offset, + (u8_t *) iov[current_iov_var].iov_base + + current_iov_pos, valid_copy_len)) + { + NSSBR_LOGERR + ("common_memcpy error]current_iov_var=%d, dst=%p,src=%p,len=%zu", + current_iov_var, + (char *) ADDR_SHTOL (first->payload_a) + pbuf_offset, + (u8_t *) iov[current_iov_var].iov_base + current_iov_pos, + valid_copy_len); + return -1; + } + + start += valid_copy_len; + copy -= valid_copy_len; + + if (iov_data_left == pbuf_data_len) + { + first = PTR_SHTOL (struct spl_pbuf *, first->next_a); + pbuf_offset = optlen; //+= valid_copy_len; + current_iov_var++; + current_iov_pos = 0; + } + else if (iov_data_left > pbuf_data_len) + { + first = PTR_SHTOL (struct spl_pbuf *, first->next_a); + pbuf_offset = optlen; //+= valid_copy_len; + current_iov_pos += valid_copy_len; + } + else + { + pbuf_offset += valid_copy_len; + + current_iov_var++; + current_iov_pos = 0; + } + } + + *iov_pos = current_iov_pos; + *iov_var = current_iov_var; + *pos = start; + + return 0; +} + +static inline void +sbr_tcp_write_add_buf_to_list (struct spl_pbuf **p_head, + struct spl_pbuf **p_tail, + struct spl_pbuf *seg_buf, size_t seglen, + size_t optlen) +{ + seg_buf->len = seglen + optlen; + seg_buf->tot_len = seglen + optlen; + seg_buf->next_a = 0; + + /*put seg_buf after p_head */ + if (NULL == (*p_head)) + { + (*p_head) = seg_buf; + (*p_tail) = seg_buf; + } + else + { + (*p_tail)->next_a = ADDR_LTOSH (seg_buf); + (*p_tail) = seg_buf; + } +} + +NSTACK_STATIC int +sbr_tcp_write (sbr_socket_t * sk, const void *data, size_t size, u8 api_flag, + size_t * written) +{ + err_t err = -1; + size_t pos = 0, left, seglen; + u32 pbuf_seg_cnt = 0; + u32 thread_index = 0; + struct spl_pbuf *seg_buf = NULL; + struct spl_pbuf *p_head = NULL; + struct spl_pbuf *p_tail = p_head; + struct spl_netconn *conn = sbr_get_conn (sk); + u32 mss = ss_get_mss (sbr_get_conn (sk)); + + if (0 == size) + { + NSSBR_LOGERR ("fd=%d,size=%u", sk->fd, (u32) size); + return 0; + } + + struct timespec ts; + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &ts))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + + while (pos < size) + { + left = size - pos; + seglen = left > mss ? mss : left; + u8 errno_set = 0; + seg_buf = + sbr_tcp_write_alloc_buf (sk, seglen, api_flag, &ts, &errno_set); + if (NULL == seg_buf) + { + NSSBR_LOGINF ("sbr_tcp_write_alloc_buf failed......"); + if (NULL != p_head) + { + err = sbr_handle_tcp_send (sk, size, p_head, api_flag); + if (ERR_OK != err) + { + NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err); + goto err_ref_buf; + } + } + + if (0 == pos) + { + /* If errno is already set in sbr_tcp_write_alloc_buf, do not overwrite here */ + if (!errno_set) + { + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + } + return -1; + } + + NSSBR_LOGDBG ("sent size %zu", pos); + *written = pos; + + return ERR_OK; + } + + if (0 != sbr_tcp_write_fill_buf (data, &pos, seg_buf, seglen, 0)) + { + sbr_set_sk_io_errno (sk, EFAULT); + NSSBR_LOGERR ("sbr_tcp_write_fill_buf error]"); + goto err_ref_buf; + } + + sbr_tcp_write_add_buf_to_list (&p_head, &p_tail, seg_buf, seglen, 0); + + ++pbuf_seg_cnt; + if (p_head + && ((SPL_TCP_SEND_MAX_SEG_PER_MSG <= pbuf_seg_cnt) + || (pos >= size))) + { + pbuf_seg_cnt = 0; + err = sbr_handle_tcp_send (sk, size, p_head, api_flag); + if (ERR_OK != err) + { + NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err); + goto err_ref_buf; + } + + p_head = NULL; + } + } + + *written = size; + + (void) conn; + return ERR_OK; + +err_ref_buf: + sbr_tcp_write_rel_buf (sk, p_head, thread_index); + (void) conn; + return -1; +} + +NSTACK_STATIC int +sbr_tcp_writev (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) +{ + err_t err = -1; + int idx = 0; + size_t pos = 0, left, seglen, optlen = 0; + u32 pbuf_seg_cnt = 0; + u32 thread_index = 0; + size_t size = 0; + size_t iov_pos = 0; + int iov_var = 0; + struct spl_pbuf *seg_buf = NULL; + struct spl_pbuf *p_head = NULL; + struct spl_pbuf *p_tail = p_head; + struct spl_netconn *conn = sbr_get_conn (sk); + u32 mss = ss_get_mss (sbr_get_conn (sk)); + + if (mss <= optlen) + { + NSSBR_LOGERR ("mss invalid]mss=%u,optlen=%zu,fd=%d", mss, optlen, + sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + + /* mss dose't include the tcp options length */ + mss -= optlen; + + while (idx < iovcnt) + { + if (SBR_MAX_INTEGER - iov[idx].iov_len <= size) + { + size = SBR_MAX_INTEGER; + break; + } + + size += iov[idx].iov_len; + idx++; + } + + struct timespec starttm; + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm))) + { + NSSBR_LOGERR ("Failed to get time, errno = %d", errno); + } + + while (pos < size) + { + left = size - pos; + + seglen = left > mss ? mss : left; + u8 errno_set = 0; + seg_buf = + sbr_tcp_write_alloc_buf (sk, seglen + optlen, SPL_NETCONN_COPY, + &starttm, &errno_set); + if (NULL == seg_buf) + { + if (NULL != p_head) + { + err = sbr_handle_tcp_send (sk, size, p_head, SPL_NETCONN_COPY); + /*If errno is already set in sbr_tcp_write_alloc_buf, do not overwrite here */ + if (err != ERR_OK) + { + NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err); + goto err_ref_buf; + } + } + + /* [Start] + 1)Set SO_SNDTIMEO to 10 + 2)Send a msg of larger buff size.and let the timeout happen for send (dont receive at peer side.) + 3)iRet will be 0 and errno received will be 11 (EAGAIN). + + Above issue is fixed. + */ + if (0 == pos) + { + if (!errno_set) + { + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + } + return -1; + } + /* [End] */ + + NSSBR_LOGDBG ("sent size %zu", pos); + + return pos; + } + + if (0 != + sbr_tcp_writev_fill_buf (iov, &iov_pos, &iov_var, &pos, seg_buf, + seglen, optlen)) + { + sbr_set_sk_io_errno (sk, EFAULT); + NSSBR_LOGERR ("sbr_tcp_writev_fill_buf error]"); + goto err_ref_buf; + } + + sbr_tcp_write_add_buf_to_list (&p_head, &p_tail, seg_buf, seglen, + optlen); + + /* @todo: for non-blocking write, check if 'size' would ever fit into + snd_queue or snd_buf */ + ++pbuf_seg_cnt; + if (p_head + && ((SPL_TCP_SEND_MAX_SEG_PER_MSG <= pbuf_seg_cnt) + || (pos >= size))) + { + pbuf_seg_cnt = 0; + err = sbr_handle_tcp_send (sk, size, p_head, SPL_NETCONN_COPY); + if (ERR_OK != err) + { + NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err); + goto err_ref_buf; + } + + p_head = NULL; + } + } + (void) conn; + return size; + +err_ref_buf: + sbr_tcp_write_rel_buf (sk, p_head, thread_index); + (void) conn; + return -1; +} + +NSTACK_STATIC int +sbr_tcp_sendto (sbr_socket_t * sk, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + return sk->fdopt->send (sk, data, size, flags); +} + +static inline int +sbr_tcp_send_state_check (sbr_socket_t * sk) +{ + if ((SPL_SHUT_WR == ss_get_shut_status (sbr_get_conn (sk))) + || (SPL_SHUT_RDWR == ss_get_shut_status (sbr_get_conn (sk)))) + { + sbr_set_sk_io_errno (sk, EPIPE); + return -1; + } + + spl_tcp_state_t state = ss_get_tcp_state (sbr_get_conn (sk)); + if ((SPL_ESTABLISHED != state) && (SPL_CLOSE_WAIT != state)) + { + /* after all data retrnasmission, connection is active */ + /* patch solution as last_err is not maintained properly */ + if ((SPL_CLOSED == state) + && (ERR_TIMEOUT == ss_get_last_errno (sbr_get_conn (sk)))) + { + sbr_set_sk_io_errno (sk, ETIMEDOUT); + } + else if ((SPL_CLOSED == state) + && (ERR_RST == ss_get_last_errno (sbr_get_conn (sk)))) + { + sbr_set_sk_io_errno (sk, ECONNRESET); + } + else + { + sbr_set_sk_io_errno (sk, EPIPE); + } + + return -1; + } + + return 0; +} + +NSTACK_STATIC int +sbr_tcp_send (sbr_socket_t * sk, const void *data, size_t size, int flags) +{ + int err; + size_t written = 0; + u8 write_flags; + + if (0 != sbr_tcp_send_state_check (sk)) + { + NSSBR_LOGDBG ("tcp state not correct]fd=%d, err=%d", sk->fd, + sbr_get_sk_errno (sk)); + return -1; + } + + write_flags = SPL_NETCONN_COPY | + ((flags & MSG_MORE) ? SPL_NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? SPL_NETCONN_DONTBLOCK : 0); + + NSSBR_LOGINF ("Sbr tcp write start"); + err = sbr_tcp_write (sk, data, size, write_flags, &written); + NSSBR_LOGINF ("Sbr tcp write end written %d", written); + + return (err == ERR_OK ? written : -1); +} + +NSTACK_STATIC int +sbr_tcp_sendmsg (sbr_socket_t * sk, const struct msghdr *pmsg, int flags) +{ + if (0 != sbr_tcp_send_state_check (sk)) + { + NSSBR_LOGDBG ("tcp state not correct]fd=%d, err=%d", sk->fd, + sbr_get_sk_errno (sk)); + return -1; + } + + return sbr_tcp_writev (sk, pmsg->msg_iov, pmsg->msg_iovlen); +} + +NSTACK_STATIC int +sbr_tcp_fcntl (sbr_socket_t * sk, int cmd, long arg) +{ + int ret = 0; + + switch (cmd) + { + case F_GETFL: + ret = ss_get_nonblock_flag (sbr_get_conn (sk)); + NSSBR_LOGDBG ("F_GETFL]fd=%d,ret=%d", sk->fd, ret); + break; + + case F_SETFL: + if (arg & O_NONBLOCK) + { + NSSBR_LOGDBG ("F_SETFL set O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, + arg); + ss_set_nonblock_flag (sbr_get_conn (sk), (arg & O_NONBLOCK)); + } + else + { + NSSBR_LOGDBG ("F_SETFL clean O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, + arg); + ss_set_nonblock_flag (sbr_get_conn (sk), 0); + } + + break; + + default: + NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%d", sk->fd, cmd); + ret = -1; + sbr_set_sk_errno (sk, EINVAL); + break; + } + + return ret; +} + +NSTACK_STATIC int +sbr_tcp_ioctl (sbr_socket_t * sk, unsigned long cmd, void *arg) +{ + int ret = 0; + int recv_avail; + + switch (cmd) + { + case FIONREAD: + { + if (ss_is_listen_state (sbr_get_conn (sk))) + { + ret = -1; + sbr_set_sk_errno (sk, EINVAL); + break; + } + + recv_avail = ss_get_recv_avail (sbr_get_conn (sk)); + *((u32 *) arg) = recv_avail >= 0 ? recv_avail : 0; + if (sbr_get_fd_share (sk)->lastdata) + { + struct spl_pbuf *buf = + ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + *((u32 *) arg) += + (buf->tot_len - sbr_get_fd_share (sk)->lastoffset); + } + } + + break; + + case FIONBIO: + { + u8 val = 0; + + if (arg && *(u32 *) arg) + { + val = 1; + } + + ss_set_nonblock_flag (sbr_get_conn (sk), val); + NSSBR_LOGDBG ("FIONBIO]fd=%d,val=%u", sk->fd, val); + } + + break; + + default: + { + NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%lu", sk->fd, cmd); + ret = -1; + sbr_set_sk_errno (sk, ENOTTY); + } + break; + } + + return ret; +} + +NSTACK_STATIC int +sbr_tcp_close (sbr_socket_t * sk) +{ + if (sbr_get_fd_share (sk)->lastdata) + { + struct spl_netbuf *buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + struct spl_pbuf *p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + sbr_tcp_free_recvbuf (sk, p); + } + + return sbr_handle_close (sk, 0); +} + +sbr_fdopt tcp_fdopt = { + .socket = sbr_tcp_socket, + .bind = sbr_tcp_bind, + .listen = sbr_tcp_listen, + .accept = sbr_tcp_accept, + .accept4 = sbr_tcp_accept4, + .connect = sbr_tcp_connect, + .shutdown = sbr_tcp_shutdown, + .getsockname = sbr_tcp_getsockname, + .getpeername = sbr_tcp_getpeername, + .getsockopt = sbr_tcp_getsockopt, + .setsockopt = sbr_tcp_setsockopt, + .recvfrom = sbr_tcp_recvfrom, + .readv = sbr_tcp_readv, + .recvmsg = sbr_tcp_recvmsg, + .send = sbr_tcp_send, + .sendto = sbr_tcp_sendto, + .sendmsg = sbr_tcp_sendmsg, + .writev = sbr_tcp_writev, + .fcntl = sbr_tcp_fcntl, + .ioctl = sbr_tcp_ioctl, + .close = sbr_tcp_close, + .peak = sbr_com_peak, + .lock_common = sbr_com_lock_common, + .unlock_common = sbr_com_unlock_common, + .fork_parent = sbr_com_fork_parent, + .fork_child = sbr_com_fork_child, + .ep_getevt = stackx_eventpoll_getEvt, + .ep_ctl = stackx_eventpoll_triggle, + .set_close_stat = NULL, +}; diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_udp.c b/stacks/lwip_stack/lwip_src/socket/stackx_udp.c new file mode 100644 index 0000000..69b822b --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_udp.c @@ -0,0 +1,1171 @@ +/* +* +* 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 "stackx_prot_com.h" +#include "stackx_msg_handler.h" +#include "stackx_pbuf.h" +#include "stackx_epoll_api.h" +#include "stackx_err.h" +#include "nstack_securec.h" +#include "common_pal_bitwide_adjust.h" +#include "stackx_cfg.h" +#include <netinet/in.h> +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif + +#define SPL_PBUF_UDP_LEN (SPL_FRAME_MTU + SPL_PBUF_LINK_HLEN) +#define L2_L3_ROOM_LEN (SPL_PBUF_LINK_HLEN + SPL_PBUF_IP_HLEN) +#define L4_ROOM_LEN SPL_PBUF_UDP_HLEN + +/***************************************************************************** +* Prototype : sbr_udp_socket +* Description : create socket +* Input : sbr_socket_t * sk +* int domain +* int type +* int protocol +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_socket (sbr_socket_t * sk, int domain, int type, int protocol) +{ + if (sbr_malloc_conn_for_sk (sk, SPL_NETCONN_UDP) != 0) + { + return -1; + } + + int ret = sbr_handle_socket (sk, SPL_NETCONN_UDP, 0); + if (ret != 0) + { + sbr_free_conn_from_sk (sk); + return ret; + } + + ss_set_nonblock_flag (sbr_get_conn (sk), (type & O_NONBLOCK)); + ss_set_send_event (sbr_get_conn (sk), 1); + return ret; +} + +/***************************************************************************** +* Prototype : sbr_udp_bind +* Description : udp bind +* Input : sbr_socket_t * sk +* const struct sockaddr * name +* socklen_t namelen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_bind (sbr_socket_t * sk, const struct sockaddr *name, + socklen_t namelen) +{ + const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; + + NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, + spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), + sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); + spl_ip_addr_t local_addr; + inet_addr_to_ipaddr (&local_addr, &addr_in->sin_addr); + u16 local_port = addr_in->sin_port; + return sbr_handle_bind (sk, &local_addr, ntohs (local_port)); +} + +/***************************************************************************** +* Prototype : sbr_udp_listen +* Description : unsupport +* Input : sbr_socket_t * sk +* int backlog +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_listen (sbr_socket_t * sk, int backlog) +{ + NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); + sbr_set_sk_errno (sk, EOPNOTSUPP); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_udp_accept +* Description : unsupport +* Input : sbr_socket_t * sk +* sbr_socket_t * new_sk +* struct sockaddr * addr +* socklen_t * addrlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_accept (sbr_socket_t * sk, sbr_socket_t * new_sk, + struct sockaddr *addr, socklen_t * addrlen) +{ + NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); + sbr_set_sk_errno (sk, EOPNOTSUPP); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_udp_accept4 +* Description : unsupport +* Input : sbr_socket_t * sk +* sbr_socket_t * new_sk +* struct sockaddr * addr +* socklen_t * addrlen +* int flags +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_accept4 (sbr_socket_t * sk, sbr_socket_t * new_sk, + struct sockaddr *addr, socklen_t * addrlen, int flags) +{ + NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); + sbr_set_sk_errno (sk, EOPNOTSUPP); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_udp_connect +* Description : udp connect +* Input : sbr_socket_t * sk +* const struct sockaddr * name +* socklen_t namelen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_connect (sbr_socket_t * sk, const struct sockaddr *name, + socklen_t namelen) +{ + const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; + + NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, + spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), + sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); + spl_ip_addr_t remote_addr; + + inet_addr_to_ipaddr (&remote_addr, &addr_in->sin_addr); + u16 remote_port = addr_in->sin_port; + + spl_ip_addr_t local_addr; + if (IPADDR_ANY == ss_get_local_ip (sbr_get_conn (sk))->addr) + { + if (sbr_get_src_ip (remote_addr.addr, &local_addr.addr) != 0) + { + sbr_set_sk_errno (sk, EHOSTUNREACH); + NSSBR_LOGERR ("get src ip failed]fd=%d", sk->fd); + return -1; + } + } + + return sbr_handle_connect (sk, &remote_addr, ntohs (remote_port), + &local_addr); +} + +/***************************************************************************** +* Prototype : sbr_udp_shutdown +* Description : udp shutdown +* Input : sbr_socket_t * sk +* int how +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_shutdown (sbr_socket_t * sk, int how) +{ + ss_set_shut_status (sbr_get_conn (sk), how); + NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); + sbr_set_sk_errno (sk, EOPNOTSUPP); + return -1; +} + +/***************************************************************************** +* Prototype : sbr_udp_getsockname +* Description : get sock name +* Input : sbr_socket_t * sk +* struct sockaddr * name +* socklen_t * namelen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_getsockname (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen) +{ + return sbr_handle_get_name (sk, name, namelen, SBR_GET_SOCK_NAME); +} + +/***************************************************************************** +* Prototype : sbr_udp_getpeername +* Description : get peer name +* Input : sbr_socket_t * sk +* struct sockaddr * name +* socklen_t * namelen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_getpeername (sbr_socket_t * sk, struct sockaddr *name, + socklen_t * namelen) +{ + return sbr_handle_get_name (sk, name, namelen, SBR_GET_PEER_NAME); +} + +/***************************************************************************** +* Prototype : sbr_udp_getsockopt +* Description : get sockopt +* Input : sbr_socket_t * sk +* int level +* int optname +* void * optval +* socklen_t * optlen +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +sbr_udp_getsockopt (sbr_socket_t * sk, int level, int optname, void *optval, + socklen_t * optlen) +{ + int err = 0; + + switch (level) + { + case SOL_SOCKET: + err = sbr_getsockopt_sol_socket (sk, optname, optval, *optlen); + break; + case IPPROTO_IP: + err = sbr_getsockopt_ipproto_ip (optname, optval, *optlen); + break; + + case NSTACK_SOCKOPT: + if ((optname == NSTACK_SEM_SLEEP) || (*optlen < sizeof (u32_t))) + { + *(u32_t *) optval = + sbr_get_fd_share (sk)->block_polling_time / 1000; + NSSOC_LOGINF + ("udp get recv sleep time success]usleep time=%d,fd=%d", + sbr_get_fd_share (sk)->block_polling_time, sk->fd); + return ERR_OK; + } + else + { + NSSOC_LOGINF ("get recv sleep time failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + + default: + err = ENOPROTOOPT; + break; + } + + if (err != 0) + { + NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, + optname, err); + /* for option not support ,getsockopt() should return fail */ + sbr_set_sk_errno (sk, err); + return -1; + } + + return sbr_handle_getsockopt (sk, level, optname, optval, optlen); +} + +/***************************************************************************** +* Prototype : sbr_udp_setsockopt +* Description : set sockopt +* Input : sbr_socket_t * sk +* int level +* int optname +* const void * optval +* socklen_t optlen +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_setsockopt (sbr_socket_t * sk, int level, int optname, + const void *optval, socklen_t optlen) +{ + NSSBR_LOGDBG ("udp setsockopt]fd=%d,level=%d,optname=%d", sk->fd, level, + optname); + int err = 0; + switch (level) + { + case SOL_SOCKET: + err = + sbr_setsockopt_sol_socket (sk, optname, optval, optlen, + SPL_NETCONN_UDP); + break; + case IPPROTO_IP: + err = + sbr_setsockopt_ipproto_ip (optname, optval, optlen, SPL_NETCONN_UDP); + break; + case NSTACK_SOCKOPT: + { + u32_t sleep_time = *(u32_t *) optval; + /*sleep time should less than 1s */ + if ((optname == NSTACK_SEM_SLEEP) && (optlen >= sizeof (u32_t)) + && (sleep_time < 1000000)) + { + sbr_get_fd_share (sk)->block_polling_time = sleep_time * 1000; + NSSOC_LOGINF + ("udp set recv sleep time success]usleep time=%d,fd=%d", + sbr_get_fd_share (sk)->block_polling_time, sk->fd); + return ERR_OK; + } + else + { + NSSOC_LOGINF ("set recv sleep time failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + } + + default: + err = ENOPROTOOPT; + break; + } + + if (err != 0) + { + NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, + optname, err); + + if (ENOPROTOOPT == err) + { + return 0; + } + else + { + sbr_set_sk_errno (sk, err); + return -1; + } + } + + return sbr_handle_setsockopt (sk, level, optname, optval, optlen); +} + +static inline int +sbr_udp_get_from_addr (sbr_socket_t * sk, struct sockaddr *from, + socklen_t * fromlen, struct spl_netbuf *buf) +{ + int ret; + u16 port = netbuf_fromport (buf); + spl_ip_addr_t *addr = netbuf_fromaddr (buf); + + ret = (from + && fromlen) ? sbr_get_sockaddr_and_len (port, addr, from, + fromlen) : 0; + if (0 != ret) + { + sbr_set_sk_io_errno (sk, EINVAL); + NSSBR_LOGERR ("sbr_udp_get_from_addr]fd=%d", sk->fd); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_udp_recv_from_ring +* Description : recv buf from ring +* Input : sbr_socket_t * sk +* struct spl_netbuf ** buf +* i32 timeout +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_udp_recv_from_ring (sbr_socket_t * sk, struct spl_netbuf **buf, + i32 timeout) +{ + void *p = NULL; + spl_netconn_t *conn = sbr_get_conn (sk); + + if (sbr_dequeue_buf (sk, &p, timeout) != 0) + { + return -1; + } + + *buf = (struct spl_netbuf *) ((char *) p + sizeof (struct spl_pbuf)); + ss_sub_recv_event (conn); + return 0; +} + +/***************************************************************************** +* Prototype : _sbr_udp_recvfrom +* Description : base recvfrom,without lock +* Input : sbr_socket_t * sk +* void * mem +* size_t len +* int flags +* struct sockaddr * from +* socklen_t * fromlen +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +_sbr_udp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t * fromlen) +{ + struct spl_netbuf *buf = NULL; + struct spl_pbuf *p; + u32 buflen; + u32 copylen; + u32 off = 0; + + if (sbr_get_fd_share (sk)->lastdata) + { + buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + } + else + { + if ((flags & MSG_DONTWAIT) || ss_is_nonblock_flag (sbr_get_conn (sk))) + { + /* + * return with last err when + * some fatal err occurs, for example, spl just recovered from a fault. + */ + int err = ss_get_last_errno (sbr_get_conn (sk)); + if (SPL_ERR_IS_FATAL (err)) + { + NSSBR_LOGDBG ("connection fatal error]sk->fd=%d,errno=%d", + sk->fd, err); + sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err)); + return -1; + } + + if (ss_get_recv_event (sbr_get_conn (sk)) <= 0) + { + NSSBR_LOGDBG ("no recv event]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EWOULDBLOCK); + return -1; + } + } + + if (sbr_udp_recv_from_ring + (sk, &buf, sbr_get_fd_share (sk)->recv_timeout) != 0) + { + return -1; + } + + sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf); + } + + p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + buflen = p->tot_len; + + if (mem) + { + copylen = len > buflen ? buflen : len; + + if ((copylen > 0) && 0 == spl_pbuf_copy_partial (p, mem, copylen, 0)) + { + NSSBR_LOGERR ("copy failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EFAULT); + return -1; + } + + off += copylen; + } + + if (sbr_udp_get_from_addr (sk, from, fromlen, buf) != 0) + { + return -1; + } + + if (!(flags & MSG_PEEK)) + { + sbr_get_fd_share (sk)->lastdata = NULL; + sbr_com_free_recv_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf->p)); + } + + return off; +} + +/***************************************************************************** +* Prototype : sbr_udp_recvfrom +* Description : recv from +* Input : sbr_socket_t * sk +* void * mem +* size_t len +* int flags +* struct sockaddr * from +* socklen_t * fromlen +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t * fromlen) +{ + sbr_com_lock_recv (sk); + int ret = _sbr_udp_recvfrom (sk, mem, len, flags, from, fromlen); + sbr_com_unlock_recv (sk); + return ret; +} + +/***************************************************************************** +* Prototype : sbr_udp_recvdata +* Description : recv data +* Input : sbr_socket_t * sk +* const struct iovec* iov +* int iovcnt +* struct spl_netbuf *buf +* Output : None +* Return Value : static inline +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_udp_recvdata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, + int flags, struct sockaddr *from, socklen_t * fromlen) +{ + sbr_com_lock_recv (sk); + if (-1 == _sbr_udp_recvfrom (sk, NULL, 0, MSG_PEEK, from, fromlen)) + { + sbr_com_unlock_recv (sk); + return -1; + } + + struct spl_netbuf *buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + struct spl_pbuf *p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + u32 buflen = p->tot_len; + u32 copylen = 0; + u32 offset = 0; + + int i; + + for (i = 0; i < iovcnt; ++i) + { + if (!iov[i].iov_base || (0 == iov[i].iov_len)) + { + continue; + } + + copylen = buflen > iov[i].iov_len ? iov[i].iov_len : buflen; + if ((copylen > 0) + && 0 == spl_pbuf_copy_partial (p, iov[i].iov_base, copylen, offset)) + { + NSSBR_LOGERR ("copy failed]fd=%d", sk->fd); + goto done; + } + + offset += copylen; + buflen -= copylen; + + if (0 == buflen) + { + goto done; + } + } + +done: + if (!(flags & MSG_PEEK)) + { + sbr_get_fd_share (sk)->lastdata = NULL; + sbr_com_free_recv_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf->p)); + } + + sbr_com_unlock_recv (sk); + return offset; +} + +/***************************************************************************** +* Prototype : sbr_udp_readv +* Description : readv +* Input : sbr_socket_t* sk +* const struct iovec* iov +* int iovcnt +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_readv (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) +{ + return sbr_udp_recvdata (sk, iov, iovcnt, 0, NULL, NULL); +} + +/***************************************************************************** +* Prototype : sbr_udp_recvmsg +* Description : recv msg +* Input : sbr_socket_t* sk +* struct msghdr* msg +* int flags +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_recvmsg (sbr_socket_t * sk, struct msghdr *msg, int flags) +{ + return sbr_udp_recvdata (sk, msg->msg_iov, msg->msg_iovlen, flags, + (struct sockaddr *) msg->msg_name, + &msg->msg_namelen); +} + +/***************************************************************************** +* Prototype : sbr_copy_iov +* Description : copy iov +* Input : sbr_socket_t * sk +* const struct iovec * iov +* int iovcnt +* struct spl_pbuf* buf +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_copy_iov (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, + struct spl_pbuf *buf) +{ + u32 buf_left = buf->len; + i8 *buf_data = (i8 *) ADDR_SHTOL (buf->payload); + u32 iov_left; + i8 *iov_data; + u32 copy_len; + + int i; + + for (i = 0; i < iovcnt; ++i) + { + if (!iov[i].iov_base || (0 == iov[i].iov_len)) + { + continue; + } + + iov_left = (u32) iov[i].iov_len; /* to u32 is ok,len is checked in sbr_udp_senddata */ + iov_data = (i8 *) iov[i].iov_base; + while (iov_left) + { + copy_len = buf_left > iov_left ? iov_left : buf_left; + + if (NULL == common_memcpy (buf_data, iov_data, copy_len)) + { + NSSBR_LOGERR ("common_memcpy error]fd=%d", sk->fd); + sbr_set_sk_errno (sk, EFAULT); + return -1; + } + + buf_data += copy_len; + buf_left -= copy_len; + iov_data += copy_len; + iov_left -= copy_len; + if (0 == buf_left) + { + buf = (struct spl_pbuf *) ADDR_SHTOL (buf->next); + if (buf) + { + buf_left = buf->len; + buf_data = (i8 *) ADDR_SHTOL (buf->payload); + } + else + { + return 0; + } + } + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : sbr_udp_senddata +* Description : send data +* Input : sbr_socket_t * sk +* const struct iovec * iov +* int iovcnt +* int flags +* const struct sockaddr * to +* socklen_t tolen +* Output : None +* Return Value : static inline int +* Calls : +* Called By : +* +*****************************************************************************/ +static inline int +sbr_udp_senddata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, + int flags, const struct sockaddr *to, socklen_t tolen) +{ + size_t size = 0; + int iov_idx; + + for (iov_idx = 0; iov_idx < iovcnt; ++iov_idx) + { + if ((SPL_MAX_UDP_MSG_LEN - size) < iov[iov_idx].iov_len) + { + NSSBR_LOGERR + ("size > SPL_MAX_UDP_MSG_LEN]fd=%d,SPL_MAX_UDP_MSG_LEN=%u", + sk->fd, SPL_MAX_UDP_MSG_LEN); + sbr_set_sk_io_errno (sk, EMSGSIZE); + return -1; + } + + size += iov[iov_idx].iov_len; + } + + if (to == NULL) + { + /* if not bind , then dest address should not be NULL */ + if (IPADDR_ANY == ss_get_remote_ip (sbr_get_conn (sk))->addr) + { + NSSBR_LOGERR ("dest address is null]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, EDESTADDRREQ); + return -1; + } + } + else if (to->sa_family != AF_INET) + { + NSSBR_LOGERR ("invalid address family]fd=%d,family=%d", sk->fd, + to->sa_family); + sbr_set_sk_io_errno (sk, EAFNOSUPPORT); + return -1; + } + else if (tolen != sizeof (struct sockaddr_in)) + { + NSSBR_LOGERR ("invalid address len]fd=%d,tolen=%u", sk->fd, tolen); + sbr_set_sk_io_errno (sk, EINVAL); + return -1; + } + + struct spl_netbuf buf; + const struct sockaddr_in *to_in = (const struct sockaddr_in *) to; + buf.p = NULL; + if (to_in) + { + NSSBR_LOGDBG ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, + spl_inet_ntoa (to_in->sin_addr), ntohs (to_in->sin_port), + sbr_get_conn (sk), + ss_get_private_data (sbr_get_conn (sk))); + inet_addr_to_ipaddr (&buf.addr, &to_in->sin_addr); + netbuf_fromport (&buf) = ntohs (to_in->sin_port); + } + else + { + spl_ip_addr_set_any (&buf.addr); + netbuf_fromport (&buf) = 0; + } + + spl_ip_addr_t local_ip; + if (IPADDR_ANY == ss_get_local_ip (sbr_get_conn (sk))->addr) + { + if (sbr_get_src_ip (buf.addr.addr, &local_ip.addr) != 0) + { + sbr_set_sk_io_errno (sk, EHOSTUNREACH); + NSSBR_LOGERR ("get src ip failed]fd=%d", sk->fd); + return -1; + } + } + + int err = ss_get_last_errno (sbr_get_conn (sk)); + if (SPL_ERR_IS_FATAL (err)) + { + NS_LOG_CTRL (LOG_CTRL_SEND, LOGSBR, "NSSBR", NSLOG_ERR, + "connection fatal error!err=%d", err); + sbr_set_sk_errno (sk, sbr_spl_err_to_errno (err)); + return -1; + } + + u16 remain_len = size; //+ head_room_len; + struct spl_pbuf *p = NULL; + PRIMARY_ADDR struct spl_pbuf *header = NULL; + struct spl_pbuf **tail = &header; + u16 head_len = L2_L3_ROOM_LEN + L4_ROOM_LEN; + u16 copy_len; + u16 alloc_len; + + do + { + copy_len = + remain_len > + (SPL_PBUF_UDP_LEN - head_len) ? (SPL_PBUF_UDP_LEN - + head_len) : remain_len; + alloc_len = head_len + copy_len; + p = sbr_malloc_tx_pbuf (alloc_len, head_len); + if (unlikely (!p)) + { + NSSBR_LOGDBG ("malloc pbuf failed]fd=%d", sk->fd); + sbr_set_sk_io_errno (sk, ENOMEM); + sbr_handle_free_send_buf (sk, + (struct spl_pbuf *) ADDR_SHTOL (header)); + // ss_set_send_event(sbr_get_conn(sk), 0); + return -1; + } + + struct spl_pbuf *tmp = (struct spl_pbuf *) ADDR_SHTOL (header); + while (tmp) + { + tmp->tot_len += p->len; + tmp = (struct spl_pbuf *) ADDR_SHTOL (tmp->next); + } + + *tail = (struct spl_pbuf *) ADDR_LTOSH (p); /* header will changed to share */ + tail = &p->next; + + remain_len -= copy_len; + head_len = L2_L3_ROOM_LEN; + } + while (remain_len); + + /*udp support len=0 */ + if (size != 0) + { + if (sbr_copy_iov + (sk, iov, iovcnt, (struct spl_pbuf *) ADDR_SHTOL (header)) != 0) + { + sbr_handle_free_send_buf (sk, + (struct spl_pbuf *) ADDR_SHTOL (header)); + return -1; + } + } + + buf.p = header; + err = sbr_handle_udp_send (sk, &buf, &local_ip); + if (0 == err) + { + epoll_triggle_event_from_api (sk, EPOLL_API_OP_SEND); + //ss_set_send_event(sbr_get_conn(sk), 1); + return size; + } + else + { + sbr_handle_free_send_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf.p)); + return -1; + } + +} + +/***************************************************************************** +* Prototype : sbr_udp_sendto +* Description : sendto +* Input : sbr_socket_t * sk +* const void * data +* size_t size +* int flags +* const struct sockaddr * to +* socklen_t tolen +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_sendto (sbr_socket_t * sk, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + struct iovec iov; + + iov.iov_base = (void *) data; + iov.iov_len = size; + return sbr_udp_senddata (sk, &iov, 1, flags, to, tolen); +} + +/***************************************************************************** +* Prototype : sbr_udp_send +* Description : send +* Input : sbr_socket_t * sk +* const void * data +* size_t size +* int flags +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_send (sbr_socket_t * sk, const void *data, size_t size, int flags) +{ + return sk->fdopt->sendto (sk, data, size, flags, NULL, 0); +} + +/***************************************************************************** +* Prototype : sbr_udp_sendmsg +* Description : send msg +* Input : sbr_socket_t * sk +* const struct msghdr * pmsg +* int flags +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_sendmsg (sbr_socket_t * sk, const struct msghdr *pmsg, int flags) +{ + return sbr_udp_senddata (sk, pmsg->msg_iov, pmsg->msg_iovlen, flags, + (struct sockaddr *) pmsg->msg_name, + pmsg->msg_namelen); +} + +/***************************************************************************** +* Prototype : sbr_udp_writev +* Description : writev +* Input : sbr_socket_t * sk +* const struct iovec * iov +* int iovcnt +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_writev (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) +{ + return sbr_udp_senddata (sk, iov, iovcnt, 0, NULL, 0); +} + +/***************************************************************************** +* Prototype : sbr_udp_fcntl +* Description : fcntl +* Input : sbr_socket_t * sk +* int cmd +* long arg +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_fcntl (sbr_socket_t * sk, int cmd, long arg) +{ + int ret = 0; + + switch (cmd) + { + case F_GETFL: + ret = ss_get_nonblock_flag (sbr_get_conn (sk)); + NSSBR_LOGDBG ("F_GETFL]fd=%d,ret=%d", sk->fd, ret); + break; + case F_SETFL: + if (arg & O_NONBLOCK) + { + NSSBR_LOGDBG ("F_SETFL set O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, + arg); + ss_set_nonblock_flag (sbr_get_conn (sk), (arg & O_NONBLOCK)); + } + else + { + NSSBR_LOGDBG ("F_SETFL clean O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, + arg); + ss_set_nonblock_flag (sbr_get_conn (sk), 0); + } + + break; + default: + NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%d", sk->fd, cmd); + ret = -1; + sbr_set_sk_errno (sk, EINVAL); + + break; + } + + return ret; +} + +/***************************************************************************** +* Prototype : sbr_udp_ioctl +* Description : ioctl +* Input : sbr_socket_t * sk +* unsigned long cmd +* void * arg +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_ioctl (sbr_socket_t * sk, unsigned long cmd, void *arg) +{ + int ret = 0; + + switch (cmd) + { + case FIONREAD: + { + if (!sbr_com_try_lock_recv (sk)) + { + return 0; + } + + struct spl_pbuf *p = NULL; + struct spl_netbuf *buf = NULL; + if (!sbr_get_fd_share (sk)->lastdata) + { + ret = sbr_udp_recv_from_ring (sk, &buf, -1); + if (ret != 0) + { + sbr_com_unlock_recv (sk); + return EWOULDBLOCK == errno ? 0 : -1; + } + + sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf); + p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + } + else + { + buf = + (struct spl_netbuf *) + ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + } + + *((u32 *) arg) = p->tot_len; + sbr_com_unlock_recv (sk); + } + break; + case FIONBIO: + { + u8 val = 0; + + if (arg && *(u32 *) arg) + { + val = 1; + } + + ss_set_nonblock_flag (sbr_get_conn (sk), val); + NSSBR_LOGDBG ("FIONBIO]fd=%d,val=%u", sk->fd, val); + } + break; + default: + { + NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%lu", sk->fd, cmd); + ret = -1; + sbr_set_sk_errno (sk, ENOTTY); + } + + break; + } + + return ret; +} + +/***************************************************************************** +* Prototype : sbr_udp_close +* Description : close +* Input : sbr_socket_t * sk +* Output : None +* Return Value : static int +* Calls : +* Called By : +* +*****************************************************************************/ +static int +sbr_udp_close (sbr_socket_t * sk) +{ + if (sbr_get_fd_share (sk)->lastdata) + { + struct spl_netbuf *buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); + struct spl_pbuf *p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); + sbr_com_free_recv_buf (sk, p); + } + + /* if failed,free it in recycle */ + return sbr_handle_close (sk, 0); +} + +sbr_fdopt udp_fdopt = { + .socket = sbr_udp_socket, + .bind = sbr_udp_bind, + .listen = sbr_udp_listen, + .accept = sbr_udp_accept, + .accept4 = sbr_udp_accept4, + .connect = sbr_udp_connect, + .shutdown = sbr_udp_shutdown, + .getsockname = sbr_udp_getsockname, + .getpeername = sbr_udp_getpeername, + .getsockopt = sbr_udp_getsockopt, + .setsockopt = sbr_udp_setsockopt, + .recvfrom = sbr_udp_recvfrom, + .readv = sbr_udp_readv, + .recvmsg = sbr_udp_recvmsg, + .send = sbr_udp_send, + .sendto = sbr_udp_sendto, + .sendmsg = sbr_udp_sendmsg, + .writev = sbr_udp_writev, + .fcntl = sbr_udp_fcntl, + .ioctl = sbr_udp_ioctl, + .close = sbr_udp_close, + .peak = sbr_com_peak, + .lock_common = sbr_com_lock_common, + .unlock_common = sbr_com_unlock_common, + .fork_parent = sbr_com_fork_parent, + .fork_child = sbr_com_fork_child, + .ep_getevt = stackx_eventpoll_getEvt, + .ep_ctl = stackx_eventpoll_triggle, + .set_close_stat = NULL, +}; diff --git a/stacks/lwip_stack/patch/.gitkeep b/stacks/lwip_stack/patch/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/stacks/lwip_stack/patch/.gitkeep diff --git a/stacks/lwip_stack/release/configure/ip_data.json b/stacks/lwip_stack/release/configure/ip_data.json new file mode 100644 index 0000000..f29103e --- /dev/null +++ b/stacks/lwip_stack/release/configure/ip_data.json @@ -0,0 +1,31 @@ +{ + "containerID": "9112d2b6aa31", + "primary_port": "PortA", + "ports_list": [ + { + "port_name": "PortA", + "ref_nic": [ + "eth7" + ], + "mac": [ + "00:54:32:19:3d:19" + ], + "net_name": "IDX-M", + "ip_cidr": ["192.168.1.207/24"], + "multicast_id": [ + { + "group_id": "cast_group_1", + "group_ip": "239.0.0.1" + }, + { + "group_id": "cast_group_2", + "group_ip": "239.0.0.2" + } + ], + "vlan_id": 42, + "vlan_inside": true, + "vxlan_id": -1, + "vxlan_inside": false + } + ] +} diff --git a/stacks/lwip_stack/release/configure/nStackConfig.json b/stacks/lwip_stack/release/configure/nStackConfig.json new file mode 100644 index 0000000..3cc54c5 --- /dev/null +++ b/stacks/lwip_stack/release/configure/nStackConfig.json @@ -0,0 +1,32 @@ +{ +"cfg_seg_socket": [ +{ + "socket_num": 8192, + "arp_stale_time": 300, + "arp_bc_retrans_num": 5 +} +], +"cfg_seg_log": [ +{ + "run_log_size": 50, + "run_log_count": 10, + "mon_log_size": 10, + "mon_log_count": 10 +} +], +"cfg_seg_thread_pri": [ +{ + "comment":"0:SCHED_OTHER, 1:SCHED_FIFO, 2:SCHED_RR", + "sched_policy": 0, + "thread_pri": 0 +} +], +"cfg_seg_path": [ +{ + "stackpool_log_path": "/var/log/nStack", + "master_log_path": "/var/log/nStack", + "nstack_log_path": "/var/log/nStack", + "dpdk_log_path": "/var/log/nstack-dpdk" +} +] +} diff --git a/stacks/lwip_stack/release/configure/network_data_tonStack.json b/stacks/lwip_stack/release/configure/network_data_tonStack.json new file mode 100644 index 0000000..7c059ef --- /dev/null +++ b/stacks/lwip_stack/release/configure/network_data_tonStack.json @@ -0,0 +1,32 @@ +[ + { + "cniVersion": "0.2.0", + "name": "IDX-M", + "multi_entry": "3", + "type": "nstack-dpdk", + "vlanID": 42, + "vlan_inside": true, + "ipam": { + "type": "canal-ipam", + "subnet": "192.168.1.1/24", + "gateway": "192.168.1.254", + "range-start": "192.168.1.198", + "range-end": "192.168.1.209", + "routes": [ + { + "dst": "192.168.1.0/24", + "gw": "192.168.1.254" + } + ] + }, + "args": { + "phynet": { + "ref_nic": [ + "eth7" + ], + "bond_name": "", + "bond_mode": -1 + } + } + }, +] diff --git a/stacks/lwip_stack/release/include/nstack_custom_api.h b/stacks/lwip_stack/release/include/nstack_custom_api.h new file mode 100644 index 0000000..e6cae1e --- /dev/null +++ b/stacks/lwip_stack/release/include/nstack_custom_api.h @@ -0,0 +1,42 @@ +/* +* +* 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 __NSTACK_CUSTOM_API_H__ +#define __NSTACK_CUSTOM_API_H__ + +/***************************************************************************** +* Prototype : create a custom socket ,when using this type . +*****************************************************************************/ +#ifndef SOCK_NS_CUSTOM +#define SOCK_NS_CUSTOM 0xf001 +#endif + +/***************************************************************************** +* Prototype : setsockopt level type +*****************************************************************************/ +enum +{ + NSTACK_SOCKOPT = 0xff02 +}; + +/***************************************************************************** +* Prototype : setsockopt optname type +*****************************************************************************/ +enum +{ + NSTACK_SEM_SLEEP = 0X0001 +}; +#endif diff --git a/stacks/lwip_stack/release/lib64/.gitkeep b/stacks/lwip_stack/release/lib64/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/stacks/lwip_stack/release/lib64/.gitkeep diff --git a/stacks/lwip_stack/release/lwip_helper_files/arch/queue.c b/stacks/lwip_stack/release/lwip_helper_files/arch/queue.c new file mode 100644 index 0000000..4916dae --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/arch/queue.c @@ -0,0 +1,120 @@ +#include <pthread.h> +#include "lwip/memp.h" +#include "lwip/mem.h" + +#include "arch/queue.h" +#include "lwip/sys.h" +#include "nstack_log.h" +#include "lwip/sockets.h" +#include "stackx_spl_share.h" +#include "lwip/api.h" +#include "lwip/ip.h" +#include <netif/sc_dpdk.h> + +err_t +queue_push (queue_t * q, void *pmsg, int isTrypush) +{ + int pushRet; + // struct tcpip_msg* _msg = pmsg; + + //enum tcpip_msg_type tcpip_type = TCPIP_MSG_MAX; + //struct new_api_msg* lo_newapimsg = NULL; + // enum api_msg_type api_type = NEW_MSG_API_MAX; + // struct netconn *lo_conn = NULL; + //u64_t tcp_tx_bytes = 0; + while (1) + { + pushRet = nsfw_mem_ring_enqueue (q->llring, pmsg); + + switch (pushRet) + { + + case -1: + NSSOC_LOGERR ("Box range check has failed]llring_a=%p, msg=%p", + q->llring, pmsg); + return ERR_MEM; + + case 1: + return ERR_OK; + + default: + if (isTrypush) + { + return ERR_MEM; + } + else + { + continue; + } + } + } +} + +void * +queue_pop (queue_t * q, u32_t * timeout, int isTryPop) +{ + void *pmsg; + int popRet; + int retVal; + u32_t ellapsetime = 0; +// struct tcpip_msg* _msg; + struct timespec starttm = { 0 }; + struct timespec endtm; + u32_t timeDiff; + if (*timeout != 0) + { + retVal = clock_gettime (CLOCK_MONOTONIC, &starttm); + if (0 != retVal) + { + NSPOL_LOGERR ("clock_gettime() failed]"); + *timeout = SYS_ARCH_TIMEOUT; + return NULL; + } + } + + while (1) + { + //TODO:May have to consider, take out the data sharing problem + popRet = nsfw_mem_ring_dequeue (q->llring, &pmsg); + + switch (popRet) + { + case 1: + *timeout = ellapsetime; + return pmsg; + + default: + + if (isTryPop) + { + *timeout = SYS_ARCH_TIMEOUT; + return NULL; + } + else + { + if (*timeout != 0) + { + retVal = clock_gettime (CLOCK_MONOTONIC, &endtm); + if (0 != retVal) + { + NSPOL_LOGERR ("clock_gettime() failed]"); + *timeout = SYS_ARCH_TIMEOUT; + return NULL; + } + + timeDiff = endtm.tv_sec - starttm.tv_sec; + if (timeDiff > *timeout) + { + *timeout = SYS_ARCH_TIMEOUT; + return NULL; + } + sys_sleep_ns (0, 100000); + } + + continue; + } + + } + } + +} diff --git a/stacks/lwip_stack/release/lwip_helper_files/arch/sys_arch.c b/stacks/lwip_stack/release/lwip_helper_files/arch/sys_arch.c new file mode 100644 index 0000000..bdda4d2 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/arch/sys_arch.c @@ -0,0 +1,237 @@ +#include <sys/queue.h> + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <stdint.h> + +#include <pthread.h> +#include <sys/time.h> +#include <time.h> +#include <linux/sched.h> + +#include <asm/unistd.h> +#include <linux/unistd.h> +#include <syscall.h> + +#include <lwip/sys.h> +#include <cc.h> +#include <arch/sys_arch.h> +#include <arch/queue.h> +#include "nstack_log.h" +#include "lwip/sockets.h" +#include "spl_timers.h" +#include "nstack_securec.h" +#include "nstack_share_res.h" +#include "nstack_log.h" + +#include "stackx_spl_share.h" +#include "lwip/api.h" +#include "lwip/ip.h" +#include <netif/sc_dpdk.h> +#include <netif/sharedmemory.h> + +#include "common_mem_common.h" +#include "common_func.h" +#include "common_mem_api.h" + +#include "mgr_com.h" +#ifdef HAL_LIB +#else +#include "rte_ring.h" +#endif + +#include "timeouts.h" + +sys_sem_st g_global_semaphore; + +/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ +int +sys_mbox_valid (sys_mbox_t * mbox) +{ + return ((*mbox == SYS_MBOX_NULL) ? 0 : 1); +} + +struct lwip_thread +{ + void (*func) (void *arg); + void *arg; +}; + +static void * +lwip_thread_entry (void *arg) +{ + struct lwip_thread *lt = arg; + + lt->func (lt->arg); + + free (lt); + return 0; +} + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t +sys_thread_new2 (const char *name, lwip_thread_fn thread, void *arg, + int stacksize, int prio, int policy) +{ + pthread_attr_t attr; + set_thread_attr (&attr, stacksize, prio, policy); + + struct lwip_thread *lt = malloc (sizeof (*lt)); + if (lt == NULL) + { + NSPOL_LOGERR ("process abort:cannot allocate thread struct"); + abort (); + } + + lt->func = thread; + lt->arg = arg; + + pthread_t t; + int r = pthread_create (&t, &attr, lwip_thread_entry, lt); + + if (r != 0) + { + NSPOL_LOGERR ("process abort:lwip:annot create]errno_string=%s", + strerror (r)); + abort (); + } + else + { + NSPOL_LOGINF (SC_DPDK_INFO, "]thread_name=%s.", name); + } + + (void) pthread_setname_np (t, name); + + return t; +} + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t +sys_thread_new (const char *name, lwip_thread_fn thread, void *arg, + int stacksize, int prio) +{ + pthread_attr_t attr; + set_thread_attr (&attr, stacksize, prio, 0); + + struct lwip_thread *lt = malloc (sizeof (*lt)); + if (lt == NULL) + { + NSPOL_LOGERR ("process abort:cannot allocate thread struct"); + abort (); + } + + lt->func = thread; + lt->arg = arg; + + pthread_t t; + int r = pthread_create (&t, &attr, lwip_thread_entry, lt); + + if (r != 0) + { + NSPOL_LOGERR ("process abort:lwip:annot create]errno_string=%s", + strerror (r)); + abort (); + } + else + { + NSPOL_LOGINF (SC_DPDK_INFO, "]thread_name=%s.", name); + } + + (void) pthread_setname_np (t, name); + + return t; +} + +void +stackx_global_lock (void) +{ + sys_arch_lock_with_pid (&g_global_semaphore); +} + +void +stackx_global_unlock (void) +{ + sys_sem_s_signal (&g_global_semaphore); +} + +void +sys_init (void) +{ + return; +} + +void +sys_timeouts_mbox_fetch (sys_mbox_t * mbox, void **msg) +{ + return; +} + +void +sys_timeout (u32_t msecs, sys_timeout_handler handler, void *arg) +{ + struct ptimer_node *tmo = arg; + + tmo = malloc (sizeof (struct ptimer_node)); /*lint !e586 */ + if (NULL == tmo) + { + NSPOL_LOGERR ("malloc ptimer node failed!"); + return; + } + + int ret = MEMSET_S (tmo, sizeof (struct ptimer_node), 0, + sizeof (struct ptimer_node)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMSET_S failed]ret=%d", ret); + free (tmo); + return; + } + + NSPOL_LOGDBG (TIMERS_DEBUG, "alloc]ptimer_node=%p", tmo); + + tmo->info.msec = msecs; + tmo->info._phandle = handler; + tmo->info.ctx = arg; + tmo->info.flags = PTIMER_ONESHOT; + tmo->index = 0; + regedit_ptimer (SYS_PTIMEROUT_MSG, handler, tmo); +} + +void +sys_untimeout (sys_timeout_handler handler, void *arg) +{ + regedit_ptimer (SYS_UNPTIMEROUT_MSG, handler, arg); + return; +} + +/** + * Timer callback function that calls mld6_tmr() and reschedules itself. + * + * @param arg unused argument + */ +void +cyclic_timer (void *arg) +{ + const struct lwip_cyclic_timer *cyclic = + (const struct lwip_cyclic_timer *) arg; +#if LWIP_DEBUG_TIMERNAMES + LWIP_DEBUGF (TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name)); +#endif + cyclic->handler (); + sys_timeout (cyclic->interval_ms, cyclic_timer, arg); +} diff --git a/stacks/lwip_stack/release/lwip_helper_files/core/timeouts.c b/stacks/lwip_stack/release/lwip_helper_files/core/timeouts.c new file mode 100644 index 0000000..efbda94 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/core/timeouts.c @@ -0,0 +1,527 @@ +/** + * @file + * Stack-internal timers implementation. + * This file includes timer callbacks for stack-internal timers as well as + * functions to set up or stop timers and check for expired timers. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#include "lwip/timeouts.h" +#include "lwip/priv/tcp_priv.h" + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/priv/tcpip_priv.h" + +#include "lwip/ip4_frag.h" +#include "lwip/etharp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/nd6.h" +#include "lwip/ip6_frag.h" +#include "lwip/mld6.h" +#include "lwip/sys.h" +#include "lwip/pbuf.h" + +#if LWIP_DEBUG_TIMERNAMES +#define HANDLER(x) x, #x +#else /* LWIP_DEBUG_TIMERNAMES */ +#define HANDLER(x) x +#endif /* LWIP_DEBUG_TIMERNAMES */ + +/** This array contains all stack-internal cyclic timers. To get the number of + * timers, use LWIP_ARRAYSIZE() */ +const struct lwip_cyclic_timer lwip_cyclic_timers[] = { +#if LWIP_TCP + /* The TCP timer is a special case: it does not have to run always and + is triggered to start from TCP using tcp_timer_needed() */ + {TCP_TMR_INTERVAL, HANDLER (tcp_tmr)}, +#endif /* LWIP_TCP */ +#if LWIP_IPV4 +#if IP_REASSEMBLY + {IP_TMR_INTERVAL, HANDLER (ip_reass_tmr)}, +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + {ARP_TMR_INTERVAL, HANDLER (etharp_tmr)}, +#endif /* LWIP_ARP */ +#if LWIP_DHCP + {DHCP_COARSE_TIMER_MSECS, HANDLER (dhcp_coarse_tmr)}, + {DHCP_FINE_TIMER_MSECS, HANDLER (dhcp_fine_tmr)}, +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + {AUTOIP_TMR_INTERVAL, HANDLER (autoip_tmr)}, +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + {IGMP_TMR_INTERVAL, HANDLER (igmp_tmr)}, +#endif /* LWIP_IGMP */ +#endif /* LWIP_IPV4 */ +#if LWIP_DNS + {DNS_TMR_INTERVAL, HANDLER (dns_tmr)}, +#endif /* LWIP_DNS */ +#if LWIP_IPV6 + {ND6_TMR_INTERVAL, HANDLER (nd6_tmr)}, +#if LWIP_IPV6_REASS + {IP6_REASS_TMR_INTERVAL, HANDLER (ip6_reass_tmr)}, +#endif /* LWIP_IPV6_REASS */ +#if LWIP_IPV6_MLD + {MLD6_TMR_INTERVAL, HANDLER (mld6_tmr)}, +#endif /* LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6 */ +}; + +#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM + +/** The one and only timeout list */ +static struct sys_timeo *next_timeout; +static u32_t timeouts_last_time; + +#if LWIP_TCP +/** global variable that shows if the tcp timer is currently scheduled or not */ +static int tcpip_tcp_timer_active; + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer (void *arg) +{ + LWIP_UNUSED_ARG (arg); + + /* call TCP timer handler */ + tcp_tmr (); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) + { + /* restart timer */ + sys_timeout (TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } + else + { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +/** + * Called from TCP_REG when registering a new PCB: + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed (void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) + { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout (TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} +#endif /* LWIP_TCP */ + +/** + * Timer callback function that calls mld6_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +cyclic_timer (void *arg) +{ + const struct lwip_cyclic_timer *cyclic = + (const struct lwip_cyclic_timer *) arg; +#if LWIP_DEBUG_TIMERNAMES + LWIP_DEBUGF (TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name)); +#endif + cyclic->handler (); + sys_timeout (cyclic->interval_ms, cyclic_timer, arg); +} + +/** Initialize this module */ +void +sys_timeouts_init (void) +{ + size_t i; + /* tcp_tmr() at index 0 is started on demand */ + for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE (lwip_cyclic_timers); i++) + { + /* we have to cast via size_t to get rid of const warning + (this is OK as cyclic_timer() casts back to const* */ + sys_timeout (lwip_cyclic_timers[i].interval_ms, cyclic_timer, + LWIP_CONST_CAST (void *, &lwip_cyclic_timers[i])); + } + + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now (); +} + +/** + * Create a one-shot timer (aka timeout). Timeouts are processed in the + * following cases: + * - while waiting for a message using sys_timeouts_mbox_fetch() + * - by calling sys_check_timeouts() (NO_SYS==1 only) + * + * @param msecs time in milliseconds after that the timer should expire + * @param handler callback function to call when msecs have elapsed + * @param arg argument to pass to the callback function + */ +#if LWIP_DEBUG_TIMERNAMES +void +sys_timeout_debug (u32_t msecs, sys_timeout_handler handler, void *arg, + const char *handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout (u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + struct sys_timeo *timeout, *t; + u32_t now, diff; + + timeout = (struct sys_timeo *) memp_malloc (MEMP_SYS_TIMEOUT); + if (timeout == NULL) + { + LWIP_ASSERT + ("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", + timeout != NULL); + return; + } + + now = sys_now (); + if (next_timeout == NULL) + { + diff = 0; + timeouts_last_time = now; + } + else + { + diff = now - timeouts_last_time; + } + + timeout->next = NULL; + timeout->h = handler; + timeout->arg = arg; + timeout->time = msecs + diff; +#if LWIP_DEBUG_TIMERNAMES + timeout->handler_name = handler_name; + LWIP_DEBUGF (TIMERS_DEBUG, + ("sys_timeout: %p msecs=%" U32_F " handler=%s arg=%p\n", + (void *) timeout, msecs, handler_name, (void *) arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) + { + next_timeout = timeout; + return; + } + + if (next_timeout->time > msecs) + { + next_timeout->time -= msecs; + timeout->next = next_timeout; + next_timeout = timeout; + } + else + { + for (t = next_timeout; t != NULL; t = t->next) + { + timeout->time -= t->time; + if (t->next == NULL || t->next->time > timeout->time) + { + if (t->next != NULL) + { + t->next->time -= timeout->time; + } + else if (timeout->time > msecs) + { + /* If this is the case, 'timeouts_last_time' and 'now' differs too much. + This can be due to sys_check_timeouts() not being called at the right + times, but also when stopping in a breakpoint. Anyway, let's assume + this is not wanted, so add the first timer's time instead of 'diff' */ + timeout->time = msecs + next_timeout->time; + } + timeout->next = t->next; + t->next = timeout; + break; + } + } + } +} + +/** + * Go through timeout list (for this task only) and remove the first matching + * entry (subsequent entries remain untouched), even though the timeout has not + * triggered yet. + * + * @param handler callback function that would be called by the timeout + * @param arg callback argument that would be passed to handler +*/ +void +sys_untimeout (sys_timeout_handler handler, void *arg) +{ + struct sys_timeo *prev_t, *t; + + if (next_timeout == NULL) + { + return; + } + + for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) + { + if ((t->h == handler) && (t->arg == arg)) + { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) + { + next_timeout = t->next; + } + else + { + prev_t->next = t->next; + } + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) + { + t->next->time += t->time; + } + memp_free (MEMP_SYS_TIMEOUT, t); + return; + } + } + return; +} + +/** + * @ingroup lwip_nosys + * Handle timeouts for NO_SYS==1 (i.e. without using + * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout + * handler functions when timeouts expire. + * + * Must be called periodically from your main loop. + */ +#if !NO_SYS && !defined __DOXYGEN__ +static +#endif /* !NO_SYS */ + void +sys_check_timeouts (void) +{ + if (next_timeout) + { + struct sys_timeo *tmptimeout; + u32_t diff; + sys_timeout_handler handler; + void *arg; + u8_t had_one; + u32_t now; + + now = sys_now (); + /* this cares for wraparounds */ + diff = now - timeouts_last_time; + do + { + PBUF_CHECK_FREE_OOSEQ (); + had_one = 0; + tmptimeout = next_timeout; + if (tmptimeout && (tmptimeout->time <= diff)) + { + /* timeout has expired */ + had_one = 1; + timeouts_last_time += tmptimeout->time; + diff -= tmptimeout->time; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) + { + LWIP_DEBUGF (TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free (MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) + { +#if !NO_SYS + /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the + timeout handler function. */ + LOCK_TCPIP_CORE (); +#endif /* !NO_SYS */ + handler (arg); +#if !NO_SYS + UNLOCK_TCPIP_CORE (); +#endif /* !NO_SYS */ + } + LWIP_TCPIP_THREAD_ALIVE (); + } + /* repeat until all expired timers have been called */ + } + while (had_one); + } +} + +/** Set back the timestamp of the last call to sys_check_timeouts() + * This is necessary if sys_check_timeouts() hasn't been called for a long + * time (e.g. while saving energy) to prevent all timer functions of that + * period being called. + */ +void +sys_restart_timeouts (void) +{ + timeouts_last_time = sys_now (); +} + +/** Return the time left before the next timeout is due. If no timeouts are + * enqueued, returns 0xffffffff + */ +#if !NO_SYS +static +#endif /* !NO_SYS */ + u32_t +sys_timeouts_sleeptime (void) +{ + u32_t diff; + if (next_timeout == NULL) + { + return 0xffffffff; + } + diff = sys_now () - timeouts_last_time; + if (diff > next_timeout->time) + { + return 0; + } + else + { + return next_timeout->time - diff; + } +} + +#if !NO_SYS + +/** + * Wait (forever) for a message to arrive in an mbox. + * While waiting, timeouts are processed. + * + * @param mbox the mbox to fetch the message from + * @param msg the place to store the message + */ +void +sys_timeouts_mbox_fetch (sys_mbox_t * mbox, void **msg) +{ + u32_t sleeptime; + +again: + if (!next_timeout) + { + sys_arch_mbox_fetch (mbox, msg, 0); + return; + } + + sleeptime = sys_timeouts_sleeptime (); + if (sleeptime == 0 + || sys_arch_mbox_fetch (mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) + { + /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred + before a message could be fetched. */ + sys_check_timeouts (); + /* We try again to fetch a message from the mbox. */ + goto again; + } +} + +#endif /* NO_SYS */ + +#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ +/* Satisfy the TCP code which calls this function */ +static int tcpip_tcp_timer_active; + +void +tcp_timer_needed (void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) + { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout (TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +void +tcpip_tcp_timer (void *arg) +{ + LWIP_UNUSED_ARG (arg); + + /* call TCP timer handler */ + tcp_tmr (); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) + { + /* restart timer */ + sys_timeout (TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } + else + { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +void +sys_timeouts_init (void) +{ + size_t i; + /* tcp_tmr() at index 0 is started on demand */ + for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE (lwip_cyclic_timers); i++) + { + /* we have to cast via size_t to get rid of const warning + (this is OK as cyclic_timer() casts back to const* */ + sys_timeout (lwip_cyclic_timers[i].interval_ms, cyclic_timer, + LWIP_CONST_CAST (void *, &lwip_cyclic_timers[i])); + } +} + +#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ diff --git a/stacks/lwip_stack/release/lwip_helper_files/download_lwip.sh b/stacks/lwip_stack/release/lwip_helper_files/download_lwip.sh new file mode 100755 index 0000000..316859b --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/download_lwip.sh @@ -0,0 +1,35 @@ +######################################################################### +# 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. +######################################################################### +#!/bin/bash -x + +set -x + +SCRIPT_DIR=$(dirname "$0") +echo $SCRIPT_DIR +LWIP_DOWNLOAD_DIR="${SCRIPT_DIR}/../../lwip_src/" +echo $LWIP_DOWNLOAD_DIR +if [ ! -d "${LWIP_DOWNLOAD_DIR}/lwip/" ]; then + mkdir -p ${LWIP_DOWNLOAD_DIR}/lwip/ + cd ${LWIP_DOWNLOAD_DIR}/ + wget -N --no-check-certificate http://download.savannah.nongnu.org/releases/lwip/lwip-2.0.3.zip + unzip ${LWIP_DOWNLOAD_DIR}/lwip-2.0.3.zip "lwip-2.0.3/src/*" -d ${LWIP_DOWNLOAD_DIR}/lwip + mv ${LWIP_DOWNLOAD_DIR}/lwip/lwip-2.0.3/src/* ${LWIP_DOWNLOAD_DIR}/lwip/ + rm -rf ${LWIP_DOWNLOAD_DIR}/lwip/lwip-2.0.3/ + cp -r ${SCRIPT_DIR}/arch/ ${LWIP_DOWNLOAD_DIR}/lwip/ + cp -r ${SCRIPT_DIR}/lwip/arch/ ${LWIP_DOWNLOAD_DIR}/lwip/include/lwip/ + cp -r ${SCRIPT_DIR}/core/* ${LWIP_DOWNLOAD_DIR}/lwip/core/ + cp -r ${SCRIPT_DIR}/include/* ${LWIP_DOWNLOAD_DIR}/lwip/include/lwip/ + mv ${LWIP_DOWNLOAD_DIR}/lwip/include/lwip/errno.h ${LWIP_DOWNLOAD_DIR}/lwip/include/lwip/lwip_errno.h +fi
\ No newline at end of file diff --git a/stacks/lwip_stack/release/lwip_helper_files/include/lwipopts.h b/stacks/lwip_stack/release/lwip_helper_files/include/lwipopts.h new file mode 100644 index 0000000..4b1cf4f --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/include/lwipopts.h @@ -0,0 +1,39 @@ +#ifndef LWIP_LWIPOPTS_H +#define LWIP_LWIPOPTS_H + +#define RING_CACHE_SIZE 1024 +#define LISTEN_CACHE_SIZE 1024 +#define RECV_MAX_POOL 4 +#define MAX_TRY_GET_MEMORY_TIMES 4 +#define MAX_MEMORY_USED_SIZE 80 + +#define IP_HLEN 20 +#define TCP_HLEN 20 +#define TCP_MAX_OPTION_LEN 40 + +#define _cache_aligned __attribute__((__aligned__(64))) +#define LWIP_NETIF_API 1 + +#define TCP_OVERSIZE 1 +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS +#define SYS_LIGHTWEIGHT_PROT 1 +#define LWIP_DISABLE_TCP_SANITY_CHECKS 1 +#define LWIP_COMPAT_MUTEX_ALLOWED 1 +#define LWIP_ERRNO_INCLUDE <errno.h> +#define LWIP_SKIP_PACKING_CHECK 1 +#define PBUF_POOL_FREE_OOSEQ 0 + +#define LWIP_DEBUG 1 +#define LWIP_TIMERS 0 +#define LWIP_TIMERS_CUSTOM 1 +#define LWIP_TCPIP_CORE_LOCKING 1 +#define MEM_LIBC_MALLOC 1 +#define MEMP_MEM_MALLOC 1 +#define LWIP_CALLBACK_API 1 +#define LWIP_SOCKET 0 +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_TCP_KEEPALIVE 1 +#define LWIP_TIMEVAL_PRIVATE 0 +#define LWIP_COMPAT_MUTEX 1 + +#endif diff --git a/stacks/lwip_stack/release/lwip_helper_files/include/opt.h b/stacks/lwip_stack/release/lwip_helper_files/include/opt.h new file mode 100644 index 0000000..040e9cf --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/include/opt.h @@ -0,0 +1,2875 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +/* + * NOTE: || defined __DOXYGEN__ is a workaround for doxygen bug - + * without this, doxygen does not see the actual #define + */ + +#if !defined LWIP_HDR_OPT_H +#define LWIP_HDR_OPT_H + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you don't like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/** + * @defgroup lwip_opts Options (lwipopts.h) + * @ingroup lwip + * + * @defgroup lwip_opts_debug Debugging + * @ingroup lwip_opts + * + * @defgroup lwip_opts_infrastructure Infrastructure + * @ingroup lwip_opts + * + * @defgroup lwip_opts_callback Callback-style APIs + * @ingroup lwip_opts + * + * @defgroup lwip_opts_threadsafe_apis Thread-safe APIs + * @ingroup lwip_opts + */ + + /* + ------------------------------------ + -------------- NO SYS -------------- + ------------------------------------ + */ +/** + * @defgroup lwip_opts_nosys NO_SYS + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * NO_SYS==1: Use lwIP without OS-awareness (no thread, semaphores, mutexes or + * mboxes). This means threaded APIs cannot be used (socket, netconn, + * i.e. everything in the 'api' folder), only the callback-style raw API is + * available (and you have to watch out for yourself that you don't access + * lwIP functions/structures from more than one context at a time!) + */ +#if !defined NO_SYS || defined __DOXYGEN__ +#define NO_SYS 0 +#endif +/** + * @} + */ + +/** + * @defgroup lwip_opts_timers Timers + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * LWIP_TIMERS==0: Drop support for sys_timeout and lwip-internal cyclic timers. + * (the array of lwip-internal cyclic timers is still provided) + * (check NO_SYS_NO_TIMERS for compatibility to old versions) + */ +#if !defined LWIP_TIMERS || defined __DOXYGEN__ +#ifdef NO_SYS_NO_TIMERS +#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) +#else +#define LWIP_TIMERS 1 +#endif +#endif + +/** + * LWIP_TIMERS_CUSTOM==1: Provide your own timer implementation. + * Function prototypes in timeouts.h and the array of lwip-internal cyclic timers + * are still included, but the implementation is not. The following functions + * will be required: sys_timeouts_init(), sys_timeout(), sys_untimeout(), + * sys_timeouts_mbox_fetch() + */ +#if !defined LWIP_TIMERS_CUSTOM || defined __DOXYGEN__ +#define LWIP_TIMERS_CUSTOM 0 +#endif +/** + * @} + */ + +/** + * @defgroup lwip_opts_memcpy memcpy + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#if !defined MEMCPY || defined __DOXYGEN__ +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#if !defined SMEMCPY || defined __DOXYGEN__ +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif +/** + * @} + */ + +/* + ------------------------------------ + ----------- Core locking ----------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_lock Core locking and MPU + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * LWIP_MPU_COMPATIBLE: enables special memory management mechanism + * which makes lwip able to work on MPU (Memory Protection Unit) system + * by not passing stack-pointers to other threads + * (this decreases performance as memory is allocated from pools instead + * of keeping it on the stack) + */ +#if !defined LWIP_MPU_COMPATIBLE || defined __DOXYGEN__ +#define LWIP_MPU_COMPATIBLE 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING + * Creates a global mutex that is held during TCPIP thread operations. + * Can be locked by client code to perform lwIP operations without changing + * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and + * UNLOCK_TCPIP_CORE(). + * Your system should provide mutexes supporting priority inversion to use this. + */ +#if !defined LWIP_TCPIP_CORE_LOCKING || defined __DOXYGEN__ +#define LWIP_TCPIP_CORE_LOCKING 1 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled, + * this lets tcpip_input() grab the mutex for input packets as well, + * instead of allocating a message and passing it to tcpip_thread. + * + * ATTENTION: this does not work when tcpip_input() is called from + * interrupt context! + */ +#if !defined LWIP_TCPIP_CORE_LOCKING_INPUT || defined __DOXYGEN__ +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * SYS_LIGHTWEIGHT_PROT==1: enable inter-task protection (and task-vs-interrupt + * protection) for certain critical regions during buffer allocation, deallocation + * and memory allocation and deallocation. + * ATTENTION: This is required when using lwIP from more than one context! If + * you disable this, you must be sure what you are doing! + */ +#if !defined SYS_LIGHTWEIGHT_PROT || defined __DOXYGEN__ +#define SYS_LIGHTWEIGHT_PROT 1 +#endif +/** + * @} + */ + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_mem Heap and memory pools + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#if !defined MEM_LIBC_MALLOC || defined __DOXYGEN__ +#define MEM_LIBC_MALLOC 0 +#endif + +/** + * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. + * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution + * speed (heap alloc can be much slower than pool alloc) and usage from interrupts + * (especially if your netif driver allocates PBUF_POOL pbufs for received frames + * from interrupt)! + * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, + * not only for internal pools defined in memp_std.h)! + */ +#if !defined MEMP_MEM_MALLOC || defined __DOXYGEN__ +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> \#define MEM_ALIGNMENT 4 + * 2 byte alignment -> \#define MEM_ALIGNMENT 2 + */ +#if !defined MEM_ALIGNMENT || defined __DOXYGEN__ +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#if !defined MEM_SIZE || defined __DOXYGEN__ +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#if !defined MEMP_OVERFLOW_CHECK || defined __DOXYGEN__ +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#if !defined MEMP_SANITY_CHECK || defined __DOXYGEN__ +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#if !defined MEM_USE_POOLS || defined __DOXYGEN__ +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#if !defined MEM_USE_POOLS_TRY_BIGGER_POOL || defined __DOXYGEN__ +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * include path somewhere. + */ +#if !defined MEMP_USE_CUSTOM_POOLS || defined __DOXYGEN__ +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#if !defined LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT || defined __DOXYGEN__ +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif +/** + * @} + */ + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * @defgroup lwip_opts_memp Internal memory pools + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#if !defined MEMP_NUM_PBUF || defined __DOXYGEN__ +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#if !defined MEMP_NUM_RAW_PCB || defined __DOXYGEN__ +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#if !defined MEMP_NUM_UDP_PCB || defined __DOXYGEN__ +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. + * (requires the LWIP_TCP option) + */ +#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__ +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#if !defined MEMP_NUM_TCP_PCB_LISTEN || defined __DOXYGEN__ +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#if !defined MEMP_NUM_TCP_SEG || defined __DOXYGEN__ +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#if !defined MEMP_NUM_REASSDATA || defined __DOXYGEN__ +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 + * with DMA-enabled MACs where the packet is not yet sent when netif->output + * returns. + */ +#if !defined MEMP_NUM_FRAG_PBUF || defined __DOXYGEN__ +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#if !defined MEMP_NUM_ARP_QUEUE || defined __DOXYGEN__ +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members at the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#if !defined MEMP_NUM_IGMP_GROUP || defined __DOXYGEN__ +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts. + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. + */ +#if !defined MEMP_NUM_SYS_TIMEOUT || defined __DOXYGEN__ +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__ +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__ +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__ +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__ +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#if !defined MEMP_NUM_NETDB || defined __DOXYGEN__ +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__ +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#if !defined PBUF_POOL_SIZE || defined __DOXYGEN__ +#define PBUF_POOL_SIZE 16 +#endif + +/** MEMP_NUM_API_MSG: the number of concurrently active calls to various + * socket, netconn, and tcpip functions + */ +#if !defined MEMP_NUM_API_MSG || defined __DOXYGEN__ +#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname + */ +#if !defined MEMP_NUM_DNS_API_MSG || defined __DOXYGEN__ +#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls + * to getsockopt/setsockopt + */ +#if !defined MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA || defined __DOXYGEN__ +#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the + * netifapi functions + */ +#if !defined MEMP_NUM_NETIFAPI_MSG || defined __DOXYGEN__ +#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API +#endif +/** + * @} + */ + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * @defgroup lwip_opts_arp ARP + * @ingroup lwip_opts_ipv4 + * @{ + */ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#if !defined LWIP_ARP || defined __DOXYGEN__ +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#if !defined ARP_TABLE_SIZE || defined __DOXYGEN__ +#define ARP_TABLE_SIZE 10 +#endif + +/** the time an ARP entry stays valid after its last update, + * for ARP_TMR_INTERVAL = 1000, this is + * (60 * 5) seconds = 5 minutes. + */ +#if !defined ARP_MAXAGE || defined __DOXYGEN__ +#define ARP_MAXAGE 300 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#if !defined ARP_QUEUEING || defined __DOXYGEN__ +#define ARP_QUEUEING 0 +#endif + +/** The maximum number of packets which may be queued for each + * unresolved address by other network layers. Defaults to 3, 0 means disabled. + * Old packets are dropped, new packets are queued. + */ +#if !defined ARP_QUEUE_LEN || defined __DOXYGEN__ +#define ARP_QUEUE_LEN 3 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving and sending ethernet packets with + * VLAN header. See the description of LWIP_HOOK_VLAN_CHECK and + * LWIP_HOOK_VLAN_SET hooks to check/set VLAN headers. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. + */ +#if !defined ETHARP_SUPPORT_VLAN || defined __DOXYGEN__ +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support even though ARP might be disabled + */ +#if !defined LWIP_ETHERNET || defined __DOXYGEN__ +#define LWIP_ETHERNET LWIP_ARP +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#if !defined ETH_PAD_SIZE || defined __DOXYGEN__ +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#if !defined ETHARP_SUPPORT_STATIC_ENTRIES || defined __DOXYGEN__ +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + +/** ETHARP_TABLE_MATCH_NETIF==1: Match netif for ARP table entries. + * If disabled, duplicate IP address on multiple netifs are not supported + * (but this should only occur for AutoIP). + */ +#if !defined ETHARP_TABLE_MATCH_NETIF || defined __DOXYGEN__ +#define ETHARP_TABLE_MATCH_NETIF 0 +#endif +/** + * @} + */ + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * @defgroup lwip_opts_ipv4 IPv4 + * @ingroup lwip_opts + * @{ + */ +/** + * LWIP_IPV4==1: Enable IPv4 + */ +#if !defined LWIP_IPV4 || defined __DOXYGEN__ +#define LWIP_IPV4 1 +#endif + +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#if !defined IP_FORWARD || defined __DOXYGEN__ +#define IP_FORWARD 0 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#if !defined IP_REASSEMBLY || defined __DOXYGEN__ +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#if !defined IP_FRAG || defined __DOXYGEN__ +#define IP_FRAG 1 +#endif + +#if !LWIP_IPV4 +/* disable IPv4 extensions when IPv4 is disabled */ +#undef IP_FORWARD +#define IP_FORWARD 0 +#undef IP_REASSEMBLY +#define IP_REASSEMBLY 0 +#undef IP_FRAG +#define IP_FRAG 0 +#endif /* !LWIP_IPV4 */ + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#if !defined IP_OPTIONS_ALLOWED || defined __DOXYGEN__ +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#if !defined IP_REASS_MAXAGE || defined __DOXYGEN__ +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#if !defined IP_REASS_MAX_PBUFS || defined __DOXYGEN__ +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#if !defined IP_DEFAULT_TTL || defined __DOXYGEN__ +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#if !defined IP_SOF_BROADCAST || defined __DOXYGEN__ +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#if !defined IP_SOF_BROADCAST_RECV || defined __DOXYGEN__ +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#if !defined IP_FORWARD_ALLOW_TX_ON_RX_NETIF || defined __DOXYGEN__ +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#if !defined LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS || defined __DOXYGEN__ +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif +/** + * @} + */ + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_icmp ICMP + * @ingroup lwip_opts_ipv4 + * @{ + */ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#if !defined LWIP_ICMP || defined __DOXYGEN__ +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#if !defined ICMP_TTL || defined __DOXYGEN__ +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#if !defined LWIP_BROADCAST_PING || defined __DOXYGEN__ +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#if !defined LWIP_MULTICAST_PING || defined __DOXYGEN__ +#define LWIP_MULTICAST_PING 0 +#endif +/** + * @} + */ + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * @defgroup lwip_opts_raw RAW + * @ingroup lwip_opts_callback + * @{ + */ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#if !defined LWIP_RAW || defined __DOXYGEN__ +#define LWIP_RAW 0 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#if !defined RAW_TTL || defined __DOXYGEN__ +#define RAW_TTL (IP_DEFAULT_TTL) +#endif +/** + * @} + */ + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_dhcp DHCP + * @ingroup lwip_opts_ipv4 + * @{ + */ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#if !defined LWIP_DHCP || defined __DOXYGEN__ +#define LWIP_DHCP 0 +#endif +#if !LWIP_IPV4 +/* disable DHCP when IPv4 is disabled */ +#undef LWIP_DHCP +#define LWIP_DHCP 0 +#endif /* !LWIP_IPV4 */ + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#if !defined DHCP_DOES_ARP_CHECK || defined __DOXYGEN__ +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/** + * LWIP_DHCP_CHECK_LINK_UP==1: dhcp_start() only really starts if the netif has + * NETIF_FLAG_LINK_UP set in its flags. As this is only an optimization and + * netif drivers might not set this flag, the default is off. If enabled, + * netif_set_link_up() must be called to continue dhcp starting. + */ +#if !defined LWIP_DHCP_CHECK_LINK_UP +#define LWIP_DHCP_CHECK_LINK_UP 0 +#endif + +/** + * LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name. + */ +#if !defined LWIP_DHCP_BOOTP_FILE || defined __DOXYGEN__ +#define LWIP_DHCP_BOOTP_FILE 0 +#endif + +/** + * LWIP_DHCP_GETS_NTP==1: Request NTP servers with discover/select. For each + * response packet, an callback is called, which has to be provided by the port: + * void dhcp_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); +*/ +#if !defined LWIP_DHCP_GET_NTP_SRV || defined __DOXYGEN__ +#define LWIP_DHCP_GET_NTP_SRV 0 +#endif + +/** + * The maximum of NTP servers requested + */ +#if !defined LWIP_DHCP_MAX_NTP_SERVERS || defined __DOXYGEN__ +#define LWIP_DHCP_MAX_NTP_SERVERS 1 +#endif + +/** + * LWIP_DHCP_MAX_DNS_SERVERS > 0: Request DNS servers with discover/select. + * DHCP servers received in the response are passed to DNS via @ref dns_setserver() + * (up to the maximum limit defined here). + */ +#if !defined LWIP_DHCP_MAX_DNS_SERVERS || defined __DOXYGEN__ +#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS +#endif +/** + * @} + */ + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_autoip AUTOIP + * @ingroup lwip_opts_ipv4 + * @{ + */ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#if !defined LWIP_AUTOIP || defined __DOXYGEN__ +#define LWIP_AUTOIP 0 +#endif +#if !LWIP_IPV4 +/* disable AUTOIP when IPv4 is disabled */ +#undef LWIP_AUTOIP +#define LWIP_AUTOIP 0 +#endif /* !LWIP_IPV4 */ + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#if !defined LWIP_DHCP_AUTOIP_COOP || defined __DOXYGEN__ +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP (the DHCP client keeps + * running in this case). This can be set as low as 1 to get an AutoIP address + * very quickly, but you should be prepared to handle a changing IP address + * when DHCP overrides AutoIP. + */ +#if !defined LWIP_DHCP_AUTOIP_COOP_TRIES || defined __DOXYGEN__ +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif +/** + * @} + */ + +/* + ---------------------------------- + ----- SNMP MIB2 support ----- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_mib2 SNMP MIB2 callbacks + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * LWIP_MIB2_CALLBACKS==1: Turn on SNMP MIB2 callbacks. + * Turn this on to get callbacks needed to implement MIB2. + * Usually MIB2_STATS should be enabled, too. + */ +#if !defined LWIP_MIB2_CALLBACKS || defined __DOXYGEN__ +#define LWIP_MIB2_CALLBACKS 0 +#endif +/** + * @} + */ + +/* + ---------------------------------- + ----- Multicast/IGMP options ----- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_igmp IGMP + * @ingroup lwip_opts_ipv4 + * @{ + */ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#if !defined LWIP_IGMP || defined __DOXYGEN__ +#define LWIP_IGMP 0 +#endif +#if !LWIP_IPV4 +#undef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/** + * LWIP_MULTICAST_TX_OPTIONS==1: Enable multicast TX support like the socket options + * IP_MULTICAST_TTL/IP_MULTICAST_IF/IP_MULTICAST_LOOP + */ +#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__ +#define LWIP_MULTICAST_TX_OPTIONS (LWIP_IGMP && LWIP_UDP) +#endif +/** + * @} + */ + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_dns DNS + * @ingroup lwip_opts_callback + * @{ + */ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#if !defined LWIP_DNS || defined __DOXYGEN__ +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#if !defined DNS_TABLE_SIZE || defined __DOXYGEN__ +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#if !defined DNS_MAX_NAME_LENGTH || defined __DOXYGEN__ +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers + * The first server can be initialized automatically by defining + * DNS_SERVER_ADDRESS(ipaddr), where 'ipaddr' is an 'ip_addr_t*' + */ +#if !defined DNS_MAX_SERVERS || defined __DOXYGEN__ +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#if !defined DNS_DOES_NAME_CHECK || defined __DOXYGEN__ +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** LWIP_DNS_SECURE: controls the security level of the DNS implementation + * Use all DNS security features by default. + * This is overridable but should only be needed by very small targets + * or when using against non standard DNS servers. */ +#if !defined LWIP_DNS_SECURE || defined __DOXYGEN__ +#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) +#endif + +/* A list of DNS security features follows */ +#define LWIP_DNS_SECURE_RAND_XID 1 +#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2 +#define LWIP_DNS_SECURE_RAND_SRC_PORT 4 + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, you have to define an initializer: + * \#define DNS_LOCAL_HOSTLIST_INIT {DNS_LOCAL_HOSTLIST_ELEM("host_ip4", IPADDR4_INIT_BYTES(1,2,3,4)), \ + * DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)} + * + * Instead, you can also use an external function: + * \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype) + * that looks up the IP address and returns ERR_OK if found (LWIP_DNS_ADDRTYPE_xxx is passed in dns_addrtype). + */ +#if !defined DNS_LOCAL_HOSTLIST || defined __DOXYGEN__ +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__ +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Set this to 1 to enable querying ".local" names via mDNS + * using a One-Shot Multicast DNS Query */ +#if !defined LWIP_DNS_SUPPORT_MDNS_QUERIES || defined __DOXYGEN__ +#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 +#endif +/** + * @} + */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * @defgroup lwip_opts_udp UDP + * @ingroup lwip_opts_callback + * @{ + */ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#if !defined LWIP_UDP || defined __DOXYGEN__ +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#if !defined LWIP_UDPLITE || defined __DOXYGEN__ +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#if !defined UDP_TTL || defined __DOXYGEN__ +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#if !defined LWIP_NETBUF_RECVINFO || defined __DOXYGEN__ +#define LWIP_NETBUF_RECVINFO 0 +#endif +/** + * @} + */ + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * @defgroup lwip_opts_tcp TCP + * @ingroup lwip_opts_callback + * @{ + */ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#if !defined LWIP_TCP || defined __DOXYGEN__ +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#if !defined TCP_TTL || defined __DOXYGEN__ +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well. + * ATTENTION: when using TCP_RCV_SCALE, TCP_WND is the total size + * with scaling applied. Maximum window value in the TCP header + * will be TCP_WND >> TCP_RCV_SCALE + */ +#if !defined TCP_WND || defined __DOXYGEN__ +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#if !defined TCP_MAXRTX || defined __DOXYGEN__ +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#if !defined TCP_SYNMAXRTX || defined __DOXYGEN__ +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#if !defined TCP_QUEUE_OOSEQ || defined __DOXYGEN__ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#if !defined TCP_MSS || defined __DOXYGEN__ +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#if !defined TCP_CALCULATE_EFF_SEND_MSS || defined __DOXYGEN__ +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#if !defined TCP_SND_BUF || defined __DOXYGEN__ +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#if !defined TCP_SND_QUEUELEN || defined __DOXYGEN__ +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#if !defined TCP_SNDLOWAT || defined __DOXYGEN__ +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#if !defined TCP_SNDQUEUELOWAT || defined __DOXYGEN__ +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. + */ +#if !defined TCP_OOSEQ_MAX_BYTES || defined __DOXYGEN__ +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. + */ +#if !defined TCP_OOSEQ_MAX_PBUFS || defined __DOXYGEN__ +#define TCP_OOSEQ_MAX_PBUFS 0 +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#if !defined TCP_LISTEN_BACKLOG || defined __DOXYGEN__ +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#if !defined TCP_DEFAULT_LISTEN_BACKLOG || defined __DOXYGEN__ +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#if !defined TCP_OVERSIZE || defined __DOXYGEN__ +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + * The timestamp option is currently only used to help remote hosts, it is not + * really used locally. Therefore, it is only enabled when a TS option is + * received in the initial SYN packet from a remote host. + */ +#if !defined LWIP_TCP_TIMESTAMPS || defined __DOXYGEN__ +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#if !defined TCP_WND_UPDATE_THRESHOLD || defined __DOXYGEN__ +#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. + */ +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) || defined __DOXYGEN__ +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#else +#ifndef LWIP_EVENT_API +#define LWIP_EVENT_API 0 +#endif +#ifndef LWIP_CALLBACK_API +#define LWIP_CALLBACK_API 0 +#endif +#endif + +/** + * LWIP_WND_SCALE and TCP_RCV_SCALE: + * Set LWIP_WND_SCALE to 1 to enable window scaling. + * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the + * range of [0..14]). + * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large + * send window while having a small receive window only. + */ +#if !defined LWIP_WND_SCALE || defined __DOXYGEN__ +#define LWIP_WND_SCALE 0 +#define TCP_RCV_SCALE 0 +#endif +/** + * @} + */ + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * @defgroup lwip_opts_pbuf PBUF + * @ingroup lwip_opts + * @{ + */ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#if !defined PBUF_LINK_HLEN || defined __DOXYGEN__ +#if defined LWIP_HOOK_VLAN_SET && !defined __DOXYGEN__ +#define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) +#else /* LWIP_HOOK_VLAN_SET */ +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif /* LWIP_HOOK_VLAN_SET */ +#endif + +/** + * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated + * for an additional encapsulation header before ethernet headers (e.g. 802.11) + */ +#if !defined PBUF_LINK_ENCAPSULATION_HLEN || defined __DOXYGEN__ +#define PBUF_LINK_ENCAPSULATION_HLEN 0u +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accommodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__ +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) +#endif +/** + * @} + */ + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * @defgroup lwip_opts_netif NETIF + * @ingroup lwip_opts + * @{ + */ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#if !defined LWIP_NETIF_HOSTNAME || defined __DOXYGEN__ +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#if !defined LWIP_NETIF_API || defined __DOXYGEN__ +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquisition) + */ +#if !defined LWIP_NETIF_STATUS_CALLBACK || defined __DOXYGEN__ +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#if !defined LWIP_NETIF_LINK_CALLBACK || defined __DOXYGEN__ +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#if !defined LWIP_NETIF_REMOVE_CALLBACK || defined __DOXYGEN__ +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#if !defined LWIP_NETIF_HWADDRHINT || defined __DOXYGEN__ +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#if !defined LWIP_NETIF_TX_SINGLE_PBUF || defined __DOXYGEN__ +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/** + * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store + * data in client_data member array of struct netif. + */ +#if !defined LWIP_NUM_NETIF_CLIENT_DATA || defined __DOXYGEN__ +#define LWIP_NUM_NETIF_CLIENT_DATA 0 +#endif +/** + * @} + */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_loop Loopback interface + * @ingroup lwip_opts_netif + * @{ + */ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1). + * This is only needed when no real netifs are available. If at least one other + * netif is available, loopback traffic uses this netif. + */ +#if !defined LWIP_HAVE_LOOPIF || defined __DOXYGEN__ +#define LWIP_HAVE_LOOPIF LWIP_NETIF_LOOPBACK +#endif + +/** + * LWIP_LOOPIF_MULTICAST==1: Support multicast/IGMP on loop interface (127.0.0.1). + */ +#if !defined LWIP_LOOPIF_MULTICAST || defined __DOXYGEN__ +#define LWIP_LOOPIF_MULTICAST 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#if !defined LWIP_NETIF_LOOPBACK || defined __DOXYGEN__ +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#if !defined LWIP_LOOPBACK_MAX_PBUFS || defined __DOXYGEN__ +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#if !defined LWIP_NETIF_LOOPBACK_MULTITHREADING || defined __DOXYGEN__ +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif +/** + * @} + */ + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_thread Threading + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#if !defined TCPIP_THREAD_NAME || defined __DOXYGEN__ +#define TCPIP_THREAD_NAME "tcpip_thread" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined TCPIP_THREAD_STACKSIZE || defined __DOXYGEN__ +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__ +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#if !defined TCPIP_MBOX_SIZE || defined __DOXYGEN__ +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * Define this to something that triggers a watchdog. This is called from + * tcpip_thread after processing a message. + */ +#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__ +#define LWIP_TCPIP_THREAD_ALIVE() +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#if !defined SLIPIF_THREAD_NAME || defined __DOXYGEN__ +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined SLIPIF_THREAD_STACKSIZE || defined __DOXYGEN__ +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined SLIPIF_THREAD_PRIO || defined __DOXYGEN__ +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#if !defined DEFAULT_THREAD_NAME || defined __DOXYGEN__ +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined DEFAULT_THREAD_STACKSIZE || defined __DOXYGEN__ +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#if !defined DEFAULT_THREAD_PRIO || defined __DOXYGEN__ +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#if !defined DEFAULT_RAW_RECVMBOX_SIZE || defined __DOXYGEN__ +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#if !defined DEFAULT_UDP_RECVMBOX_SIZE || defined __DOXYGEN__ +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#if !defined DEFAULT_TCP_RECVMBOX_SIZE || defined __DOXYGEN__ +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#if !defined DEFAULT_ACCEPTMBOX_SIZE || defined __DOXYGEN__ +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif +/** + * @} + */ + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * @defgroup lwip_opts_netconn Netconn + * @ingroup lwip_opts_threadsafe_apis + * @{ + */ +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#if !defined LWIP_NETCONN || defined __DOXYGEN__ +#define LWIP_NETCONN 1 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create + * timers running in tcpip_thread from another thread. + */ +#if !defined LWIP_TCPIP_TIMEOUT || defined __DOXYGEN__ +#define LWIP_TCPIP_TIMEOUT 0 +#endif + +/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per + * thread calling socket/netconn functions instead of allocating one + * semaphore per netconn (and per select etc.) + * ATTENTION: a thread-local semaphore for API calls is needed: + * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t* + * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore + * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore + * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). + * Ports may call these for threads created with sys_thread_new(). + */ +#if !defined LWIP_NETCONN_SEM_PER_THREAD || defined __DOXYGEN__ +#define LWIP_NETCONN_SEM_PER_THREAD 0 +#endif + +/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, + * writing from a 2nd thread and closing from a 3rd thread at the same time. + * ATTENTION: This is currently really alpha! Some requirements: + * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from + * multiple threads at once + * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox + * and prevent a task pending on this during/after deletion + */ +#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__ +#define LWIP_NETCONN_FULLDUPLEX 0 +#endif +/** + * @} + */ + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * @defgroup lwip_opts_socket Sockets + * @ingroup lwip_opts_threadsafe_apis + * @{ + */ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#if !defined LWIP_SOCKET || defined __DOXYGEN__ +#define LWIP_SOCKET 1 +#endif + +/* LWIP_SOCKET_SET_ERRNO==1: Set errno when socket functions cannot complete + * successfully, as required by POSIX. Default is POSIX-compliant. + */ +#if !defined LWIP_SOCKET_SET_ERRNO || defined __DOXYGEN__ +#define LWIP_SOCKET_SET_ERRNO 1 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names through defines. + * LWIP_COMPAT_SOCKETS==2: Same as ==1 but correctly named functions are created. + * While this helps code completion, it might conflict with existing libraries. + * (only used if you use sockets.c) + */ +#if !defined LWIP_COMPAT_SOCKETS || defined __DOXYGEN__ +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#if !defined LWIP_POSIX_SOCKETS_IO_NAMES || defined __DOXYGEN__ +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n. + * This can be useful when there are multiple APIs which create file descriptors. + * When they all start with a different offset and you won't make them overlap you can + * re implement read/write/close/ioctl/fnctl to send the requested action to the right + * library (sharing select will need more work though). + */ +#if !defined LWIP_SOCKET_OFFSET || defined __DOXYGEN__ +#define LWIP_SOCKET_OFFSET 0 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#if !defined LWIP_TCP_KEEPALIVE || defined __DOXYGEN__ +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#if !defined LWIP_SO_SNDTIMEO || defined __DOXYGEN__ +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#if !defined LWIP_SO_RCVTIMEO || defined __DOXYGEN__ +#define LWIP_SO_RCVTIMEO 0 +#endif + +/** + * LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int + * (milliseconds, much like winsock does) instead of a struct timeval (default). + */ +#if !defined LWIP_SO_SNDRCVTIMEO_NONSTANDARD || defined __DOXYGEN__ +#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__ +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * LWIP_SO_LINGER==1: Enable SO_LINGER processing. + */ +#if !defined LWIP_SO_LINGER || defined __DOXYGEN__ +#define LWIP_SO_LINGER 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#if !defined RECV_BUFSIZE_DEFAULT || defined __DOXYGEN__ +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * By default, TCP socket/netconn close waits 20 seconds max to send the FIN + */ +#if !defined LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT || defined __DOXYGEN__ +#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#if !defined SO_REUSE || defined __DOXYGEN__ +#define SO_REUSE 0 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#if !defined SO_REUSE_RXTOALL || defined __DOXYGEN__ +#define SO_REUSE_RXTOALL 0 +#endif + +/** + * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of + * pending data in the network buffer. This is the way windows does it. It's + * the default for lwIP since it is smaller. + * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next + * pending datagram in bytes. This is the way linux does it. This code is only + * here for compatibility. + */ +#if !defined LWIP_FIONREAD_LINUXMODE || defined __DOXYGEN__ +#define LWIP_FIONREAD_LINUXMODE 0 +#endif +/** + * @} + */ + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * @defgroup lwip_opts_stats Statistics + * @ingroup lwip_opts_debug + * @{ + */ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#if !defined LWIP_STATS || defined __DOXYGEN__ +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#if !defined LWIP_STATS_DISPLAY || defined __DOXYGEN__ +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#if !defined LINK_STATS || defined __DOXYGEN__ +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#if !defined ETHARP_STATS || defined __DOXYGEN__ +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#if !defined IP_STATS || defined __DOXYGEN__ +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#if !defined IPFRAG_STATS || defined __DOXYGEN__ +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#if !defined ICMP_STATS || defined __DOXYGEN__ +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#if !defined IGMP_STATS || defined __DOXYGEN__ +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#if !defined UDP_STATS || defined __DOXYGEN__ +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#if !defined TCP_STATS || defined __DOXYGEN__ +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#if !defined MEM_STATS || defined __DOXYGEN__ +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#if !defined MEMP_STATS || defined __DOXYGEN__ +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#if !defined SYS_STATS || defined __DOXYGEN__ +#define SYS_STATS (NO_SYS == 0) +#endif + +/** + * IP6_STATS==1: Enable IPv6 stats. + */ +#if !defined IP6_STATS || defined __DOXYGEN__ +#define IP6_STATS (LWIP_IPV6) +#endif + +/** + * ICMP6_STATS==1: Enable ICMP for IPv6 stats. + */ +#if !defined ICMP6_STATS || defined __DOXYGEN__ +#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) +#endif + +/** + * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. + */ +#if !defined IP6_FRAG_STATS || defined __DOXYGEN__ +#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) +#endif + +/** + * MLD6_STATS==1: Enable MLD for IPv6 stats. + */ +#if !defined MLD6_STATS || defined __DOXYGEN__ +#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) +#endif + +/** + * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. + */ +#if !defined ND6_STATS || defined __DOXYGEN__ +#define ND6_STATS (LWIP_IPV6) +#endif + +/** + * MIB2_STATS==1: Stats for SNMP MIB2. + */ +#if !defined MIB2_STATS || defined __DOXYGEN__ +#define MIB2_STATS 0 +#endif + +#else + +#define LINK_STATS 0 +#define ETHARP_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define IP6_STATS 0 +#define ICMP6_STATS 0 +#define IP6_FRAG_STATS 0 +#define MLD6_STATS 0 +#define ND6_STATS 0 +#define MIB2_STATS 0 + +#endif /* LWIP_STATS */ +/** + * @} + */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * @defgroup lwip_opts_checksum Checksum + * @ingroup lwip_opts_infrastructure + * @{ + */ +/** + * LWIP_CHECKSUM_CTRL_PER_NETIF==1: Checksum generation/check can be enabled/disabled + * per netif. + * ATTENTION: if enabled, the CHECKSUM_GEN_* and CHECKSUM_CHECK_* defines must be enabled! + */ +#if !defined LWIP_CHECKSUM_CTRL_PER_NETIF || defined __DOXYGEN__ +#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 +#endif + +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#if !defined CHECKSUM_GEN_IP || defined __DOXYGEN__ +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#if !defined CHECKSUM_GEN_UDP || defined __DOXYGEN__ +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#if !defined CHECKSUM_GEN_TCP || defined __DOXYGEN__ +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#if !defined CHECKSUM_GEN_ICMP || defined __DOXYGEN__ +#define CHECKSUM_GEN_ICMP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets. + */ +#if !defined CHECKSUM_GEN_ICMP6 || defined __DOXYGEN__ +#define CHECKSUM_GEN_ICMP6 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#if !defined CHECKSUM_CHECK_IP || defined __DOXYGEN__ +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#if !defined CHECKSUM_CHECK_UDP || defined __DOXYGEN__ +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#if !defined CHECKSUM_CHECK_TCP || defined __DOXYGEN__ +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets. + */ +#if !defined CHECKSUM_CHECK_ICMP || defined __DOXYGEN__ +#define CHECKSUM_CHECK_ICMP 1 +#endif + +/** + * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets + */ +#if !defined CHECKSUM_CHECK_ICMP6 || defined __DOXYGEN__ +#define CHECKSUM_CHECK_ICMP6 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#if !defined LWIP_CHECKSUM_ON_COPY || defined __DOXYGEN__ +#define LWIP_CHECKSUM_ON_COPY 0 +#endif +/** + * @} + */ + +/* + --------------------------------------- + ---------- IPv6 options --------------- + --------------------------------------- +*/ +/** + * @defgroup lwip_opts_ipv6 IPv6 + * @ingroup lwip_opts + * @{ + */ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#if !defined LWIP_IPV6 || defined __DOXYGEN__ +#define LWIP_IPV6 0 +#endif + +/** + * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. + */ +#if !defined LWIP_IPV6_NUM_ADDRESSES || defined __DOXYGEN__ +#define LWIP_IPV6_NUM_ADDRESSES 3 +#endif + +/** + * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs + */ +#if !defined LWIP_IPV6_FORWARD || defined __DOXYGEN__ +#define LWIP_IPV6_FORWARD 0 +#endif + +/** + * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. + */ +#if !defined LWIP_IPV6_FRAG || defined __DOXYGEN__ +#define LWIP_IPV6_FRAG 0 +#endif + +/** + * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented + */ +#if !defined LWIP_IPV6_REASS || defined __DOXYGEN__ +#define LWIP_IPV6_REASS (LWIP_IPV6) +#endif + +/** + * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during + * network startup. + */ +#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__ +#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 +#endif + +/** + * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. + */ +#if !defined LWIP_IPV6_AUTOCONFIG || defined __DOXYGEN__ +#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) +#endif + +/** + * LWIP_IPV6_DUP_DETECT_ATTEMPTS=[0..7]: Number of duplicate address detection attempts. + */ +#if !defined LWIP_IPV6_DUP_DETECT_ATTEMPTS || defined __DOXYGEN__ +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 +#endif +/** + * @} + */ + +/** + * @defgroup lwip_opts_icmp6 ICMP6 + * @ingroup lwip_opts_ipv6 + * @{ + */ +/** + * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) + */ +#if !defined LWIP_ICMP6 || defined __DOXYGEN__ +#define LWIP_ICMP6 (LWIP_IPV6) +#endif + +/** + * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in + * ICMPv6 error messages. + */ +#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__ +#define LWIP_ICMP6_DATASIZE 8 +#endif + +/** + * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages + */ +#if !defined LWIP_ICMP6_HL || defined __DOXYGEN__ +#define LWIP_ICMP6_HL 255 +#endif +/** + * @} + */ + +/** + * @defgroup lwip_opts_mld6 Multicast listener discovery + * @ingroup lwip_opts_ipv6 + * @{ + */ +/** + * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. + * If LWIP_IPV6 is enabled but this setting is disabled, the MAC layer must + * indiscriminately pass all inbound IPv6 multicast traffic to lwIP. + */ +#if !defined LWIP_IPV6_MLD || defined __DOXYGEN__ +#define LWIP_IPV6_MLD (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast groups that can be joined. + * There must be enough groups so that each netif can join the solicited-node + * multicast group for each of its local addresses, plus one for MDNS if + * applicable, plus any number of groups to be joined on UDP sockets. + */ +#if !defined MEMP_NUM_MLD6_GROUP || defined __DOXYGEN__ +#define MEMP_NUM_MLD6_GROUP 4 +#endif +/** + * @} + */ + +/** + * @defgroup lwip_opts_nd6 Neighbor discovery + * @ingroup lwip_opts_ipv6 + * @{ + */ +/** + * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address + * is being resolved. + */ +#if !defined LWIP_ND6_QUEUEING || defined __DOXYGEN__ +#define LWIP_ND6_QUEUEING (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. + */ +#if !defined MEMP_NUM_ND6_QUEUE || defined __DOXYGEN__ +#define MEMP_NUM_ND6_QUEUE 20 +#endif + +/** + * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache + */ +#if !defined LWIP_ND6_NUM_NEIGHBORS || defined __DOXYGEN__ +#define LWIP_ND6_NUM_NEIGHBORS 10 +#endif + +/** + * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache + */ +#if !defined LWIP_ND6_NUM_DESTINATIONS || defined __DOXYGEN__ +#define LWIP_ND6_NUM_DESTINATIONS 10 +#endif + +/** + * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache + */ +#if !defined LWIP_ND6_NUM_PREFIXES || defined __DOXYGEN__ +#define LWIP_ND6_NUM_PREFIXES 5 +#endif + +/** + * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache + */ +#if !defined LWIP_ND6_NUM_ROUTERS || defined __DOXYGEN__ +#define LWIP_ND6_NUM_ROUTERS 3 +#endif + +/** + * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send + * (neighbor solicit and router solicit) + */ +#if !defined LWIP_ND6_MAX_MULTICAST_SOLICIT || defined __DOXYGEN__ +#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 +#endif + +/** + * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages + * to send during neighbor reachability detection. + */ +#if !defined LWIP_ND6_MAX_UNICAST_SOLICIT || defined __DOXYGEN__ +#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 +#endif + +/** + * Unused: See ND RFC (time in milliseconds). + */ +#if !defined LWIP_ND6_MAX_ANYCAST_DELAY_TIME || defined __DOXYGEN__ +#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 +#endif + +/** + * Unused: See ND RFC + */ +#if !defined LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT || defined __DOXYGEN__ +#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 +#endif + +/** + * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). + * May be updated by router advertisement messages. + */ +#if !defined LWIP_ND6_REACHABLE_TIME || defined __DOXYGEN__ +#define LWIP_ND6_REACHABLE_TIME 30000 +#endif + +/** + * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages + */ +#if !defined LWIP_ND6_RETRANS_TIMER || defined __DOXYGEN__ +#define LWIP_ND6_RETRANS_TIMER 1000 +#endif + +/** + * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation + * message is sent, during neighbor reachability detection. + */ +#if !defined LWIP_ND6_DELAY_FIRST_PROBE_TIME || defined __DOXYGEN__ +#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 +#endif + +/** + * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update + * Reachable time and retransmission timers, and netif MTU. + */ +#if !defined LWIP_ND6_ALLOW_RA_UPDATES || defined __DOXYGEN__ +#define LWIP_ND6_ALLOW_RA_UPDATES 1 +#endif + +/** + * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery + * with reachability hints for connected destinations. This helps avoid sending + * unicast neighbor solicitation messages. + */ +#if !defined LWIP_ND6_TCP_REACHABILITY_HINTS || defined __DOXYGEN__ +#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 +#endif + +/** + * LWIP_ND6_RDNSS_MAX_DNS_SERVERS > 0: Use IPv6 Router Advertisement Recursive + * DNS Server Option (as per RFC 6106) to copy a defined maximum number of DNS + * servers to the DNS module. + */ +#if !defined LWIP_ND6_RDNSS_MAX_DNS_SERVERS || defined __DOXYGEN__ +#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 +#endif +/** + * @} + */ + +/** + * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. + */ +#if !defined LWIP_IPV6_DHCP6 || defined __DOXYGEN__ +#define LWIP_IPV6_DHCP6 0 +#endif + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/** + * @defgroup lwip_opts_hooks Hooks + * @ingroup lwip_opts_infrastructure + * Hooks are undefined by default, define them to a function if you need them. + * @{ + */ + +/** + * LWIP_HOOK_FILENAME: Custom filename to #include in files that provide hooks. + * Declare your hook function prototypes in there, you may also #include all headers + * providing data types that are need in this file. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_FILENAME "path/to/my/lwip_hooks.h" +#endif + +/** + * LWIP_HOOK_TCP_ISN: + * Hook for generation of the Initial Sequence Number (ISN) for a new TCP + * connection. The default lwIP ISN generation algorithm is very basic and may + * allow for TCP spoofing attacks. This hook provides the means to implement + * the standardized ISN generation algorithm from RFC 6528 (see contrib/adons/tcp_isn), + * or any other desired algorithm as a replacement. + * Called from tcp_connect() and tcp_listen_input() when an ISN is needed for + * a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n + * Signature: u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port); + * - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n + * Arguments: + * - local_ip: pointer to the local IP address of the connection + * - local_port: local port number of the connection (host-byte order) + * - remote_ip: pointer to the remote IP address of the connection + * - remote_port: remote port number of the connection (host-byte order)\n + * Return value: + * - the 32-bit Initial Sequence Number to use for the new TCP connection. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port) +#endif + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_IP4_INPUT(pbuf, input_netif) +#endif + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_IP4_ROUTE() +#endif + +/** + * LWIP_HOOK_IP4_ROUTE_SRC(dest, src): + * - source-based routing for IPv4 (see LWIP_HOOK_IP4_ROUTE(), src may be NULL) + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_IP4_ROUTE_SRC(dest, src) +#endif + +/** + * LWIP_HOOK_ETHARP_GET_GW(netif, dest): + * - called from etharp_output() (IPv4) + * - netif: the netif used for sending + * - dest: the destination IPv4 address + * Returns the IPv4 address of the gateway to handle the specified destination + * IPv4 address. If NULL is returned, the netif's default gateway is used. + * The returned address MUST be directly reachable on the specified netif! + * This function is meant to implement advanced IPv4 routing together with + * LWIP_HOOK_IP4_ROUTE(). The actual routing/gateway table implementation is + * not part of lwIP but can e.g. be hidden in the netif's state argument. +*/ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_ETHARP_GET_GW(netif, dest) +#endif + +/** + * LWIP_HOOK_IP6_INPUT(pbuf, input_netif): + * - called from ip6_input() (IPv6) + * - pbuf: received struct pbuf passed to ip6_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_IP6_INPUT(pbuf, input_netif) +#endif + +/** + * LWIP_HOOK_IP6_ROUTE(src, dest): + * - called from ip6_route() (IPv6) + * - src: sourc IPv6 address + * - dest: destination IPv6 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip6_route() continues as normal. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_IP6_ROUTE(src, dest) +#endif + +/** + * LWIP_HOOK_ND6_GET_GW(netif, dest): + * - called from nd6_get_next_hop_entry() (IPv6) + * - netif: the netif used for sending + * - dest: the destination IPv6 address + * Returns the IPv6 address of the next hop to handle the specified destination + * IPv6 address. If NULL is returned, a NDP-discovered router is used instead. + * The returned address MUST be directly reachable on the specified netif! + * This function is meant to implement advanced IPv6 routing together with + * LWIP_HOOK_IP6_ROUTE(). The actual routing/gateway table implementation is + * not part of lwIP but can e.g. be hidden in the netif's state argument. +*/ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_ND6_GET_GW(netif, dest) +#endif + +/** + * LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr): + * - called from ethernet_input() if VLAN support is enabled + * - netif: struct netif on which the packet has been received + * - eth_hdr: struct eth_hdr of the packet + * - vlan_hdr: struct eth_vlan_hdr of the packet + * Return values: + * - 0: Packet must be dropped. + * - != 0: Packet must be accepted. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr) +#endif + +/** + * LWIP_HOOK_VLAN_SET: + * Hook can be used to set prio_vid field of vlan_hdr. If you need to store data + * on per-netif basis to implement this callback, see @ref netif_cd. + * Called from ethernet_output() if VLAN support (@ref ETHARP_SUPPORT_VLAN) is enabled.\n + * Signature: s32_t my_hook_vlan_set(struct netif* netif, struct pbuf* pbuf, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type);\n + * Arguments: + * - netif: struct netif that the packet will be sent through + * - p: struct pbuf packet to be sent + * - src: source eth address + * - dst: destination eth address + * - eth_type: ethernet type to packet to be sent\n + * + * + * Return values: + * - <0: Packet shall not contain VLAN header. + * - 0 <= return value <= 0xFFFF: Packet shall contain VLAN header. Return value is prio_vid in host byte order. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type) +#endif + +/** + * LWIP_HOOK_MEMP_AVAILABLE(memp_t_type): + * - called from memp_free() when a memp pool was empty and an item is now available + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_MEMP_AVAILABLE(memp_t_type) +#endif + +/** + * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif): + * Called from ethernet_input() when an unknown eth type is encountered. + * Return ERR_OK if packet is accepted, any error code otherwise. + * Payload points to ethernet header! + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif) +#endif +/** + * @} + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * @defgroup lwip_opts_debugmsg Debug messages + * @ingroup lwip_opts_debug + * @{ + */ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + * @see debugging_levels + */ +#if !defined LWIP_DBG_MIN_LEVEL || defined __DOXYGEN__ +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + * @see debugging_levels + */ +#if !defined LWIP_DBG_TYPES_ON || defined __DOXYGEN__ +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#if !defined ETHARP_DEBUG || defined __DOXYGEN__ +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#if !defined NETIF_DEBUG || defined __DOXYGEN__ +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#if !defined PBUF_DEBUG || defined __DOXYGEN__ +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#if !defined API_LIB_DEBUG || defined __DOXYGEN__ +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#if !defined API_MSG_DEBUG || defined __DOXYGEN__ +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#if !defined SOCKETS_DEBUG || defined __DOXYGEN__ +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#if !defined ICMP_DEBUG || defined __DOXYGEN__ +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#if !defined IGMP_DEBUG || defined __DOXYGEN__ +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#if !defined INET_DEBUG || defined __DOXYGEN__ +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#if !defined IP_DEBUG || defined __DOXYGEN__ +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#if !defined IP_REASS_DEBUG || defined __DOXYGEN__ +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#if !defined RAW_DEBUG || defined __DOXYGEN__ +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#if !defined MEM_DEBUG || defined __DOXYGEN__ +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#if !defined MEMP_DEBUG || defined __DOXYGEN__ +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#if !defined SYS_DEBUG || defined __DOXYGEN__ +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#if !defined TIMERS_DEBUG || defined __DOXYGEN__ +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#if !defined TCP_DEBUG || defined __DOXYGEN__ +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#if !defined TCP_INPUT_DEBUG || defined __DOXYGEN__ +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#if !defined TCP_FR_DEBUG || defined __DOXYGEN__ +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#if !defined TCP_RTO_DEBUG || defined __DOXYGEN__ +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#if !defined TCP_CWND_DEBUG || defined __DOXYGEN__ +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#if !defined TCP_WND_DEBUG || defined __DOXYGEN__ +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#if !defined TCP_OUTPUT_DEBUG || defined __DOXYGEN__ +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#if !defined TCP_RST_DEBUG || defined __DOXYGEN__ +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#if !defined TCP_QLEN_DEBUG || defined __DOXYGEN__ +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#if !defined UDP_DEBUG || defined __DOXYGEN__ +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#if !defined TCPIP_DEBUG || defined __DOXYGEN__ +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#if !defined SLIP_DEBUG || defined __DOXYGEN__ +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#if !defined DHCP_DEBUG || defined __DOXYGEN__ +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#if !defined AUTOIP_DEBUG || defined __DOXYGEN__ +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#if !defined DNS_DEBUG || defined __DOXYGEN__ +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP6_DEBUG: Enable debugging for IPv6. + */ +#if !defined IP6_DEBUG || defined __DOXYGEN__ +#define IP6_DEBUG LWIP_DBG_OFF +#endif +/** + * @} + */ + +/* + -------------------------------------------------- + ---------- Performance tracking options ---------- + -------------------------------------------------- +*/ +/** + * @defgroup lwip_opts_perf Performance + * @ingroup lwip_opts_debug + * @{ + */ +/** + * LWIP_PERF: Enable performance testing for lwIP + * (if enabled, arch/perf.h is included) + */ +#if !defined LWIP_PERF || defined __DOXYGEN__ +#define LWIP_PERF 0 +#endif +/** + * @} + */ + +#endif /* LWIP_HDR_OPT_H */ diff --git a/stacks/lwip_stack/release/lwip_helper_files/include/sys.h b/stacks/lwip_stack/release/lwip_helper_files/include/sys.h new file mode 100644 index 0000000..8eed041 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/include/sys.h @@ -0,0 +1,455 @@ +/** + * @file + * OS abstraction layer + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + */ + +#ifndef LWIP_HDR_SYS_H +#define LWIP_HDR_SYS_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ + typedef u8_t sys_sem_t; + typedef u8_t sys_mutex_t; + typedef u8_t sys_mbox_t; + +#define sys_sem_new(s, c) ERR_OK +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_valid_val(s) 0 +#define sys_sem_set_invalid(s) +#define sys_sem_set_invalid_val(s) +#define sys_mutex_new(mu) ERR_OK +#define sys_mutex_lock(mu) +#define sys_mutex_unlock(mu) +#define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) +#define sys_mbox_new(m, s) ERR_OK +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_valid_val(m) +#define sys_mbox_set_invalid(m) +#define sys_mbox_set_invalid_val(m) + +#define sys_thread_new(n,t,a,s,p) + +#define sys_msleep(t) + +#else /* NO_SYS */ + +/** 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 + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +/** Function prototype for thread functions */ + typedef void (*lwip_thread_fn) (void *arg); + +/* Function prototypes for functions to be implemented by platform ports + (in sys_arch.c) */ + +/* Mutex functions: */ + +/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#ifndef LWIP_COMPAT_MUTEX +#define LWIP_COMPAT_MUTEX 0 +#endif + +#if LWIP_COMPAT_MUTEX +/* for old ports that don't have mutexes: define them to binary semaphores */ +#define sys_mutex_t sys_sem_t +#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) +#define sys_mutex_lock(mutex) sys_sem_wait(mutex) +#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) +#define sys_mutex_free(mutex) sys_sem_free(mutex) +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +#else /* LWIP_COMPAT_MUTEX */ + +/** + * @ingroup sys_mutex + * Create a new mutex. + * Note that mutexes are expected to not be taken recursively by the lwIP code, + * so both implementation types (recursive or non-recursive) should work. + * @param mutex pointer to the mutex to create + * @return ERR_OK if successful, another err_t otherwise + */ + err_t sys_mutex_new (sys_mutex_t * mutex); +/** + * @ingroup sys_mutex + * Lock a mutex + * @param mutex the mutex to lock + */ + void sys_mutex_lock (sys_mutex_t * mutex); +/** + * @ingroup sys_mutex + * Unlock a mutex + * @param mutex the mutex to unlock + */ + void sys_mutex_unlock (sys_mutex_t * mutex); +/** + * @ingroup sys_mutex + * Delete a semaphore + * @param mutex the mutex to delete + */ + void sys_mutex_free (sys_mutex_t * mutex); +#ifndef sys_mutex_valid +/** + * @ingroup sys_mutex + * Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid + */ + int sys_mutex_valid (sys_mutex_t * mutex); +#endif +#ifndef sys_mutex_set_invalid +/** + * @ingroup sys_mutex + * Set a mutex invalid so that sys_mutex_valid returns 0 + */ + void sys_mutex_set_invalid (sys_mutex_t * mutex); +#endif +#endif /* LWIP_COMPAT_MUTEX */ + +/* Semaphore functions: */ + +/** + * @ingroup sys_sem + * Create a new semaphore + * @param sem pointer to the semaphore to create + * @param count initial count of the semaphore + * @return ERR_OK if successful, another err_t otherwise + */ + err_t sys_sem_new (sys_sem_t * sem, u8_t count); +/** + * @ingroup sys_sem + * Signals a semaphore + * @param sem the semaphore to signal + */ + void sys_sem_signal (sys_sem_t * sem); +/** + * @ingroup sys_sem + * Wait for a semaphore for the specified timeout + * @param sem the semaphore to wait for + * @param timeout timeout in milliseconds to wait (0 = wait forever) + * @return time (in milliseconds) waited for the semaphore + * or SYS_ARCH_TIMEOUT on timeout + */ + u32_t sys_arch_sem_wait (sys_sem_t * sem, u32_t timeout); +/** + * @ingroup sys_sem + * Delete a semaphore + * @param sem semaphore to delete + */ + void sys_sem_free (sys_sem_t * sem); +/** Wait for a semaphore - forever/no timeout */ +#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) +#ifndef sys_sem_valid +/** + * @ingroup sys_sem + * Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid + */ + int sys_sem_valid (sys_sem_t * sem); +#endif +#ifndef sys_sem_set_invalid +/** + * @ingroup sys_sem + * Set a semaphore invalid so that sys_sem_valid returns 0 + */ + void sys_sem_set_invalid (sys_sem_t * sem); +#endif +#ifndef sys_sem_valid_val +/** + * Same as sys_sem_valid() but taking a value, not a pointer + */ +#define sys_sem_valid_val(sem) sys_sem_valid(&(sem)) +#endif +#ifndef sys_sem_set_invalid_val +/** + * Same as sys_sem_set_invalid() but taking a value, not a pointer + */ +#define sys_sem_set_invalid_val(sem) sys_sem_set_invalid(&(sem)) +#endif + +#ifndef sys_msleep +/** + * @ingroup sys_misc + * Sleep for specified number of ms + */ + void sys_msleep (u32_t ms); /* only has a (close to) 1 ms resolution. */ +#endif + +/* Mailbox functions. */ + +/** + * @ingroup sys_mbox + * Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (minimum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise + */ + err_t sys_mbox_new (sys_mbox_t * mbox, int size); +/** + * @ingroup sys_mbox + * Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) + */ + void sys_mbox_post (sys_mbox_t * mbox, void *msg); +/** + * @ingroup sys_mbox + * Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) + */ + err_t sys_mbox_trypost (sys_mbox_t * mbox, void *msg); +/** + * @ingroup sys_mbox + * Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! + */ + u32_t sys_arch_mbox_fetch (sys_mbox_t * mbox, void **msg, u32_t timeout); +/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ +#ifndef sys_arch_mbox_tryfetch +/** + * @ingroup sys_mbox + * Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty + */ + u32_t sys_arch_mbox_tryfetch (sys_mbox_t * mbox, void **msg); +#endif +/** + * For now, we map straight to sys_arch implementation. + */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +/** + * @ingroup sys_mbox + * Delete an mbox + * @param mbox mbox to delete + */ + void sys_mbox_free (sys_mbox_t * mbox); +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) +#ifndef sys_mbox_valid +/** + * @ingroup sys_mbox + * Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid + */ + int sys_mbox_valid (sys_mbox_t * mbox); +#endif +#ifndef sys_mbox_set_invalid +/** + * @ingroup sys_mbox + * Set an mbox invalid so that sys_mbox_valid returns 0 + */ + void sys_mbox_set_invalid (sys_mbox_t * mbox); +#endif +#ifndef sys_mbox_valid_val +/** + * Same as sys_mbox_valid() but taking a value, not a pointer + */ +#define sys_mbox_valid_val(mbox) sys_mbox_valid(&(mbox)) +#endif +#ifndef sys_mbox_set_invalid_val +/** + * Same as sys_mbox_set_invalid() but taking a value, not a pointer + */ +#define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox)) +#endif + +/** + * @ingroup sys_misc + * The only thread function: + * Creates a new thread + * ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!) + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ + sys_thread_t sys_thread_new (const char *name, lwip_thread_fn thread, + void *arg, int stacksize, int prio); + +#endif /* NO_SYS */ + +/* sys_init() must be called before anything else. */ + void sys_init (void); + +#ifndef sys_jiffies +/** + * Ticks/jiffies since power up. + */ + u32_t sys_jiffies (void); +#endif + +/** + * @ingroup sys_time + * Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. + */ + u32_t sys_now (void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** + * @ingroup sys_prot + * SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** + * @ingroup sys_prot + * SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** + * @ingroup sys_prot + * SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) + sys_prot_t sys_arch_protect (void); + void sys_arch_unprotect (sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_SYS_H */ diff --git a/stacks/lwip_stack/release/lwip_helper_files/include/timeouts.h b/stacks/lwip_stack/release/lwip_helper_files/include/timeouts.h new file mode 100644 index 0000000..005db52 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/include/timeouts.h @@ -0,0 +1,134 @@ +/** + * @file + * Timer implementations + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + * Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_TIMEOUTS_H +#define LWIP_HDR_TIMEOUTS_H + +#include "lwip/opt.h" +#include "lwip/err.h" +#if !NO_SYS +#include "lwip/sys.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef LWIP_DEBUG_TIMERNAMES +#ifdef LWIP_DEBUG +#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG +#else /* LWIP_DEBUG */ +#define LWIP_DEBUG_TIMERNAMES 0 +#endif /* LWIP_DEBUG */ +#endif + +/** Function prototype for a stack-internal timer function that has to be + * called at a defined interval */ + typedef void (*lwip_cyclic_timer_handler) (void); + +/** This struct contains information about a stack-internal timer function + that has to be called at a defined interval */ + struct lwip_cyclic_timer + { + u32_t interval_ms; + lwip_cyclic_timer_handler handler; +#if LWIP_DEBUG_TIMERNAMES + const char *handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ + }; + +/** This array contains all stack-internal cyclic timers. To get the number of + * timers, use LWIP_ARRAYSIZE() */ + extern const struct lwip_cyclic_timer lwip_cyclic_timers[]; + +#if LWIP_TIMERS + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ + typedef void (*sys_timeout_handler) (void *arg); + + struct sys_timeo + { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +#if LWIP_DEBUG_TIMERNAMES + const char *handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ + }; + + void sys_timeouts_init (void); + +#if LWIP_DEBUG_TIMERNAMES + void sys_timeout_debug (u32_t msecs, sys_timeout_handler handler, void *arg, + const char *handler_name); +#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) +#else /* LWIP_DEBUG_TIMERNAMES */ + void sys_timeout (u32_t msecs, sys_timeout_handler handler, void *arg); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + void sys_untimeout (sys_timeout_handler handler, void *arg); + void sys_restart_timeouts (void); +#if NO_SYS + void sys_check_timeouts (void); + u32_t sys_timeouts_sleeptime (void); +#else /* NO_SYS */ + void sys_timeouts_mbox_fetch (sys_mbox_t * mbox, void **msg); +#endif /* NO_SYS */ + +#else /* LWIP_TIMERS */ + typedef void (*sys_timeout_handler) (void *arg); + + void sys_timeouts_init (void); + void sys_timeout (u32_t msecs, sys_timeout_handler handler, void *arg); + void sys_untimeout (sys_timeout_handler handler, void *arg); + void sys_timeouts_mbox_fetch (sys_mbox_t * mbox, void **msg); + void cyclic_timer (void *arg); + void tcpip_tcp_timer (void *arg); + void tcp_timer_needed (void); + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_TIMEOUTS_H */ diff --git a/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/atomic_32.h b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/atomic_32.h new file mode 100644 index 0000000..15a058b --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/atomic_32.h @@ -0,0 +1,53 @@ +/* + * atomic_32.h + * + */ + +#ifndef ATOMIC_32_H_ +#define ATOMIC_32_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct + { + volatile int counter; + } atomic_t; + +#define ATOMIC_INIT(i) {(i)} +#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_set(v, i) (((v)->counter) = (i)) + + static inline void atomic_add (int i, atomic_t * v) + { + __asm__ __volatile__ ( + /*LOCK_PREFIX "addl %1,%0" */ + "addl %1,%0":"+m" (v->counter):"ir" (i)); + } + + static inline void atomic_sub (int i, atomic_t * v) + { + __asm__ __volatile__ ( + /*LOCK_PREFIX "subl %1,%0" */ + "subl %1,%0":"+m" (v->counter):"ir" (i)); + } + + static __inline__ void atomic_inc (atomic_t * v) + { + __asm__ __volatile__ ( + /*LOCK_PREFIX "incl %0" */ + "incl %0":"+m" (v->counter)); + } + + static __inline__ void atomic_dec (atomic_t * v) + { + __asm__ __volatile__ ( + /*LOCK_PREFIX "decl %0" */ + "decl %0":"+m" (v->counter)); + } +#ifdef __cplusplus +} +#endif +#endif /* ATOMIC_32_H_ */ diff --git a/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/cc.h b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/cc.h new file mode 100644 index 0000000..4e21a75 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/cc.h @@ -0,0 +1,82 @@ +#ifndef LWIP_ARCH_CC_H +#define LWIP_ARCH_CC_H + +#include <sys/time.h> +#include <sys/types.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef LWIP_MAX_S16_NUM +#define LWIP_MAX_S16_NUM ((s16_t)0x7fff) +#endif + +#ifndef LWIP_MAX_U16_NUM +#define LWIP_MAX_U16_NUM ((u16_t)0xFfff) +#endif + +#ifndef LWIP_MAX_U32_NUM +#define LWIP_MAX_U32_NUM ((u32_t)0xffffffff) +#endif + +#ifndef LWIP_MAX_S32_NUM +#define LWIP_MAX_S32_NUM ((s32_t)0x7fffffff) +#endif + +#ifndef LWIP_MAX_U64_NUM +#define LWIP_MAX_U64_NUM ((u64_t)0xffffffffffffffff) +#endif + +#ifndef LWIP_MAX_S64_NUM +#define LWIP_MAX_S64_NUM ((s64_t)0x7fffffffffffffff) +#endif + +#define NONBLOCK_MODE_FOR_ALG 2 /* it is possible to get fail */ +#define BLOCK_MODE_FOR_ALG 1 /* will block till success */ +#define NONBLOCK_MODE_NOT_FOR_ALG 0 + +typedef uint64_t u64_t; +typedef int64_t s64_t; + +typedef uint32_t u32_t; +typedef int32_t s32_t; + +typedef uint16_t u16_t; +typedef int16_t s16_t; + +typedef uint8_t u8_t; +typedef int8_t s8_t; + +typedef uintptr_t mem_ptr_t; + +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END + +#define S16_F "d" +#define U16_F "u" +#define X16_F "x" + +#define S32_F "d" +#define U32_F "u" +#define X32_F "x" + +#define S64_F "ld" +#define U64_F "lu" +#define X64_F "x" + +#ifndef BYTE_ORDER +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +//#define LWIP_PROVIDE_ERRNO + +#ifndef LWIP_PLATFORM_DIAG +#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0) +#endif +#ifndef LWIP_DEBUG +#define LWIP_DEBUG 1 +#endif +#endif diff --git a/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/queue.h b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/queue.h new file mode 100644 index 0000000..238ef05 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/queue.h @@ -0,0 +1,30 @@ +#ifndef __QUEUE_H__ +#define __QUEUE_H__ +#ifdef __cplusplus +extern "C" +{ + +#endif +#include "common_mem_base_type.h" +#ifdef HAL_LIB +#else +#include "rte_ring.h" +#endif +#include "nsfw_mem_api.h" +//#include "stackx_dfx_api.h" + +#include "sys.h" + + typedef struct queue + { + PRIMARY_ADDR mring_handle llring; + } queue_t; + + err_t queue_push (queue_t * q, void *msg, int isTrypush); + void *queue_pop (queue_t * q, u32_t * timeout, int isTryPop); + +#ifdef __cplusplus + +} +#endif +#endif diff --git a/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/sys_arch.h b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/sys_arch.h new file mode 100644 index 0000000..92ff049 --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/sys_arch.h @@ -0,0 +1,29 @@ +#ifndef STACKX_ARCH_SYS_ARCH_H +#define STACKX_ARCH_SYS_ARCH_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <sys/types.h> +#include <semaphore.h> + +#include "cc.h" + +/*add by daifen 2012.7.27*/ + typedef uint64_t sys_thread_t; + + extern u64_t hz_per_ms; + + void stackx_global_lock (void); + void stackx_global_unlock (void); + +#define SYS_ARCH_PROTECT(lev) stackx_global_lock() +#define SYS_ARCH_UNPROTECT(lev) stackx_global_unlock() +#define SYS_ARCH_DECL_PROTECT(lev) + +#ifdef __cplusplus + +} +#endif +#endif diff --git a/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/win_minmax.h b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/win_minmax.h new file mode 100644 index 0000000..e1e64ac --- /dev/null +++ b/stacks/lwip_stack/release/lwip_helper_files/lwip/arch/win_minmax.h @@ -0,0 +1,120 @@ +/** + * lib/minmax.c: windowed min/max tracker by Kathleen Nichols. + * + */ +#ifndef MINMAX_H +#define MINMAX_H + +#include "types.h" +#include "rtp_branch_prediction.h" + +/* A single data point for our parameterized min-max tracker */ +struct minmax_sample +{ + u32_t t; /* time measurement was taken */ + u32_t v; /* value measured */ +}; + +/* State for the parameterized min-max tracker */ +struct minmax +{ + struct minmax_sample s[3]; +}; + +static inline u32_t +minmax_get (const struct minmax *m) +{ + return m->s[0].v; +} + +static inline u32_t +minmax_reset (struct minmax *m, u32_t t, u32_t meas) +{ + struct minmax_sample val = {.t = t,.v = meas }; + + m->s[2] = m->s[1] = m->s[0] = val; + return m->s[0].v; +} + +/* As time advances, update the 1st, 2nd, and 3rd choices. */ +static u32_t +minmax_subwin_update (struct minmax *m, u32_t win, + const struct minmax_sample *val) +{ + u32_t dt = val->t - m->s[0].t; + + if (unlikely (dt > win)) + { + /* + * Passed entire window without a new val so make 2nd + * choice the new val & 3rd choice the new 2nd choice. + * we may have to iterate this since our 2nd choice + * may also be outside the window (we checked on entry + * that the third choice was in the window). + */ + m->s[0] = m->s[1]; + m->s[1] = m->s[2]; + m->s[2] = *val; + if (unlikely (val->t - m->s[0].t > win)) + { + m->s[0] = m->s[1]; + m->s[1] = m->s[2]; + m->s[2] = *val; + } + } + else if (unlikely (m->s[1].t == m->s[0].t) && dt > win / 4) + { + /* + * We've passed a quarter of the window without a new val + * so take a 2nd choice from the 2nd quarter of the window. + */ + m->s[2] = m->s[1] = *val; + } + else if (unlikely (m->s[2].t == m->s[1].t) && dt > win / 2) + { + /* + * We've passed half the window without finding a new val + * so take a 3rd choice from the last half of the window + */ + m->s[2] = *val; + } + return m->s[0].v; +} + +/* Check if new measurement updates the 1st, 2nd or 3rd choice max. */ +static inline u32_t +minmax_running_max (struct minmax *m, u32_t win, u32_t t, u32_t meas) +{ + struct minmax_sample val = {.t = t,.v = meas }; + + if (unlikely (val.v >= m->s[0].v) || /* found new max? */ + unlikely (val.t - m->s[2].t > win)) /* nothing left in window? */ + return minmax_reset (m, t, meas); /* forget earlier samples */ + + if (unlikely (val.v >= m->s[1].v)) + m->s[2] = m->s[1] = val; + else if (unlikely (val.v >= m->s[2].v)) + m->s[2] = val; + + return minmax_subwin_update (m, win, &val); +} + +/* Check if new measurement updates the 1st, 2nd or 3rd choice min. */ +static inline u32_t +minmax_running_min (struct minmax *m, u32_t win, u32_t t, u32_t meas) +{ + struct minmax_sample val = {.t = t,.v = meas }; + + if (unlikely (val.v <= m->s[0].v) || /* found new min? */ + unlikely (val.t - m->s[2].t > win)) /* nothing left in window? */ + return minmax_reset (m, t, meas); /* forget earlier samples */ + + if (unlikely (val.v <= m->s[1].v)) + m->s[2] = m->s[1] = val; + else if (unlikely (val.v <= m->s[2].v)) + m->s[2] = val; + + return minmax_subwin_update (m, win, &val); +} + +#endif diff --git a/stacks/lwip_stack/release/script/nstack_fun.sh b/stacks/lwip_stack/release/script/nstack_fun.sh new file mode 100644 index 0000000..bb33a6a --- /dev/null +++ b/stacks/lwip_stack/release/script/nstack_fun.sh @@ -0,0 +1,591 @@ +#!/bin/bash + +check_file_size() +{ + if [ -n "$1" ]&&[ -f "$1" ] + then + local log_size=`stat -c %s $1` + if [ ${log_size} -gt $MAX_LOG_FILE_SIZE ] + then + mv $1 $1.bk + fi + fi +} + +log() +{ + check_file_size $LOG_FILE + + #1 line number + local printStr="$2" + cur_date=`date +'%m%d %H:%M:%S.%6N' -u` + pid=$$ + file=$0 + local log_head="I${cur_date} ${file##*/}:$1 ${pid}]" + + printf "${log_head} $printStr\n" >> $LOG_FILE 2>/dev/null +} + +get_call_stack() +{ + local proc_name="$1" + log $LINENO "gdb info in call stack:" + gdb -batch -ex "t a a bt" -p `pidof $proc_name`>> $LOG_FILE 2>/dev/null + log $LINENO "top in call stack:" + top -H -p `pidof $proc_name` -n 1 -b >> $LOG_FILE 2>/dev/null + log $LINENO "mpstat in call stack:" + mpstat -A >> $LOG_FILE 2>/dev/null +} + +gdb_set() +{ + local mod="$1" + if [ "$mod" = "stop" ];then + gdb -batch -ex "set g_hbt_switch=0" -p `pidof nStackMain` + gdb -batch -ex "set g_hbt_switch=0" -p `pidof nStackMaster` + log $LINENO "gdb stop" + else + gdb -batch -ex "set g_hbt_switch=1" -p `pidof nStackMain` + gdb -batch -ex "set g_hbt_switch=1" -p `pidof nStackMaster` + log $LINENO "gdb start" + fi +} + +get_core_mask() +{ + local sys_core=`cat /proc/cpuinfo | grep processor | wc -l` + log $LINENO "system has ${sys_core} cores" + #if sys_core too large 2^$sys_core will overflow; so reset sys_core; z00203440 20170323 + if [ $sys_core -gt 8 ] + then + sys_core=8 + log $LINENO "sys_core too large reset to ${sys_core}" + fi + + base=`echo | awk -v ex=$sys_core 'BEGIN{a=2^ex; print a}'` + local temp=`expr $base - 1` + printf %X $temp + return $sys_core +} + +init_log_file() +{ + if [ -n $LOG_FILE_DIR ]&&[ ! -f $LOG_FILE_DIR ] + then + sudo mkdir -p $LOG_FILE_DIR + fi + + check_file_size $LOG_FILE + + if [ -n $DPDK_FILE_DIR ]&&[ ! -f $DPDK_FILE_DIR ] + then + sudo mkdir -p $DPDK_FILE_DIR + fi + + check_file_size $DPDK_FILE + + #must create the directory under the current user account + if [ -n $RUNTIME_DIR ]&&[ ! -f $RUNTIME_DIR ] + then + mkdir -p $RUNTIME_DIR + fi +} + +delete_log_file() { + if [ -n $RUNNING_FILE_DIR ]&&[ -d $RUNNING_FILE_DIR ]&&[ -n $RUNNING_FILE_NAME ]; then + rm -rf $RUNNING_FILE_DIR/*${RUNNING_FILE_NAME}* + fi + if [ -n $RUNNING_FILE_DIR ]&&[ -d $RUNNING_FILE_DIR ]&&[ -n $OPERATION_FILE_NAME ]; then + rm -rf $RUNNING_FILE_DIR/*${OPERATION_FILE_NAME}* + fi + if [ -n $RUNNING_FILE_DIR ]&&[ -d $RUNNING_FILE_DIR ]&&[ -n $GLOG_FAILURE_FILE_NAME ]; then + rm -rf $RUNNING_FILE_DIR/*${GLOG_FAILURE_FILE_NAME}* + fi + if [ -n $RUNNING_FILE_DIR ]&&[ -d $RUNNING_FILE_DIR ]&&[ -n $NSTACK_FAILURE_FILE_NAME ]; then + rm -rf $RUNNING_FILE_DIR/*${NSTACK_FAILURE_FILE_NAME}* + fi + if [ -n $MASTER_FILE_DIR ]&&[ -d $MASTER_FILE_DIR ]&&[ -n $MASTER_FILE_NAME ]; then + rm -rf $MASTER_FILE_DIR/*${MASTER_FILE_NAME}* + fi + if [ -n $MASTER_FILE_DIR ]&&[ -d $MASTER_FILE_DIR ]&&[ -n $GLOG_FAILURE_FILE_NAME ]; then + rm -rf $MASTER_FILE_DIR/*${GLOG_FAILURE_FILE_NAME}* + fi + if [ -n $MASTER_FILE_DIR ]&&[ -d $MASTER_FILE_DIR ]&&[ -n $NSTACK_FAILURE_FILE_NAME ]; then + rm -rf $MASTER_FILE_DIR/*${NSTACK_FAILURE_FILE_NAME}* + fi + if [ -n $LOG_FILE_DIR ]&&[ -d $LOG_FILE_DIR ]&&[ -n $LOG_FILE_NAME ]; then + rm -rf $LOG_FILE_DIR/*${LOG_FILE_NAME}* + fi + if [ -n $DPDK_FILE_DIR ]&&[ -d $DPDK_FILE_DIR ]&&[ -n $DPDK_FILE_NAME ]; then + rm -rf $DPDK_FILE_DIR/*${DPDK_FILE_NAME}* + fi + if [ -n $RUNTIME_DIR ]&&[ -d $RUNTIME_DIR ]; then + rm -rf $RUNTIME_DIR + fi + if [ -n ${MASTER_EXEC_PATH} ]&&[ -d $MASTER_EXEC_PATH ]; then + rm -rf $MASTER_EXEC_PATH + fi +} + +init_hugepage() +{ + log $LINENO "init hugepage..." +############################################################## +# +# TO DO: +# verify the free pages carefully, but not with 1G pagesize +# +############################################################# + + #for 1G hugepage + + # check total hugepage number +# local nr_pagedir=/sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages +# if [ ! -f ${nr_pagedir} ] +# then +# log $LINENO "system not support 1G huge pages, exit!" +# exit 1 +# fi + + # local nr_huge_pages=`cat ${nr_pagedir}` + # if [ ${nr_huge_pages} -lt 3 ] + # then + # log $LINENO "total huge pages is not set correctly, current ${nr_huge_pages}, exit!" + # exit 1 + # fi + + # check free hugepage number + # local fr_pagedir=/sys/devices/system/node/node0/hugepages/hugepages-1048576kB/free_hugepages + # if [ ! -f ${fr_pagedir} ] + # then + # log $LINENO "system not support 1G huge pages, exit!" + # exit 1 + # fi + + # local fr_huge_pages=`cat ${fr_pagedir}` + # if [ ${fr_huge_pages} -lt 3 ] + # then + # log $LINENO "free huge pages is not set correctly, current ${fr_huge_pages}, exit!" + # lsof $HUGE_DIR >> $LOG_FILE 2>/dev/null + # exit 1 + # fi + + # mount | grep $HUGE_DIR >> $LOG_FILE 2>/dev/null + # if [ $? -eq 0 ] ; then + # log $LINENO "$HUGE_DIR dir exist" + # if test $(pgrep -f $1 | wc -l) -eq 0 ; then + # log $LINENO "proccess $1 not exist and clean huge files" + # if [ -n $HUGE_DIR ]&&[ -d $HUGE_DIR ]; then + # rm -rf $HUGE_DIR/* + # fi + # else + # log $LINENO "proccess $1 exist" + # fi + # else + # log $LINENO "$HUGE_DIR not exist and create" + # sudo mkdir -p $HUGE_DIR + #directory right can't larger than 750 + + # cur_user=`whoami` + # if [ "root" != "$cur_user" ] + # then + # non_root_uid=`id -u $cur_user` + # non_root_gid=`id -g $cur_user` + # sudo mount -t hugetlbfs -o pagesize=1G,uid=$non_root_uid,gid=$non_root_gid none $HUGE_DIR >> $LOG_FILE 2>/dev/null + # else + # mount -t hugetlbfs -o pagesize=1G none $HUGE_DIR >> $LOG_FILE 2>/dev/null + # fi + # fi +} + +recover_hugepage() +{ + log $LINENO "recover hugepage..." + + if [ -n "$HUGE_DIR" ]&&[ -d "$HUGE_DIR" ]; then + rm -rf $HUGE_DIR/* + fi +} + +init_network() +{ + log $LINENO "init network..." + + recover_network + + sudo modprobe uio + + local script_path=$(cd "$(dirname "$0")"; pwd) + local is_igb_uio_loaded=`lsmod | grep igb_uio | wc -l` + if [ ${is_igb_uio_loaded} -eq 0 ] + then + log $LINENO "igb_uio is not installed. install it now." + sudo insmod $DPDK_MOD_PATH/igb_uio.ko + fi + + # check if there is un-recognized nic + sudo $DPDK_TOOL_DIR/dpdk-devbind.py -s | grep -A32 "Other network" | \ + grep unused | awk -F"'" '{print $1, $2}' | while read NIC_BFS BIND_DRIVER_NAME + do + local TYPE_CHECK_ixgbe=`echo $BIND_DRIVER_NAME |grep "82599ES 10-Gigabit SFI/SFP+ Network Connection"|wc -l` + local TYPE_CHECK_ixgbevf=`echo $BIND_DRIVER_NAME |grep "82599 Ethernet Controller Virtual Function"|wc -l` + local TYPE_CHECK_vmxnet3=`echo $BIND_DRIVER_NAME |grep "VMXNET3 Ethernet Controller"|wc -l` + local TYPE_CHECK_virtio=`echo $BIND_DRIVER_NAME |grep "Virtio network device"|wc -l` + + if [ $TYPE_CHECK_ixgbe -gt 0 ]; then + sudo $DPDK_TOOL_DIR/dpdk-devbind.py --bind=ixgbe $NIC_BFS + elif [ $TYPE_CHECK_ixgbevf -gt 0 ]; then + sudo $DPDK_TOOL_DIR/dpdk-devbind.py --bind=ixgbevf $NIC_BFS + elif [ $TYPE_CHECK_vmxnet3 -gt 0 ]; then + sudo $DPDK_TOOL_DIR/dpdk-devbind.py --bind=vmxnet3 $NIC_BFS + elif [ $TYPE_CHECK_virtio -gt 0 ]; then + sudo $DPDK_TOOL_DIR/dpdk-devbind.py --bind=virtio-pci $NIC_BFS + fi + + done +} + +recover_network() +{ + log $LINENO "recover network..." + + if [ -z "$DPDK_NIC_LIST_FILE" ]||[ ! -f "$DPDK_NIC_LIST_FILE" ] + then + log $LINENO "$DPDK_NIC_LIST_FILE is not exist. There is no nic used by nstack to unbind." + else + log $LINENO "The NIC(s) to unbind: " + cat $DPDK_NIC_LIST_FILE | awk -F" '|' | drv=| unused=" '{print $1,$4}' >> $LOG_FILE 2>/dev/null + cat $DPDK_NIC_LIST_FILE | awk -F" '|' | drv=| unused=" '{print $1,$4}' | while read NIC_BFS BIND_DRIVER_TYPE + do + sudo $DPDK_TOOL_DIR/dpdk-devbind.py --bind=$BIND_DRIVER_TYPE $NIC_BFS >> $LOG_FILE 2>/dev/null + done + rm $DPDK_NIC_LIST_FILE + fi + + touch $DPDK_NIC_LIST_FILE + chmod 600 $DPDK_NIC_LIST_FILE +} + + +check_args_main() +{ +if [ -z $HUGE_DIR ]||[ -z $MEM_SIZE ]||[ -z $RTP_CORE_MASK ]||[ -z $SLEEP_INTERVAL ]||\ + [ -z $BIND_CPU ]||[ -z $START_TYPE ] +then + log $LINENO "nStackMain Args is null" + return 1 +fi + +# check CORE_MASK -- see in get_core_mask() +# check HUGE_DIR +if [ -z $HUGE_DIR ]||[ ! -d $HUGE_DIR ]; then + log $LINENO "HUGE_DIR="$HUGE_DIR" is invalid" + return 1 +fi + +# check MEM_SIZE +if [ $MEM_SIZE -lt 2048 ]||[ $MEM_SIZE -gt 32768 ]; then + log $LINENO "MEM_SIZE="$MEM_SIZE" is invalid" + return 1 +fi + +# check RTP_CORE_MASK +if [ $RTP_CORE_MASK -lt 1 ]; then + log $LINENO "RTP_CORE_MASK="$RTP_CORE_MASK" is invalid" + return 1 +fi + +# check SLEEP_INTERVAL +if [ $SLEEP_INTERVAL -lt 0 ]; then + log $LINENO "SLEEP_INTERVAL="$SLEEP_INTERVAL" is invalid" + return 1 +fi + +# check BIND_CPU +if [ $BIND_CPU -lt 0 ]; then + log $LINENO "BIND_CPU="$BIND_CPU" is invalid" + return 1 +fi + +# check START_TYPE +if [ $START_TYPE -lt 0 ]||[ $START_TYPE -gt 5 ]; then + log $LINENO "START_TYPE="$START_TYPE" is invalid" + return 1 +fi + +return 0 +} + +run_nStackMain() +{ + + log $LINENO "run nstack main..." + + sudo setcap CAP_IPC_OWNER,CAP_FOWNER,CAP_NET_ADMIN,CAP_IPC_LOCK,CAP_NET_RAW,CAP_SYS_RAWIO,CAP_SYS_ADMIN,CAP_CHOWN,CAP_SYS_NICE=eip ./bin/nStackMain 2>/dev/null + + local script_path=$(cd "$(dirname "$0")"; pwd) + export NSTACK_CONFIG_PATH=${script_path}/../configure + export LD_LIBRARY_PATH=${script_path}/lib64/:$LD_LIBRARY_PATH + export NSTACK_LOG_ON=INF + + log $LINENO "$env NSTACK_CONFIG_PATH=$NSTACK_CONFIG_PATH" + log $LINENO "$env DPDK_TOOL_DIR=$DPDK_TOOL_DIR" + log $LINENO "$env LD_LIBRARY_PATH=$LD_LIBRARY_PATH" + log $LINENO "$env DPDK_LIB_PATH=$DPDK_LIB_PATH" + log $LINENO "./bin/nStackMain -c $1 -n 4 --huge-dir=$2 -m $3 stack -c $4 -sleep $5 -bind_cpu $6" + check_file_size $DPDK_FILE + cd ..; cd bin/ + ./nStackMain -c $1 -n 4 --huge-dir=$2 -m $3 stack -c $4 -sleep $5 -bind_cpu $6 >> $DPDK_FILE & +} + + +stop_nStackProcess() +{ + log $LINENO "$1 exiting..." + + local i=0 + + while [ ${i} -lt $2 ] + do + #pid=`ps aux | grep $1 |grep -v grep| awk '{print $2}'` + pid=`pidof $1` + if [ "x${pid}" != "x" ] + then + kill -9 $pid 2>/dev/null + else + break + fi + i=`expr ${i} + 1` + sleep 1 + done +} + +stop_nStackApps() +{ + log $LINENO "stop the apps that use the shared nstackhuge memory..." + + app_pid=`lsof $HUGE_DIR | awk '{print $2}'` + if [ "x${app_pid}" != "x" ] + then + kill -9 ${app_pid} 2>/dev/null + fi +} + +get_nstack_bin() +{ + local app=$1 + master_pid=`pidof $app | head -n 1` + if [ "x${master_pid}" != "x" ];then + sudo readlink -f "/proc/${master_pid}/exe" | sed "s/$app$//g" 2>/dev/null + fi +} + + + +get_abs_path() +{ + local input_path=$1 + if [ -d "$input_path" -o -f "$input_path" ]; then + echo "$(dirname $(readlink -e $input_path))/$(basename $input_path)" + return 0 + fi + echo $input_path + return 1 +} + + + +CONFIG_FILE="nStackConfig.json" +VAR_FILE="nstack_var.sh" + +modify_nstack_log_path() +{ + if echo $1 |grep -Eq '^((/[a-zA-Z_]+[a-zA-Z0-9_-]+(/[a-zA-Z0-9_-]+)*/?)|/)$' > /dev/null + then + local parameter=$1 + else + log $LINENO "the path is invalid, use the default config path!" + return + fi + + if [ ! -d $1 ]; then + log $LINENO "the folder is not existed, use the default config!" + return + fi + + if [ ! -w $1 ]; then + log $LINENO "the folder has no permission, use the default config!" + return + fi + + local script_path=$(cd "$(dirname "$0")"; pwd) + local config_name=${script_path}/configure/$CONFIG_FILE + + if [ ! -f $config_name ]; then + log $LINENO "$CONFIG_FILE no exit! use default config in code." + return + fi + + sed -i 's#\("stackpool_log_path": "\).*#\1'"$1"'",#g' ${config_name} + sed -i 's#\("master_log_path": "\).*#\1'"$1"'",#g' ${config_name} + sed -i 's#\("nstack_log_path": "\).*#\1'"$1"'",#g' ${config_name} + sed -i 's#\("dpdk_log_path": "\).*#\1'"$1"'"#g' ${config_name} +} + +modify_log_var() +{ + local script_path=$(cd "$(dirname "$0")"; pwd) + local config_name=${script_path}/configure/$CONFIG_FILE + + if [ ! -f $config_name ]; then + log $LINENO "$CONFIG_FILE no exit! use default config in code." + return + fi + + local running_log_path=`grep -Po '"stackpool_log_path": ".*?"' $config_name | sed -n -e 's/"//gp' | awk -F' ' '{print $2}'` + local master_log_path=`grep -Po '"master_log_path": ".*?"' $config_name | sed -n -e 's/"//gp' | awk -F' ' '{print $2}'` + local nstack_log_path=`grep -Po '"nstack_log_path": ".*?"' $config_name | sed -n -e 's/"//gp' | awk -F' ' '{print $2}'` + local dpdk_log_path=`grep -Po '"dpdk_log_path": ".*?"' $config_name | sed -n -e 's/"//gp' | awk -F' ' '{print $2}'` + +#modify the nstack_var.sh + local var_config_name=${script_path}/script/$VAR_FILE + + if [ ! -f $var_config_name ]; then + log $LINENO "$VAR_FILE not exist , exit!" + exit 1 + fi + +#check the path from json if it is OK. + if [ -n "$running_log_path" ]&&[ -w "$running_log_path" ]; then + sed -i "s:RUNNING_FILE_DIR=.*:RUNNING_FILE_DIR=${running_log_path}:g" $var_config_name + else + log $LINENO "stackpool_log_path:$running_log_path in $CONFIG_FILE is invalid, use the default config!" + fi + + if [ -n "$master_log_path" ]&&[ -w "$master_log_path" ]; then + sed -i "s:MASTER_FILE_DIR=.*:MASTER_FILE_DIR=${master_log_path}:g" $var_config_name + else + log $LINENO "master_log_path:$master_log_path in $CONFIG_FILE is invalid, use the default config!" + fi + + if [ -n "$nstack_log_path" ]&&[ -w "$nstack_log_path" ]; then + sed -i "s:LOG_FILE_DIR=.*:LOG_FILE_DIR=${nstack_log_path}:g" $var_config_name + else + log $LINENO "nstack_log_path:$nstack_log_path in $CONFIG_FILE is invalid, use the default config!" + fi + + if [ -n "$dpdk_log_path" ]&&[ -w "$dpdk_log_path" ]; then + sed -i "s:DPDK_FILE_DIR=.*:DPDK_FILE_DIR=${dpdk_log_path}:g" $var_config_name + else + log $LINENO "dpdk_log_path:$dpdk_log_path in $CONFIG_FILE is invalid, use the default config!" + fi +} + + +modify_local_ip_env() +{ + +#modify the nstack_var.sh + local var_config_name=${script_path}/script/$VAR_FILE + + if [ ! -f $var_config_name ]; then + log $LINENO "$VAR_FILE not exist , exit!" + exit 1 + fi + + sed -i "s:VM_ID=.*:VM_ID=${nstack_alarm_local_ip}:g" $var_config_name 2>/dev/null +} + + +delete_pid_file() +{ + if [ -n "$PID_FILE" ]&&[ -f "$PID_FILE" ] + then + rm -rf ${PID_FILE} + fi +} + +save_pid_file() +{ + if [ ! -d ${PID_FILE_DIR} ]; + then + sudo mkdir -p ${PID_FILE_DIR} + chmod 750 ${PID_FILE_DIR} + fi + + if [ -f ${PID_FILE} ]; + then + cur_pid=`cat ${PID_FILE}` + if [ ${cur_pid} != $1 ]; + then + rm -rf ${PID_FILE} + else + return + fi + fi + + touch ${PID_FILE} + echo $1 > $PID_FILE + + chown paas:paas $PID_FILE + chmod 640 $PID_FILE +} + +write_pid_to_file() +{ + retry=3 + i=0 + fail=1 + + while [ ${i} -lt ${retry} ] + do + PID=`pidof nStackMaster` + if [ ${PID} ] + then + fail=0 + break + fi + + i=`expr ${i} + 1` + + sleep 1 + done + + if [ ${fail} -ne 0 ] + then + return 1 + fi + + if [ ! -d ${PID_FILE_DIR} ]; + then + sudo mkdir -p ${PID_FILE_DIR} + chmod 750 ${PID_FILE_DIR} + fi + + touch ${PID_FILE} + echo $PID > $PID_FILE + #check log file right + chown paas:paas $PID_FILE + chmod 640 $PID_FILE + return 0 +} + + + +install_config() +{ + # set nStackConfig values + if [ -n "$DEF_SOCK_NUM" ] ;then + sed -i "s/\"socket_num\":[ \t0-9]*,/\"socket_num\":$DEF_SOCK_NUM,/g" ./configure/nStackConfig.json + fi +} + +copy_config() +{ + # $1 for src nStackServer path + # $2 for dst nStackServer path + + # NOTE: set src socket_num value into dst path config file, this is for copying old configuration from old version to new version path when upgrading. + SRC_SOCK_NUM=`grep 'socket_num' $1/configure/nStackConfig.json | awk -F"," '{for (i=1;i<=NF;++i) print $i}' | awk 'gsub("\"socket_num\":","") {sub("^[ \t]*","");sub("[ \t]*$",""); print $0}'` + sed -i "s/\"socket_num\":[ \t0-9]*,/\"socket_num\":$SRC_SOCK_NUM,/g" $2/configure/nStackConfig.json +} diff --git a/stacks/lwip_stack/release/script/nstack_var.sh b/stacks/lwip_stack/release/script/nstack_var.sh new file mode 100644 index 0000000..15ef2f0 --- /dev/null +++ b/stacks/lwip_stack/release/script/nstack_var.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +PID_FILE_DIR=/var/ICTS_BASE/run +PID_FILE=${PID_FILE_DIR}/nstack.pid + +RUNNING_FILE_DIR=/var/log/nStack +RUNNING_FILE_NAME=running.log + +OPERATION_FILE_NAME=operation.log +NSTACK_CTRL_LOG_FILE_NAME=omc_ctrl.log +GLOG_FAILURE_FILE_NAME=fail_dump.log +NSTACK_FAILURE_FILE_NAME=nstack_error.log + +MASTER_FILE_DIR=/var/log/nStack +MASTER_FILE_NAME=master.log + +LOG_FILE_DIR=/var/log/nStack +LOG_FILE=${LOG_FILE_DIR}/nstack.log +LOG_FILE_NAME=nstack.log + +DPDK_FILE_DIR=/var/log/nstack-dpdk +DPDK_FILE=${DPDK_FILE_DIR}/nstack_dpdk.log +DPDK_FILE_NAME=nstack_dpdk.log + +#this is env variable, it is for nstack usage, it will be modified from ./start_nstack -i hostinfo.ini + +export VM_ID=agent-node-x + +export DPDK_INSTALL_PATH="/root/dpdk/dpdk-18.02" +export DPDK_LIB_PATH=${DPDK_INSTALL_PATH}/x86_64-native-linuxapp-gcc/lib +export DPDK_TOOL_DIR=${DPDK_INSTALL_PATH}/usertools +export DPDK_MOD_PATH=${DPDK_INSTALL_PATH}/x86_64-native-linuxapp-gcc/kmod + +cur_user=`whoami` +if [ "root" != "${cur_user}" ] +then + HOME_DIR=$HOME + if [ -z "${HOME}" ] + then + HOME_DIR=/var/run + fi +else + HOME_DIR=/var/run +fi +RUNTIME_DIR=$HOME_DIR/ip_module + +DPDK_NIC_LIST_FILE=$RUNTIME_DIR/.nstack_dpdk_nic_list + +#single file is 50M=50*1024*1024 +MAX_LOG_FILE_SIZE=52428800 +HUGE_PAGES=2048 +HUGE_DIR=/mnt/nstackhuge +SLEEP_INTERVAL=100 # tcpip thread sleep time, unit: us +BIND_CPU=0 +MEM_SIZE=2048 +RTP_CORE_MASK=2 + +MASTER_EXEC_PATH="/product/gpaas/nStackMaster/bin" +RUN_NSTACK_FILE=run_nstack.sh + + +#default config definitions +DEF_SOCK_NUM=8192 diff --git a/stacks/lwip_stack/release/script/run_nstack_main.sh b/stacks/lwip_stack/release/script/run_nstack_main.sh new file mode 100644 index 0000000..2bd9e0d --- /dev/null +++ b/stacks/lwip_stack/release/script/run_nstack_main.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +DIR=`S=\`readlink "$0"\`; [ -z "$S" ] && S=$0; dirname $S` +cd $DIR + +. ./nstack_var.sh +. ./nstack_fun.sh + +######################################################## +# check parameter + +log $LINENO "dir=$DIR" + +######################################################## +# init netrork:unbind->/* modprobe uio->insmod igb_uio */->bind +init_network + +######################################################## +# start nstack main +CORE_MASK=1 +log $LINENO "start run nstackmain" +log $LINENO "COREMASK=$CORE_MASK, HUGE_DIR=$1, MEM_SIZE=$2, RTP_CORE_MASK=$RTP_CORE_MASK, SLEEP_INTERVAL=$SLEEP_INTERVAL, BIND_CPU=$BIND_CPU" + +run_nStackMain $CORE_MASK $1 $2 $RTP_CORE_MASK $SLEEP_INTERVAL $BIND_CPU + +exit 0 diff --git a/stacks/lwip_stack/release/script/run_nstack_master.sh b/stacks/lwip_stack/release/script/run_nstack_master.sh new file mode 100644 index 0000000..8da0d49 --- /dev/null +++ b/stacks/lwip_stack/release/script/run_nstack_master.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +DIR=`S=\`readlink "$0"\`; [ -z "$S" ] && S=$0; dirname $S` +cd $DIR +. ./nstack_var.sh + + +if [ -n "${MASTER_EXEC_PATH}" ]; then + mkdir -p $MASTER_EXEC_PATH + chown -R paas: $MASTER_EXEC_PATH + chmod 750 $MASTER_EXEC_PATH + cp ../bin/nStackMaster $MASTER_EXEC_PATH -rf + cp ../configure/nStackConfig.json $MASTER_EXEC_PATH -rf + ln -s -f $(cd "$(dirname "$0")"; pwd)/run_nstack_main.sh $MASTER_EXEC_PATH/${RUN_NSTACK_FILE} + cd $MASTER_EXEC_PATH +fi + +runnStackMaster(){ + sudo setcap CAP_IPC_OWNER,CAP_NET_ADMIN,CAP_DAC_OVERRIDE=eip ./nStackMaster + + script_path=$(cd "$(dirname "$0")"; pwd) + export NSTACK_CONFIG_PATH=${script_path} + + ./nStackMaster -c $1 -n 4 --huge-dir=$2 -m $3 --proc-type=$4 >> ${DPDK_FILE} +} + +runnStackMaster $1 $2 $3 $4 & + +exit 0 diff --git a/stacks/lwip_stack/release/send_alarm.sh b/stacks/lwip_stack/release/send_alarm.sh new file mode 100644 index 0000000..46ea413 --- /dev/null +++ b/stacks/lwip_stack/release/send_alarm.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +cur_dir=$(cd "$(dirname "$0")"; pwd) +alarm_history=${cur_dir}/.nstack_fault_alarm + +. ./script/nstack_var.sh +. ./script/nstack_fun.sh + +if [ ! -f ${alarm_history} ]; then + ./nStackCtrl --module alm -n nsMain -t abnormal + log $LINENO "nstack is not running ok, send fault alarm" + touch ${alarm_history} +else + log $LINENO "nstack is not running ok, send fault alarm already" +fi + +exit 0
\ No newline at end of file diff --git a/stacks/lwip_stack/release/start_nstack.sh b/stacks/lwip_stack/release/start_nstack.sh new file mode 100644 index 0000000..c005f25 --- /dev/null +++ b/stacks/lwip_stack/release/start_nstack.sh @@ -0,0 +1,124 @@ +#!/bin/bash + +. ./script/nstack_var.sh +. ./script/nstack_fun.sh + +script_path=$(cd "$(dirname "$0")"; pwd) +config_name=${script_path}/script/nstack_var.sh +if [ ! -e $config_name ]; then + log $LINENO "nstack_var.sh not exit, plz check!" + exit 1 +fi + +######################################################## +##get the log info from the parameter of ./start -l XXX -a XXX ### +nstack_log_path="" +hostinfo_path="" +while getopts "l:i:a:" arg +do + case $arg in + l) + nstack_log_path="$OPTARG" + ;; + i) + hostinfo_path="$OPTARG" + ;; + esac +done + +hostinfo_stat=0 + +( +flock -e -n 200 +if [ $? -eq 1 ] +then + log $LINENO "another process is running now, exit" + exit 1 +fi + +######################################################## +# modify the nstack & dpdk log path config: nStackConfig.json +if [ -n "$nstack_log_path" ]; then + modify_nstack_log_path $nstack_log_path +fi + +if [ -n "$hostinfo_path" -a -e "$hostinfo_path" -a -r "$hostinfo_path" ]; then + nstack_alarm_local_ip=($(awk -F '=' '/\['AGENT'\]/{a=1}a==1&&$1"="~/^(\s*)(VM_ID)(\s*)(=)/{print $2 ;exit}' $hostinfo_path)) + modify_local_ip_env +else + hostinfo_stat=1 +fi + + +######################################################## +#set the log path in nstack_var.sh##### +modify_log_var +) 200>>./lockfile + +if [ -f "lockfile" ]; then + rm lockfile +fi + +. ./script/nstack_var.sh + + +######################################################## +# init_log_file:nstack.log and dpdk.log +# if need print log, the messgae need add after init_log_file +init_log_file + +if [ "$hostinfo_stat" -ne 0 ]; then + log $LINENO "please use correct -i parameter for start_nstack.sh" + log $LINENO "host info path:$hostinfo_path" + hostinfo_stat=0 +fi + +log $LINENO "######################start nstack######################" + +######################################################## +# check application running +process_nstack_main=nStackMain + +pid_nstack=`pidof $process_nstack_main` + +nstack_ctrl_path=${script_path}/bin + +pgrep nStackMain +main_run_status=$? +if [ ${main_run_status} -eq 0 ]; then + log $LINENO "nStackMain is running ok, please stop it first!" + save_pid_file ${pid_master} + exit 0 +fi + +huge_files=`ls /mnt/nstackhuge` +if [ "x${huge_files}" != "x" ] +then + if [ "x${pid_nstack}" = "x" ] + then + log $LINENO "huge page file exist and nStackMain not exist" + exit 1 + fi +fi + + +######################################################## +# set hugepage +init_hugepage $process_nstack_main + + +######################################################## +# install config +install_config + +######################################################## +core_mask=1 +START_TYPE="primary" +log $LINENO "./script/run_nstack_main.sh ${core_mask} $HUGE_DIR $MEM_SIZE $START_TYPE" +cd script +./run_nstack_main.sh $HUGE_DIR $MEM_SIZE + +print_pid=$(ps -ux | grep nStackMain | awk '{print $2}' | awk 'NR == 2') +echo "nStackMain PID:$print_pid" +log $LINENO "nstack start success" +exit 0 diff --git a/stacks/lwip_stack/release/stop_nstack.sh b/stacks/lwip_stack/release/stop_nstack.sh new file mode 100644 index 0000000..9b9fe94 --- /dev/null +++ b/stacks/lwip_stack/release/stop_nstack.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +. ./script/nstack_var.sh +. ./script/nstack_fun.sh + +script_path=$(cd "$(dirname "$0")"; pwd) +config_name=${script_path}/script/nstack_var.sh +if [ ! -e $config_name ]; then + log $LINENO "$config_name not exit, plz pay attention and add back!,or it has resourcce leak." +fi + +cur_user=`whoami` + +######################################################## +# init_log_file:nstack.log and dpdk.log +init_log_file +log $LINENO "#######################stop nstack#######################" + +############################################# +# step1 stop nstack master +retry=3 +stop_nStackProcess nStackMaster $retry + +############################################# +# step2 stop nstack +stop_nStackProcess nStackMain $retry + + +############################################# +# step3 stop all apps that usg the nstack hugepage +if [ ${cur_user} = "root" ]; then + stop_nStackApps +else + log $LINENO "not root, app not stopped" +fi + +############################################# +# step4 delete the huge page files created by nstack +recover_hugepage + +############################################# +# step5 recover the nic configuration +recover_network + +############################################# +# step6 delete pid file +delete_pid_file + +exit 0 diff --git a/stacks/lwip_stack/release/uninstall.sh b/stacks/lwip_stack/release/uninstall.sh new file mode 100644 index 0000000..92ae5fe --- /dev/null +++ b/stacks/lwip_stack/release/uninstall.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +. ./script/nstack_var.sh +. ./script/nstack_fun.sh + +######################################################## +# init_log_file:nstack.log and dpdk.log +init_log_file +log $LINENO "#######################uninstall nstack#######################" + + +############################################# +# step1 stop the applications that use the shared huge memory of nstack +stop_nStackApps + +############################################# +# step2 delete the huge page files created by nstack +recover_hugepage + + +############################################# +# step3 recover the nic configuration +recover_network + + +############################################# +# step4 delete nstack log files +delete_log_file + + +# log file has been deleted, should print on screen now +echo "uninstall nStack successfully!" + +exit 0 diff --git a/stacks/lwip_stack/release/upgrade_nstack.sh b/stacks/lwip_stack/release/upgrade_nstack.sh new file mode 100644 index 0000000..9302da6 --- /dev/null +++ b/stacks/lwip_stack/release/upgrade_nstack.sh @@ -0,0 +1,452 @@ +#!/bin/bash + +. ./script/nstack_var.sh +. ./script/nstack_fun.sh + +VERSION_CHK=0 +UPG_MASTER=0 + +# OLD_VERSION indicates the nStackServer version, in order to support Version upgrade and rollback feature +# OLD_VERSION=1 B031~newest +# OLD_VERSION=0 B020~B030 +OLD_VERSION=1 +cur_user=`whoami` + +upg_pre_chk() +{ + ##########check input info########################### + if [ -z "${DST_VER_PATH}" ]; then + log $LINENO "dst ${DST_VER_PATH} path error!" + return 1 + fi + + if [ "x${UPG_RBK}" != "x1" -a "x${UPG_RBK}" != "x2" ]; then + log $LINENO "type error ${UPG_RBK}!" + return 1 + fi + + ##########check src version info###################### + SRC_STOP_FILE=${SRC_VER_PATH}/stop_nstack.sh + if [ ! -f "$SRC_STOP_FILE" ]; then + log $LINENO "${SRC_STOP_FILE} path error!" + return 1 + fi + + MASTER_PATH=`get_nstack_bin nStackMaster` + if [ -z "${MASTER_PATH}" ]; then + log $LINENO "master not start" + return 1 + fi + + if [ ! -d "${MASTER_PATH}${MASTERBIN}" ]; then + log $LINENO "${MASTER_PATH} path error!" + return 1 + fi + + SRC_VERSION=`get_version 1` + if [ -z "${SRC_VERSION}" ]; then + log $LINENO "get srcVersion error" + exit 1 + fi + + ###########check dst version info###################### + DST_RUN_FILE=${DST_VER_PATH}/script/run_nstack_main.sh + if [ ! -f "$DST_RUN_FILE" ]; then + log $LINENO "${DST_RUN_FILE} path error. Try the path of older nstack version then." + DST_RUN_FILE=${DST_VER_PATH}/bin/run_nstack_main.sh + OLD_VERSION=0 + if [ ! -f "$DST_RUN_FILE" ]; then + log $LINENO "${DST_RUN_FILE} older path error!" + return 1 + fi + fi + + DST_STOP_FILE=${DST_VER_PATH}/stop_nstack.sh + if [ ! -f "$DST_STOP_FILE" ]; then + log $LINENO "${DST_STOP_FILE} path error!" + return 1 + fi + + DST_STAT_FILE=${DST_VER_PATH}/start_nstack.sh + if [ ! -f "$DST_STAT_FILE" ]; then + log $LINENO "${DST_STAT_FILE} path error!" + return 1 + fi + + if [ ! -x "${DST_VER_PATH}/bin/nStackCtrl" ]; then + log $LINENO "${DST_VER_PATH} path nStackCtrl exec error!" + return 1 + fi + + DST_VERSION=`get_version 4 ${DST_VER_PATH}/bin/nStackCtrl` + if [ -z "${DST_VERSION}" ]; then + log $LINENO "get dstversion error" + return 1 + fi +} + +restart_upgrade() +{ + local monipid=`pidof monit` + local stop_moni=0 + if [ ! -z "${monipid}" ]; then + for i in `seq 60` + do + if [ ${cur_user} = "paas" ]; then + stop_fin=`/var/ICTS_BASE/Monit/bin/monit summary | grep nstack | grep "Not monitored"` + else + stop_fin=`su paas -s /bin/bash -c "/var/ICTS_BASE/Monit/bin/monit summary" | grep nstack | grep "Not monitored"` + fi + if [ -n "${stop_fin}" ]; then + break; + fi + + if [ $stop_moni -eq 0 ]; then + if [ ${cur_user} = "paas" ]; then + /var/ICTS_BASE/Monit/bin/monit unmonitor nstack + else + su paas -s /bin/bash -c "/var/ICTS_BASE/Monit/bin/monit unmonitor nstack" + fi + stop_moni=1 + log $LINENO "stop monit" + fi + + sleep 1 + done + cd ${SRC_VER_PATH} + ./stop_nstack.sh + cd - + cd ${DST_VER_PATH} + if [ -n "${LOG_PATH}" ]; then + ./start_nstack.sh -l $LOG_PATH -i $hostinfo_path + else + ./start_nstack.sh -i $hostinfo_path + fi + cd - + + log $LINENO "with monit restart" + if [ $stop_moni -eq 1 ]; then + if [ ${cur_user} = "paas" ]; then + /var/ICTS_BASE/Monit/bin/monit monitor nstack + else + su paas -s /bin/bash -c "/var/ICTS_BASE/Monit/bin/monit monitor nstack" + fi + log $LINENO "monit restart" + fi + else + cd ${SRC_VER_PATH} + ./stop_nstack.sh + cd - + cd ${DST_VER_PATH} + if [ -n "${LOG_PATH}" ]; then + ./start_nstack.sh -l $LOG_PATH -i $hostinfo_path + else + ./start_nstack.sh -i $hostinfo_path + fi + cd - + log $LINENO "none monit restart" + fi + return 0 +} + +run_upgrade() +{ + + if [ -n "${DST_RUN_FILE}" ]; then + if [ $OLD_VERSION -ge 1 ]; then + ln -s -f "$DST_RUN_FILE" "${DST_VER_PATH}/script/${RUN_NSTACK_FILE}" + else + ln -s -f "$DST_RUN_FILE" "${DST_VER_PATH}/bin/${RUN_NSTACK_FILE}" + fi + if [ $? -ne 0 ]; then + log $LINENO "dst version link failed!" + return 1 + fi + fi + + # copy old config to avoid config change issue + copy_config $SRC_VER_PATH $DST_VER_PATH + + ./bin/nStackCtrl --module vermgr -t $UPG_RBK -s $SRC_VERSION -d $DST_VERSION + ret=$? + if [ $ret -eq 121 ]; then + restart_upgrade + WAIT_TIME=50 + RESTART_MASTER=1 + return 0 + fi + + if [ $ret -ne 0 ]; then + log $LINENO "nStackCtrl send vermsg err $ret code" + return 1 + fi + + nStackMain_pid=`pidof nStackMain` + if [ -n "${DST_RUN_FILE}" ]; then + ln -s -f "$DST_RUN_FILE" "${MASTER_PATH}${RUN_NSTACK_FILE}" + if [ $? -ne 0 ]; then + log $LINENO "link failed!" + kill -9 $nStackMain_pid + return 1 + fi + fi + kill -9 $nStackMain_pid + return 0 +} + +after_upg_chk() +{ + for i in `seq $WAIT_TIME` + do + NEW_DST_VERSION=`get_version 1` + if [ -n "${NEW_DST_VERSION}" ]; then + if [ "$NEW_DST_VERSION" != "$DST_VERSION" ]; then + log $LINENO "new version:$NEW_DST_VERSION maybe error! expect version is:$DST_VERSION" + else + break; + fi + fi + sleep 1 + done + + if [ -z "${NEW_DST_VERSION}" ]; then + log $LINENO "nStackCtrl get dstVersion error" + return 1 + fi + + if [ "$NEW_DST_VERSION" != "$DST_VERSION" -a $VERSION_CHK -eq 1 ]; then + log $LINENO "new version:$NEW_DST_VERSION maybe error! expect version is:$DST_VERSION" + return 1 + fi + + DST_MAIN_PATH=`get_nstack_bin nStackMain` + if [ -z "${DST_MAIN_PATH}" ]; then + log $LINENO "main not start" + return 1 + fi + + if [ "$DST_MAIN_PATH" != "${DST_VER_PATH}/bin/" ]; then + log $LINENO "main start failed run;$DST_MAIN_PATH expect:${DST_VER_PATH}/script !" + return 1 + fi +} + + +run_upgrade_master() +{ + core_mask=`get_core_mask` + START_TYPE="secondary" + ./bin/nStackCtrl --module vermgr -t $UPG_RBK -s $SRC_VERSION -d $DST_VERSION -p 2 + ret=$? + if [ $ret -ne 0 ]; then + log $LINENO "nStackMaster nStackCtrl send vermsg err $ret code" + return 1 + fi + + nStackMaster_pid=`pidof nStackMaster` + kill -9 $nStackMaster_pid + cd ${DST_VER_PATH}/script/ + ./run_nstack_master.sh ${core_mask} $HUGE_DIR $MEM_SIZE $START_TYPE + log $LINENO "./script/run_nstack_master.sh ${core_mask} $HUGE_DIR $MEM_SIZE $START_TYPE" + cd - + return 0 +} + + +after_upg_master_chk() +{ + for i in `seq 10` + do + NEW_MAS_VERSION=`get_version 2` + if [ -n "${NEW_MAS_VERSION}" ]; then + if [ "$NEW_MAS_VERSION" != "$DST_VERSION" ]; then + log $LINENO "new version:$NEW_MAS_VERSION maybe error! expect version is:$DST_VERSION" + else + break; + fi + fi + sleep 1 + done + + if [ -z "${NEW_MAS_VERSION}" ]; then + log $LINENO "nStackCtrl get dstVersion error" + return 1 + fi + + if [ "$NEW_MAS_VERSION" != "$DST_VERSION" -a $VERSION_CHK -eq 1 ]; then + log $LINENO "new version:$NEW_MAS_VERSION maybe error! expect version is:$DST_VERSION" + return 1 + fi + + DST_MAS_PATH=`get_nstack_bin nStackMaster` + if [ -z "${DST_MAS_PATH}" ]; then + log $LINENO "master not start" + return 1 + fi + + if [ "$DST_MAS_PATH" != "${DST_VER_PATH}/script/" ]; then + log $LINENO "main start failed run;$DST_MAS_PATH expect:${DST_VER_PATH}/script !" + return 1 + fi + return 0 +} + +opr_suc() +{ + log $LINENO "operation successful $SRC_VERSION to $NEW_DST_VERSION" +} + +mod_log_path() +{ + local dst_proc=$1 + local dst_log_path=$2 + ./bin/nStackCtrl --module setlog -n maspath -v ${dst_log_path} -p $dst_proc + ret=$? + if [ $ret -ne 0 ]; then + log $LINENO "mod_log_path error err $ret code" + return 1 + fi + return 0 +} + +ini_file_path="invalid_path_upgrade" + +while getopts 's:d:t:l:i:' opt +do + case $opt in + s) + SRC_VER_PATH=`get_abs_path $OPTARG` + ;; + :) + echo "-$OPTARG needs an argument" + exit 1 + ;; + d) + DST_VER_PATH=`get_abs_path $OPTARG` + ;; + :) + echo "-$OPTARG needs an argument" + exit 1 + ;; + t) + UPG_RBK=$OPTARG + ;; + :) + echo "-$OPTARG needs an argument" + exit 1 + ;; + l) + LOG_PATH=`get_abs_path $OPTARG` + ;; + :) + echo "-$OPTARG needs an argument" + exit 1 + ;; + i) + ini_file_path=`get_abs_path $OPTARG` + ;; + :) + echo "-$OPTARG needs an argument" + exit 1 + ;; + *) + echo "command not recognized" + usage + exit 1 + ;; + esac +done + +if [ -z $ini_file_path ]; then + hostinfo_path="invalid_path_upgrade" + else + hostinfo_path=$ini_file_path +fi + +( +flock -e -n 201 +if [ $? -eq 1 ] +then + log $LINENO "another upgrade process is running now, exit" + exit 1 +fi + +if [ -n "${LOG_PATH}" ]; then + modify_nstack_log_path ${LOG_PATH} +fi +modify_log_var +) 201>>./uplockfile + +if [ -f "uplockfile" ]; then + rm uplockfile +fi + +. ./script/nstack_var.sh + +RESTART_MASTER=0 +WAIT_TIME=60 + +log $LINENO "######################upgrade nstack######################" +log $LINENO "src ver path ${SRC_VER_PATH},dst ver path ${DST_VER_PATH}, type ${UPG_RBK}, log path ${LOG_PATH}" + +upg_pre_chk +ret=$? +if [ $ret -ne 0 ]; then + log $LINENO "pre_chk error err $ret code" + exit 1 +fi + +if [ "${DST_VERSION}" = "${SRC_VERSION}" -a $VERSION_CHK -eq 1 ]; then + log $LINENO "version equal ${DST_VERSION} ${SRC_VERSION}" + exit 0 +fi +log $LINENO "prepare ok" + +log $LINENO "src ver $SRC_VERSION with master path $MASTER_PATH,dst ver $DST_VERSION,dst run file $DST_RUN_FILE, type ${UPG_RBK}" +run_upgrade +ret=$? +if [ $ret -ne 0 ]; then + log $LINENO "run_proc error err $ret code" + exit 1 +fi + +log $LINENO "wait new version start" +sleep 2 +after_upg_chk +ret=$? +if [ $ret -ne 0 ]; then + log $LINENO "after_chk error err $ret code" + exit 1 +fi + +if [ $RESTART_MASTER -ne 0 ]; then + log $LINENO "master has restart!" + opr_suc + exit 0 +fi + +if [ $UPG_MASTER -eq 0 ]; then + if [ -n "${LOG_PATH}" ]; then + mod_log_path 2 ${LOG_PATH} + fi + opr_suc + exit 0 +fi + +run_upgrade_master +ret=$? +if [ $ret -ne 0 ]; then + log $LINENO "run_proc master error err $ret code" + exit 1 +fi + +log $LINENO "wait new version master start" +sleep 2 +after_upg_master_chk +ret=$? +if [ $ret -ne 0 ]; then + log $LINENO "after_chk master error err $ret code" + exit 1 +fi + +opr_suc diff --git a/stacks/lwip_stack/release_tar.sh b/stacks/lwip_stack/release_tar.sh new file mode 100644 index 0000000..6c2928f --- /dev/null +++ b/stacks/lwip_stack/release_tar.sh @@ -0,0 +1,86 @@ +if [ ! -d "./nStackServer" ]; then + mkdir ./nStackServer +else + rm -rf ./nStackServer/* +fi + +if [ ! -d "./nStackClient" ]; then + mkdir ./nStackClient +else + rm -rf ./nStackClient/* +fi + +if [ ! -d "./nStackTools" ]; then + mkdir ./nStackTools +else + rm -rf ./nStackTools/* +fi + +if [ -f "./nStackServer.tar.gz" ]; then + rm -rf ./nStackServer.tar.gz +fi + +if [ -f "./nStackClient.tar.gz" ]; then + rm -rf ./nStackClient.tar.gz +fi + +if [ -f "./nStackTools.tar.gz" ]; then + rm -rf ./nStackTools.tar.gz +fi + +mkdir ./nStackServer/lib64 +cp ./release/lib64/libnstack.so ./release/lib64/libnStackAPI.so ./release/lib64/libnstackcmd.so ./release/lib64/libsecurec.so ./nStackServer/lib64 +mkdir ./nStackServer/bin +cp ./release/bin/nStackCtrl ./release/bin/nStackMain ./release/bin/nStackMaster ./release/bin/set_permission.sh ./nStackServer/bin +mkdir ./nStackServer/conf +cp ./release/conf/nstack.monitrc ./release/conf/nstack_ctl ./release/conf/srvnstack ./nStackServer/conf +mkdir ./nStackServer/configure +cp ./release/configure/ip_data.json ./release/configure/network_data_tonStack.json ./release/configure/nStackConfig.json ./nStackServer/configure +mkdir ./nStackServer/script +cp -d ./release/script/nstack_fun.sh ./release/script/nstack_var.sh ./release/script/run_nstack_main.sh ./release/script/run_nstack_master.sh ./nStackServer/script +mkdir ./nStackServer/tools +cp ./release/tools/nping ./nStackServer/tools/ + +cp ./release/check_status.sh ./release/send_alarm.sh ./release/start_nstack.sh ./release/stop_nstack.sh ./release/graceful_stop_nstack.sh ./release/uninstall.sh ./release/upgrade_nstack.sh ./nStackServer/ + +dos2unix ./nStackServer/*.sh +find ./nStackServer -type f | grep -E "*.sh|*.py" | xargs chmod +x + +mkdir ./nStackClient/lib64 +cp ./release/lib64/libnstack.so ./release/lib64/libnStackAPI.so ./release/lib64/libsecurec.so ./nStackClient/lib64 +mkdir ./nStackClient/include +cp ./release/include/nstack_custom_api.h ./nStackClient/include + +cp ./release/tools/nping ./release/tools/ntcpdump ./nStackTools/ + +# set permission +chown -R paas: ./nStackServer/ +chown -R paas: ./nStackClient/ +chown -R paas: ./nStackTools/ + +chmod 750 ./nStackServer +chmod 550 ./nStackServer/bin/ +chmod 750 ./nStackServer/configure +chmod 750 ./nStackServer/script +chmod 750 ./nStackServer/conf +chmod 750 ./nStackServer/lib64 +chmod 750 ./nStackServer/tools +chmod 750 ./nStackClient +chmod 750 ./nStackClient/include +chmod 750 ./nStackClient/lib64 +chmod 750 ./nStackTools + +chmod 750 ./nStackServer/bin/nStack* +chmod 750 ./nStackServer/*.sh +chmod 750 ./nStackServer/bin/*.sh +chmod 750 ./nStackServer/conf/* +chmod 750 ./nStackServer/script/*.sh +chmod 640 ./nStackServer/lib64/* +chmod 640 ./nStackServer/configure/* +chmod 500 ./nStackServer/bin/set_permission.sh +chmod 750 ./nStackTools/* + + +tar -zcvf nStackServer.tar.gz nStackServer +tar -zcvf nStackClient.tar.gz nStackClient +tar -zcvf nStackTools.tar.gz nStackTools diff --git a/stacks/lwip_stack/run_stackx.txt b/stacks/lwip_stack/run_stackx.txt new file mode 100644 index 0000000..7322635 --- /dev/null +++ b/stacks/lwip_stack/run_stackx.txt @@ -0,0 +1,131 @@ +######################################################################### +# +# 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. +######################################################################### + +#build DPDK +#Note: build path /root/dpdk/ , install path /root/dpdk_install/tmp +=================================================================== +if [ -d /root/dpdk_install/tmp ]; then + rm -rf /root/dpdk_install/tmp +fi + +mkdir -p /root/dpdk + +cd /root/dpdk +rm -rf dpdk-16.04/ +wget https://fast.dpdk.org/rel/dpdk-16.04.tar.xz +tar xvf dpdk-16.04.tar.xz +cd dpdk-16.04/ + +sed -i 's!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1' config/common_base +sed -i 's!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1' config/common_base +sed -i 's!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1' config/common_base + +make install T=x86_64-native-linuxapp-gcc DESTDIR=/root/dpdk_install/tmp +cd x86_64-native-linuxapp-gcc +make + +cp -r /root/dpdk/dpdk-16.04/tools/dpdk_nic_bind.py /root/dpdk/dpdk-16.04/tools/dpdk-devbind.py + +mount -t hugetlbfs -o pagesize=1G none /mnt/nstackhuge/ +mkdir /var/run/ip_module + +#verify hugepages 8GB free hugepages are required +================================================= +cat /proc/meminfo + +#build DMM +============ +#got to DMM/ + +cd thirdparty/glog/glog-0.3.4/ +sudo autoreconf -ivf + +cd - +cd build/ + +cmake .. +make -j 8 + +#build stackx +================ +cd ../thirdparty/glog/glog-0.3.4/ +sudo autoreconf -ivf + +cd - +cd ../stacks/lwip_stack/build/ + +cmake .. +make -j 8 + +#run app +======== +cd ../ +chmod +x release_tar.sh +./release_tar.sh + +tar -zxf nStackServer.tar.gz + +cd nStackServer/ +cp configure/*.json bin/ + +##make json file changes +#I have copied the working configs in the path /home/sharath/working_config/ + +#server +cp -r /home/sharath/working_config/server/ip_data.json bin/ +cp -r /home/sharath/working_config/server/network_data_tonStack.json bin/ +cp -r /home/sharath/working_config/server/nStackConfig.json bin/ + +#client +cp -r /home/sharath/working_config/client/ip_data.json bin/ +cp -r /home/sharath/working_config/client/network_data_tonStack.json bin/ +cp -r /home/sharath/working_config/client/nStackConfig.json bin/ + +#dpdk download path : /root/dpdk/dpdk-16.04/ +sed -i 's!export DPDK_INSTALL_PATH.*!export DPDK_INSTALL_PATH="/root/dpdk/dpdk-16.04"!1' ../release/script/nstack_var.sh + +cd ../../../release/bin/ +cp ../configure/*.json . + +#server +cp -r /home/sharath/working_config/server/module_config.json . +cp -r /home/sharath/working_config/server/nStackConfig.json . +cp -r /home/sharath/working_config/server/rd_config.json . + +#client +cp -r /home/sharath/working_config/client/module_config.json . +cp -r /home/sharath/working_config/client/nStackConfig.json . +cp -r /home/sharath/working_config/client/rd_config.json . + +cd - +./stop_nstack.sh +./start_nstack.sh + +#verify process up +ps aux | grep nS + +cd bin +./nStackCtrl -a add -p ./network_data_tonStack.json -t network +./nStackCtrl -a add -p ./ip_data.json -t ip + +cd ../../../../release/bin/ +cp ../../stacks/lwip_stack/release/lib64/libnstack.so . + +#server +./vs_epoll -p 20000 -d 192.168.1.207 -a 10000 -s 192.168.1.206 -l 200 -t 5000000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 10000 -e 10 -x 1 + +#client +./vc_epoll -p 20000 -d 192.168.1.206 -a 10000 -s 192.168.1.207 -l 200 -t 50000 -i 1000 -f 1 -r 20000 -n 1 -w 10 -u 10000 -e 10 -x 1 diff --git a/stacks/lwip_stack/src/CMakeLists.txt b/stacks/lwip_stack/src/CMakeLists.txt new file mode 100644 index 0000000..6aacf07 --- /dev/null +++ b/stacks/lwip_stack/src/CMakeLists.txt @@ -0,0 +1,62 @@ +######################################################################### +# +# 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.4/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}/../../../src/framework/common/base/include/common/common_sys_config.h) +endif() +SET(COMPLE_CONFIG ${PROJECT_SOURCE_DIR}/src/include/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(io_adpt) +ADD_SUBDIRECTORY(sbr) +#ADD_SUBDIRECTORY(nStackCtrl) +ADD_SUBDIRECTORY(nStackMain) +ADD_SUBDIRECTORY(tools) +ADD_SUBDIRECTORY(alarm) +#ADD_SUBDIRECTORY(nstackcmd) diff --git a/stacks/lwip_stack/src/alarm/CMakeLists.txt b/stacks/lwip_stack/src/alarm/CMakeLists.txt new file mode 100644 index 0000000..3de07b0 --- /dev/null +++ b/stacks/lwip_stack/src/alarm/CMakeLists.txt @@ -0,0 +1,34 @@ +######################################################################### +# +# 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 dmm_api) +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/ +) +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..5f89cdd --- /dev/null +++ b/stacks/lwip_stack/src/alarm/alarm.c @@ -0,0 +1,863 @@ +/* +* +* 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.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_MASTER: + case NSFW_PROC_CTRL: + + /* [S138713][p00329905][20171219]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 (NSTACK_DMM_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..4c5f692 --- /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..8c7aca1 --- /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/nsfw_msg.h b/stacks/lwip_stack/src/include/nsfw_msg.h new file mode 100644 index 0000000..e5254d3 --- /dev/null +++ b/stacks/lwip_stack/src/include/nsfw_msg.h @@ -0,0 +1,203 @@ +/* +* +* 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 (MAX_MSG_SIZE, 512); +#define MAX_MSG_PARAM_SIZE 128 +COMPAT_PROTECT (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..85dca49 --- /dev/null +++ b/stacks/lwip_stack/src/include/nsfw_msg_api.h @@ -0,0 +1,309 @@ +/* +* +* 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" + +#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..e1a7899 --- /dev/null +++ b/stacks/lwip_stack/src/include/nsfw_mt_config.h @@ -0,0 +1,292 @@ +/* +* +* 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 + +#define NSFW_CONFIG_MODULE "nsfw_config" +#define NSTACK_SHARE_CONFIG "nstack_share_config" + +#define CFG_PATH "NSTACK_CONFIG_PATH" +#define CFG_FILE_NAME "nStackConfig.json" +#define MAX_FILE_NAME_LEN 512 +#define CFG_BUFFER_LEN 2048 +#define MAX_CFG_ITEM 128 +#define CFG_ITEM_LENGTH 64 + +enum NSTACK_BASE_CFG +{ + CFG_BASE_SOCKET_NUM = 0, + CFG_BASE_RING_SIZE, + CFG_BASE_HAL_PORT_NUM, + CFG_BASE_ARP_STALE_TIME, + CFG_BASE_ARP_BC_RETRANS_NUM, + MAX_BASE_CFG +}; +COMPAT_PROTECT (MAX_BASE_CFG, 5); + +enum NSTACK_CUSTOM_CFG +{ + /* mBuf config */ + CFG_MBUF_DATA_SIZE, + CFG_TX_MBUF_NUM, + CFG_RX_MBUF_NUM, + + /* memory pool config */ + CFG_MP_TCPSEG_NUM, + CFG_MP_MSG_NUM, + + /* RING config */ + CFG_HAL_TX_RING_SIZE, + CFG_HAL_RX_RING_SIZE, + CFG_MBOX_RING_SIZE, + CFG_SPL_MAX_RING_SIZE, + + /* PCB config */ + CFG_TCP_PCB_NUM, + CFG_UDP_PCB_NUM, + CFG_RAW_PCB_NUM, + + CFG_ARP_QUEUE_NUM, + + MAX_CUSTOM_CFG +}; +COMPAT_PROTECT (CFG_SPL_MAX_RING_SIZE, 8); + +enum EN_CFG_SEG +{ + CFG_SEG_BASE = 0, + CFG_SEG_LOG, + CFG_SEG_PATH, + CFG_SEG_PRI, + CFG_SEG_MAX +}; + +enum EN_CFG_ITEM_TYPE +{ + CFG_ITEM_TYPE_INT = 0, + CFG_ITEM_TYPE_STRING +}; + +enum EN_SEG_BASE_ITEM +{ + CFG_SEG_BASE_SOCKET_NUM = 0, + CFG_SEG_BASE_ARP_STALE_TIME, + CFG_SEG_BASE_ARP_BC_RETRANS_NUM, + CFG_SEG_BASE_MAX +}; + +enum EN_SEG_THREAD_PRI_ITEM +{ + CFG_SEG_THREAD_PRI_POLICY = 0, + CFG_SEG_THREAD_PRI_PRI, + CFG_SEG_THREAD_PRI_MAX +}; + +typedef void (*custom_check_fn) (void *pitem); + +// pack size? +struct cfg_item_info +{ + char *name; + int type; + int min_value; + int max_value; + int default_value; + char *default_str; + custom_check_fn custom_check; + union + { + int value; + char *pvalue; + }; +}; + +typedef struct _cfg_module_param +{ + u32 proc_type; + i32 argc; + u8 **argv; +} cfg_module_param; + +extern u32 g_custom_cfg_items[MAX_CUSTOM_CFG]; +extern u32 g_base_cfg_items[MAX_BASE_CFG]; + +#define get_base_cfg(tag) g_base_cfg_items[(tag)] +#define get_custom_cfg(tag) g_custom_cfg_items[(tag)] +#define set_custom_cfg_item(tag, value) g_custom_cfg_items[(tag)] = (value) + +/* stackx config data definition */ + +/* app socket num */ +#define DEF_APP_SOCKET_NUM 1024 + +/* socket num config */ +#define SOCKET_NUM_PER_THREAD 1024 /* socket number per thread */ +COMPAT_PROTECT (SOCKET_NUM_PER_THREAD, 1024); + +/* + MAX_SOCKET_NUM: max socket fd number one app can use, it should equal the max socket + number nstack support(CUR_CFG_SOCKET_NUM) +*/ + +#define DEF_SOCKET_NUM 1024 /* default socket number */ +COMPAT_PROTECT (DEF_SOCKET_NUM, 1024); +#define MIN_SOCKET_NUM 1024 /* min socket number */ + +#define MAX_SOCKET_NUM 8192 /* default: 8K sockets */ + +#define CUR_CFG_SOCKET_NUM get_base_cfg(CFG_BASE_SOCKET_NUM) /* max socket numbere nstack support */ + +#define DEF_ARP_STACLE_TIME 300 /* default arp stale time: second */ +#define MIN_ARP_STACLE_TIME 30 /* min arp stale time: second */ +#define MAX_ARP_STACLE_TIME 1200 /* max arp stale time: second */ +#define ARP_STALE_TIME get_base_cfg(CFG_BASE_ARP_STALE_TIME) + +#define DEF_ARP_BC_RETRANS_NUM 5 /* default arp broadcast retransmission times */ +#define MIN_ARP_BC_RETRANS_NUM 1 /* min arp broadcast retransmission times */ +#define MAX_ARP_BC_RETRANS_NUM 20 /* max arp broadcast retransmission times */ +#define ARP_BC_RETRANS_NUM get_base_cfg(CFG_BASE_ARP_BC_RETRANS_NUM) + +/* application mumber config */ +#define APP_POOL_NUM 32 /* max application number */ +COMPAT_PROTECT (APP_POOL_NUM, 32); + +/* thread number config */ +#define DEF_THREAD_NUM 1 /* default stackx thread number */ +#define MIN_THREAD_NUM 1 /* min thread number */ +#define MAX_THREAD_NUM 1 /* max thread number */ +COMPAT_PROTECT (MAX_THREAD_NUM, 1); + +/* hash size */ +#define MAX_TCP_HASH_SIZE 4096 + +/* hal port number config */ +#define DEF_HAL_PORT_NUM 20 /* port number */ +COMPAT_PROTECT (DEF_HAL_PORT_NUM, 20); +#define MIN_HAL_PORT_NUM 1 +#define MAX_HAL_PORT_NUM 255 +#define CUR_CFG_HAL_PORT_NUM get_base_cfg(CFG_BASE_HAL_PORT_NUM) + +/* vm number config */ +#define MAX_VF_NUM 4 /* max vf number */ +COMPAT_PROTECT (MAX_VF_NUM, 4); + +/* base ring size config */ +#define DEF_RING_BASE_SIZE 2048 /* base ring size */ +COMPAT_PROTECT (DEF_RING_BASE_SIZE, 2048); +#define MIN_RING_BASE_SIZE 1024 +#define MAX_RING_BASE_SIZE 4096 +#define POOL_RING_BASE_SIZE get_base_cfg(CFG_BASE_RING_SIZE) + +/* mbuf data size config */ +#define DEF_MBUF_DATA_SIZE 2048 /* mbuf data size */ +COMPAT_PROTECT (DEF_MBUF_DATA_SIZE, 2048); +#define TX_MBUF_MAX_LEN get_custom_cfg(CFG_MBUF_DATA_SIZE) + +/* tx mbuf pool size config */ +#define DEF_TX_MBUF_POOL_SIZE (4*POOL_RING_BASE_SIZE) /* tx mbuf pool size */ + +#define TX_MBUF_POOL_SIZE get_custom_cfg(CFG_TX_MBUF_NUM) + +/* rx mbuf pool size config */ +#define DEF_RX_MBUF_POOL_SIZE (8*POOL_RING_BASE_SIZE) /* rx mbuf pool size */ + +#define RX_MBUF_POOL_SIZE get_custom_cfg(CFG_RX_MBUF_NUM) + +/* hal netif rx/tx ring size config */ +#define DEF_HAL_RX_RING_SIZE 2048 /* hal rx ring size */ + +#define DEF_HAL_TX_RING_SIZE 2048 /* hal tx ring size */ +#define HAL_RX_RING_SIZE get_custom_cfg(CFG_HAL_RX_RING_SIZE) +#define HAL_TX_RING_SIZE get_custom_cfg(CFG_HAL_TX_RING_SIZE) + +/* stackx recv ring size config */ +#define DEF_SPL_MAX_RING_SIZE 1024 +COMPAT_PROTECT (DEF_SPL_MAX_RING_SIZE, 1024); + +#define SPL_MAX_RING_SIZE get_custom_cfg(CFG_SPL_MAX_RING_SIZE) /* ring size config, used in recv ring(per socket) */ + +/* pcb number config */ +#define DEF_TCP_PCB_NUM 4096 /* tcp pcb number, per thread */ +COMPAT_PROTECT (DEF_TCP_PCB_NUM, 4096); +#define DEF_UDP_PCB_NUM 512 /* udp pcb number, per thread */ +COMPAT_PROTECT (DEF_UDP_PCB_NUM, 512); +#define DEF_RAW_PCB_NUM 600 /* raw pcb number, per thread */ +COMPAT_PROTECT (DEF_RAW_PCB_NUM, 600); + +#define DEF_ARP_QUEUE_NUM 300 +#define LARGE_ARP_QUEUE_NUM (512*1024) + +#define SPL_MEMP_NUM_TCP_PCB get_custom_cfg(CFG_TCP_PCB_NUM) + +#define SPL_MEMP_NUM_UDP_PCB get_custom_cfg(CFG_UDP_PCB_NUM) +#define SPL_MEMP_NUM_RAW_PCB get_custom_cfg(CFG_RAW_PCB_NUM) + +#define SPL_MEMP_NUM_ARP_QUEUE get_custom_cfg(CFG_ARP_QUEUE_NUM) + +/* tcp seg number config */ +#define DEF_MEMP_NUM_TCP_SEG (2*APP_POOL_NUM*DEF_TX_MBUF_POOL_SIZE) +#define SPL_MEMP_NUM_TCP_SEG get_custom_cfg(CFG_MP_TCPSEG_NUM) /* tcp segment number, per thread */ + +/* 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) + +#define TX_MSG_POOL_SIZE get_custom_cfg(CFG_MP_MSG_NUM) /* msg number, used by stackx internal, per thread */ + +/* mbox ring size config */ +#define DEF_MBOX_RING_SIZE (DEF_RING_BASE_SIZE/4) +COMPAT_PROTECT (DEF_MBOX_RING_SIZE, 512); + +#define MBOX_RING_SIZE get_custom_cfg(CFG_MBOX_RING_SIZE) /* mbox ring size config, per thread */ + +/*some probem if CUSOTM_RECV_RING_SIZE more than 4096*/ +#define CUSOTM_RECV_RING_SIZE 4096 +COMPAT_PROTECT (CUSOTM_RECV_RING_SIZE, 4096); + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ +#define set_cfg_info(tag, item, min, max, def) { \ + g_cfg_item_info[tag][item].min_value = (min); \ + g_cfg_item_info[tag][item].max_value = (max); \ + g_cfg_item_info[tag][item].default_value = (def);\ + g_cfg_item_info[tag][item].value = (def);\ +} + +#define get_cfg_info(tag, item) g_cfg_item_info[tag][item].value + +u32 get_cfg_share_mem_size (); + +int get_share_cfg_from_mem (void *mem); + +int set_share_cfg_to_mem (void *mem); + +void config_module_init (cfg_module_param * param); + +#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..6b81942 --- /dev/null +++ b/stacks/lwip_stack/src/include/nsfw_rti.h @@ -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. +*/ + +#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; + +typedef struct nsfw_app_info +{ + int nsocket_fd; + int sbr_fd; + + int hostpid; + int pid; + int ppid; + + u64 reserve1; + u64 reserve2; + u64 reserve3; + u64 reserve4; + + u64 extend_member_bit; +} nsfw_app_info_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/io_adpt/CMakeLists.txt b/stacks/lwip_stack/src/io_adpt/CMakeLists.txt new file mode 100644 index 0000000..ae18116 --- /dev/null +++ b/stacks/lwip_stack/src/io_adpt/CMakeLists.txt @@ -0,0 +1,31 @@ +######################################################################### +# +# 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_HAL_LIB) +else() +endif() + + +INCLUDE_DIRECTORIES( + ./ + ${PROJECT_SOURCE_DIR}/src/include/ + ${PROJECT_SOURCE_DIR}/src/include/generic/ + /usr/include/dpdk/ +) +LINK_LIBRARIES(m dl rt dmm_api) +ADD_LIBRARY(nStackHal STATIC ${HAL}) 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..da2cfb6 --- /dev/null +++ b/stacks/lwip_stack/src/io_adpt/dpdk.c @@ -0,0 +1,2319 @@ +/* +* +* 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 "nsfw_init.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, + }, +}; + +/***************************************************************************** +* 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; + + 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 + + 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 + + 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 + + return (*dev->tx_pkt_burst) (dev->data->tx_queues[queue_id], tx_pkts, + nb_pkts); +} + +/***************************************************************************** + 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_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) + { + NSCOMM_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) +{ + int ret; + + 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; + } + + 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 + { + *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, ð_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, + hal_netif_capa_t * capa) +{ + int retVal = + MEMSET_S (capa, sizeof (hal_netif_capa_t), 0, sizeof (hal_netif_capa_t)); + if (EOK != retVal) + { + NSHAL_LOGERR ("MEMSET_S fail]retVal=%d", retVal); + } + + capa->tx_offload_capa = dev_info->tx_offload_capa; +} + +/***************************************************************************** + 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, hal_netif_capa_t * 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, + hal_mbuf_t ** 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, + hal_mbuf_t ** 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 (ð_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, ð_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, ð_addr); + + ret = rte_eth_bond_mac_address_set ((uint8_t) port, ð_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/maintain/CMakeLists.txt b/stacks/lwip_stack/src/maintain/CMakeLists.txt new file mode 100644 index 0000000..05c5117 --- /dev/null +++ b/stacks/lwip_stack/src/maintain/CMakeLists.txt @@ -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. +######################################################################### + +if(WITH_HAL_LIB) +else() + SET(PAL_H_DIRECTORIES "/usr/include/dpdk/") + SET(PAL_BITWIDE_ADJUST ${PROJECT_SOURCE_DIR}/../../src/framework/common/base/include/common_pal_bitwide_adjust.h) + ADD_DEFINITIONS(-include ${PAL_BITWIDE_ADJUST}) + INCLUDE_DIRECTORIES( + ${PAL_H_DIRECTORIES} + ) +endif() + +FILE(GLOB_RECURSE NSTACKMAINTAIN *.c) + +LINK_LIBRARIES(m dl rt dmm_api) +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/ +) +endif() +ADD_LIBRARY(nStackMaintain STATIC ${NSTACKMAINTAIN}) diff --git a/stacks/lwip_stack/src/maintain/fw_mt_config.c b/stacks/lwip_stack/src/maintain/fw_mt_config.c new file mode 100644 index 0000000..400eaa0 --- /dev/null +++ b/stacks/lwip_stack/src/maintain/fw_mt_config.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 header files * + *----------------------------------------------*/ + +#include "types.h" +#include "nsfw_mt_config.h" +#include <stdlib.h> +#include <pthread.h> +#include "nstack_log.h" +#include "nstack_securec.h" +#include "json.h" +#include "nsfw_init.h" +#include "nsfw_mgr_com_api.h" + +/*==============================================* + * project-wide global variables * + *----------------------------------------------*/ + +// can be read from config file +u32 g_base_cfg_items[MAX_BASE_CFG] = { 0 }; + +// calculated according to base config +u32 g_custom_cfg_items[MAX_CUSTOM_CFG] = { 0 }; + +// note: if seg number greater than 16, such buffer should use malloc +// or it will be exceed 2K +struct cfg_item_info g_cfg_item_info[CFG_SEG_MAX][MAX_CFG_ITEM]; + +NSTACK_STATIC int g_cfg_item_count[CFG_SEG_MAX] = { 0 }; + +NSTACK_STATIC char *g_cfg_seg_name[CFG_SEG_MAX]; + +/*==============================================* + * routines' or functions' implementations * + *----------------------------------------------*/ + +/* nStackCtrl cannot get the env path info, no start by shell script, need get + the path info ,and legal check , add a input parameter proc_type*/ + +NSTACK_STATIC int +get_ctrl_dir_info (char *current_path, unsigned path_len) +{ + char ctrl_dir[MAX_FILE_NAME_LEN] = { 0 }; + int count = 0; + unsigned int dir_len = 0; + + //nStackCtrl cannot get the path from the env, so need get from current pwd. + count = readlink ("/proc/self/exe", ctrl_dir, MAX_FILE_NAME_LEN); + if ((count < 0) || (count >= MAX_FILE_NAME_LEN)) + { + save_pre_init_log (NSLOG_ERR, + "readlink get nStackCtrl path failed, write nothing!"); + return -1; + } + ctrl_dir[count] = '\0'; + + dir_len = strlen (ctrl_dir); + if ((dir_len > strlen ("nStackCtrl")) && (dir_len < MAX_FILE_NAME_LEN)) + { + ctrl_dir[dir_len - strlen ("nStackCtrl")] = '\0'; + } + else + { + save_pre_init_log (NSLOG_ERR, "path strlen is illegal, write nothing!"); + return -1; + } + + if (NULL == strstr (ctrl_dir, "bin")) + { + /* Exit before nstack_log_init, use printf */ + printf + ("the nStackServer content change, plz keep same with nStack release, exit!\n"); +#ifdef FOR_NSTACK_UT + return -1; +#else + exit (1); +#endif + } + if (EOK != + STRNCAT_S (ctrl_dir, sizeof (ctrl_dir), "/../configure", + strlen ("/../configure"))) + { + save_pre_init_log (NSLOG_ERR, "STRNCAT_S failed, current_dir = %s", + ctrl_dir); + return -1; + } + + if (-1 == SNPRINTF_S (current_path, path_len, path_len - 1, "%s", ctrl_dir)) + { + save_pre_init_log (NSLOG_ERR, + "SNPRINTF_S path name failed, ctrl_dir %s.", + ctrl_dir); + return -1; + } + + return 0; + +} + +NSTACK_STATIC int +get_cfg_buf (u32 proc_type, char *cfg_buf, unsigned buf_size) +{ + char current_dir[MAX_FILE_NAME_LEN] = { 0 }; + char cfg_file_name[MAX_FILE_NAME_LEN] = { 0 }; + char *cfg_resolved_path = NULL; + char *cfg_path = NULL; + FILE *fp = NULL; + int cfg_buf_len = 0; + + cfg_path = getenv (CFG_PATH); + if ((NULL == cfg_path) && (NSFW_PROC_CTRL == proc_type)) + { + if (-1 == get_ctrl_dir_info (current_dir, sizeof (current_dir))) + { + save_pre_init_log (NSLOG_ERR, "get_ctrl_dir_info failed."); + return -1; + } + cfg_path = current_dir; + } + else if ((NULL == cfg_path) && (NSFW_PROC_CTRL != proc_type)) + { + save_pre_init_log (NSLOG_ERR, + "main or master process get nstack config path failed, will use default config!"); + return -1; + } + + if (-1 == + SPRINTF_S (cfg_file_name, sizeof (cfg_file_name), "%s/%s", cfg_path, + CFG_FILE_NAME)) + { + save_pre_init_log (NSLOG_ERR, + "format config file name failed, path %s, name %s.", + cfg_path, CFG_FILE_NAME); + return -1; + } + + cfg_resolved_path = realpath (cfg_file_name, NULL); + if (NULL == cfg_resolved_path) + { + save_pre_init_log (NSLOG_ERR, "config file path invalid, cfg name %s.", + cfg_file_name); + return -1; + } + + fp = fopen (cfg_resolved_path, "r"); + if (NULL == fp) + { + free (cfg_resolved_path); + save_pre_init_log (NSLOG_ERR, "config file path invalid, cfg name %s.", + cfg_file_name); + return -1; + } + + free (cfg_resolved_path); + // read config file to json buffer + cfg_buf_len = fread (cfg_buf, 1, buf_size, fp); + + fclose (fp); + + return cfg_buf_len; +} + +NSTACK_STATIC inline int +get_value_from_json_obj (struct json_object *obj, struct cfg_item_info *pitem) +{ + switch (pitem->type) + { + case CFG_ITEM_TYPE_INT: + pitem->value = json_object_get_int (obj); + break; + case CFG_ITEM_TYPE_STRING: + pitem->pvalue = (char *) json_object_get_string (obj); + break; + default: + // print log here? + return -1; + } + return 0; +} + +NSTACK_STATIC inline void +get_cfg_item (struct json_object *obj, int seg_index) +{ + struct json_object *cfg_seg_obj = NULL; + struct json_object *cfg_seg = NULL; + struct json_object *cfg_item_obj[MAX_CFG_ITEM] = { 0 }; + int i = 0; + int cfg_num = 0; + + (void) json_object_object_get_ex (obj, g_cfg_seg_name[seg_index], + &cfg_seg_obj); + if (NULL == cfg_seg_obj) + { + save_pre_init_log (NSLOG_ERR, "get config segment obj failed, seg:%s.", + g_cfg_seg_name[seg_index]); + return; + } + + cfg_num = json_object_array_length (cfg_seg_obj); + if (cfg_num < 1) + { + save_pre_init_log (NSLOG_ERR, + "config segment count invalid, config segment %s, count %d.", + g_cfg_seg_name[seg_index], cfg_num); + return; + } + + // each config segment just has 1 array element + cfg_seg = (struct json_object *) json_object_array_get_idx (cfg_seg_obj, 0); + if (NULL == cfg_seg) + { + save_pre_init_log (NSLOG_ERR, "no config item in seg %s.", + g_cfg_seg_name[seg_index]); + return; + } + + for (; i < g_cfg_item_count[seg_index]; i++) + { + (void) json_object_object_get_ex (cfg_seg, + g_cfg_item_info[seg_index][i].name, + &cfg_item_obj[i]); + + if (NULL == cfg_item_obj[i]) + { + save_pre_init_log (NSLOG_ERR, + "get config item failed, config item %s.", + g_cfg_item_info[seg_index][i].name); + return; + } + + // note: should specify the config item type if not only int item exist + if (get_value_from_json_obj + (cfg_item_obj[i], &g_cfg_item_info[seg_index][i]) != 0) + { + return; + } + } + + return; +} + +NSTACK_STATIC inline void +parse_cfg (char *cfg_buf) +{ + if (NULL == cfg_buf) + { + return; + } + + struct json_object *obj = + (struct json_object *) json_tokener_parse (cfg_buf); + int i = 0; + + for (; i < CFG_SEG_MAX; i++) + { + if (0 == g_cfg_item_count[i]) + { + continue; + } + + get_cfg_item (obj, i); + } +} + +NSTACK_STATIC inline int +is_valid (int value, int min_value, int max_value) +{ + if ((value < min_value) || (value > max_value)) + { + return 0; + } + + return 1; +} + +NSTACK_STATIC inline void +check_cfg_item_int (struct cfg_item_info *pitem) +{ + if (!is_valid (pitem->value, pitem->min_value, pitem->max_value)) + { + pitem->value = pitem->default_value; + } +} + +NSTACK_STATIC inline void +check_cfg_item_string (struct cfg_item_info *pitem) +{ + if ((NULL == pitem->pvalue) || ((pitem->pvalue) && (0 == pitem->pvalue[0]))) + { + pitem->pvalue = pitem->default_str; + } +} + +NSTACK_STATIC inline void +check_cfg_item (struct cfg_item_info *pitem) +{ + switch (pitem->type) + { + case CFG_ITEM_TYPE_INT: + check_cfg_item_int (pitem); + if (pitem->custom_check) + pitem->custom_check (pitem); + break; + case CFG_ITEM_TYPE_STRING: + check_cfg_item_string (pitem); + if (pitem->custom_check) + pitem->custom_check (pitem); + break; + default: + break; + } +} + +NSTACK_STATIC inline void +check_cfg () +{ + int i = 0; + int j = 0; + for (i = 0; i < CFG_SEG_MAX; i++) + { + for (j = 0; j < g_cfg_item_count[i]; j++) + { + check_cfg_item (&g_cfg_item_info[i][j]); + } + } +} + +NSTACK_STATIC inline void +print_item_info (char *seg_name, struct cfg_item_info *pitem) +{ + switch (pitem->type) + { + case CFG_ITEM_TYPE_INT: + save_pre_init_log (NSLOG_INF, "config read seg:%s, name:%s, value:%d.", + seg_name, pitem->name, pitem->value); + break; + case CFG_ITEM_TYPE_STRING: + save_pre_init_log (NSLOG_INF, "config read seg:%s, name:%s, pvalue:%s.", + seg_name, pitem->name, pitem->pvalue); + break; + default: + break; + } +} + +NSTACK_STATIC inline void +print_config_item_info () +{ + int i = 0; + int j = 0; + for (; i < CFG_SEG_MAX; i++) + { + for (j = 0; j < g_cfg_item_count[i]; j++) + { + print_item_info (g_cfg_seg_name[i], &g_cfg_item_info[i][j]); + } + } +} + +void +check_socket_config (void *pitem) +{ + struct cfg_item_info *item = (struct cfg_item_info *) pitem; + if (item->value > 0 && !(item->value & (item->value - 1))) + return; + save_pre_init_log (NSLOG_WAR, + "warning: config socket_num (%u) is not 2^n, will use the default value:%u", + item->value, item->default_value); + item->value = item->default_value; +} + +/* thread schedule mode and thread priority should be matched */ +void +check_thread_config (void *pitem) +{ + struct cfg_item_info *pri_cfg = (struct cfg_item_info *) pitem; + struct cfg_item_info *policy_cfg = + &g_cfg_item_info[CFG_SEG_PRI][CFG_SEG_THREAD_PRI_POLICY]; + + int max_pri = sched_get_priority_max (policy_cfg->value); + int min_pri = sched_get_priority_min (policy_cfg->value); + if ((pri_cfg->value > max_pri) || (pri_cfg->value < min_pri)) + { + save_pre_init_log (NSLOG_INF, + "detect invalid thread priority configuration, use default value] policy=%d, pri=%d, def policy=%d, def pri=%d", + policy_cfg->value, pri_cfg->value, + policy_cfg->default_value, pri_cfg->default_value); + + policy_cfg->value = policy_cfg->default_value; + pri_cfg->value = pri_cfg->default_value; + } +} + +#define SET_CFG_ITEM(seg, item, field, value) g_cfg_item_info[seg][item].field = (value) +#define SET_THREAD_CFG_ITEM(item, field, value) SET_CFG_ITEM(CFG_SEG_PRI, item, field, value) + +NSTACK_STATIC void +init_main_def_config_items () +{ + /* base config */ + g_cfg_seg_name[CFG_SEG_BASE] = "cfg_seg_socket"; + g_cfg_item_count[CFG_SEG_BASE] = CFG_SEG_BASE_MAX; + /* -- socket number */ + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_SOCKET_NUM].name = "socket_num"; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_SOCKET_NUM].type = + CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_SOCKET_NUM].custom_check = + check_socket_config; + set_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_SOCKET_NUM, MIN_SOCKET_NUM, + MAX_SOCKET_NUM, DEF_SOCKET_NUM); + /* -- arp stale time */ + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_STALE_TIME].name = + "arp_stale_time"; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_STALE_TIME].type = + CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_STALE_TIME].custom_check = + NULL; + set_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_ARP_STALE_TIME, + MIN_ARP_STACLE_TIME, MAX_ARP_STACLE_TIME, + DEF_ARP_STACLE_TIME); + /* -- arp braodcast retransmission times */ + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_BC_RETRANS_NUM].name = + "arp_bc_retrans_num"; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_BC_RETRANS_NUM].type = + CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_BASE][CFG_SEG_BASE_ARP_BC_RETRANS_NUM].custom_check + = NULL; + set_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_ARP_BC_RETRANS_NUM, + MIN_ARP_BC_RETRANS_NUM, MAX_ARP_BC_RETRANS_NUM, + DEF_ARP_BC_RETRANS_NUM); + + /* support thread priority configuration */ + g_cfg_seg_name[CFG_SEG_PRI] = "cfg_seg_thread_pri"; + g_cfg_item_count[CFG_SEG_PRI] = CFG_SEG_THREAD_PRI_MAX; + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_POLICY, name, "sched_policy"); + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_POLICY, type, CFG_ITEM_TYPE_INT); + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_POLICY, custom_check, NULL); + set_cfg_info (CFG_SEG_PRI, CFG_SEG_THREAD_PRI_POLICY, 0, 2, 0); + + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_PRI, name, "thread_pri"); + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_PRI, type, CFG_ITEM_TYPE_INT); + SET_THREAD_CFG_ITEM (CFG_SEG_THREAD_PRI_PRI, custom_check, + check_thread_config); + set_cfg_info (CFG_SEG_PRI, CFG_SEG_THREAD_PRI_PRI, 0, 99, 0); + + /* remove unsed operation config set */ + /* log config */ + g_cfg_seg_name[CFG_SEG_LOG] = "cfg_seg_log"; + g_cfg_item_count[CFG_SEG_LOG] = 2; + g_cfg_item_info[CFG_SEG_LOG][0].name = "run_log_size"; + g_cfg_item_info[CFG_SEG_LOG][0].type = CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_LOG][0].custom_check = NULL; + g_cfg_item_info[CFG_SEG_LOG][1].name = "run_log_count"; + g_cfg_item_info[CFG_SEG_LOG][1].type = CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_LOG][1].custom_check = NULL; + set_cfg_info (CFG_SEG_LOG, 0, 10, 100, 50); + set_cfg_info (CFG_SEG_LOG, 1, 2, 20, 10); + + /* path config */ + /* set the path string and default str */ + g_cfg_seg_name[CFG_SEG_PATH] = "cfg_seg_path"; + g_cfg_item_count[CFG_SEG_PATH] = 1; + g_cfg_item_info[CFG_SEG_PATH][0].name = "stackx_log_path"; + g_cfg_item_info[CFG_SEG_PATH][0].type = CFG_ITEM_TYPE_STRING; + g_cfg_item_info[CFG_SEG_PATH][0].default_str = NSTACK_LOG_NAME; + g_cfg_item_info[CFG_SEG_PATH][0].custom_check = NULL; +} + +/* master and ctrl both use the function to reduce the redundancy, +* as the parameter and operation all same. +*/ +NSTACK_STATIC void +init_master_def_config_items () +{ + int i = 0; + for (; i < CFG_SEG_MAX; i++) + { + if (i != CFG_SEG_LOG) + { + g_cfg_item_count[i] = 0; + } + } + + g_cfg_seg_name[CFG_SEG_LOG] = "cfg_seg_log"; + g_cfg_item_count[CFG_SEG_LOG] = 2; + g_cfg_item_info[CFG_SEG_LOG][0].name = "mon_log_size"; + g_cfg_item_info[CFG_SEG_LOG][0].type = CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_LOG][0].custom_check = NULL; + g_cfg_item_info[CFG_SEG_LOG][1].name = "mon_log_count"; + g_cfg_item_info[CFG_SEG_LOG][1].type = CFG_ITEM_TYPE_INT; + g_cfg_item_info[CFG_SEG_LOG][1].custom_check = NULL; + + set_cfg_info (CFG_SEG_LOG, 0, 2, 20, 10); + set_cfg_info (CFG_SEG_LOG, 1, 2, 20, 10); + + g_cfg_seg_name[CFG_SEG_PATH] = "cfg_seg_path"; + g_cfg_item_count[CFG_SEG_PATH] = 1; + g_cfg_item_info[CFG_SEG_PATH][0].name = "master_log_path"; + g_cfg_item_info[CFG_SEG_PATH][0].type = CFG_ITEM_TYPE_STRING; + g_cfg_item_info[CFG_SEG_PATH][0].default_str = NSTACK_LOG_NAME; + g_cfg_item_info[CFG_SEG_PATH][0].custom_check = NULL; +} + +NSTACK_STATIC void +read_init_config (u32 proc_type) +{ + int cfg_buf_len = 0; + char cfg_json_buf[CFG_BUFFER_LEN] = { 0 }; + + cfg_buf_len = get_cfg_buf (proc_type, cfg_json_buf, sizeof (cfg_json_buf)); + if (cfg_buf_len < 0) + { + save_pre_init_log (NSLOG_WAR, + "warning:file not exist, use default config."); + return; + } + else + { + /* parse json buffer */ + parse_cfg (cfg_json_buf); + } + save_pre_init_log (NSLOG_INF, "read configuration finished."); +} + +/* =========== set config items ========= */ +NSTACK_STATIC inline void +set_base_config () +{ + g_base_cfg_items[CFG_BASE_RING_SIZE] = DEF_RING_BASE_SIZE; + g_base_cfg_items[CFG_BASE_HAL_PORT_NUM] = DEF_HAL_PORT_NUM; + + g_base_cfg_items[CFG_BASE_SOCKET_NUM] = + (u32) get_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_SOCKET_NUM); + g_base_cfg_items[CFG_BASE_ARP_STALE_TIME] = + (u32) get_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_ARP_STALE_TIME); + g_base_cfg_items[CFG_BASE_ARP_BC_RETRANS_NUM] = + (u32) get_cfg_info (CFG_SEG_BASE, CFG_SEG_BASE_ARP_BC_RETRANS_NUM); +} + +NSTACK_STATIC void +init_base_config (cfg_module_param * param) +{ + /* initial default config */ + /* omc_ctrl single log file should be 10M */ + if (param->proc_type == NSFW_PROC_MASTER + || param->proc_type == NSFW_PROC_CTRL) + { + init_master_def_config_items (); + } + else + { + init_main_def_config_items (); + } + + /* read base config from file */ + read_init_config (param->proc_type); + /* check config and reset value */ + check_cfg (); + + /* print config info */ + print_config_item_info (); + + set_base_config (); +} + +NSTACK_STATIC void +init_stackx_config () +{ + u32 socket_num_per_thread = CUR_CFG_SOCKET_NUM; + u32 factor = socket_num_per_thread / SOCKET_NUM_PER_THREAD; + + if (factor == 0 || socket_num_per_thread % SOCKET_NUM_PER_THREAD > 0) + { + factor += 1; + } + + save_pre_init_log (NSLOG_INF, "socket num:%d, factor:%d", + CUR_CFG_SOCKET_NUM, factor); + + /* MBUF config */ + set_custom_cfg_item (CFG_MBUF_DATA_SIZE, DEF_MBUF_DATA_SIZE); + set_custom_cfg_item (CFG_TX_MBUF_NUM, DEF_TX_MBUF_POOL_SIZE); + set_custom_cfg_item (CFG_RX_MBUF_NUM, DEF_RX_MBUF_POOL_SIZE); + set_custom_cfg_item (CFG_MP_TCPSEG_NUM, DEF_MEMP_NUM_TCP_SEG); /* tcp segment number */ + set_custom_cfg_item (CFG_MP_MSG_NUM, DEF_TX_MSG_POOL_SIZE); /* msg number */ + + /* ring config */ + set_custom_cfg_item (CFG_HAL_RX_RING_SIZE, DEF_HAL_RX_RING_SIZE); /* netif ring size not changed */ + set_custom_cfg_item (CFG_HAL_TX_RING_SIZE, DEF_HAL_TX_RING_SIZE); /* netif ring size not changed */ + set_custom_cfg_item (CFG_MBOX_RING_SIZE, DEF_MBOX_RING_SIZE); + set_custom_cfg_item (CFG_SPL_MAX_RING_SIZE, DEF_SPL_MAX_RING_SIZE); /* stackx ring size */ + + /* pcb config */ + set_custom_cfg_item (CFG_TCP_PCB_NUM, DEF_TCP_PCB_NUM * factor); + set_custom_cfg_item (CFG_UDP_PCB_NUM, DEF_UDP_PCB_NUM * factor); + set_custom_cfg_item (CFG_RAW_PCB_NUM, DEF_RAW_PCB_NUM * factor); + set_custom_cfg_item (CFG_ARP_QUEUE_NUM, + CUR_CFG_SOCKET_NUM > + DEF_SOCKET_NUM ? LARGE_ARP_QUEUE_NUM : + DEF_ARP_QUEUE_NUM); +} + +void +print_final_config_para () +{ + save_pre_init_log (NSLOG_INF, "socket_num :%u", + get_base_cfg (CFG_BASE_SOCKET_NUM)); + save_pre_init_log (NSLOG_INF, "base_ring_size :%u", + get_base_cfg (CFG_BASE_RING_SIZE)); + save_pre_init_log (NSLOG_INF, "hal_port_num :%u", + get_base_cfg (CFG_BASE_HAL_PORT_NUM)); + save_pre_init_log (NSLOG_INF, "arp_stale_num :%u", + get_base_cfg (CFG_BASE_ARP_STALE_TIME)); + save_pre_init_log (NSLOG_INF, "arp_bc_retrans_num :%u", + get_base_cfg (CFG_BASE_ARP_BC_RETRANS_NUM)); + + save_pre_init_log (NSLOG_INF, "mbuf_data_size :%u", + get_custom_cfg (CFG_MBUF_DATA_SIZE)); + save_pre_init_log (NSLOG_INF, "tx_mbuf_num :%u", + get_custom_cfg (CFG_TX_MBUF_NUM)); + save_pre_init_log (NSLOG_INF, "rx_mbuf_num :%u", + get_custom_cfg (CFG_RX_MBUF_NUM)); + save_pre_init_log (NSLOG_INF, "tcp_seg_mp_num :%u", + get_custom_cfg (CFG_MP_TCPSEG_NUM)); + save_pre_init_log (NSLOG_INF, "msg_mp_num :%u", + get_custom_cfg (CFG_MP_MSG_NUM)); + save_pre_init_log (NSLOG_INF, "hal_tx_ring_size :%u", + get_custom_cfg (CFG_HAL_TX_RING_SIZE)); + save_pre_init_log (NSLOG_INF, "hal_rx_ring_size :%u", + get_custom_cfg (CFG_HAL_RX_RING_SIZE)); + save_pre_init_log (NSLOG_INF, "mbox_ring_size :%u", + get_custom_cfg (CFG_MBOX_RING_SIZE)); + save_pre_init_log (NSLOG_INF, "spl_ring_size :%u", + get_custom_cfg (CFG_SPL_MAX_RING_SIZE)); + save_pre_init_log (NSLOG_INF, "tcp_pcb_num :%u", + get_custom_cfg (CFG_TCP_PCB_NUM)); + save_pre_init_log (NSLOG_INF, "udp_pcb_num :%u", + get_custom_cfg (CFG_UDP_PCB_NUM)); + save_pre_init_log (NSLOG_INF, "raw_pcb_num :%u", + get_custom_cfg (CFG_RAW_PCB_NUM)); +} + +NSTACK_STATIC void +init_module_cfg_default () +{ + init_stackx_config (); + + print_final_config_para (); +} + +NSTACK_STATIC void +init_main_log_cfg_para () +{ + struct log_init_para log_para; + log_para.run_log_size = g_cfg_item_info[CFG_SEG_LOG][0].value; + log_para.run_log_count = g_cfg_item_info[CFG_SEG_LOG][1].value; + + /* log path valid check */ + if (0 == access (g_cfg_item_info[CFG_SEG_PATH][0].pvalue, W_OK)) + { + log_para.run_log_path = g_cfg_item_info[CFG_SEG_PATH][0].pvalue; + } + else + { + log_para.run_log_path = g_cfg_item_info[CFG_SEG_PATH][0].default_str; + } + + set_log_init_para (&log_para); +} + +NSTACK_STATIC void +init_master_log_cfg_para () +{ + struct log_init_para log_para; + log_para.mon_log_size = g_cfg_item_info[CFG_SEG_LOG][0].value; + log_para.mon_log_count = g_cfg_item_info[CFG_SEG_LOG][1].value; + + /* log path valid check */ + if (0 == access (g_cfg_item_info[CFG_SEG_PATH][0].pvalue, W_OK)) + { + log_para.mon_log_path = g_cfg_item_info[CFG_SEG_PATH][0].pvalue; + } + else + { + log_para.mon_log_path = g_cfg_item_info[CFG_SEG_PATH][0].default_str; + } + + set_log_init_para (&log_para); +} + +/* nStackCtrl is the diff process with main, cannot use main process info, + need get the configure info respectively */ +/* omc_ctrl single log file should be 10M */ +NSTACK_STATIC void +init_ctrl_log_cfg_para () +{ + struct log_init_para log_para; + log_para.mon_log_size = g_cfg_item_info[CFG_SEG_LOG][0].value; + log_para.mon_log_count = g_cfg_item_info[CFG_SEG_LOG][1].value; + + /* log path valid check */ + if (0 == access (g_cfg_item_info[CFG_SEG_PATH][0].pvalue, W_OK)) + { + log_para.mon_log_path = g_cfg_item_info[CFG_SEG_PATH][0].pvalue; + } + else + { + log_para.mon_log_path = g_cfg_item_info[CFG_SEG_PATH][0].default_str; + } + + set_log_init_para (&log_para); +} + +/*===========config init for nstack main=============*/ + +NSTACK_STATIC void +init_module_cfg_nstackmain () +{ + /* init config data */ + init_module_cfg_default (); + + /* init log para */ + init_main_log_cfg_para (); +} + +/*===========config init for nstack master=============*/ + +NSTACK_STATIC void +init_module_cfg_nstackmaster () +{ + /* init config data */ + init_module_cfg_default (); + + init_master_log_cfg_para (); +} + +/*===========config init for nstack ctrl=============*/ + +/* nStackCtrl is the diff process with main, + cannot use main process info, need get the configure info respectively */ + +NSTACK_STATIC void +init_module_cfg_nstackctrl () +{ + init_ctrl_log_cfg_para (); +} + +/*===========init config module=============*/ +void +config_module_init (cfg_module_param * param) +{ + save_pre_init_log (NSLOG_INF, "config module init begin] proc type=%d", + param->proc_type); + + init_base_config (param); + + switch (param->proc_type) + { + case NSFW_PROC_MAIN: + init_module_cfg_nstackmain (); + break; + + case NSFW_PROC_MASTER: + init_module_cfg_nstackmaster (); + break; + + case NSFW_PROC_CTRL: + init_module_cfg_nstackctrl (); + break; + + default: + init_module_cfg_default (); + break; + } + + save_pre_init_log (NSLOG_INF, "config module init end."); +} + +u32 +get_cfg_share_mem_size () +{ + return sizeof (g_base_cfg_items) + sizeof (g_custom_cfg_items); +} + +int +get_share_cfg_from_mem (void *mem) +{ + if (EOK != + MEMCPY_S (g_base_cfg_items, sizeof (g_base_cfg_items), mem, + sizeof (g_base_cfg_items))) + { + return -1; + } + + char *custom_cfg_mem = (char *) mem + sizeof (g_base_cfg_items); + + if (EOK != + MEMCPY_S (g_custom_cfg_items, sizeof (g_custom_cfg_items), + custom_cfg_mem, sizeof (g_custom_cfg_items))) + { + return -1; + } + + return 0; +} + +int +set_share_cfg_to_mem (void *mem) +{ + if (EOK != + MEMCPY_S (mem, sizeof (g_base_cfg_items), g_base_cfg_items, + sizeof (g_base_cfg_items))) + { + return -1; + } + + char *custom_cfg_mem = (char *) mem + sizeof (g_base_cfg_items); + + if (EOK != + MEMCPY_S (custom_cfg_mem, sizeof (g_custom_cfg_items), + g_custom_cfg_items, sizeof (g_custom_cfg_items))) + { + return -1; + } + + return 0; +} diff --git a/stacks/lwip_stack/src/maintain/nsfw_msg.c b/stacks/lwip_stack/src/maintain/nsfw_msg.c new file mode 100644 index 0000000..338f803 --- /dev/null +++ b/stacks/lwip_stack/src/maintain/nsfw_msg.c @@ -0,0 +1,23 @@ +/* +* +* 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_msg.h" +/* *INDENT-OFF* */ +msg_fun g_msg_module_fun_array[MAX_MODULE_TYPE] = {NULL}; +msg_fun g_msg_module_major_fun_array[MAX_MODULE_TYPE][MAX_MAJOR_TYPE] = {{NULL}}; +msg_fun g_msg_module_major_minor_fun_array[MAX_MODULE_TYPE][MAX_MAJOR_TYPE][MAX_MINOR_TYPE] = {{{NULL}}}; +msg_fun g_msg_unsupport_fun = NULL; +/* *INDENT-ON* */ diff --git a/stacks/lwip_stack/src/maintain/nsfw_rti.c b/stacks/lwip_stack/src/maintain/nsfw_rti.c new file mode 100644 index 0000000..e5a1d3c --- /dev/null +++ b/stacks/lwip_stack/src/maintain/nsfw_rti.c @@ -0,0 +1,92 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mem_api.h" +#include "nsfw_rti.h" +#include "nsfw_msg.h" +#ifdef HAL_LIB +#else +#include "common_pal_bitwide_adjust.h" +#endif + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +char g_dfx_switch = 1; + +struct rti_queue *g_nsfw_rti_primary_stat = NULL; + +void +nsfw_rti_stat (nsfw_rti_stat_type_t statType, const data_com_msg * m) +{ + if (!g_nsfw_rti_primary_stat || !m) + { + return; + } + + struct rti_queue *primary_stat = ADDR_SHTOL (g_nsfw_rti_primary_stat); + + switch (statType) + { + case NSFW_STAT_PRIMARY_DEQ: + if ((m->param.major_type >= MAX_MAJOR_TYPE) + || (m->param.minor_type >= MAX_MINOR_TYPE)) + { + return; + } + /*call_msg_fun() is only called in nStackMain, no reentrance risk, ++ operation is ok */ + primary_stat->tcpip_msg_deq[m->param.major_type]++; + if (0 == m->param.major_type) //SPL_TCPIP_NEW_MSG_API + { + primary_stat->api_msg_deq[m->param.minor_type]++; + } + break; + case NSFW_STAT_PRIMARY_ENQ_FAIL: + if ((m->param.major_type >= MAX_MAJOR_TYPE) + || (m->param.minor_type >= MAX_MINOR_TYPE)) + { + return; + } + __sync_fetch_and_add (&primary_stat->tcpip_msg_enq_fail + [m->param.major_type], 1); + if (0 == m->param.major_type) //SPL_TCPIP_NEW_MSG_API + { + __sync_fetch_and_add (&primary_stat->api_msg_enq_fail + [m->param.minor_type], 1); + } + break; + case NSFW_STAT_PRIMARY_ENQ: + //not use + break; + default: + break; + } +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/stacks/lwip_stack/src/nStackMain/CMakeLists.txt b/stacks/lwip_stack/src/nStackMain/CMakeLists.txt new file mode 100644 index 0000000..24f6c9d --- /dev/null +++ b/stacks/lwip_stack/src/nStackMain/CMakeLists.txt @@ -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. +######################################################################### + +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 + dmm_api + nStackMaintain + stacklwip + nStackHal + nStackAlarm + nTcpdump + -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 nStackHal nStackMaintain nStackAlarm stacklwip SECUREC) +else() +ADD_DEPENDENCIES(nStackMain nStackHal nStackMaintain nStackAlarm stacklwip) +endif() + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../alarm/ + ${CMAKE_CURRENT_LIST_DIR}/../maintain/ + ${CMAKE_CURRENT_LIST_DIR}/../include/ +) diff --git a/stacks/lwip_stack/src/nStackMain/main.c b/stacks/lwip_stack/src/nStackMain/main.c new file mode 100644 index 0000000..ce05068 --- /dev/null +++ b/stacks/lwip_stack/src/nStackMain/main.c @@ -0,0 +1,427 @@ +/* +* +* 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.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" + +#define GLOBAL_Stack_ARG "stack" +#define GlOBAL_HELP "--help" +#define GLOBAL_Dpdk_ARG "dpdk" +#define GLOBAL_STACK_PORT "-port" +#define NSTACK_MAIN_MAX_PARA 19 +#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 (); + +#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 ()); + + (void) nstack_framework_setModuleParam (NSFW_ALARM_MODULE, + (void *) ((u64) proc_type)); + (void) nstack_framework_setModuleParam (TCPDUMP_MODULE, + (void *) ((u64) proc_type)); + + nstack_dmm_para stpara; + stpara.argc = uStackArgIndex; + stpara.argv = gArgv; + stpara.deploy_type = NSTACK_MODEL_TYPE3; + stpara.proc_type = NSFW_PROC_MAIN; + stpara.attr.policy = get_cfg_info (CFG_SEG_PRI, CFG_SEG_THREAD_PRI_POLICY); + stpara.attr.pri = get_cfg_info (CFG_SEG_PRI, CFG_SEG_THREAD_PRI_PRI); + + if (nstack_adpt_init (&stpara) != 0) + { + NSFW_LOGERR ("nstack adpt init fail"); + 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"); + } + + if (0 != get_ip_json_data ()) + { + NSFW_LOGINF ("get_ip_json_data error"); + } + + 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..42ab4a4 --- /dev/null +++ b/stacks/lwip_stack/src/sbr/CMakeLists.txt @@ -0,0 +1,30 @@ +######################################################################### +# +# 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(nstack SHARED ${SBR}) +TARGET_LINK_LIBRARIES(nstack -Wl,--whole-archive socket -Wl,--no-whole-archive dmm_api nStackMaintain) +ADD_DEPENDENCIES(nstack socket DPDK) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../include + ${PAL_H_DIRECTORIES} +) 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..be3bc3b --- /dev/null +++ b/stacks/lwip_stack/src/sbr/sbr_err.h @@ -0,0 +1,191 @@ +/* +* +* 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..0daa465 --- /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..86e8345 --- /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..0eac1c4 --- /dev/null +++ b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h @@ -0,0 +1,101 @@ +/* +* +* 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); + unsigned int (*ep_ctl) (sbr_socket_t *, int triggle_ops, + struct epoll_event * event, void *pdata); + unsigned int (*ep_getevt) (sbr_socket_t *, unsigned int events); + 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 */ + +#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..f40f101 --- /dev/null +++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c @@ -0,0 +1,88 @@ +/* +* +* 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..e731314 --- /dev/null +++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h @@ -0,0 +1,159 @@ +/* +* +* 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..e088224 --- /dev/null +++ b/stacks/lwip_stack/src/sbr/sbr_socket.c @@ -0,0 +1,1274 @@ +/* +* +* 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 "nstack_dmm_api.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 + +/***************************************************************************** +* 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 -1; +} + +SBR_INTERCEPT (unsigned int, ep_getevt, + (int epfd, int profd, unsigned int events)) +{ + NSSBR_LOGDBG ("epfd= %d, proFD=%d,epi=0x%x", epfd, profd, events); + sbr_socket_t *sk = sbr_lookup_sk (profd); + + if (!sk) + { + return -1; + } + + return sk->fdopt->ep_getevt (sk, events); +} + +SBR_INTERCEPT (unsigned int, ep_ctl, + (int epfd, int profd, int triggle_ops, + struct epoll_event * event, void *pdata)) +{ + NSSBR_LOGDBG ("epfd = %d, proFD=%d,triggle_ops=%d,pdata=%p", epfd, profd, + triggle_ops, pdata); + sbr_socket_t *sk = sbr_lookup_sk (profd); + + if (!sk) + { + return -1; + } + + return sk->fdopt->ep_ctl (sk, triggle_ops, event, pdata); +} + +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, pid_t p, pid_t c)) +{ + NSSBR_LOGDBG ("fork_free_fd() is called]"); + sbr_free_fd (s); +} + +/***************************************************************************** +* 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 +nstack_stack_register (nstack_proc_cb * ops, nstack_event_cb * val) +{ + if (!ops || !val || !val->handle) + { + return -1; + } + +#undef NSTACK_MK_DECL +#define NSTACK_MK_DECL(ret, fn, args) \ + (ops->socket_ops).pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, "sbr_" # fn); +#include "declare_syscalls.h" + + (ops->extern_ops).module_init = sbr_init_res; + (ops->extern_ops).ep_getevt = GET_SBR_INTERCEPT (ep_getevt); + (ops->extern_ops).ep_ctl = GET_SBR_INTERCEPT (ep_ctl); + (ops->extern_ops).peak = GET_SBR_INTERCEPT (peak); + (ops->extern_ops).stack_alloc_fd = GET_SBR_INTERCEPT (fd_alloc); /*alloc a fd id for epoll */ + (ops->extern_ops).fork_init_child = GET_SBR_INTERCEPT (fork_init_child); + (ops->extern_ops).fork_parent_fd = GET_SBR_INTERCEPT (fork_parent_fd); + (ops->extern_ops).fork_child_fd = GET_SBR_INTERCEPT (fork_child_fd); + (ops->extern_ops).fork_free_fd = GET_SBR_INTERCEPT (fork_free_fd); + 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..bd485b8 --- /dev/null +++ b/stacks/lwip_stack/src/tools/CMakeLists.txt @@ -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. +######################################################################### + +FILE(GLOB_RECURSE Tcpdump *.c) +ADD_LIBRARY(nTcpdump STATIC ${Tcpdump}) +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_LIST_DIR}/../include +) +TARGET_LINK_LIBRARIES(nTcpdump dmm_api)
\ No newline at end of file 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..53f0e44 --- /dev/null +++ b/stacks/lwip_stack/src/tools/dump_tool.c @@ -0,0 +1,622 @@ +/* +* +* 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.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_RIGN_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 = 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 = 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 (NSTACK_DMM_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..8c32523 --- /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 diff --git a/stacks/lwip_stack/tools/CMakeLists.txt b/stacks/lwip_stack/tools/CMakeLists.txt new file mode 100644 index 0000000..cfb5615 --- /dev/null +++ b/stacks/lwip_stack/tools/CMakeLists.txt @@ -0,0 +1,91 @@ +######################################################################### +# +# 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() +endif() +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${NSTACKTOOLS_PATH}) +LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC}) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/platform/SecureC/include/) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fPIC -fPIE -pie -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,.") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack -mcmodel=medium") + +INCLUDE_DIRECTORIES( + ../src/include/ + ../../../thirdparty/glog/glog-0.3.4/src/ + ../../SecureC/include/ +) + +#ADD_EXECUTABLE(narp narp.c) +#ADD_EXECUTABLE(nnetstat nnetstat.c) + +ADD_EXECUTABLE(ntcpdump ntcpdump.c) +if(WITH_SECUREC_LIB) +TARGET_LINK_LIBRARIES( + ntcpdump + pthread + rt + securec + -Wl,--whole-archive + libjson-c.a + libglog.a + dmm_api + -Wl,--no-whole-archive,-lstdc++ -ldl + rte_eal + rte_mempool + rte_mbuf + rte_ring +) +else() +TARGET_LINK_LIBRARIES( + ntcpdump + pthread + rt + -Wl,--whole-archive + libjson-c.a + libglog.a + dmm_api + -Wl,--no-whole-archive,-lstdc++ -ldl + rte_eal + rte_mempool + rte_mbuf + rte_ring +) +endif() + +if(WITH_SECUREC_LIB) +ADD_DEPENDENCIES(ntcpdump JSON GLOG SECUREC DPDK) +else() +ADD_DEPENDENCIES(ntcpdump JSON GLOG DPDK) +endif() + + +ADD_EXECUTABLE(nping nping.c) + +if(WITH_SECUREC_LIB) +ADD_DEPENDENCIES(nping SECUREC DPDK) +else() +ADD_DEPENDENCIES(nping DPDK) +endif() + +if(WITH_SECUREC_LIB) +TARGET_LINK_LIBRARIES(nping libnStackAPI.so securec -Wl,-rpath=. -lpthread -lrt -ldl) +else() +TARGET_LINK_LIBRARIES(nping libnStackAPI.so -Wl,-rpath=. -lpthread -lrt -ldl) +endif() diff --git a/stacks/lwip_stack/tools/nping.c b/stacks/lwip_stack/tools/nping.c new file mode 100644 index 0000000..09e604f --- /dev/null +++ b/stacks/lwip_stack/tools/nping.c @@ -0,0 +1,627 @@ +/* +* +* 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 <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <errno.h> +#include <time.h> +#include <fcntl.h> +#include <memory.h> +#include <strings.h> +#include <limits.h> +#include <getopt.h> +#include "nstack_securec.h" +#include "tool_common.h" + +/*======== for global variables =======*/ + +NSTACK_STATIC input_info g_input_info = { 0 }; +static stat_info g_stat_info = { 0 }; + +static char *g_nping_short_options = "c:r:I:"; + +int g_exit = 0; +void +user_exit (int sig) +{ + g_exit = 1; +} + +NSTACK_STATIC inline double +get_cost_time (struct timespec *pstart, struct timespec *pend) +{ + double sec = (double) (pend->tv_sec - pstart->tv_sec); + double nsec = (double) (pend->tv_nsec - pstart->tv_nsec); + + return (sec * 1000 + (nsec / 1000000)); +} + +NSTACK_STATIC inline double +get_lost_rate (unsigned int lost_count, unsigned int send_count) +{ + if (0 == send_count) + { + return 0; + } + + return ((double) lost_count / send_count); +} + +void +print_stat (stat_info * info, const char *remote_ip) +{ + unsigned int send_count = info->send_seq; + unsigned int recv_count = info->recv_ok; + unsigned int lost_count = send_count - recv_count; + double lost_rate = 100 * get_lost_rate (lost_count, send_count); + double cost_time = get_cost_time (&info->start_time, &info->end_time); + + printf ("\n------ %s ping statistics ------\n", remote_ip); + + printf + ("%u packets transmitted, %u received, %.2f%% packet loss, time %.2fms\n", + send_count, recv_count, lost_rate, cost_time); + + if (0 != recv_count) + { + double min_interval = info->min_interval; + double max_interval = info->max_interval; + double avg_interval = info->all_interval / recv_count; + printf ("rtt min/avg/max = %.3f/%.3f/%.3f ms\n", min_interval, + avg_interval, max_interval); + } +} + +NSTACK_STATIC inline u16 +get_chksum (icmp_head * pmsg) +{ + int len = sizeof (icmp_head); + u32 sum = 0; + u16 *msg_stream = (u16 *) pmsg; + u16 check_sum = 0; + + while (len > 1) + { + sum += *msg_stream; + len -= 2; + msg_stream++; + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + check_sum = ~sum; + + return check_sum; +} + +#ifndef MAX_SHORT +#define MAX_SHORT 0xFFFF +#endif + +NSTACK_STATIC inline void +code_icmp_req (icmp_head * pmsg, u32 send_seq, pid_t my_pid) +{ + struct timespec cur_time; + + pmsg->icmp_type = ICMP_ECHO; + pmsg->icmp_code = 0; + pmsg->icmp_cksum = 0; + pmsg->icmp_seq = send_seq % (MAX_SHORT + 1); + pmsg->icmp_id = my_pid; + pmsg->timestamp = 0; + + if (0 != clock_gettime (CLOCK_MONOTONIC, &cur_time)) + { + printf ("Failed to get time, errno = %d\n", errno); + } + + pmsg->icmp_sec = cur_time.tv_sec; + pmsg->icmp_nsec = cur_time.tv_nsec; + + pmsg->icmp_cksum = get_chksum (pmsg); + return; +} + +NSTACK_STATIC int +send_icmp_req (int socket, pid_t my_pid, stat_info * stat, + struct sockaddr_in *remote_addr) +{ + int send_ret; + icmp_head icmp_req; + + stat->send_seq++; + code_icmp_req (&icmp_req, stat->send_seq, my_pid); + + send_ret = sendto (socket, &icmp_req, sizeof (icmp_head), 0, + (struct sockaddr *) remote_addr, + sizeof (struct sockaddr_in)); + + if (send_ret < 0) + { + printf ("send icmp request failed.\n"); + return -1; + } + + return send_ret; +} + +NSTACK_STATIC inline double +cal_interval (struct timespec *psend, struct timespec *precv, + stat_info * stat) +{ + double interval = get_cost_time (psend, precv); + + stat->all_interval += interval; + + if (interval < stat->min_interval) + { + stat->min_interval = interval; + } + + if (interval > stat->max_interval) + { + stat->max_interval = interval; + } + + return interval; +} + +NSTACK_STATIC inline void +print_info_on_reply (long send_sec, long send_usec, u32 send_seq, + stat_info * stat, struct sockaddr_in *dst_addr) +{ + struct timespec send_time; + struct timespec recv_time; + if (0 != clock_gettime (CLOCK_MONOTONIC, &recv_time)) + { + printf ("Failed to get time, errno = %d\n", errno); + } + + send_time.tv_sec = send_sec; + send_time.tv_nsec = send_usec; + + double interval = cal_interval (&send_time, &recv_time, stat); + const char *remote_ip = inet_ntoa (dst_addr->sin_addr); + printf ("%lu bytes from %s: icmp_seq=%u, time=%.3f ms\n", + sizeof (icmp_head), remote_ip, send_seq % (MAX_SHORT + 1), + interval); +} + +NSTACK_STATIC inline void +print_info_on_no_reply (u32 send_seq, const char *remote_ip) +{ + printf ("No data from %s, icmp_seq=%u, Destination Host Unreachable\n", + remote_ip, send_seq); +} + +static inline int +expect_addr (int expect, int addr) +{ + return (expect == addr); +} + +NSTACK_STATIC inline int +parse_icmp_reply (char *buf, unsigned int buf_len, u32 my_pid, u32 send_seq, + stat_info * stat, struct sockaddr_in *dst_addr) +{ + unsigned int ip_head_len; + ip_head *recv_ip_head; + icmp_head *recv_icmp_head; + + // parse all received ip package + while (buf_len > sizeof (ip_head)) + { + recv_ip_head = (ip_head *) buf; + + ip_head_len = recv_ip_head->ihl << 2; + recv_icmp_head = (icmp_head *) (buf + ip_head_len); + buf_len -= htons (recv_ip_head->tot_len); + + if (!expect_addr (dst_addr->sin_addr.s_addr, recv_ip_head->local_ip)) + { + return 0; + } + + if ((recv_icmp_head->icmp_type == ICMP_REPLY) + && (recv_icmp_head->icmp_id == my_pid) + && (recv_icmp_head->icmp_seq == send_seq % (MAX_SHORT + 1))) + { + print_info_on_reply (recv_icmp_head->icmp_sec, + recv_icmp_head->icmp_nsec, send_seq, stat, + dst_addr); + + return 1; + } + + buf += ip_head_len; + } + + return 0; +} + +NSTACK_STATIC inline int +recv_icmp_reply_ok (int socket, int my_pid, u32 send_seq, stat_info * stat, + struct sockaddr_in *dst_addr) +{ +#define MAX_RECV_BUFF_SIZE (200 * sizeof(icmp_head)) + + struct sockaddr_in remote_addr; + unsigned int addr_len = sizeof (remote_addr); + char recv_buf[MAX_RECV_BUFF_SIZE]; + + int recv_ret = recvfrom (socket, recv_buf, MAX_RECV_BUFF_SIZE, 0, + (struct sockaddr *) &remote_addr, &addr_len); + + if (recv_ret < 0) + { + return 0; + } + + if (!parse_icmp_reply + (recv_buf, (unsigned int) recv_ret, my_pid, send_seq, stat, dst_addr)) + { + return 0; + } + + return 1; +} + +// check recv msg in 2 us +/* BEGIN: Added for PN:CODEDEX by l00351127, 2017/11/14 CID:50811*/ +NSTACK_STATIC void +recv_icmp_reply (int socket, pid_t my_pid, input_info * input, + stat_info * stat, struct sockaddr_in *dst_addr) +/* END: Added for PN:CODEDEX by l00351127, 2017/11/14 */ +{ +#define MAX_SLEEP_TIME (2 * US_TO_NS) +#define MAX_WAIT_TIME (1000 * MS_TO_NS) + + int recv_ok = 0; + int retry = 0; + long sleep_all = 0; + long sleep_time = 0; + + u32 expect_seq = stat->send_seq; + + while (retry < input->retry_count) + { + if (recv_icmp_reply_ok (socket, my_pid, expect_seq, stat, dst_addr)) + { + recv_ok = 1; + stat->recv_ok++; + break; + } + + sleep_all += MAX_SLEEP_TIME; + sys_sleep_ns (0, MAX_SLEEP_TIME); + retry++; + } + + if (!recv_ok) + { + print_info_on_no_reply (expect_seq, input->dst_ip); + } + + if (sleep_all < MAX_WAIT_TIME) + { + sleep_time = MAX_WAIT_TIME - sleep_all; + sys_sleep_ns (0, sleep_time); + } +} + +NSTACK_STATIC inline int +is_digit_nping (char *str) +{ + if (NULL == str || '\0' == str[0]) + { + return 0; + } + + while (*str) + { + if (*str > '9' || *str < '0') + { + return 0; + } + + str++; + } + + return 1; +} + +#define MIN_IP_LEN_NPING 7 //the length of string ip addr x.x.x.x is 7, 4 numbers + 3 dots = 7 +#define MAX_IP_LEN_NPING 15 //the length of string ip addr xxx.xxx.xxx.xxx is 15, 12 numbers + 3 dots = 15 + +NSTACK_STATIC inline int +is_ip_addr_nping (char *param_addr) +{ + int ipseg1; + int ipseg2; + int ipseg3; + int ipseg4; + + if (NULL == param_addr) + { + return 0; + } + + size_t len = strlen (param_addr); + if (len < MIN_IP_LEN_NPING || len > MAX_IP_LEN_NPING) // valid ip MIN_IP_LEN=7, MAX_IP_LEN=15 + { + printf ("Input IP format error.\n"); + return 0; + } + + if (SSCANF_S (param_addr, "%d.%d.%d.%d", &ipseg1, &ipseg2, &ipseg3, &ipseg4) + != 4) + { + return 0; + } + + if ((ipseg1 & 0xffffff00) + || (ipseg2 & 0xffffff00) + || (ipseg3 & 0xffffff00) || (ipseg4 & 0xffffff00)) + { + return 0; + } + + return 1; +} + +NSTACK_STATIC inline bool +check_nping_input_para (input_info * input) +{ + if (input->send_count < 1) + { + return false; + } + + if (input->retry_count < NPING_RETRY_COUNT + || input->retry_count > MAX_NPING_RETRY_COUNT) + { + return false; + } + + if (0 == input->src_ip[0] || 0 == input->dst_ip[0]) + { + return false; + } + + return true; +} + +NSTACK_STATIC inline bool +get_nping_input_para (int argc, char **argv, input_info * input) +{ + int opt = 0; + bool arg_invalid = false; + + if (argc < 2) + { + return false; + } + + if (!is_ip_addr_nping (argv[1])) + { + return false; + } + + /* CID 36687 (#1 of 2): Unchecked return value (CHECKED_RETURN) */ + if (EOK != STRCPY_S (input->dst_ip, sizeof (input->dst_ip), argv[1])) + { + printf ("STRCPY_S failed.\n"); + return false; + } + + while (1) + { + opt = getopt (argc - 1, &argv[1], g_nping_short_options); + if (-1 == opt) + { + break; + } + + switch (opt) + { + // for short options + case 'c': + input->send_count = atoi (optarg); + break; + case 'r': + input->retry_count = atoi (optarg); + break; + case 'I': + /* CID 36687 (#2 of 2): Unchecked return value (CHECKED_RETURN) */ + if (!is_ip_addr_nping (optarg)) + { + return false; + } + if (EOK != STRCPY_S (input->src_ip, sizeof (input->src_ip), optarg)) + { + printf ("STRCPY_S failed.\n"); + return false; + } + break; + default: + arg_invalid = true; + break; + } + + if (arg_invalid) + { + return false; + } + } + + if (!check_nping_input_para (input)) + { + return false; + } + + return true; +} + +void +print_help_nping () +{ + printf + ("usage:nping destination [-c send_count -I src_addr -r retry_count]\n"); + printf ("send count range:1-2147483647\n"); + printf ("retry count range:1000-20000\n"); +} + +NSTACK_STATIC inline void +init_input_info (input_info * input) +{ + if (EOK != MEMSET_S (input, sizeof (input_info), 0, sizeof (input_info))) + { + printf ("MEMSET_S failed.\n"); + return; + } + + input->send_count = 100000; + input->retry_count = NPING_RETRY_COUNT; +} + +NSTACK_STATIC inline void +init_stat_info (stat_info * stat) +{ + stat->max_interval = 0; + stat->min_interval = 0xFFFFFFFF; +} + +#ifndef NSTACK_STATIC_CHECK +int +main (int argc, char *argv[]) +#else +int +nping_main (int argc, char *argv[]) +#endif +{ + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + int send_ret; + int ret = -1; + int icmp_sock; + + pid_t my_pid; + + if (EOK != + MEMSET_S (&local_addr, sizeof (local_addr), 0, sizeof (local_addr))) + { + printf ("MEMSET_S failed.\n"); + return 0; + } + local_addr.sin_family = AF_INET; + + init_input_info (&g_input_info); + init_stat_info (&g_stat_info); + + if (!get_nping_input_para (argc, argv, &g_input_info)) + { + print_help_nping (); + return 0; + } + + if ((icmp_sock = socket (AF_INET, CUSTOM_SOCK_TYPE, IPPROTO_ICMP)) < 0) + { + printf ("create socket failed.\n"); + return 0; + } + + local_addr.sin_addr.s_addr = inet_addr (g_input_info.src_ip); + + if (0 != + bind (icmp_sock, (struct sockaddr *) &local_addr, + sizeof (struct sockaddr))) + { + printf ("bind failed, src ip %s\n", g_input_info.src_ip); + close (icmp_sock); + return 0; + } + + int opt = 1; + ret = ioctl (icmp_sock, FIONBIO, &opt); + if (-1 == ret) + { + printf ("fcntl O_NONBLOCK fail\n"); + close (icmp_sock); + return 0; + } + + if (EOK != + MEMSET_S (&remote_addr, sizeof (remote_addr), 0, sizeof (remote_addr))) + { + printf ("MEMSET_S failed.\n"); + close (icmp_sock); + return 0; + } + + remote_addr.sin_family = AF_INET; + remote_addr.sin_addr.s_addr = inet_addr (g_input_info.dst_ip); + + my_pid = getpid (); + printf ("nping %s %lu bytes of data, pid:%d.\n", g_input_info.dst_ip, + sizeof (icmp_head), my_pid); + + signal (SIGINT, user_exit); + + int loop_count = 0; + if (0 != clock_gettime (CLOCK_MONOTONIC, &g_stat_info.start_time)) + { + printf ("Failed to get time, errno = %d\n", errno); + } + +/* BEGIN: Added for PN:CODEDEX by l00351127, 2017/11/14 CID:50811*/ + i32 send_count = g_input_info.send_count; +/* END: Added for PN:CODEDEX by l00351127, 2017/11/14 */ + + while (!g_exit && (loop_count < send_count)) + { + send_ret = + send_icmp_req (icmp_sock, my_pid, &g_stat_info, &remote_addr); + if (send_ret < 0) + { + break; + } + + recv_icmp_reply (icmp_sock, my_pid, &g_input_info, &g_stat_info, + &remote_addr); + + loop_count++; + } + + close (icmp_sock); + + if (0 != clock_gettime (CLOCK_MONOTONIC, &g_stat_info.end_time)) + { + printf ("Failed to get time, errno = %d\n", errno); + } + + print_stat (&g_stat_info, g_input_info.dst_ip); + + return 0; +} diff --git a/stacks/lwip_stack/tools/ntcpdump.c b/stacks/lwip_stack/tools/ntcpdump.c new file mode 100644 index 0000000..31a96bc --- /dev/null +++ b/stacks/lwip_stack/tools/ntcpdump.c @@ -0,0 +1,1368 @@ +/* +* +* 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 <unistd.h> +#include <signal.h> +#include <time.h> +#include <malloc.h> +#include <stdio.h> +#include <getopt.h> +#include <unistd.h> +#include "types.h" +#include "nsfw_init.h" +#include "nsfw_mem_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_maintain_api.h" +#include "nstack_securec.h" + +#include "tool_common.h" + +NSTACK_STATIC struct option g_dump_long_options[] = { + {"host", 1, NULL, OPT_ARG_HOST}, + {"lhost", 1, NULL, OPT_ARG_LOCAL_HOST}, + {"rhost", 1, NULL, OPT_ARG_REMOTE_HOST}, + {"port", 1, NULL, OPT_ARG_PORT}, + {"lport", 1, NULL, OPT_ARG_LOCAL_PORT}, + {"rport", 1, NULL, OPT_ARG_REMOTE_PORT}, + {"mac", 1, NULL, OPT_ARG_MAC}, + {"lmac", 1, NULL, OPT_ARG_LOCAL_MAC}, + {"rmac", 1, NULL, OPT_ARG_REMOTE_MAC}, + {0, 0, 0, 0} +}; + +static char *g_dump_short_options = "c:s:w:y:G:P:T:"; + +NSTACK_STATIC FILE *g_dump_fp = NULL; +static u32 g_dumped_packet = 0; +NSTACK_STATIC u32 g_captured_packet = 0; +static u32 g_filtered_packet = 0; + +NSTACK_STATIC bool g_dump_exit = 0; + +static dump_timer_info g_dump_hbt_timer; +NSTACK_STATIC dump_condition g_dump_condition; +static nsfw_mem_name g_dump_mem_ring_info = + { NSFW_SHMEM, NSFW_PROC_MAIN, DUMP_SHMEM_RIGN_NAME }; +static nsfw_mem_name g_dump_mem_pool_info = + { NSFW_SHMEM, NSFW_PROC_MAIN, DUMP_SHMEM_POOL_NAME }; + +void +dump_exit () +{ + g_dump_exit = 1; +} + +void +print_help_ntcpdump () +{ + printf ("usage:ntcpdump \n\ + -c count \n\ + -s len \n\ + -w file \n\ + -y l2_protocol \n\ + -T l3_protocol \n\ + -G dump_seconds \n\ + -P in/out/inout \n\ + --host/rhost/lhost ip_addr \n\ + --port/rport/lport port \n\ + --mac/rmac/lmac mac_addr\n"); +} + +bool +is_digit_ntcpdump (char *str, size_t src_len) +{ + size_t count = 0; + + if (NULL == str || 0 == *str) + { + return FALSE; + } + + while (*str) + { + if (*str > '9' || *str < '0') + { + return false; + } + + str++; + count++; + } + + if (count > src_len) + { + return false; + } + + return true; +} + +NSTACK_STATIC inline bool +is_ip_addr (const char *addr, ip_addr_bits * addr_info) +{ + u32 ip1; + u32 ip2; + u32 ip3; + u32 ip4; + + if (SSCANF_S (addr, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) + { + return false; + } + + if ((ip1 & 0xffffff00) || (ip2 & 0xffffff00) || (ip3 & 0xffffff00) + || (ip4 & 0xffffff00)) + { + return false; + } + + addr_info->addr_bits1 = ip1; + addr_info->addr_bits2 = ip2; + addr_info->addr_bits3 = ip3; + addr_info->addr_bits4 = ip4; + + return true; +} + +NSTACK_STATIC inline bool +get_ip_addr (const char *addr, u32 * ip_addr) +{ + ip_addr_bits addr_info; + if (!is_ip_addr (addr, &addr_info)) + { + return false; + } + + *ip_addr = ((addr_info.addr_bits1 & 0xFF) + | (addr_info.addr_bits2 & 0xFF) << 8 + | (addr_info.addr_bits3 & 0xFF) << 16 + | (addr_info.addr_bits4 & 0xFF) << 24); + + return true; +} + +NSTACK_STATIC inline bool +get_dump_port (const char *pport, u16 * port) +{ + int user_port; + + if (!is_digit_ntcpdump ((char *) pport, MAX_PORT_STR_LEN)) + { + return false; + } + + user_port = atoi (pport); + if (user_port < 1024 || user_port > 65535) + { + return false; + } + + *port = (unsigned short) user_port; + return true; +} + +NSTACK_STATIC inline bool +get_dump_len (char *plen, u32 * limit_len) +{ + if (!is_digit_ntcpdump (plen, MAX_INTEGER_STR_LEN)) + { + return false; + } + + *limit_len = atoi (plen); + return true; +} + +NSTACK_STATIC inline bool +get_mac_addr (const char *opt_value, char *mac_addr) +{ + /* avoid coredump when opt_value is NULL */ + if (NULL == opt_value) + { + return false; + } + + size_t org_len = strlen (opt_value); + if (org_len != MAC_ADDR_STR_LEN) + { + return false; + } + + u32 tmp_mac[MAC_ADDR_LEN]; + + if (6 != SSCANF_S (opt_value, "%x:%x:%x:%x:%x:%x", + &tmp_mac[0], + &tmp_mac[1], + &tmp_mac[2], &tmp_mac[3], &tmp_mac[4], &tmp_mac[5])) + { + return false; + } + + int i = 0; + for (; i < MAC_ADDR_LEN; i++) + { + if (tmp_mac[i] > 0xFF) + { + // 01:02:03:04:5:1FF + return false; + } + + mac_addr[i] = tmp_mac[i]; + } + + return true; +} + +NSTACK_STATIC inline bool +check_file_name (const char *file_name) +{ + if (0 == access (file_name, F_OK)) + { + printf ("dump file exist, file name=%s.\n", file_name); + return false; + } + return true; +} + +NSTACK_STATIC inline u16 +get_para_direction (const char *para) +{ + if (0 == strcasecmp (para, "out")) + { + return DUMP_SEND; + } + + if (0 == strcasecmp (para, "in")) + { + return DUMP_RECV; + } + + if (0 == strcasecmp (para, "inout")) + { + return DUMP_SEND_RECV; + } + + return INVALID_DIRECTION; +} + +NSTACK_STATIC inline u16 +get_para_l2_protocol (const char *para) +{ + if (0 == strcasecmp (para, "arp")) + { + return PROTOCOL_ARP; + } + + if (0 == strcasecmp (para, "rarp")) + { + return PROTOCOL_RARP; + } + + if (0 == strcasecmp (para, "ip")) + { + return PROTOCOL_IP; + } + + if (0 == strcasecmp (para, "oam")) + { + return PROTOCOL_OAM_LACP; + } + + if (0 == strcasecmp (para, "lacp")) + { + return PROTOCOL_OAM_LACP; + } + + return INVALID_L2_PROTOCOL; +} + +NSTACK_STATIC inline u16 +get_para_l3_protocol (const char *para) +{ + if (0 == strcasecmp (para, "tcp")) + { + return PROTOCOL_TCP; + } + + if (0 == strcasecmp (para, "udp")) + { + return PROTOCOL_UDP; + } + + if (0 == strcasecmp (para, "icmp")) + { + return PROTOCOL_ICMP; + } + + return INVALID_L3_PROTOCOL; +} + +NSTACK_STATIC bool +parse_long_options (int opt, const char *long_opt_arg, int optindex, + dump_condition * filter_info) +{ + switch (opt) + { + case OPT_ARG_HOST: + if (!get_ip_addr (long_opt_arg, &filter_info->ip_addr)) + { + printf ("invalid ip addr, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->ip_set_flag |= COND_OR_SET; + break; + case OPT_ARG_LOCAL_HOST: + if (!get_ip_addr (long_opt_arg, &filter_info->local_ip)) + { + printf ("invalid ip addr, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->ip_set_flag |= COND_LOCAL_SET; + break; + case OPT_ARG_REMOTE_HOST: + if (!get_ip_addr (long_opt_arg, &filter_info->remote_ip)) + { + printf ("invalid ip addr, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->ip_set_flag |= COND_REMOTE_SET; + break; + case OPT_ARG_PORT: + if (!get_dump_port (long_opt_arg, &filter_info->port)) + { + printf ("invalid port, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->port_set_flag |= COND_OR_SET; + break; + case OPT_ARG_LOCAL_PORT: + if (!get_dump_port (long_opt_arg, &filter_info->local_port)) + { + printf ("invalid port, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->port_set_flag |= COND_LOCAL_SET; + break; + case OPT_ARG_REMOTE_PORT: + if (!get_dump_port (long_opt_arg, &filter_info->remote_port)) + { + printf ("invalid port, optindex=%d, port=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->port_set_flag |= COND_REMOTE_SET; + break; + case OPT_ARG_MAC: + if (!get_mac_addr (long_opt_arg, filter_info->mac_addr)) + { + printf ("invalid mac addr, optindex=%d, mac=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->mac_set_flag |= COND_OR_SET; + break; + case OPT_ARG_LOCAL_MAC: + if (!get_mac_addr (long_opt_arg, filter_info->local_mac)) + { + printf ("invalid mac addr, optindex=%d, mac=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->mac_set_flag |= COND_LOCAL_SET; + break; + case OPT_ARG_REMOTE_MAC: + if (!get_mac_addr (long_opt_arg, filter_info->remote_mac)) + { + printf ("invalid mac addr, optindex=%d, mac=%s.\n", optindex, + long_opt_arg); + return false; + } + filter_info->mac_set_flag |= COND_REMOTE_SET; + break; + default: + printf ("unknow arg, optindex=%d, arg=%s.\n", optindex, long_opt_arg); + return false; + } + + return true; +} + +NSTACK_STATIC inline bool +condition_valid (dump_condition * condition) +{ + // check direction + if (INVALID_DIRECTION == condition->direction) + { + printf ("direction invalid.\n"); + return false; + } + + // check l2 protocol + if (INVALID_L2_PROTOCOL == condition->l2_protocol) + { + printf ("L2 protocol invalid.\n"); + return false; + } + + // check l3 protocol + if (INVALID_L3_PROTOCOL == condition->l3_protocol) + { + printf ("L3 protocol invalid.\n"); + return false; + } + + // check ip + if (condition->ip_set_flag > 0x4) + { + printf ("IP options invalid.\n"); + return false; + } + + // check port + if (condition->port_set_flag > 0x4) + { + printf ("Port options invalid.\n"); + return false; + } + + // check mac + if (condition->mac_set_flag > 0x4) + { + printf ("MAC options invalid.\n"); + return false; + } + + if (condition->dump_time > MAX_DUMP_TIME + || condition->dump_time < MIN_DUMP_TIME) + { + printf ("dump time invalid.\n"); + return false; + } + + return true; +} + +NSTACK_STATIC inline bool +get_dump_condition (int argc, char **argv, dump_condition * filter_info) +{ + int opt = 0; + int opt_index = 0; + bool arg_invalid = false; + filter_info->has_condition = 0; + + if (argc < 2) + { + // dump all package + return true; + } + + while (1) + { + opt = + getopt_long (argc, argv, g_dump_short_options, g_dump_long_options, + &opt_index); + if (-1 == opt) + { + break; + } + + switch (opt) + { + // for short options + case 'c': + filter_info->dump_count = atoi (optarg); + break; + case 's': + if (!get_dump_len (optarg, &filter_info->limit_len)) + { + printf ("length invalid, optindex=%d, arg=%s.\n", opt_index, + optarg); + arg_invalid = true; + } + break; + case 'w': + if (!check_file_name (optarg)) + { + printf ("invalid file name, optindex=%d, arg=%s.\n", opt_index, + optarg); + arg_invalid = true; + } + else + { + filter_info->dump_file_name = optarg; + } + break; + case 'y': + filter_info->l2_protocol = get_para_l2_protocol (optarg); + break; + case 'G': + filter_info->dump_time = atoi (optarg); + break; + case 'P': + filter_info->direction = get_para_direction (optarg); + break; + case 'T': + filter_info->l3_protocol = get_para_l3_protocol (optarg); + break; + case '?': + arg_invalid = true; + break; + // for long options + default: + if (!parse_long_options (opt, optarg, opt_index, filter_info)) + { + arg_invalid = true; + } + break; + } + + if (arg_invalid) + { + print_help_ntcpdump (); + return false; + } + + filter_info->has_condition = 1; + } + + if (!condition_valid (filter_info)) + { + filter_info->has_condition = 0; + return false; + } + + return true; +} + +NSTACK_STATIC inline void +open_file () +{ + if (NULL == g_dump_condition.dump_file_name) + { + return; + } + + g_dump_fp = fopen (g_dump_condition.dump_file_name, "w+"); + if (NULL == g_dump_fp) + { + printf ("open file %s failed\n", g_dump_condition.dump_file_name); + } +} + +NSTACK_STATIC inline void +close_file () +{ + if (NULL != g_dump_fp) + { + fclose (g_dump_fp); + g_dump_fp = NULL; + } +} + +NSTACK_STATIC inline void +write_file_head (FILE * fp) +{ + dump_file_head file_head; + file_head.magic = 0xA1B2C3D4; + file_head.major_ver = 2; // 0x0200; + file_head.minor_ver = 4; // 0x0400; + file_head.area = 0; + file_head.time_stamp = 0; + file_head.max_pack_size = 0x0000FFFF; // 0xFFFF0000; + file_head.link_type = 1; //0x01000000; + + if (fwrite (&file_head, sizeof (dump_file_head), 1, fp) != 1) + { + return; + } + + fflush (fp); +} + +NSTACK_STATIC inline void +write_packet (parse_msg_info * pmsg, FILE * fp) +{ + packet_head pack_head; + dump_msg_info *org_msg = (dump_msg_info *) pmsg->org_msg; + pack_head.sec = org_msg->dump_sec; + pack_head.usec = org_msg->dump_usec; + pack_head.save_len = + (u32) nstack_min (org_msg->len, g_dump_condition.limit_len); + pack_head.org_len = org_msg->len; + + if (fwrite (&pack_head, sizeof (packet_head), 1, fp) != 1) + { + // log error + return; + } + + if (fwrite (org_msg->buf, pack_head.save_len, 1, fp) != 1) + { + // log error + return; + } + + fflush (fp); + return; +} + +#define EMPTY(x) (0 == (x)) +#define EQUAL(x, y) ((x) == (y)) + +#define STR_EMPTY(str) (0 == str[0]) +#define STR_EQUAL(str1, str2, len) (0 == memcmp(str1, str2, len)) + +#define MATCH(cond, info, field) \ + (EQUAL(cond->field, info->field)) + +#define MATCH_MORE(cond, field, info, field1, field2) \ + (EQUAL(cond->field, info->field1) || EQUAL(cond->field, info->field2)) + +#define MATCH_STR(cond, info, field, len) \ + (STR_EQUAL(cond->field, info->field, len)) + +#define MATCH_STR_MORE(cond, field, info, field1, field2, len) \ + (STR_EQUAL(cond->field, info->field1, len) || STR_EQUAL(cond->field, info->field2, len)) + +NSTACK_STATIC inline bool +ip_match (dump_condition * condition, parse_msg_info * msg_info) +{ + bool ret = false; + switch (condition->ip_set_flag) + { + case COND_NOT_SET: + ret = true; + break; + case COND_LOCAL_SET: + if (MATCH (condition, msg_info, local_ip)) + { + ret = true; + } + break; + case COND_REMOTE_SET: + if (MATCH (condition, msg_info, remote_ip)) + { + ret = true; + } + break; + case COND_AND_SET: + if (MATCH_MORE (condition, local_ip, msg_info, local_ip, remote_ip) + && MATCH_MORE (condition, remote_ip, msg_info, local_ip, remote_ip)) + { + ret = true; + } + break; + case COND_OR_SET: + if (MATCH_MORE (condition, ip_addr, msg_info, local_ip, remote_ip)) + { + ret = true; + } + break; + default: + break; + } + + return ret; +} + +NSTACK_STATIC inline bool +port_match (dump_condition * condition, parse_msg_info * msg_info) +{ + bool ret = false; + switch (condition->port_set_flag) + { + case COND_NOT_SET: + ret = true; + break; + case COND_LOCAL_SET: + if (MATCH (condition, msg_info, local_port)) + { + ret = true; + } + break; + case COND_REMOTE_SET: + if (MATCH (condition, msg_info, remote_port)) + { + ret = true; + } + break; + case COND_AND_SET: + if (MATCH (condition, msg_info, local_port) + && MATCH (condition, msg_info, remote_port)) + { + ret = true; + } + break; + case COND_OR_SET: + if (MATCH_MORE (condition, port, msg_info, local_port, remote_port)) + { + ret = true; + } + break; + default: + break; + } + + return ret; +} + +NSTACK_STATIC inline bool +mac_match (dump_condition * condition, parse_msg_info * msg_info) +{ + bool ret = false; + switch (condition->mac_set_flag) + { + case COND_NOT_SET: + ret = true; + break; + case COND_LOCAL_SET: + if (MATCH_STR (condition, msg_info, local_mac, MAC_ADDR_LEN)) + { + ret = true; + } + break; + case COND_REMOTE_SET: + if (MATCH_STR (condition, msg_info, remote_mac, MAC_ADDR_LEN)) + { + ret = true; + } + break; + case COND_AND_SET: + if ((MATCH_STR_MORE + (condition, local_mac, msg_info, local_mac, remote_mac, + MAC_ADDR_LEN) + && MATCH_STR_MORE (condition, remote_mac, msg_info, local_mac, + remote_mac, MAC_ADDR_LEN))) + { + ret = true; + } + break; + case COND_OR_SET: + if (MATCH_STR_MORE + (condition, mac_addr, msg_info, local_mac, remote_mac, + MAC_ADDR_LEN)) + { + ret = true; + } + break; + default: + break; + } + + return ret; +} + +NSTACK_STATIC inline bool +filter_by_condition (dump_condition * condition, parse_msg_info * msg_info) +{ + dump_msg_info *org_msg = (dump_msg_info *) msg_info->org_msg; + if (0 == condition->has_condition) + { + return false; + } + + // direction + if (!(condition->direction & org_msg->direction)) + { + return true; + } + + // l2_protocol + if ((0 != condition->l2_protocol) + && !MATCH (condition, msg_info, l2_protocol)) + { + return true; + } + + // l3_protocol + if ((0 != condition->l3_protocol) + && !MATCH (condition, msg_info, l3_protocol)) + { + return true; + } + + // ip + if (!ip_match (condition, msg_info)) + { + return true; + } + + // port + if (!port_match (condition, msg_info)) + { + return true; + } + + // mac + if (!mac_match (condition, msg_info)) + { + return true; + } + + return false; +} + +NSTACK_STATIC inline char * +get_l2_protocol_desc (u16 l2_protocol) +{ + switch (l2_protocol) + { + case PROTOCOL_IP: + return "IP"; + case PROTOCOL_ARP: + return "ARP"; + case PROTOCOL_RARP: + return "RARP"; + case PROTOCOL_OAM_LACP: + return "OAM/LACP"; + default: + return "unknown"; + } +} + +NSTACK_STATIC inline char * +get_l3_protocol_desc (u16 l3_protocol) +{ + switch (l3_protocol) + { + case PROTOCOL_ICMP: + return "ICMP"; + case PROTOCOL_TCP: + return "TCP"; + case PROTOCOL_UDP: + return "UDP"; + default: + return "unknown"; + } +} + +NSTACK_STATIC inline void +get_ip_str (char *pip_addr, u32 ip_addr_len, u32 ip) +{ + int retVal; + retVal = SPRINTF_S (pip_addr, ip_addr_len, "%d.%d.%d.%d", + ip & 0x000000FF, + (ip & 0x0000FF00) >> 8, + (ip & 0x00FF0000) >> 16, (ip & 0xFF000000) >> 24); + if (-1 == retVal) + { + printf ("get_ip_str:SPRINTF_S failed %d.\n", retVal); + } +} + +NSTACK_STATIC inline void +print_packet (parse_msg_info * msg_info, u32 seq) +{ + char str_local_ip[IP_ADDR_LEN]; + char str_remote_ip[IP_ADDR_LEN]; + get_ip_str (str_local_ip, sizeof (str_local_ip), msg_info->local_ip); + get_ip_str (str_remote_ip, sizeof (str_remote_ip), msg_info->remote_ip); + + dump_msg_info *org_msg = (dump_msg_info *) msg_info->org_msg; + + printf ("%-6d %-6d:%6d %-8s %-8s %-16s %-16s %-10d %-10d %-8d\n", + seq, + org_msg->dump_sec, org_msg->dump_usec, + get_l2_protocol_desc (msg_info->l2_protocol), + get_l3_protocol_desc (msg_info->l3_protocol), + str_local_ip, + str_remote_ip, + msg_info->local_port, msg_info->remote_port, org_msg->len); +} + +void +print_head () +{ + if (NULL != g_dump_fp) + { + write_file_head (g_dump_fp); + } + else + { + printf ("ntcpdump start listening:\n"); + printf ("%-6s %-18s %-8s %-8s %-16s %-16s %-10s %-10s %-8s\n", + "Frame", "sec:usec", "L2", "L3", "Src IP", "Dest IP", + "Src Port", "Dest Port", "Length"); + } +} + +void +register_dump_signal () +{ + signal (SIGINT, dump_exit); +} + +NSTACK_STATIC inline void +init_parse_msg_info (parse_msg_info * info) +{ + int retVal = + MEMSET_S (info, sizeof (parse_msg_info), 0, sizeof (parse_msg_info)); + if (EOK != retVal) + { + printf ("MEMSET_S failed.\n"); + } +} + +NSTACK_STATIC inline void +parse_msg (dump_msg_info * msg, parse_msg_info * info) +{ + init_parse_msg_info (info); + + info->org_msg = msg; + + char *pmsg = msg->buf; + u32 len = msg->len; + /* BEGIN: Added for PN:CODEDEX by l00351127, 2017/11/14 CID:50886 */ + if (len < MAC_ADDR_LEN + MAC_ADDR_LEN + sizeof (u16)) + { + return; + } + /* END: Added for PN:CODEDEX by l00351127, 2017/11/14 */ + + // get mac addr + if (EOK != + MEMCPY_S (info->remote_mac, sizeof (info->remote_mac), pmsg, + MAC_ADDR_LEN)) + { + return; + } + + pmsg += MAC_ADDR_LEN; + len -= MAC_ADDR_LEN; + + if (EOK != + MEMCPY_S (info->local_mac, sizeof (info->local_mac), pmsg, + MAC_ADDR_LEN)) + { + return; + } + + pmsg += MAC_ADDR_LEN; + len -= MAC_ADDR_LEN; + + info->l2_protocol = htons (*(u16 *) pmsg); + pmsg += sizeof (u16); + len -= sizeof (u16); + + if (PROTOCOL_IP != info->l2_protocol) + { + return; + } + + ip_head *p_ip_head = (ip_head *) pmsg; + if (len < p_ip_head->ihl) + { + return; + } + + info->local_ip = p_ip_head->local_ip; + info->remote_ip = p_ip_head->remote_ip; + info->l3_protocol = p_ip_head->protocol; + + pmsg += p_ip_head->ihl * sizeof (u32); + + if (PROTOCOL_TCP == info->l3_protocol) + { + tcp_head *p_tcp_head = (tcp_head *) pmsg; + info->local_port = htons (p_tcp_head->src_port); + info->remote_port = htons (p_tcp_head->dst_port); + return; + } + + if (PROTOCOL_UDP == info->l3_protocol) + { + udp_head *p_udp_head = (udp_head *) pmsg; + info->local_port = htons (p_udp_head->src_port); + info->remote_port = htons (p_udp_head->dst_port); + return; + } + + return; +} + +NSTACK_STATIC inline bool +time_expired (struct timespec * start_time, u32 work_sec) +{ +#define TIME_EXPIRE_CHECK_COUNT 1000 + + static u32 loop_count = 0; + loop_count++; + + if (0 != loop_count % TIME_EXPIRE_CHECK_COUNT) + { + return false; + } + + struct timespec cur_time; + GET_CUR_TIME (&cur_time); + + if (cur_time.tv_sec - start_time->tv_sec > work_sec) + { + return true; + } + + return false; +} + +NSTACK_STATIC void +dump_packet (parse_msg_info * msg) +{ + g_dumped_packet++; + if (!g_dump_fp) + { + print_packet (msg, g_dumped_packet); + return; + } + + write_packet (msg, g_dump_fp); +} + +NSTACK_STATIC void +dump_msg (mring_handle dump_ring, mring_handle dump_pool, + dump_condition * condition, struct timespec *start_time) +{ + u32 dump_count = 0; + open_file (); + + print_head (); + + void *msg = NULL; + while (!g_dump_exit + && (dump_count < condition->dump_count) + && !time_expired (start_time, condition->dump_time)) + { + if (nsfw_mem_ring_dequeue (dump_ring, &msg) <= 0) + { + sys_sleep_ns (0, 10000); + continue; + } + + if (NULL == msg) + { + continue; + } + + parse_msg_info msg_info; + parse_msg (msg, &msg_info); + + g_captured_packet++; + if (!condition->has_condition) + { + dump_packet (&msg_info); + dump_count++; + nsfw_mem_ring_enqueue (dump_pool, msg); + continue; + } + + if (filter_by_condition (condition, &msg_info)) + { + g_filtered_packet++; + nsfw_mem_ring_enqueue (dump_pool, msg); + continue; + } + + dump_packet (&msg_info); + dump_count++; + nsfw_mem_ring_enqueue (dump_pool, msg); + } + + close_file (); +} + +mring_handle +dump_get_mem_ring () +{ + return nsfw_mem_ring_lookup (&g_dump_mem_ring_info); +} + +mring_handle +dump_get_mem_pool () +{ + return nsfw_mem_sp_lookup (&g_dump_mem_pool_info); +} + +NSTACK_STATIC void +dump_clear_mem (mring_handle ring, mring_handle pool) +{ + void *msg = NULL; + while (nsfw_mem_ring_dequeue (ring, &msg) > 0) + { + nsfw_mem_ring_enqueue (pool, msg); + sys_sleep_ns (0, 1000); + } +} + +/* BEGIN: Added for PN:CODEDEX by l00351127, 2017/11/14 CID:50859*/ +i16 +dump_send_req (u16 op_type, i16 task_id, u32 task_keep_time) +/* END: Added for PN:CODEDEX by l00351127, 2017/11/14 */ +{ + nsfw_mgr_msg *req = + (nsfw_mgr_msg *) nsfw_mgr_msg_alloc (MGR_MSG_TOOL_TCPDUMP_REQ, + NSFW_PROC_MAIN); + if (NULL == req) + { + printf ("all message for getting instance id failed.\n"); + return -1; + } + + nsfw_tool_dump_msg *req_body = GET_USER_MSG (nsfw_tool_dump_msg, req); + req_body->op_type = op_type; + req_body->task_id = task_id; + req_body->task_keep_time = task_keep_time; + + nsfw_mgr_msg *rsp = nsfw_mgr_null_rspmsg_alloc (); + if (NULL == rsp) + { + printf ("alloc rsp message for getting memory failed.\n"); + nsfw_mgr_msg_free (req); + return -1; + } + + if (!nsfw_mgr_send_req_wait_rsp (req, rsp)) + { + printf ("request memory can not get response.\n"); + nsfw_mgr_msg_free (req); + nsfw_mgr_msg_free (rsp); + return -1; + } + + if (rsp->src_proc_type != NSFW_PROC_MAIN + || rsp->dst_proc_type != NSFW_PROC_TOOLS) + { + printf + ("dump get wrong response, src or dst proc type error,src proc type=%u, dst proc type=%u.\n", + rsp->src_proc_type, rsp->dst_proc_type); + nsfw_mgr_msg_free (req); + nsfw_mgr_msg_free (rsp); + return -1; + } + + if (rsp->msg_type != MGR_MSG_TOOL_TCPDUMP_RSP) + { + printf ("dump get wrong response, msg type error, msg type=%d.\n", + rsp->msg_type); + nsfw_mgr_msg_free (req); + nsfw_mgr_msg_free (rsp); + return -1; + } + + nsfw_tool_dump_msg *rsp_body = GET_USER_MSG (nsfw_tool_dump_msg, rsp); + +/* BEGIN: Added for PN:CODEDEX by l00351127, 2017/11/14 CID:50859*/ + i16 new_task_id = rsp_body->task_id; +/* END: Added for PN:CODEDEX by l00351127, 2017/11/14 */ + + nsfw_mgr_msg_free (req); + nsfw_mgr_msg_free (rsp); + + return new_task_id; +} + +i16 +start_dump_task (u32 task_keep_time) +{ + return dump_send_req (START_DUMP_REQ, -1, task_keep_time); +} + +i16 +stop_dump_task (i16 task_id) +{ + return dump_send_req (STOP_DUMP_REQ, task_id, 0); +} + +NSTACK_STATIC void +init_dump_condition (dump_condition * condition) +{ + if (EOK != + MEMSET_S (condition, sizeof (dump_condition), 0, + sizeof (dump_condition))) + { + printf ("MEMSET_S failed.\n"); + } + condition->limit_len = DUMP_MSG_SIZE; + condition->dump_time = DEFAULT_DUMP_TIME; + condition->direction = 3; + condition->dump_count = DEFAULT_DUMP_COUNT; +} + +NSTACK_STATIC inline bool +send_hbt_req (u32 seq, i16 task_id) +{ + nsfw_mgr_msg *req = + (nsfw_mgr_msg *) nsfw_mgr_msg_alloc (MGR_MSG_TOOL_HEART_BEAT, + NSFW_PROC_MAIN); + if (NULL == req) + { + printf ("all message for getting instance id failed.\n"); + return false; + } + + nsfw_tool_hbt *req_body = GET_USER_MSG (nsfw_tool_hbt, req); + req_body->seq = seq; + req_body->task_id = task_id; + + if (!nsfw_mgr_send_msg (req)) + { + printf ("request memory can not get response.\n"); + } + + nsfw_mgr_msg_free (req); + + return true; +} + +NSTACK_STATIC bool +on_send_hbt_req (u32 timer_type, void *data) +{ + dump_timer_info *ptimer_info = (dump_timer_info *) data; + // send heartbeat + + send_hbt_req (ptimer_info->seq, ptimer_info->task_id); + ptimer_info->seq++; + + ptimer_info->ptimer = + nsfw_timer_reg_timer (DUMP_HBT_TIMER, ptimer_info, on_send_hbt_req, + *(struct timespec *) (ptimer_info->interval)); + return true; +} + +NSTACK_STATIC bool +start_dump_hbt (dump_timer_info * ptimer_info, i16 task_id) +{ + struct timespec *time_interval = + (struct timespec *) malloc (sizeof (struct timespec)); + if (NULL == time_interval) + { + return false; + } + + time_interval->tv_sec = DUMP_HBT_INTERVAL; + time_interval->tv_nsec = 0; + + ptimer_info->interval = time_interval; + ptimer_info->seq = 1; + ptimer_info->task_id = task_id; + + ptimer_info->ptimer = + nsfw_timer_reg_timer (DUMP_HBT_TIMER, ptimer_info, on_send_hbt_req, + *time_interval); + + return true; +} + +NSTACK_STATIC bool +stop_dump_hbt (dump_timer_info * ptimer_info) +{ + free (ptimer_info->interval); + /* fix "SET_NULL_AFTER_FREE" type codedex issue */ + ptimer_info->interval = NULL; + nsfw_timer_rmv_timer (ptimer_info->ptimer); + return true; +} + +#ifndef NSTACK_STATIC_CHECK +int +main (int argc, char *argv[]) +#else +int +ntcpdump_main (int argc, char *argv[]) +#endif +{ + register_dump_signal (); + + init_dump_condition (&g_dump_condition); + if (!get_dump_condition (argc, argv, &g_dump_condition)) + { + printf ("dump exit because of input invalid.\n"); + return INPUT_INVALID; + } + + printf ("parse filter condition ok.\n"); + + fw_poc_type proc_type = NSFW_PROC_TOOLS; + nsfw_mem_para stinfo = { 0 }; + stinfo.iargsnum = 0; + stinfo.pargs = NULL; + stinfo.enflag = proc_type; + nstack_framework_setModuleParam (NSFW_MEM_MGR_MODULE, &stinfo); + nstack_framework_setModuleParam (NSFW_MGR_COM_MODULE, + (void *) ((u64) proc_type)); + nstack_framework_setModuleParam (NSFW_TIMER_MODULE, + (void *) ((u64) proc_type)); + + if (0 != nstack_framework_init ()) + { + printf ("dump init failed.\n"); + return FRAMEWORK_INIT_FAILED; + } + + mring_handle dump_mem_pool = dump_get_mem_pool (); + if (NULL == dump_mem_pool) + { + printf ("dump init mem pool failed.\n"); + return MEMPOOL_INIT_FAILED; + } + + mring_handle dump_mem_ring = dump_get_mem_ring (); + if (NULL == dump_mem_ring) + { + printf ("dump init mem ring failed.\n"); + return MEMRING_INIT_FAILED; + } + + // initialize queue first + dump_clear_mem (dump_mem_ring, dump_mem_pool); + + i16 task_id = start_dump_task (g_dump_condition.dump_time); + if (task_id < 0 || task_id > MAX_DUMP_TASK) + { + printf ("start dump task failed.\n"); + return START_TASK_FAILED; + } + + if (!start_dump_hbt (&g_dump_hbt_timer, task_id)) + { + printf ("start dump heart beat timer failed.\n"); + return START_TIMER_FAILED; + } + + struct timespec dump_start_time; + GET_CUR_TIME (&dump_start_time); + dump_msg (dump_mem_ring, dump_mem_pool, &g_dump_condition, + &dump_start_time); + + i16 new_task_id = stop_dump_task (task_id); + if (new_task_id != task_id) + { + printf ("stop dump task failed.\n"); + } + /* modify deadcode type codedex issue */ + (void) stop_dump_hbt (&g_dump_hbt_timer); + + printf ("dump complete.\n"); + printf ("captured packets=%u.\n", g_captured_packet); + printf ("dumped packets=%u.\n", g_dumped_packet); + printf ("filtered packets=%u.\n", g_filtered_packet); + + return 0; +} diff --git a/stacks/lwip_stack/tools/tool_common.h b/stacks/lwip_stack/tools/tool_common.h new file mode 100644 index 0000000..6d3526b --- /dev/null +++ b/stacks/lwip_stack/tools/tool_common.h @@ -0,0 +1,243 @@ +/* +* +* 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 _TOOL_COMMON_H_ +#define _TOOL_COMMON_H_ + +#include <time.h> +#include "types.h" + +#ifndef NSTACK_STATIC +#ifndef NSTACK_STATIC_CHECK +#define NSTACK_STATIC static +#else +#define NSTACK_STATIC +#endif +#endif + +#ifndef IP_ADDR_LEN +#define IP_ADDR_LEN 16 +#endif + +#ifndef MAC_ADDR_LEN +#define MAC_ADDR_LEN 6 +#endif + +#ifndef MAC_ADDR_STR_LEN +#define MAC_ADDR_STR_LEN 17 +#endif + +#define ICMP_ECHO 8 +#define ICMP_REPLY 0 +#define MS_TO_NS 1000000 +#define US_TO_NS 1000 +#define NPING_RETRY_COUNT 1000 +#define MAX_NPING_RETRY_COUNT 20000 + +#define MAX_PORT_STR_LEN 5 +#define MAX_IP_STR_LEN 15 +#define MAX_INTEGER_STR_LEN 10 + +#define DUMP_HBT_TIMER 1 + +#define INVALID_DIRECTION 0xFFFF +#define DEFAULT_DUMP_COUNT 1000 + +#ifndef CUSTOM_SOCK_TYPE +#define CUSTOM_SOCK_TYPE 0xF001 +#endif + +enum DUMP_ERR_CODE +{ + RET_OK = 0, + INPUT_INVALID = 1, + FRAMEWORK_INIT_FAILED = 2, + MEMPOOL_INIT_FAILED = 3, + MEMRING_INIT_FAILED = 4, + START_TASK_FAILED = 5, + START_TIMER_FAILED = 6, + UNKNOW_ERR +}; + +enum COND_LOCAL_REMOTE_SET +{ + COND_NOT_SET = 0, + COND_REMOTE_SET = 0x1, + COND_LOCAL_SET = 0x2, + COND_AND_SET = 0x3, + COND_OR_SET = 0x4 +}; + +enum DUMP_OPT_ARG +{ + OPT_ARG_HOST = 256, + OPT_ARG_LOCAL_HOST, + OPT_ARG_REMOTE_HOST, + OPT_ARG_PORT, + OPT_ARG_LOCAL_PORT, + OPT_ARG_REMOTE_PORT, + OPT_ARG_MAC, + OPT_ARG_LOCAL_MAC, + OPT_ARG_REMOTE_MAC, + OPT_ARG_INVALID +}; + +typedef struct _ip_head +{ + u8 ihl:4; + u8 version:4; + u8 tos; + u16 tot_len; + u16 id; + u16 frag_off; + u8 ttl; + u8 protocol; + u16 chk_sum; + u32 local_ip; + u32 remote_ip; +} ip_head; + +typedef struct _tcp_head +{ + u16 src_port; + u16 dst_port; + u32 seq_no; + u32 ack_no; +} tcp_head; + +typedef struct _udp_head +{ + u16 src_port; + u16 dst_port; + u16 uhl; + u16 chk_sum; +} udp_head; + +typedef struct _dump_file_head +{ + u32 magic; + u16 major_ver; + u16 minor_ver; + u32 area; + u32 time_stamp; + u32 max_pack_size; + u32 link_type; +} dump_file_head; + +typedef struct _packet_head +{ + u32 sec; + u32 usec; + u32 save_len; + u32 org_len; +} packet_head; + +typedef struct _ip_addr_bits +{ + u32 addr_bits1; + u32 addr_bits2; + u32 addr_bits3; + u32 addr_bits4; +} ip_addr_bits; + +typedef struct _parse_msg_info +{ + u16 l2_protocol; // ARP/IP/OAM/LACP + u16 l3_protocol; // TCP/UDP/ICMP + u16 local_port; + u16 remote_port; + u32 local_ip; + u32 remote_ip; + char local_mac[MAC_ADDR_LEN + 1]; + char remote_mac[MAC_ADDR_LEN + 1]; + + void *org_msg; +} parse_msg_info; + +typedef struct _dump_condition +{ + bool has_condition; + u32 dump_count; + u32 dump_time; + u32 limit_len; + u16 direction; //1:send 2:recv 3:send-recv + u16 l2_protocol; // ARP/IP/OAM/LACP + u16 l3_protocol; // TCP/UDP/ICMP + u16 port_set_flag; + u16 port; + u16 local_port; + u16 remote_port; + u16 ip_set_flag; + u32 ip_addr; + u32 local_ip; + u32 remote_ip; + u16 mac_set_flag; + char mac_addr[MAC_ADDR_LEN + 1]; + char local_mac[MAC_ADDR_LEN + 1]; + char remote_mac[MAC_ADDR_LEN + 1]; + + char *dump_file_name; +} dump_condition; + +typedef struct _icmp_head +{ + u8 icmp_type; + u8 icmp_code; + u16 icmp_cksum; + u16 icmp_id; + u16 icmp_seq; + u32 timestamp; + + long icmp_sec; + long icmp_nsec; +} icmp_head; + +typedef struct _ning_input_info +{ + i32 send_count; // total send req + i32 retry_count; // retry count for 1 req + char src_ip[IP_ADDR_LEN]; + char dst_ip[IP_ADDR_LEN]; +} input_info; + +typedef struct _nping_stat_info +{ + u32 send_seq; + u32 recv_ok; + double all_interval; + double min_interval; + double max_interval; + struct timespec start_time; + struct timespec end_time; +} stat_info; + +#ifndef sys_sleep_ns +#define sys_sleep_ns(_s, _ns)\ +{ \ + if (_s >= 0 && _ns >= 0) \ + { \ + struct timespec delay, remain; \ + delay.tv_sec = _s; \ + delay.tv_nsec = _ns; \ + while (nanosleep(&delay, &remain) < 0) \ + { \ + delay = remain; \ + } \ + } \ +} +#endif + +#endif diff --git a/stacks/lwip_stack/vagrant/Vagrantfile b/stacks/lwip_stack/vagrant/Vagrantfile new file mode 100644 index 0000000..b3a31c1 --- /dev/null +++ b/stacks/lwip_stack/vagrant/Vagrantfile @@ -0,0 +1,65 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + + # Pick the right distro and bootstrap, default is ubuntu1604 + distro = ( ENV['DMM_VAGRANT_DISTRO'] || "ubuntu") + if distro == 'centos7' + config.vm.box = "puppetlabs/centos-7.2-64-nocm" + else + config.vm.box = "puppetlabs/ubuntu-16.04-64-nocm" + end + config.vm.box_check_update = false + + # Create DMM client and server VM's + config.vm.define "dmm-stackx-server" do |server| + server.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../scripts/install_prereq.sh") + server.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"build.sh"), :args => "/DMM vagrant" + server.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"start_nstackMain.sh"), :args => "/DMM vagrant" + end + config.vm.define "dmm-stackx-client" do |client| + client.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../scripts/install_prereq.sh") + client.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"build.sh"), :args => "/DMM vagrant" + client.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"start_nstackMain.sh"), :args => "/DMM vagrant" + end + + + # vagrant-cachier caches apt/yum etc to speed subsequent + # vagrant up + # to enable, run + # vagrant plugin install vagrant-cachier + # + if Vagrant.has_plugin?("vagrant-cachier") + config.cache.scope = :box + end + + # Define some physical ports for your VMs to be used by DPDK + nics = (ENV['DMM_VAGRANT_NICS'] || "2").to_i(10) + for i in 1..nics + config.vm.network "private_network", type: "dhcp" + # config.vm.network "private_network", ip: "172.28.128.200" + # config.vm.network "private_network", ip: "172.28.128.201" + end + + # use http proxy if avaiable + if ENV['http_proxy'] && Vagrant.has_plugin?("vagrant-proxyconf") + config.proxy.http = ENV['http_proxy'] + config.proxy.https = ENV['https_proxy'] + config.proxy.no_proxy = "localhost,127.0.0.1" + end + + vmcpu=(ENV['DMM_VAGRANT_VMCPU'] || 4) + vmram=(ENV['DMM_VAGRANT_VMRAM'] || 5120) + + config.ssh.forward_agent = true + config.ssh.forward_x11 = true + + config.vm.provider "virtualbox" do |vb| + vb.customize ["modifyvm", :id, "--ioapic", "on"] + vb.memory = "#{vmram}" + vb.cpus = "#{vmcpu}" + + config.vm.synced_folder "../../../", "/DMM", type: "rsync" + end +end diff --git a/stacks/lwip_stack/vagrant/build.sh b/stacks/lwip_stack/vagrant/build.sh new file mode 100755 index 0000000..a934eef --- /dev/null +++ b/stacks/lwip_stack/vagrant/build.sh @@ -0,0 +1,59 @@ +######################################################################### +# 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. +######################################################################### +#!/bin/bash -x + +set -x + +TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) +log_file="/tmp/build_log.txt-$TIMESTAMP" +exec 1> >(tee -a "$log_file") 2>&1 + +# Get Command Line arguements if present +if [ "$1" == "from-base-build" ]; then + WAS_DMM_BUILT="YES" +fi + +if [ "x$1" != "x" ] && [ "$1" != "from-base-build" ]; then + TEMP_DIR=$1 + DMM_BUILD_SCRIPT_DIR=${TEMP_DIR}/scripts + LWIP_BUILD_DIR=${TEMP_DIR}/stacks/lwip_stack/build/ +else + TEMP_DIR=`dirname $(readlink -f $0)`/.. + DMM_BUILD_SCRIPT_DIR=${TEMP_DIR}/../../scripts + LWIP_BUILD_DIR=${TEMP_DIR}/build/ +fi + +echo 0:$0 +echo 1:$1 +echo 2:$2 +echo TEMP_DIR: $TEMP_DIR +echo DMM_BUILD_SCRIPT_DIR: $DMM_BUILD_SCRIPT_DIR +echo LWIP_BUILD_DIR: $LWIP_BUILD_DIR + +if [ 'x$WAS_DMM_BUILT' != "xYES" ]; then + bash -x $DMM_BUILD_SCRIPT_DIR/build.sh +fi + +#===========build LWIP=========== +echo "LWIP build started....." +cd $LWIP_BUILD_DIR +cmake .. +make -j 8 +if [ $? -eq 0 ]; then + echo "LWIP build is SUCCESS" +else + echo "LWIP build has FAILED" + exit 1 +fi diff --git a/stacks/lwip_stack/vagrant/env.sh b/stacks/lwip_stack/vagrant/env.sh new file mode 100755 index 0000000..96ad346 --- /dev/null +++ b/stacks/lwip_stack/vagrant/env.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +#export DMM_VAGRANT_DISTRO="ubuntu1604" +export DMM_VAGRANT_DISTRO="centos7" +export DMM_VAGRANT_NICS=2 +export DMM_VAGRANT_VMCPU=4 +export DMM_VAGRANT_VMRAM=8192 diff --git a/stacks/lwip_stack/vagrant/start_nstackMain.sh b/stacks/lwip_stack/vagrant/start_nstackMain.sh new file mode 100755 index 0000000..72d1375 --- /dev/null +++ b/stacks/lwip_stack/vagrant/start_nstackMain.sh @@ -0,0 +1,118 @@ +######################################################################### +# 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. +######################################################################### +#!/bin/bash -x + +set -x + +DPDK_DOWNLOAD_PATH=/tmp/dpdk +ifname=enp0s8 + +if [ "x$1" != "x" ] && [ "$1" != "from-base-build" ]; then + TEMP_DIR=$1 + DMM_BUILD_SCRIPT_DIR=${TEMP_DIR}/scripts + LWIP_BUILD_DIR=${TEMP_DIR}/stacks/lwip_stack/build/ +else + TEMP_DIR=`dirname $(readlink -f $0)`/.. + DMM_BUILD_SCRIPT_DIR=${TEMP_DIR}/../../scripts + LWIP_BUILD_DIR=${TEMP_DIR}/build/ +fi + +LIB_PATH=$LWIP_BUILD_DIR/../release/lib64/ + +echo 0:$0 +echo 1:$1 +echo 2:$2 +echo TEMP_DIR: $TEMP_DIR +echo DMM_BUILD_SCRIPT_DIR: $DMM_BUILD_SCRIPT_DIR +echo LWIP_BUILD_DIR: $LWIP_BUILD_DIR +echo LIB_PATH: $LIB_PATH + +#===========check hugepages================= +source $DMM_BUILD_SCRIPT_DIR/check_hugepage.sh + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +if [ "$OS_ID" == "centos" ]; then + ifaddress1=$(ifconfig $ifname | grep 'inet' | cut -d: -f2 | awk '{print $2}') + echo $ifaddress1 + ifaddresscut=$(ifconfig $ifname | grep 'inet' | head -n 1 | awk -F " " '{print $2}' | awk -F "." '{print $1"."$2"."$3}') + echo $ifaddresscut + ifmac=$(ifconfig $ifname | grep 'ether' | awk -F " " '{print $2}') + echo $ifmac +elif [ "$OS_ID" == "ubuntu" ]; then + ifaddress1=$(ifconfig $ifname | grep 'inet' | head -n 1 | cut -d: -f2 | awk '{print $1}') + echo $ifaddress1 + ifaddresscut=$(ifconfig $ifname | grep 'inet' | head -n 1 | cut -d: -f2 | awk '{print $1}' | awk -F "." '{print $1"."$2"."$3}') + echo $ifaddresscut + ifmac=$(ifconfig $ifname | grep 'HWaddr' | awk -F " " '{print $5}') + echo $ifmac +fi + +cd $LWIP_BUILD_DIR/../ +bash ./release_tar.sh +cd nStackServer/script +sed -i 's!/root/dpdk/dpdk-18.02!'$DPDK_DOWNLOAD_PATH'/dpdk-18.02!1' nstack_var.sh + +cd ../ +chmod 775 * +cp ./configure/*.json bin/ +cd bin + +if [ "$OS_ID" == "centos" ]; then + sed -i 's!eth7!'$ifname'!1' ip_data.json +elif [ "$OS_ID" == "ubuntu" ]; then + sed -i 's!eth7!'$ifname'!1' ip_data.json +fi + +sed -i 's!00:54:32:19:3d:19!'$ifmac'!1' ip_data.json +sed -i 's!192.168.1.207!'$ifaddress1'!1' ip_data.json + +sed -i 's!192.168.1.1!'$ifaddresscut'.0!1' network_data_tonStack.json +sed -i 's!192.168.1.254!'$ifaddresscut'.1!1' network_data_tonStack.json +sed -i 's!192.168.1.098!'$ifaddresscut'.5!1' network_data_tonStack.json +sed -i 's!192.168.1.209!'$ifaddresscut'.254!1' network_data_tonStack.json +sed -i 's!192.168.1.0!'$ifaddresscut'.0!1' network_data_tonStack.json +sed -i 's!192.168.1.254!'$ifaddresscut'.1!1' network_data_tonStack.json + +if [ "$OS_ID" == "centos" ]; then + sed -i 's!eth7!'$ifname'!1' network_data_tonStack.json +elif [ "$OS_ID" == "ubuntu" ]; then + sed -i 's!eth7!'$ifname'!1' network_data_tonStack.json +fi +sed -i 's!eth7!'$ifname'!1' network_data_tonStack.json + +cd $DMM_BUILD_SCRIPT_DIR/../release/bin +cp -r . ../../stacks/lwip_stack/app_test +cd $DMM_BUILD_SCRIPT_DIR/../stacks/lwip_stack/app_test +cp -r ../app_conf/*.json . + +sed -i 's!192.168.1.1!'$ifaddresscut'.0!1' rd_config.json + +sudo mkdir -p /var/run/ip_module/ +sudo mkdir -p /var/log/nStack/ip_module/ + +export LD_LIBRARY_PATH=$LIB_PATH +export NSTACK_LOG_ON=DBG + +cd $LWIP_BUILD_DIR/../nStackServer +bash -x ./stop_nstack.sh +bash -x ./start_nstack.sh +check_result=$(pgrep nStackMain) +if [ -z "$check_result" ]; then + echo "nStackMain execute failed" + exit 1 +else + echo "nStackMain execute successful" + exit 0 +fi diff --git a/stacks/rsocket/CMakeLists.txt b/stacks/rsocket/CMakeLists.txt new file mode 100644 index 0000000..c1b2f18 --- /dev/null +++ b/stacks/rsocket/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(rdmacm_dir librdmacm-1.1.0) +SET(dmm_inc_dir ${DMM_REL_INC_DIR}) +SET(RSOCKET_DEBUG 0) + +######################## + +SET(rdmacm_url https://github.com/ofiwg/librdmacm/archive/v1.1.0.tar.gz) + +INCLUDE(ExternalProject) +ExternalProject_Add( + rdmacm + URL ${rdmacm_url} + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/${rdmacm_dir} + DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} + PATCH_COMMAND patch -p1 -i ../rsocket.patch + CONFIGURE_COMMAND ./autogen.sh && ./configure dmm_inc_dir=${DMM_REL_INC_DIR} RSOCKET_DEBUG=${RSOCKET_DEBUG} + BUILD_IN_SOURCE 1 + BUILD_COMMAND make + INSTALL_COMMAND cp -f libdmm_rdmacm.a ${LIB_PATH_STATIC}/ + DEPENDS DPDK +) +set_target_properties(rdmacm PROPERTIES EXCLUDE_FROM_ALL TRUE) + +######################## + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC -m64 -pthread") + +ADD_LIBRARY(dmm_rsocket SHARED src/rsocket_adpt.c) + +ADD_DEFINITIONS(-D_GNU_SOURCE -DRSOCKET_DEBUG=${RSOCKET_DEBUG}) + +INCLUDE_DIRECTORIES(${DMM_REL_INC_DIR}) +INCLUDE_DIRECTORIES(./src ${rdmacm_dir} ${rdmacm_dir}/include ${rdmacm_dir}/src) + +TARGET_LINK_LIBRARIES(dmm_rsocket + -Wl,--whole-archive + ${LIB_PATH_STATIC}/libdmm_rdmacm.a + -Wl,--no-whole-archive + ibverbs pthread dl rt +) + +ADD_DEPENDENCIES(dmm_rsocket rdmacm DPDK) + +set_target_properties(dmm_rsocket PROPERTIES EXCLUDE_FROM_ALL TRUE) diff --git a/stacks/rsocket/config/module_config.json b/stacks/rsocket/config/module_config.json new file mode 100644 index 0000000..2df82cd --- /dev/null +++ b/stacks/rsocket/config/module_config.json @@ -0,0 +1,30 @@ +{ + "default_stack_name": "kernel", /*when rd can't be find maybe choose the defualt one*/ + "module_list": [ + { + "stack_name": "kernel", /*stack name*/ + "function_name": "kernel_stack_register", /*function name*/ + "libname": "./", /*library name, if loadtype is static, this maybe + null, else must give a library name*/ + "loadtype": "static", /*library load type: static or dynamic*/ + "deploytype": "1", /*deploy model type:model type1, model type2, + model type3. Indicating single or multi process + deployment. Used during shared memory initialization.*/ + "maxfd": "1024", /*the max fd supported*/ + "minfd": "0", /*the min fd supported*/ + "priorty": "1", /*priorty when executing, reserv*/ + "stackid": "0", /*stack id, this must be ordered and not be repeated*/ + }, + { + "stack_name": "rsocket", + "function_name": "rsocket_stack_register", + "libname": "libdmm_rsocket.so", + "loadtype": "dynmic", + "deploytype": "1", + "maxfd": "1024", + "minfd": "0", + "priorty": "1", + "stackid": "1", + }, + ] +} diff --git a/stacks/rsocket/config/rd_config.json b/stacks/rsocket/config/rd_config.json new file mode 100644 index 0000000..ea1fc7b --- /dev/null +++ b/stacks/rsocket/config/rd_config.json @@ -0,0 +1,10 @@ +{ + "ip_route": [ + { + "subnet": "192.168.1.1/24", + "type": "nstack-rsocket", + }, + ], + "prot_route": [ + ], +} diff --git a/stacks/rsocket/doc/README.md b/stacks/rsocket/doc/README.md new file mode 100644 index 0000000..237db68 --- /dev/null +++ b/stacks/rsocket/doc/README.md @@ -0,0 +1,110 @@ +# 1. What is rsocket +Rsockets is a protocol over RDMA that supports a socket-level API for +applications. +The dmm_rsocket adapted to DMM based on the librdmacm 1.1.0 version make it a +protocol in DMM framework. + +# 2. How to use DMM-rsocket + +## How to integrate rsocket into DMM +![](rsocket1.png) +The file CMakeList.txt defined the compiling process, including downloading +librdmacm 1.1.0 and patch it with rsocket.patch. The patch will +modify the related files when necessary, and finally provide +library of "libdmm_rdmacm.a" and "libdmm_rsocket.so". + +Target 'dmm_rsocket' could not be get automatically unless you run 'make dmm_rsocket' manually. +'make dmm_rsocket' will compile the adaption code and linking with libdmm_rdmacm.a. + +![](rsocket2.png) + +## Compile +(refer to dmm/doc/Build_DMM.md) +```sh + #cd dmm/build && cmake .. + #make help + #make dmm_rsocket +``` +Note: + After these processes, libdmm_rsocket.so protocol module would be created in +dmm/release/lib64/libdmm_rsocket.so + +## Test +- Steps 1: update some environment variables +```sh + #export LD_LIBRARY_PATH=${dmm}/release/lib64 + #export LD_PRELOAD=${dmm}/release/lib64/libnStackAPI.so + #export NSTACK_MOD_CFG_FILE=${dmm}/stacks/rsocket/config/module_config.json + #export NSTACK_MOD_CFG_RD=${dmm}/stacks/rsocket/config/rd_config.json +``` +- Steps 2: Modify rd_config.json(located at dmm/stacks/rsocket/config/) +```sh + #vim rd_config.json + //set "subnet": "192.168.21.1/24" +``` +Note: + Means dmm will hijack data from subnet 192.168.21.* + +- Steps 3: Communication test between machine A(as server) with machine B + (as client) + +##### Run in machine A +```sh + #./dmm/release/bin/vs_epoll -p 20000 -d 192.168.21.180 -a 10000 -s 192.168.21.181 -l 1000 -t 500000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 50000 -e 10 -x 1 +``` +Note: + Means the current machine would be server, and it's +destination address is 192.168.21.180 (client address), +source address is 192.168.21.181(server address) + +##### Run in machine B +``` + #./dmm/release/bin/vc_common -p 20000 -d 192.168.21.181 -a 10000 -s 192.168.21.180 -l 1000 -t 500000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 50000 -e 10 -x 1 +``` +Note: + Means the current machine would be client, and it's +destination address is 192.168.21.181 (server address), +source address is 192.168.21.180(client address) + +# 3. Document description + +(dmm/stacks/rsocket) + +## CMakeLists.txt +Control file for Cmake compiling. + +## config folder +##### module_config.json +- module_config.json is for configuring dmm protocol stack module + +##### rd_config.json +- rd_config.json is to choose which module is better to go through. It will go + through rsocket protocol stack when RD type is nstack-rsocket + +## rsocket.patch +For the librdmacm patch, the key modification is to find the point where the +epoll event is executed, all using the DMM_RSOCKET macro control. +Other changes are to package the hijacked API, so that the code can calls +libc API directly to avoid calls to the hijacked functions in the DMM, +all using GSAPI macro control. + +## src folder +##### rsocket_adpt.c && rsocket_adpt.h +- Rsocket adaptation section, including initialization and adaptation functions. + +##### rsocket_rdma.h +- Public header file. + +##### rsocket_in.h && rsocket_rs.c +- rsocket_in.h is included in rsocket.c.(rsocket.c is located at + dmm/stacks/rsocket/librdmacm-1.1.0/src) +- rsocket_rs.c is embedded at the end of rsocket.c + +##### rsocket_sapi.h +- List of libc functions which only be used internally. + +# 4. More Information +https://wiki.fd.io/view/DMM +https://github.com/ofiwg/librdmacm/blob/master/docs/rsocket +https://github.com/rsocket/rsocket +http://www.mellanox.com/page/products_dyn?product_family=26
\ No newline at end of file diff --git a/stacks/rsocket/doc/rsocket1.png b/stacks/rsocket/doc/rsocket1.png Binary files differnew file mode 100644 index 0000000..0adf269 --- /dev/null +++ b/stacks/rsocket/doc/rsocket1.png diff --git a/stacks/rsocket/doc/rsocket2.png b/stacks/rsocket/doc/rsocket2.png Binary files differnew file mode 100644 index 0000000..9a5b44b --- /dev/null +++ b/stacks/rsocket/doc/rsocket2.png diff --git a/stacks/rsocket/rsocket.patch b/stacks/rsocket/rsocket.patch new file mode 100644 index 0000000..430f178 --- /dev/null +++ b/stacks/rsocket/rsocket.patch @@ -0,0 +1,751 @@ +diff --git a/Makefile.am b/Makefile.am +index bf72134..cb02f56 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -22,6 +22,12 @@ src_librdmacm_la_LDFLAGS = -version-info 1 -export-dynamic \ + $(librdmacm_version_script) + src_librdmacm_la_DEPENDENCIES = $(srcdir)/src/librdmacm.map + ++noinst_LIBRARIES = libdmm_rdmacm.a ++libdmm_rdmacm_a_CFLAGS = $(src_librdmacm_la_CFLAGS) -O2 -fPIC -m64 \ ++ -I@dmm_inc_dir@ -I$(srcdir)/../src -DDMM_RSOCKET=1 -DRSOCKET_DEBUG=@RSOCKET_DEBUG@ ++libdmm_rdmacm_a_LDFLAGS = ++libdmm_rdmacm_a_SOURCES = $(src_librdmacm_la_SOURCES) ++ + src_librspreload_la_SOURCES = src/preload.c src/indexer.c + src_librspreload_la_LDFLAGS = -version-info 1 -export-dynamic + src_librspreload_la_LIBADD = $(top_builddir)/src/librdmacm.la +diff --git a/configure.ac b/configure.ac +index 4a43995..98601ea 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -104,5 +104,12 @@ if test "x$rdmadir" = "x"; then + AC_SUBST(rdmadir, rdma) + fi + ++AC_ARG_VAR(dmm_inc_dir, [Directory for dmm include files]) ++if test "x$dmm_inc_dir" = "x"; then ++ AC_MSG_ERROR([must set dmm_inc_dir]) ++fi ++ ++AC_ARG_VAR(RSOCKET_DEBUG, [rsocket debug flag 0 or 1]) ++ + AC_CONFIG_FILES([Makefile librdmacm.spec]) + AC_OUTPUT +diff --git a/src/cma.c b/src/cma.c +index a89e663..071222d 100644 +--- a/src/cma.c ++++ b/src/cma.c +@@ -60,6 +60,12 @@ + #include <rdma/rdma_verbs.h> + #include <infiniband/ib.h> + ++#ifdef DMM_RSOCKET ++#include "rsocket_rdma.h" ++#else ++#define GSAPI(name) name ++#endif ++ + #define CMA_INIT_CMD(req, req_size, op) \ + do { \ + memset(req, 0, req_size); \ +@@ -564,7 +570,7 @@ static int rdma_create_id2(struct rdma_event_channel *channel, + cmd.ps = ps; + cmd.qp_type = qp_type; + +- ret = write(id_priv->id.channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id_priv->id.channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + goto err; + +@@ -599,7 +605,7 @@ static int ucma_destroy_kern_id(int fd, uint32_t handle) + CMA_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_ID, &resp, sizeof resp); + cmd.id = handle; + +- ret = write(fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -659,7 +665,7 @@ static int ucma_query_addr(struct rdma_cm_id *id) + cmd.id = id_priv->handle; + cmd.option = UCMA_QUERY_ADDR; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -692,7 +698,7 @@ static int ucma_query_gid(struct rdma_cm_id *id) + cmd.id = id_priv->handle; + cmd.option = UCMA_QUERY_GID; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -753,7 +759,7 @@ static int ucma_query_path(struct rdma_cm_id *id) + cmd.id = id_priv->handle; + cmd.option = UCMA_QUERY_PATH; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -784,7 +790,7 @@ static int ucma_query_route(struct rdma_cm_id *id) + id_priv = container_of(id, struct cma_id_private, id); + cmd.id = id_priv->handle; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -835,7 +841,7 @@ static int rdma_bind_addr2(struct rdma_cm_id *id, struct sockaddr *addr, + cmd.addr_size = addrlen; + memcpy(&cmd.addr, addr, addrlen); + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -863,7 +869,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) + cmd.id = id_priv->handle; + memcpy(&cmd.addr, addr, addrlen); + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -916,7 +922,7 @@ static int rdma_resolve_addr2(struct rdma_cm_id *id, struct sockaddr *src_addr, + cmd.dst_size = dst_len; + cmd.timeout_ms = timeout_ms; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -951,7 +957,7 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + memcpy(&cmd.dst_addr, dst_addr, dst_len); + cmd.timeout_ms = timeout_ms; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1003,7 +1009,7 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms) + cmd.id = id_priv->handle; + cmd.timeout_ms = timeout_ms; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1029,7 +1035,7 @@ static int rdma_init_qp_attr(struct rdma_cm_id *id, struct ibv_qp_attr *qp_attr, + cmd.id = id_priv->handle; + cmd.qp_state = qp_attr->qp_state; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1530,7 +1536,7 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) + conn_param, 0, 0); + } + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1553,7 +1559,7 @@ int rdma_listen(struct rdma_cm_id *id, int backlog) + cmd.id = id_priv->handle; + cmd.backlog = backlog; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1656,7 +1662,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) + conn_param, conn_param->qp_num, + conn_param->srq); + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + ucma_modify_qp_err(id); + return (ret >= 0) ? ERR(ENODATA) : -1; +@@ -1684,7 +1690,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data, + cmd.private_data_len = private_data_len; + } + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1702,7 +1708,7 @@ int rdma_notify(struct rdma_cm_id *id, enum ibv_event_type event) + id_priv = container_of(id, struct cma_id_private, id); + cmd.id = id_priv->handle; + cmd.event = event; +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1735,7 +1741,7 @@ int rdma_disconnect(struct rdma_cm_id *id) + id_priv = container_of(id, struct cma_id_private, id); + cmd.id = id_priv->handle; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -1778,7 +1784,7 @@ static int rdma_join_multicast2(struct rdma_cm_id *id, struct sockaddr *addr, + cmd.uid = (uintptr_t) mc; + cmd.reserved = 0; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + ret = (ret >= 0) ? ERR(ENODATA) : -1; + goto err2; +@@ -1791,7 +1797,7 @@ static int rdma_join_multicast2(struct rdma_cm_id *id, struct sockaddr *addr, + memcpy(&cmd.addr, addr, addrlen); + cmd.uid = (uintptr_t) mc; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + ret = (ret >= 0) ? ERR(ENODATA) : -1; + goto err2; +@@ -1857,7 +1863,7 @@ int rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr) + CMA_INIT_CMD_RESP(&cmd, sizeof cmd, LEAVE_MCAST, &resp, sizeof resp); + cmd.id = mc->handle; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + ret = (ret >= 0) ? ERR(ENODATA) : -1; + goto free; +@@ -2019,7 +2025,7 @@ static int ucma_process_conn_resp(struct cma_id_private *id_priv) + CMA_INIT_CMD(&cmd, sizeof cmd, ACCEPT); + cmd.id = id_priv->handle; + +- ret = write(id_priv->id.channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id_priv->id.channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + ret = (ret >= 0) ? ERR(ENODATA) : -1; + goto err; +@@ -2103,7 +2109,7 @@ int rdma_get_cm_event(struct rdma_event_channel *channel, + retry: + memset(evt, 0, sizeof(*evt)); + CMA_INIT_CMD_RESP(&cmd, sizeof cmd, GET_EVENT, &resp, sizeof resp); +- ret = write(channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + free(evt); + return (ret >= 0) ? ERR(ENODATA) : -1; +@@ -2274,7 +2280,7 @@ int rdma_set_option(struct rdma_cm_id *id, int level, int optname, + cmd.optname = optname; + cmd.optlen = optlen; + +- ret = write(id->channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(id->channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) + return (ret >= 0) ? ERR(ENODATA) : -1; + +@@ -2302,7 +2308,7 @@ int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel) + cmd.id = id_priv->handle; + cmd.fd = id->channel->fd; + +- ret = write(channel->fd, &cmd, sizeof cmd); ++ ret = GSAPI(write)(channel->fd, &cmd, sizeof cmd); + if (ret != sizeof cmd) { + if (sync) + rdma_destroy_event_channel(channel); +diff --git a/src/rsocket.c b/src/rsocket.c +index c4f1b57..faa3d3a 100644 +--- a/src/rsocket.c ++++ b/src/rsocket.c +@@ -382,6 +382,11 @@ struct rsocket { + dlist_entry iomap_queue; + int iomap_pending; + int unack_cqe; ++#ifdef DMM_RSOCKET ++ int rr_epoll_ref; ++ int rr_epoll_fd; ++ void *rr_epoll_pdata; ++#endif + }; + + #define DS_UDP_TAG 0x55555555 +@@ -404,6 +409,12 @@ struct ds_udp_header { + + #define ds_next_qp(qp) container_of((qp)->list.next, struct ds_qp, list) + ++#ifdef DMM_RSOCKET ++#include "rsocket_in.h" ++#else ++#define GSAPI(name) name ++#endif ++ + static void ds_insert_qp(struct rsocket *rs, struct ds_qp *qp) + { + if (!rs->qp_list) +@@ -444,16 +455,16 @@ static int rs_notify_svc(struct rs_svc *svc, struct rsocket *rs, int cmd) + msg.cmd = cmd; + msg.status = EINVAL; + msg.rs = rs; +- write(svc->sock[0], &msg, sizeof msg); +- read(svc->sock[0], &msg, sizeof msg); ++ GSAPI(write)(svc->sock[0], &msg, sizeof msg); ++ GSAPI(read)(svc->sock[0], &msg, sizeof msg); + ret = rdma_seterrno(msg.status); + if (svc->cnt) + goto unlock; + + pthread_join(svc->id, NULL); + closepair: +- close(svc->sock[0]); +- close(svc->sock[1]); ++ GSAPI(close)(svc->sock[0]); ++ GSAPI(close)(svc->sock[1]); + unlock: + pthread_mutex_unlock(&mut); + return ret; +@@ -607,6 +618,9 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs, int type) + fastlock_init(&rs->map_lock); + dlist_init(&rs->iomap_list); + dlist_init(&rs->iomap_queue); ++#ifdef DMM_RSOCKET ++ rr_rs_init(rs); ++#endif + return rs; + } + +@@ -617,16 +631,16 @@ static int rs_set_nonblocking(struct rsocket *rs, int arg) + + if (rs->type == SOCK_STREAM) { + if (rs->cm_id->recv_cq_channel) +- ret = fcntl(rs->cm_id->recv_cq_channel->fd, F_SETFL, arg); ++ ret = GSAPI(fcntl)(rs->cm_id->recv_cq_channel->fd, F_SETFL, arg); + + if (!ret && rs->state < rs_connected) +- ret = fcntl(rs->cm_id->channel->fd, F_SETFL, arg); ++ ret = GSAPI(fcntl)(rs->cm_id->channel->fd, F_SETFL, arg); + } else { +- ret = fcntl(rs->epfd, F_SETFL, arg); ++ ret = GSAPI(fcntl)(rs->epfd, F_SETFL, arg); + if (!ret && rs->qp_list) { + qp = rs->qp_list; + do { +- ret = fcntl(qp->cm_id->recv_cq_channel->fd, ++ ret = GSAPI(fcntl)(qp->cm_id->recv_cq_channel->fd, + F_SETFL, arg); + qp = ds_next_qp(qp); + } while (qp != rs->qp_list && !ret); +@@ -767,7 +781,7 @@ static int rs_create_cq(struct rsocket *rs, struct rdma_cm_id *cm_id) + goto err1; + + if (rs->fd_flags & O_NONBLOCK) { +- if (fcntl(cm_id->recv_cq_channel->fd, F_SETFL, O_NONBLOCK)) ++ if (GSAPI(fcntl)(cm_id->recv_cq_channel->fd, F_SETFL, O_NONBLOCK)) + goto err2; + } + +@@ -918,7 +932,7 @@ static void ds_free_qp(struct ds_qp *qp) + if (qp->cm_id) { + if (qp->cm_id->qp) { + tdelete(&qp->dest.addr, &qp->rs->dest_map, ds_compare_addr); +- epoll_ctl(qp->rs->epfd, EPOLL_CTL_DEL, ++ GSAPI(epoll_ctl)(qp->rs->epfd, EPOLL_CTL_DEL, + qp->cm_id->recv_cq_channel->fd, NULL); + rdma_destroy_qp(qp->cm_id); + } +@@ -932,8 +946,12 @@ static void ds_free(struct rsocket *rs) + { + struct ds_qp *qp; + ++#ifdef DMM_RSOCKET ++ rr_rs_dest(rs); ++#endif ++ + if (rs->udp_sock >= 0) +- close(rs->udp_sock); ++ GSAPI(close)(rs->udp_sock); + + if (rs->index >= 0) + rs_remove(rs); +@@ -947,7 +965,7 @@ static void ds_free(struct rsocket *rs) + } + + if (rs->epfd >= 0) +- close(rs->epfd); ++ GSAPI(close)(rs->epfd); + + if (rs->sbuf) + free(rs->sbuf); +@@ -968,6 +986,10 @@ static void rs_free(struct rsocket *rs) + return; + } + ++#ifdef DMM_RSOCKET ++ rr_rs_dest(rs); ++#endif ++ + if (rs->rmsg) + free(rs->rmsg); + +@@ -1059,11 +1081,11 @@ static void rs_save_conn_data(struct rsocket *rs, struct rs_conn_data *conn) + + static int ds_init(struct rsocket *rs, int domain) + { +- rs->udp_sock = socket(domain, SOCK_DGRAM, 0); ++ rs->udp_sock = GSAPI(socket)(domain, SOCK_DGRAM, 0); + if (rs->udp_sock < 0) + return rs->udp_sock; + +- rs->epfd = epoll_create(2); ++ rs->epfd = GSAPI(epoll_create)(2); + if (rs->epfd < 0) + return rs->epfd; + +@@ -1164,7 +1186,7 @@ int rbind(int socket, const struct sockaddr *addr, socklen_t addrlen) + if (ret) + return ret; + } +- ret = bind(rs->udp_sock, addr, addrlen); ++ ret = GSAPI(bind)(rs->udp_sock, addr, addrlen); + } + return ret; + } +@@ -1229,8 +1251,11 @@ int raccept(int socket, struct sockaddr *addr, socklen_t *addrlen) + goto err; + } + +- if (rs->fd_flags & O_NONBLOCK) +- fcntl(new_rs->cm_id->channel->fd, F_SETFL, O_NONBLOCK); ++ if (rs->fd_flags & O_NONBLOCK) { ++ ret = GSAPI(fcntl)(new_rs->cm_id->channel->fd, F_SETFL, O_NONBLOCK); ++ if (0 == ret) ++ new_rs->fd_flags |= O_NONBLOCK; ++ } + + ret = rs_create_ep(new_rs); + if (ret) +@@ -1354,7 +1379,7 @@ connected: + break; + case rs_accepting: + if (!(rs->fd_flags & O_NONBLOCK)) +- fcntl(rs->cm_id->channel->fd, F_SETFL, 0); ++ GSAPI(fcntl)(rs->cm_id->channel->fd, F_SETFL, 0); + + ret = ucma_complete(rs->cm_id); + if (ret) +@@ -1375,6 +1400,10 @@ connected: + rs->err = errno; + } + } ++#ifdef DMM_RSOCKET ++ rr_rs_connected(rs); ++#endif ++ + return ret; + } + +@@ -1397,24 +1426,24 @@ static int ds_get_src_addr(struct rsocket *rs, + uint16_t port; + + *src_len = sizeof(*src_addr); +- ret = getsockname(rs->udp_sock, &src_addr->sa, src_len); ++ ret = GSAPI(getsockname)(rs->udp_sock, &src_addr->sa, src_len); + if (ret || !rs_any_addr(src_addr)) + return ret; + + port = src_addr->sin.sin_port; +- sock = socket(dest_addr->sa_family, SOCK_DGRAM, 0); ++ sock = GSAPI(socket)(dest_addr->sa_family, SOCK_DGRAM, 0); + if (sock < 0) + return sock; + +- ret = connect(sock, dest_addr, dest_len); ++ ret = GSAPI(connect)(sock, dest_addr, dest_len); + if (ret) + goto out; + + *src_len = sizeof(*src_addr); +- ret = getsockname(sock, &src_addr->sa, src_len); ++ ret = GSAPI(getsockname)(sock, &src_addr->sa, src_len); + src_addr->sin.sin_port = port; + out: +- close(sock); ++ GSAPI(close)(sock); + return ret; + } + +@@ -1512,7 +1541,7 @@ static int ds_create_qp(struct rsocket *rs, union socket_addr *src_addr, + + event.events = EPOLLIN; + event.data.ptr = qp; +- ret = epoll_ctl(rs->epfd, EPOLL_CTL_ADD, ++ ret = GSAPI(epoll_ctl)(rs->epfd, EPOLL_CTL_ADD, + qp->cm_id->recv_cq_channel->fd, &event); + if (ret) + goto err; +@@ -1609,7 +1638,7 @@ int rconnect(int socket, const struct sockaddr *addr, socklen_t addrlen) + } + + fastlock_acquire(&rs->slock); +- ret = connect(rs->udp_sock, addr, addrlen); ++ ret = GSAPI(connect)(rs->udp_sock, addr, addrlen); + if (!ret) + ret = ds_get_dest(rs, addr, addrlen, &rs->conn_dest); + fastlock_release(&rs->slock); +@@ -1903,12 +1932,18 @@ static int rs_poll_cq(struct rsocket *rs) + case RS_OP_CTRL: + if (rs_msg_data(msg) == RS_CTRL_DISCONNECT) { + rs->state = rs_disconnected; ++#ifdef DMM_RSOCKET ++ rr_rs_notify_tcp(rs); ++#endif + return 0; + } else if (rs_msg_data(msg) == RS_CTRL_SHUTDOWN) { + if (rs->state & rs_writable) { + rs->state &= ~rs_readable; + } else { + rs->state = rs_disconnected; ++#ifdef DMM_RSOCKET ++ rr_rs_notify_tcp(rs); ++#endif + return 0; + } + } +@@ -1959,6 +1994,9 @@ static int rs_poll_cq(struct rsocket *rs) + rs->err = errno; + } + } ++#ifdef DMM_RSOCKET ++ rr_rs_notify_tcp(rs); ++#endif + return ret; + } + +@@ -1977,7 +2015,11 @@ static int rs_get_cq_event(struct rsocket *rs) + ibv_ack_cq_events(rs->cm_id->recv_cq, rs->unack_cqe); + rs->unack_cqe = 0; + } ++#ifdef DMM_RSOCKET ++ __sync_fetch_and_sub(&rs->cq_armed, 1); ++#else + rs->cq_armed = 0; ++#endif + } else if (!(errno == EAGAIN || errno == EINTR)) { + rs->state = rs_error; + } +@@ -2015,8 +2057,13 @@ static int rs_process_cq(struct rsocket *rs, int nonblock, int (*test)(struct rs + } else if (nonblock) { + ret = ERR(EWOULDBLOCK); + } else if (!rs->cq_armed) { ++#ifdef DMM_RSOCKET ++ if (0 == ibv_req_notify_cq(rs->cm_id->recv_cq, 0)) ++ __sync_fetch_and_add(&rs->cq_armed, 1); ++#else + ibv_req_notify_cq(rs->cm_id->recv_cq, 0); + rs->cq_armed = 1; ++#endif + } else { + rs_update_credits(rs); + fastlock_acquire(&rs->cq_wait_lock); +@@ -2116,11 +2163,19 @@ static void ds_poll_cqs(struct rsocket *rs) + qp = ds_next_qp(qp); + if (!rs->rqe_avail && rs->sqe_avail) { + rs->qp_list = qp; ++#ifdef DMM_RSOCKET ++ goto END; ++#else + return; ++#endif + } + cnt++; + } while (qp != rs->qp_list); + } while (cnt); ++#ifdef DMM_RSOCKET ++END: ++ rr_rs_notify_udp(rs); ++#endif + } + + static void ds_req_notify_cqs(struct rsocket *rs) +@@ -2150,7 +2205,7 @@ static int ds_get_cq_event(struct rsocket *rs) + if (!rs->cq_armed) + return 0; + +- ret = epoll_wait(rs->epfd, &event, 1, -1); ++ ret = GSAPI(epoll_wait)(rs->epfd, &event, 1, -1); + if (ret <= 0) + return ret; + +@@ -2607,7 +2662,7 @@ static ssize_t ds_sendv_udp(struct rsocket *rs, const struct iovec *iov, + msg.msg_namelen = ucma_addrlen(&rs->conn_dest->addr.sa); + msg.msg_iov = miov; + msg.msg_iovlen = iovcnt + 1; +- ret = sendmsg(rs->udp_sock, &msg, flags); ++ ret = GSAPI(sendmsg)(rs->udp_sock, &msg, flags); + return ret > 0 ? ret - hdr.length : ret; + } + +@@ -2958,7 +3013,7 @@ check_cq: + fds.fd = rs->cm_id->channel->fd; + fds.events = events; + fds.revents = 0; +- poll(&fds, 1, 0); ++ GSAPI(poll)(&fds, 1, 0); + return fds.revents; + } + +@@ -2994,7 +3049,7 @@ static int rs_poll_check(struct pollfd *fds, nfds_t nfds) + if (rs) + fds[i].revents = rs_poll_rs(rs, fds[i].events, 1, rs_poll_all); + else +- poll(&fds[i], 1, 0); ++ GSAPI(poll)(&fds[i], 1, 0); + + if (fds[i].revents) + cnt++; +@@ -3094,7 +3149,7 @@ int rpoll(struct pollfd *fds, nfds_t nfds, int timeout) + if (ret) + break; + +- ret = poll(rfds, nfds, timeout); ++ ret = GSAPI(poll)(rfds, nfds, timeout); + if (ret <= 0) + break; + +@@ -3314,7 +3369,7 @@ int rgetpeername(int socket, struct sockaddr *addr, socklen_t *addrlen) + rs_copy_addr(addr, rdma_get_peer_addr(rs->cm_id), addrlen); + return 0; + } else { +- return getpeername(rs->udp_sock, addr, addrlen); ++ return GSAPI(getpeername)(rs->udp_sock, addr, addrlen); + } + } + +@@ -3329,7 +3384,7 @@ int rgetsockname(int socket, struct sockaddr *addr, socklen_t *addrlen) + rs_copy_addr(addr, rdma_get_local_addr(rs->cm_id), addrlen); + return 0; + } else { +- return getsockname(rs->udp_sock, addr, addrlen); ++ return GSAPI(getsockname)(rs->udp_sock, addr, addrlen); + } + } + +@@ -3371,7 +3426,7 @@ int rsetsockopt(int socket, int level, int optname, + if (!rs) + return ERR(EBADF); + if (rs->type == SOCK_DGRAM && level != SOL_RDMA) { +- ret = setsockopt(rs->udp_sock, level, optname, optval, optlen); ++ ret = GSAPI(setsockopt)(rs->udp_sock, level, optname, optval, optlen); + if (ret) + return ret; + } +@@ -3985,7 +4040,7 @@ static void udp_svc_process_sock(struct rs_svc *svc) + { + struct rs_svc_msg msg; + +- read(svc->sock[1], &msg, sizeof msg); ++ GSAPI(read)(svc->sock[1], &msg, sizeof msg); + switch (msg.cmd) { + case RS_SVC_ADD_DGRAM: + msg.status = rs_svc_add_rs(svc, msg.rs); +@@ -4009,7 +4064,7 @@ static void udp_svc_process_sock(struct rs_svc *svc) + break; + } + +- write(svc->sock[1], &msg, sizeof msg); ++ GSAPI(write)(svc->sock[1], &msg, sizeof msg); + } + + static uint8_t udp_svc_sgid_index(struct ds_dest *dest, union ibv_gid *sgid) +@@ -4137,7 +4192,7 @@ static void udp_svc_process_rs(struct rsocket *rs) + socklen_t addrlen = sizeof addr; + int len, ret; + +- ret = recvfrom(rs->udp_sock, buf, sizeof buf, 0, &addr.sa, &addrlen); ++ ret = GSAPI(recvfrom)(rs->udp_sock, buf, sizeof buf, 0, &addr.sa, &addrlen); + if (ret < DS_UDP_IPV4_HDR_LEN) + return; + +@@ -4184,7 +4239,7 @@ static void *udp_svc_run(void *arg) + ret = rs_svc_grow_sets(svc, 4); + if (ret) { + msg.status = ret; +- write(svc->sock[1], &msg, sizeof msg); ++ GSAPI(write)(svc->sock[1], &msg, sizeof msg); + return (void *) (uintptr_t) ret; + } + +@@ -4195,7 +4250,7 @@ static void *udp_svc_run(void *arg) + for (i = 0; i <= svc->cnt; i++) + udp_svc_fds[i].revents = 0; + +- poll(udp_svc_fds, svc->cnt + 1, -1); ++ GSAPI(poll)(udp_svc_fds, svc->cnt + 1, -1); + if (udp_svc_fds[0].revents) + udp_svc_process_sock(svc); + +@@ -4222,7 +4277,7 @@ static void tcp_svc_process_sock(struct rs_svc *svc) + struct rs_svc_msg msg; + int i; + +- read(svc->sock[1], &msg, sizeof msg); ++ GSAPI(read)(svc->sock[1], &msg, sizeof msg); + switch (msg.cmd) { + case RS_SVC_ADD_KEEPALIVE: + msg.status = rs_svc_add_rs(svc, msg.rs); +@@ -4253,7 +4308,7 @@ static void tcp_svc_process_sock(struct rs_svc *svc) + default: + break; + } +- write(svc->sock[1], &msg, sizeof msg); ++ GSAPI(write)(svc->sock[1], &msg, sizeof msg); + } + + /* +@@ -4282,7 +4337,7 @@ static void *tcp_svc_run(void *arg) + ret = rs_svc_grow_sets(svc, 16); + if (ret) { + msg.status = ret; +- write(svc->sock[1], &msg, sizeof msg); ++ GSAPI(write)(svc->sock[1], &msg, sizeof msg); + return (void *) (uintptr_t) ret; + } + +@@ -4291,7 +4346,7 @@ static void *tcp_svc_run(void *arg) + fds.events = POLLIN; + timeout = -1; + do { +- poll(&fds, 1, timeout * 1000); ++ GSAPI(poll)(&fds, 1, timeout * 1000); + if (fds.revents) + tcp_svc_process_sock(svc); + +@@ -4311,3 +4366,8 @@ static void *tcp_svc_run(void *arg) + + return NULL; + } ++ ++#ifdef DMM_RSOCKET ++#include "rsocket_rs.c" ++#endif ++ diff --git a/stacks/rsocket/src/rsocket_adpt.c b/stacks/rsocket/src/rsocket_adpt.c new file mode 100644 index 0000000..ea22c76 --- /dev/null +++ b/stacks/rsocket/src/rsocket_adpt.c @@ -0,0 +1,243 @@ +/* +* +* 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 <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <dlfcn.h> + +#include "nstack_dmm_api.h" + +#include "rsocket_adpt.h" +#include "rdma/rsocket.h" + +#define RR_EVFD(u64) ((int)((u64) >> 32)) +#define RR_RSFD(u64) ((int)((u64) & 0xFFFFFFFF)) +#define RR_DATA(evfd, rsfd) ((((uint64_t)(evfd)) << 32) | (uint64_t)(uint32_t)(rsfd)) + +#define RR_EV_NUM 64 + +rsocket_var_t g_rr_var = { 0 }; + +rr_sapi_t g_sapi = { 0 }; + +int g_rr_log_level = -1; + +int +rr_notify_event (void *pdata, int events) +{ + int ret; + + ret = g_rr_var.event_cb (pdata, events); + + RR_DBG ("event_cb(%p, 0x%x)=%d,%d\n", pdata, events, ret, errno); + + return ret; +} + +int +rr_epoll_ctl (int op, int evfd, uint32_t events, int rsfd) +{ + int ret; + struct epoll_event event; + event.events = events; + event.data.u64 = RR_DATA (evfd, rsfd); + ret = GSAPI (epoll_ctl) (g_rr_var.epfd, op, evfd, &event); + return ret; +} + +static void * +rr_epoll_thread (void *arg) +{ + int i, ret, e; + struct epoll_event events[RR_EV_NUM]; + + while (1) + { + ret = GSAPI (epoll_wait) (g_rr_var.epfd, events, RR_EV_NUM, 100); + e = errno; + + for (i = 0; i < ret; ++i) + { + if (rr_rs_handle (RR_RSFD (events[i].data.u64), events[i].events)) + { + (void) rr_ep_del (RR_EVFD (events[i].data.u64)); + } + } + + if (ret < 0) + { + RR_STAT_INC (RR_STAT_EPW_ERR); + if (e == EINTR) + { + RR_STAT_INC (RR_STAT_EPW_EINTR); + } + else if (e == ETIMEDOUT) + { + RR_STAT_INC (RR_STAT_EPW_ETIMEOUT); + } + else + { + RR_ERR ("epoll_wait()=%d:%d\n", ret, errno); + } + } + } + + return NULL; +} + +static int +rr_init_sapi () +{ + void *handle = dlopen ("libc.so.6", RTLD_NOW | RTLD_GLOBAL); + if (!handle) + { + RR_ERR ("dlopen(libc.so.6):NULL\n"); + return -1; + } + +#define RR_SAPI(name) \ + GSAPI(name) = dlsym(handle, #name); \ + if (!GSAPI(name)) \ + RR_ERR("dlsym(" #name "):NULL\n"); +#include "rsocket_sapi.h" +#undef RR_SAPI + + return 0; +} + +static void +rr_init_log () +{ + int level; + char *log; + + if (g_rr_log_level >= 0) + return; + + log = getenv ("RSOCKET_LOG"); + if (!log || !log[0]) + { + g_rr_log_level = RR_LOG_OFF; + return; + } + + level = atoi (log); + if (level < 0 || level > 99999) + { + g_rr_log_level = RR_LOG_OFF; + return; + } + + g_rr_log_level = level; +} + +static int +rsocket_init () +{ + int ret; + + rr_init_log (); + + if (rr_init_sapi ()) + { + return -1; + } + + g_rr_var.epfd = GSAPI (epoll_create) (1); + if (g_rr_var.epfd < 0) + return g_rr_var.epfd; + + ret = + pthread_create (&g_rr_var.epoll_threadid, NULL, rr_epoll_thread, NULL); + if (ret) + { + GSAPI (close) (g_rr_var.epfd); + g_rr_var.epfd = -1; + return ret; + } + (void) pthread_setname_np (g_rr_var.epoll_threadid, "rsocket_epoll"); + + return 0; +} + +int +rsocket_exit () +{ + if (g_rr_var.epfd >= 0) + { + (void) GSAPI (close) (g_rr_var.epfd); + g_rr_var.epfd = -1; + } + + return 0; +} + +unsigned int +rsocket_ep_ctl (int epFD, int proFD, int ctl_ops, struct epoll_event *event, + void *pdata) +{ + int ret; + struct eventpoll *ep; + unsigned int revents = 0; + + RR_DBG ("(%d, %d, %d, 0x%x, %p)\n", epFD, proFD, ctl_ops, event->events, + pdata); + + switch (ctl_ops) + { + case nstack_ep_triggle_add: + ret = rr_rs_ep_add (proFD, pdata, &revents); + if (ret) + return -1; + return revents; + + case nstack_ep_triggle_mod: + ret = rr_rs_ep_mod (proFD, pdata, &revents); + if (ret) + return -1; + return revents; + case nstack_ep_triggle_del: + return rr_rs_ep_del (proFD); + } + + return _err (EPERM); +} + +int +rsocket_stack_register (nstack_proc_cb * proc_fun, + nstack_event_cb * event_ops) +{ + rr_init_log (); + +#define NSTACK_MK_DECL(ret, fn, args) \ + do { \ + proc_fun->socket_ops.pf##fn = dlsym(event_ops->handle, "r"#fn); \ + if (!proc_fun->socket_ops.pf##fn) \ + RR_LOG("socket API '" #fn "' not found\n"); \ + } while (0) +#include "declare_syscalls.h" +#undef NSTACK_MK_DECL + + proc_fun->extern_ops.module_init = rsocket_init; + proc_fun->extern_ops.ep_ctl = rsocket_ep_ctl; + proc_fun->extern_ops.ep_getevt = NULL; + + g_rr_var.type = event_ops->type; + g_rr_var.event_cb = event_ops->event_cb; + + return 0; +} diff --git a/stacks/rsocket/src/rsocket_adpt.h b/stacks/rsocket/src/rsocket_adpt.h new file mode 100644 index 0000000..9c53330 --- /dev/null +++ b/stacks/rsocket/src/rsocket_adpt.h @@ -0,0 +1,54 @@ +/* +* +* 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 _RSOCKET_ADPT_H_ +#define _RSOCKET_ADPT_H_ + +#include "indexer.h" +#include "rsocket_rdma.h" + +enum +{ + RR_STAT_EPW_ERR, + RR_STAT_EPW_EINTR, + RR_STAT_EPW_ETIMEOUT, + + RR_STAT_NUM +}; + +#define RR_STAT_ADD(id, num) __sync_add_and_fetch(&g_rr_var.stat[(id)], num) +#define RR_STAT_SUB(id, num) __sync_sub_and_fetch(&g_rr_var.stat[(id)], num) +#define RR_STAT_INC(id) RR_STAT_ADD((id), 1) +#define RR_STAT_DEC(id) RR_STAT_SUB((id), 1) + +#define RSRDMA_EXIT 1 + +typedef struct rsocket_var +{ + pthread_t epoll_threadid; + + int epfd; + int type; + int (*event_cb) (void *pdata, int events); + + uint64_t stat[RR_STAT_NUM]; +} rsocket_var_t; + +extern rsocket_var_t g_rr_var; + +int rr_rs_handle (int fd, uint32_t events); + +#endif /* #ifndef _RSOCKET_ADPT_H_ */ diff --git a/stacks/rsocket/src/rsocket_in.h b/stacks/rsocket/src/rsocket_in.h new file mode 100644 index 0000000..1e868d4 --- /dev/null +++ b/stacks/rsocket/src/rsocket_in.h @@ -0,0 +1,32 @@ +/* +* +* 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 _RSOCKET_IN_H_ +#define _RSOCKET_IN_H_ + +#include "rsocket_rdma.h" + +inline static void rr_rs_init (struct rsocket *rs); +inline static void rr_rs_dest (struct rsocket *rs); + +static inline void rr_rs_notify_tcp (struct rsocket *rs); +static inline void rr_rs_notify_udp (struct rsocket *rs); + +inline static void rr_rs_handle_tcp (struct rsocket *rs); +inline static int rr_rs_evfd (struct rsocket *rs); +inline static void rr_rs_connected (struct rsocket *rs); + +#endif /* #ifndef _RSOCKET_IN_H_ */ diff --git a/stacks/rsocket/src/rsocket_rdma.h b/stacks/rsocket/src/rsocket_rdma.h new file mode 100644 index 0000000..75f4268 --- /dev/null +++ b/stacks/rsocket/src/rsocket_rdma.h @@ -0,0 +1,96 @@ +/* +* +* 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 _RSOCKET_RDMA_H_ +#define _RSOCKET_RDMA_H_ + +#include <stdint.h> +#include <unistd.h> +#include <stddef.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/epoll.h> +#include <netinet/in.h> +#include <pthread.h> +#include <poll.h> +#include <fcntl.h> +#include <time.h> + +enum +{ + RR_LOG_OFF = 0x00, + RR_LOG_ERR = 0x01, + RR_LOG_WRN = 0x02, + RR_LOG_LOG = 0x03, + RR_LOG_DBG = 0x04, +}; + +#define RR_OUT(level, name, fmt, arg...) do { \ + extern int g_rr_log_level; \ + if (g_rr_log_level >= level) { \ + (void)printf("#RSOCKET:%s# %s:%d> " fmt "", \ + name, __func__, __LINE__, ##arg); \ + } \ +} while (0) + +#define RR_ERR(fmt, arg...) RR_OUT(RR_LOG_ERR, "ERR", fmt, ##arg) +#define RR_WRN(fmt, arg...) RR_OUT(RR_LOG_WRN, "WRN", fmt, ##arg) +#define RR_LOG(fmt, arg...) RR_OUT(RR_LOG_LOG, "LOG", fmt, ##arg) +#if defined(RSOCKET_DEBUG) && RSOCKET_DEBUG > 0 +#define RR_DBG(fmt, arg...) RR_OUT(RR_LOG_DBG, "DBG", fmt, ##arg) +#else +#define RR_DBG(fmt, arg...) ((void)0) +#endif + +#define _err(err_no) ((errno = (err_no)), -1) + +int rr_rs_ep_add (int fd, void *pdata, uint32_t * revent); +int rr_rs_ep_mod (int fd, void *pdata, uint32_t * revent); +int rr_rs_ep_del (int fd); + +uint32_t rr_rs_poll (int fd, uint32_t revents); + +int rr_notify_event (void *pdata, int events); + +typedef struct rr_socket_api +{ +#define RR_SAPI(name) typeof(name) *n_##name; /* native api */ +#include "rsocket_sapi.h" +#undef RR_SAPI +} rr_sapi_t; + +extern rr_sapi_t g_sapi; + +#define GSAPI(name) g_sapi.n_##name + +int rr_epoll_ctl (int op, int evfd, uint32_t events, int rsfd); + +inline static int +rr_ep_add (int evfd, int rsfd) +{ + return rr_epoll_ctl (EPOLL_CTL_ADD, evfd, EPOLLET | EPOLLIN | EPOLLOUT, + rsfd); +} + +inline static int +rr_ep_del (int evfd) +{ + if (evfd < 0) + return 0; + return rr_epoll_ctl (EPOLL_CTL_DEL, evfd, 0, 0); +} + +#endif /* #ifndef _RSOCKET_RDMA_H_ */ diff --git a/stacks/rsocket/src/rsocket_rs.c b/stacks/rsocket/src/rsocket_rs.c new file mode 100644 index 0000000..0f4e73f --- /dev/null +++ b/stacks/rsocket/src/rsocket_rs.c @@ -0,0 +1,393 @@ +/* +* +* 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 _RSOCKET_RS_C_ +#define _RSOCKET_RS_C_ + +inline static void +rr_rs_init (struct rsocket *rs) +{ + RR_DBG ("(rs:%p{index:%d})\n", rs, rs->index); + rs->rr_epoll_ref = 0; + rs->rr_epoll_fd = -1; + rs->rr_epoll_pdata = NULL; +} + +inline static void +rr_rs_dest (struct rsocket *rs) +{ + RR_DBG ("(rs:%p{index:%d})\n", rs, rs->index); + + if (rs->rr_epoll_ref) + { + (void) rr_ep_del (rs->rr_epoll_fd); + rs->rr_epoll_ref = 0; + rs->rr_epoll_fd = -1; + rs->rr_epoll_pdata = NULL; + } +} + +#ifndef POLL__RSOCKET_RS_H_ +#define POLL__RSOCKET_RS_H_ + +static inline uint32_t +rr_rs_poll_tcp (struct rsocket *rs) +{ + uint32_t events = 0; + if (rs->state & rs_connected) + { + if (rs_have_rdata (rs)) + events |= EPOLLIN; + if (rs_can_send (rs)) + events |= EPOLLOUT; + } + if (rs->state & (rs_error | rs_connect_error)) + events |= EPOLLERR; + if (rs->state & rs_disconnected) + events |= EPOLLHUP; + return events; +} + +static inline uint32_t +rr_rs_poll_udp (struct rsocket *rs) +{ + uint32_t events = 0; + if (rs_have_rdata (rs)) + events |= EPOLLIN; + if (ds_can_send (rs)) + events |= EPOLLOUT; + if (rs->state & rs_error) + events |= EPOLLERR; + return events; +} + +static inline uint32_t +rr_rs_poll_both (struct rsocket *rs) +{ + if (rs->type == SOCK_STREAM) + return rr_rs_poll_tcp (rs); + + if (rs->type == SOCK_DGRAM) + return rr_rs_poll_udp (rs); + + return 0; +} + +uint32_t +rr_rs_poll (int fd, uint32_t revents) +{ + struct rsocket *rs = (struct rsocket *) idm_lookup (&idm, fd); + + if (!rs) + return 0; + + if (rs->state == rs_listening) + return revents; + + return rr_rs_poll_both (rs); +} + +#endif /* #ifndef POLL__RSOCKET_RS_H_ */ + +static inline void +rr_rs_notify_tcp (struct rsocket *rs) +{ + if (rs->rr_epoll_ref) + { + uint32_t events = rr_rs_poll_tcp (rs); + if (events) + (void) rr_notify_event (rs->rr_epoll_pdata, events); + } +} + +static inline void +rr_rs_notify_udp (struct rsocket *rs) +{ + if (rs->rr_epoll_ref) + { + uint32_t events = rr_rs_poll_udp (rs); + if (events) + (void) rr_notify_event (rs->rr_epoll_pdata, events); + } +} + +#ifndef HANDLE__RSOCKET_RS_H_ +#define HANDLE__RSOCKET_RS_H_ + +inline static void +rr_rs_handle_tcp (struct rsocket *rs) +{ + int ret; + + RR_DBG ("(%d)@ state:0x%x\n", rs->index, rs->state); + + if (!(rs->state & (rs_connected | rs_opening))) + return; + + fastlock_acquire (&rs->cq_wait_lock); + ret = rs_get_cq_event (rs); + RR_DBG ("rs_get_cq_event({%d})=%d,%d\n", rs->index, ret, errno); + fastlock_release (&rs->cq_wait_lock); + + fastlock_acquire (&rs->cq_lock); + + if (rs->state & rs_connected) + { + rs_update_credits (rs); + ret = rs_poll_cq (rs); + RR_DBG ("rs_poll_cq({%d})=%d,%d {ref:%d, armed:%d}\n", + rs->index, ret, errno, rs->rr_epoll_ref, rs->cq_armed); + } + + if (rs->rr_epoll_ref && rs->cq_armed < 1) + { + ret = ibv_req_notify_cq (rs->cm_id->recv_cq, 0); + RR_DBG ("ibv_req_notify_cq({%d})=%d,%d\n", rs->index, ret, errno); + if (0 == ret) + __sync_fetch_and_add (&rs->cq_armed, 1); + } + + if (rs->state & rs_connected) + { + ret = rs_poll_cq (rs); + RR_DBG ("rs_poll_cq({%d})=%d,%d\n", rs->index, ret, errno); + rs_update_credits (rs); + } + + fastlock_release (&rs->cq_lock); + + RR_DBG ("(%d)=\n", rs->index); +} + +inline static void +rr_rs_handle_udp (struct rsocket *rs) +{ + fastlock_acquire (&rs->cq_wait_lock); + ds_get_cq_event (rs); + fastlock_release (&rs->cq_wait_lock); + + fastlock_acquire (&rs->cq_lock); + ds_poll_cqs (rs); + if (rs->rr_epoll_ref && !rs->cq_armed) + { + ds_req_notify_cqs (rs); + rs->cq_armed = 1; + } + fastlock_release (&rs->cq_lock); +} + +inline static void +rr_rs_handle_rs (struct rsocket *rs) +{ + if (rs->state & rs_opening) + { + int ret = rs_do_connect (rs); + RR_DBG ("rs_do_connect(%p{%d}):%d:%d\n", rs, rs->index, ret, errno); + return; + } + + if (rs->type == SOCK_STREAM) + { + rr_rs_handle_tcp (rs); + } + + if (rs->type == SOCK_DGRAM) + { + rr_rs_handle_udp (rs); + } +} + +int +rr_rs_handle (int fd, uint32_t events) +{ + struct rsocket *rs = (struct rsocket *) idm_lookup (&idm, fd); + + RR_DBG ("(fd:%d, events:0x%x):rs:%p\n", fd, events, rs); + + if (!rs) + return _err (EBADF); + + if (rs->state == rs_listening) + { + if (events & EPOLLIN) + { + (void) rr_notify_event (rs->rr_epoll_pdata, events); + } + return 0; + } + + rr_rs_handle_rs (rs); + + return 0; +} + +#endif /* #ifndef HANDLE__RSOCKET_RS_H_ */ + +#ifndef ADPT__RSOCKET_RS_H_ +#define ADPT__RSOCKET_RS_H_ + +inline static int +rr_rs_evfd (struct rsocket *rs) +{ + if (rs->type == SOCK_STREAM) + { + if (rs->state >= rs_connected) + return rs->cm_id->recv_cq_channel->fd; + else + return rs->cm_id->channel->fd; + } + else + { + return rs->epfd; + } + + return -1; +} + +int +rr_rs_ep_add (int fd, void *pdata, uint32_t * revent) +{ + int ref; + struct rsocket *rs = (struct rsocket *) idm_lookup (&idm, fd); + RR_DBG ("(%d(%p),)\n", fd, rs); + if (!rs) + return _err (EBADF); + + ref = __sync_add_and_fetch (&rs->rr_epoll_ref, 1); + if (1 == ref) + { + rs->rr_epoll_fd = rr_rs_evfd (rs); + (void) rr_ep_add (rs->rr_epoll_fd, rs->index); + } + + (void) rr_rs_handle_rs (rs); + *revent = rs->state == rs_listening ? 0 : rr_rs_poll_both (rs); + + rs->rr_epoll_pdata = pdata; + + RR_DBG ("*revent=0x%x\n", *revent); + return 0; +} + +int +rr_rs_ep_mod (int fd, void *pdata, uint32_t * revent) +{ + struct rsocket *rs = (struct rsocket *) idm_lookup (&idm, fd); + RR_DBG ("(%d(%p),)\n", fd, rs); + if (!rs) + return _err (EBADF); + + if (rs->rr_epoll_ref <= 0) + return _err (ENOENT); + + (void) rr_rs_handle_rs (rs); + *revent = rs->state == rs_listening ? 0 : rr_rs_poll_both (rs); + + rs->rr_epoll_pdata = pdata; + + RR_DBG ("*revent=0x%x\n", *revent); + return 0; +} + +int +rr_rs_ep_del (int fd) +{ + int ref; + struct rsocket *rs = (struct rsocket *) idm_lookup (&idm, fd); + RR_DBG ("(%d(%p))\n", fd, rs); + + if (!rs) + return _err (EBADF); + + ref = __sync_sub_and_fetch (&rs->rr_epoll_ref, 1); + if (0 == ref) + { + (void) rr_ep_del (rs->rr_epoll_fd); + rs->rr_epoll_fd = -1; + } + + return 0; +} + +#endif /* #ifndef ADPT__RSOCKET_RS_H_ */ + +inline static void +rr_rs_connected (struct rsocket *rs) +{ + RR_DBG ("rsfd:%d ref:%d evfd:%d->%d state:0x%x\n", rs->index, + rs->rr_epoll_ref, rs->rr_epoll_fd, rr_rs_evfd (rs), rs->state); + + if (!(rs->state & rs_connected)) + { + rr_rs_notify_tcp (rs); + return; + } + + if (rs->rr_epoll_ref) + { + int evfd = rr_rs_evfd (rs); + + if (evfd != rs->rr_epoll_fd) + { + (void) rr_ep_del (rs->rr_epoll_fd); + rs->rr_epoll_fd = evfd; + (void) rr_ep_add (evfd, rs->index); + } + + rr_rs_handle_tcp (rs); + } +} + +int +raccept4 (int socket, struct sockaddr *addr, socklen_t * addrlen, int flags) +{ + int ret, fd; + struct rsocket *rs; + + RR_DBG ("(%d, %p, %p, %d)@\n", socket, addr, addrlen, flags); + fd = raccept (socket, addr, addrlen); + RR_DBG ("(%d, , , %d):%d:%d\n", socket, flags, fd, errno); + if (fd < 0) + return fd; + + rs = (struct rsocket *) idm_lookup (&idm, fd); + if (!rs) + { + RR_ERR ("panic\n"); + return -1; + } + + if (flags & SOCK_NONBLOCK) + { + if (0 == (rs->fd_flags & O_NONBLOCK)) + { + RR_DBG ("orig flag:%x\n", + GSAPI (fcntl) (rs->cm_id->channel->fd, F_GETFL)); + ret = GSAPI (fcntl) (rs->cm_id->channel->fd, F_SETFL, O_NONBLOCK); + if (0 == ret) + rs->fd_flags |= O_NONBLOCK; + } + } + + if (flags & SOCK_CLOEXEC) + { + RR_LOG ("ignore flag:SOCK_CLOEXEC\n"); + } + + return fd; +} + +#endif /* #ifndef _RSOCKET_RS_C_ */ diff --git a/stacks/rsocket/src/rsocket_sapi.h b/stacks/rsocket/src/rsocket_sapi.h new file mode 100644 index 0000000..21a7481 --- /dev/null +++ b/stacks/rsocket/src/rsocket_sapi.h @@ -0,0 +1,35 @@ +/* +* +* 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. +*/ + +/* *INDENT-OFF* */ +RR_SAPI (socket) +RR_SAPI (close) +RR_SAPI (bind) +RR_SAPI (connect) +RR_SAPI (getpeername) +RR_SAPI (getsockname) +RR_SAPI (fcntl) +RR_SAPI (setsockopt) +RR_SAPI (getsockopt) +RR_SAPI (read) +RR_SAPI (write) +RR_SAPI (sendmsg) +RR_SAPI (recvfrom) +RR_SAPI (poll) +RR_SAPI (epoll_create) +RR_SAPI (epoll_ctl) +RR_SAPI (epoll_wait) +/* *INDENT-ON* */ diff --git a/stacks/vpp/adapt/dmm_vcl.h b/stacks/vpp/adapt/dmm_vcl.h new file mode 100644 index 0000000..f0d8c85 --- /dev/null +++ b/stacks/vpp/adapt/dmm_vcl.h @@ -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. + */ + +#ifndef included_dmm_vcl_h +#define included_dmm_vcl_h + +#include "nstack_dmm_api.h" + +#define DMM_VCL_ENV_DEBUG "DMM_VCL_DEBUG" + +typedef struct dmm_vcl +{ + int epfd; + long unsigned int epoll_threadid; + nstack_event_cb regVal; + int (*p_epoll_create) (int size); + unsigned int (*p_epoll_ctl) (int epFD, int proFD, int ctl_ops, + struct epoll_event * events); + unsigned int (*p_epoll_wait) (int epfd, struct epoll_event * events, + int maxevents, int timeout); + int (*p_close) (int fd); +} dmm_vcl_t; + +#endif /* included_dmm_vcl_h */ diff --git a/stacks/vpp/adapt/dmm_vcl_adpt.c b/stacks/vpp/adapt/dmm_vcl_adpt.c new file mode 100644 index 0000000..d4974e2 --- /dev/null +++ b/stacks/vpp/adapt/dmm_vcl_adpt.c @@ -0,0 +1,173 @@ +/* + * 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. + */ + +#define _GNU_SOURCE +#include <pthread.h> +#include <dlfcn.h> +#include <sys/epoll.h> +#include "dmm_vcl.h" +#include "nstack_dmm_api.h" // nstack_socket_ops* +#include <vppinfra/error.h> // clib_warning() + +#define DMM_VCL_ADPT_DEBUG dmm_vcl_debug +static unsigned int dmm_vcl_debug; +dmm_vcl_t g_dmm_vcl; + +unsigned int +vpphs_ep_ctl_ops (int epFD, int proFD, int ctl_ops, + struct epoll_event *events, void *pdata) +{ + struct epoll_event tmpEvt; + int ret = 0; + int dmm_epfd; + + tmpEvt.data.ptr = pdata; + tmpEvt.events = events->events; + tmpEvt.events |= (EPOLLIN | EPOLLOUT); + + if (DMM_VCL_ADPT_DEBUG > 0) + clib_warning ("DMM VCL ADPT<%d>: epfd=%d,fd=%d,ops=%d, events=%u", + getpid (), epFD, proFD, ctl_ops, events->events); + + dmm_epfd = g_dmm_vcl.epfd; + switch (ctl_ops) + { + case nstack_ep_triggle_add: + ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_ADD, proFD, &tmpEvt); + break; + case nstack_ep_triggle_mod: + ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_MOD, proFD, &tmpEvt); + break; + case nstack_ep_triggle_del: + ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_DEL, proFD, &tmpEvt); + break; + default: + ret = -1; + break; + } + return ret; +} + +#define DMM_VCL_MAX_EP_EVENT 1024 + +static void * +dmm_vcl_epoll_thread (void *arg) +{ + int num, i; + + struct epoll_event events[DMM_VCL_MAX_EP_EVENT]; + + while (1) + { + num = + g_dmm_vcl.p_epoll_wait (g_dmm_vcl.epfd, events, DMM_VCL_MAX_EP_EVENT, + 100); + + for (i = 0; i < num; ++i) + { + if (DMM_VCL_ADPT_DEBUG > 0) + clib_warning + ("DMM_VCL_ADPT<%d>: dmm_vcl_epoll i[%d] events=%u, epfd=%d, ptr=%d", + getpid (), i, events[i].events, events[i].data.fd, + events[i].data.ptr); + + g_dmm_vcl.regVal.event_cb (events[i].data.ptr, events[i].events); + + } + } + + return NULL; +} + +int +dmm_vpphs_init () +{ + char *env_var_str; + int rv = 0; + + env_var_str = getenv (DMM_VCL_ENV_DEBUG); + if (env_var_str) + { + u32 tmp; + if (sscanf (env_var_str, "%u", &tmp) != 1) + clib_warning + ("DMM_VCL_ADPT<%d>: WARNING: Invalid debug level specified " + "in the environment variable " DMM_VCL_ENV_DEBUG " (%s)!\n", + getpid (), env_var_str); + else + { + dmm_vcl_debug = tmp; + if (DMM_VCL_ADPT_DEBUG > 0) + clib_warning + ("DMM_VCL_ADPT<%d>: configured DMM VCL ADPT debug (%u) from " + "DMM_VCL_ENV_DEBUG ", getpid (), dmm_vcl_debug); + } + } + + g_dmm_vcl.epfd = g_dmm_vcl.p_epoll_create (1000); + if (g_dmm_vcl.epfd < 0) + return g_dmm_vcl.epfd; + + rv = + pthread_create (&g_dmm_vcl.epoll_threadid, NULL, dmm_vcl_epoll_thread, + NULL); + if (rv != 0) + { + clib_warning ("dmm vcl epoll thread create fail, errno:%d!", errno); + g_dmm_vcl.p_close (g_dmm_vcl.epfd); + g_dmm_vcl.epfd = -1; + return rv; + } + + rv = pthread_setname_np (g_dmm_vcl.epoll_threadid, "dmm_vcl_epoll"); + if (rv != 0) + { + clib_warning + ("pthread_setname_np failed for dmm_vcl_epoll, rv=%d, errno:%d", + rv, errno); + } + + return rv; +} + +int +vpphs_stack_register (nstack_proc_cb * ops, nstack_event_cb * val) +{ + +#undef NSTACK_MK_DECL +#define NSTACK_MK_DECL(ret, fn, args) \ + (ops->socket_ops).pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, # fn); +#include "declare_syscalls.h" + (ops->socket_ops).pfepoll_create = NULL; + + g_dmm_vcl.p_epoll_ctl = dlsym (val->handle, "epoll_ctl"); + g_dmm_vcl.p_epoll_create = dlsym (val->handle, "epoll_create1"); + g_dmm_vcl.p_epoll_wait = dlsym (val->handle, "epoll_wait"); + g_dmm_vcl.p_close = dlsym (val->handle, "close"); + g_dmm_vcl.regVal = *val; + + ops->extern_ops.module_init = dmm_vpphs_init; + ops->extern_ops.fork_init_child = NULL; + ops->extern_ops.fork_parent_fd = NULL; + ops->extern_ops.fork_child_fd = NULL; + ops->extern_ops.fork_free_fd = NULL; + ops->extern_ops.ep_ctl = vpphs_ep_ctl_ops; + ops->extern_ops.ep_prewait_proc = NULL; + ops->extern_ops.stack_fd_check = NULL; + ops->extern_ops.stack_alloc_fd = NULL; + ops->extern_ops.peak = NULL; + + return 0; +} diff --git a/stacks/vpp/configure/module_config.json b/stacks/vpp/configure/module_config.json new file mode 100644 index 0000000..49b7ca9 --- /dev/null +++ b/stacks/vpp/configure/module_config.json @@ -0,0 +1,30 @@ +{ + "default_stack_name": "kernel", /*when rd can't be find maybe choose the defualt one*/ + "module_list": [ + { + "stack_name": "kernel", /*stack name*/ + "function_name": "kernel_stack_register", /*function name*/ + "libname": "./", /*library name, if loadtype is static, this maybe + null, else must give a library name*/ + "loadtype": "static", /*library load type: static or dynamic*/ + "deploytype": "1", /*deploy model type:model type1, model type2, + model type3. Indicating single or multi process + deployment. Used during shared memory initialization.*/ + "maxfd": "1024", /*the max fd supported*/ + "minfd": "0", /*the min fd supported*/ + "priorty": "1", /*priorty when executing, reserv*/ + "stackid": "0", /*stack id, this must be ordered and not be repeated*/ + }, + { + "stack_name": "vpp_hoststack", + "function_name": "vpphs_stack_register", + "libname": "../lib64/libdmm_vcl.so", + "loadtype": "dynmic", + "deploytype": "4", + "maxfd": "1024", + "minfd": "0", + "priorty": "1", + "stackid": "1", + }, + ] +} diff --git a/stacks/vpp/configure/rd_config.json b/stacks/vpp/configure/rd_config.json new file mode 100644 index 0000000..2ea10d1 --- /dev/null +++ b/stacks/vpp/configure/rd_config.json @@ -0,0 +1,26 @@ +{ + "ip_route": [ + { + "subnet": "192.168.1.1/24", + "type": "nstack-vpp", + }, + { + "subnet": "10.145.240.1/24", + "type": "nstack-kernel", + }, + { + "subnet": "192.166.1.1/24", + "type": "nstack-kernel", + } + ], + "prot_route": [ + { + "proto_type": "1", + "type": "nstack-vpp", + }, + { + "proto_type": "2", + "type": "nstack-kernel", + } + ], +} diff --git a/stacks/vpp/configure/startup.conf b/stacks/vpp/configure/startup.conf new file mode 100644 index 0000000..ada7fdf --- /dev/null +++ b/stacks/vpp/configure/startup.conf @@ -0,0 +1,21 @@ +unix { + interactive + log /var/log/vpp/vpp.log + cli-listen localhost:5002 + full-coredump + exec /etc/vpp/vpp_config +} + +api-trace { + on +} + +cpu { + main-core 2 +} + +dpdk { + socket-mem 1024 + uio-driver igb_uio + dev 0000:00:09.0 +} diff --git a/stacks/vpp/configure/vpp_config b/stacks/vpp/configure/vpp_config new file mode 100644 index 0000000..56d80b5 --- /dev/null +++ b/stacks/vpp/configure/vpp_config @@ -0,0 +1,6 @@ +set int state GigabitEthernet0/9/0 up +set int ip addr GigabitEthernet0/9/0 192.168.1.1/24 +show version +show version verbose +show cpu +show int diff --git a/stacks/vpp/doc/README.md b/stacks/vpp/doc/README.md new file mode 100644 index 0000000..e09aefe --- /dev/null +++ b/stacks/vpp/doc/README.md @@ -0,0 +1,115 @@ +# 1. What is VPP Host Stack +VPP's host stack is a user space implementation of a number of transport, +session and application layer protocols that leverages VPP's existing +protocol stack. + +# 2. How to use VPP Host Stack + +## How to integrate VPP Host Stack into DMM +The file CMakeList.txt defined the compiling process, including downloading +the vpp code and patch it. The patch will modify the makefile to adapt dmm. + +Target 'libdmm_vcl' could not be get automatically unless you run +'make vpp-stack' manually. It will compile the adaption code and link the +libraries of vpp and finally generate the library of "libdmm_vcl.so". + + +## Compile +```sh + #cd dmm/build && cmake .. + #make vpp-statck +``` +Note: + After these processes, libdmm_vcl.so library would be generated in +vpp/build-root/install-vpp_debug-native/vpp/lib64/. + +##Start VPP Host Stack +- Steps 1: copy the plugins to /usr/lib/. +```sh + #cp -r vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_plugins /usr/lib/ +``` + +- Steps 2: load dpdk network card driver manually. +```sh + #cd dpdk-18.02/x86_64-native-linuxapp-gcc/kmod/ + #modprobe uio + #insmod igb_uio.ko +``` + +- Steps 3: choose a network card that is not in use and down it. +```sh + #ifconfig eth1 down +``` +- Steps 4: copy the config file and start vpp +```sh + #cp dmm/stacks/vpp/configure/startup.conf /etc/vpp/ + #cp dmm/stacks/vpp/configure/vpp_config /etc/vpp/ + #cd vpp/build-root/install-vpp_debug-native/vpp/bin + #./vpp -c /etc/vpp/startup.conf +``` +Note: + 1.modify the dev of dpdk in startup.conf. + 2.modify the interface name and ip in vpp_config. + +## Test app +Note: + Before testing, we should anotation the dmm code that "close (listenFd);" in + function process_server_accept_thread for server. Otherwize the app can + not send and recieve packets. + +- Steps 1: copy the libdmm_vcl.so to dmm/release/lib64/ +- Steps 2: copy the config file from dmm/stacks/vpp/configure/*.json to + dmm/release/bin and modify the rd_config.json. +```sh + #vim rd_config.json + //set "subnet": "192.168.21.1/24" +``` +Note: + Means dmm will hijack data from subnet 192.168.21.* + +- Steps 3: Communication test between machine A(as server) with machine B + (as client) + +##### Run in machine A +```sh + #cd dmm/release/bin/ + #./vs_epoll -p 20000 -d 192.168.21.180 -a 10000 -s 192.168.21.181 -l 1000 -t 500000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 50000 -e 10 -x 1 +``` +Note: + Means the current machine would be server, and it's +destination address is 192.168.21.180 (client address), +source address is 192.168.21.181(server address) + +##### Run in machine B +``` + #cd dmm/release/bin/ + #./vc_common -p 20000 -d 192.168.21.181 -a 10000 -s 192.168.21.180 -l 1000 -t 500000 -i 0 -f 1 -r 20000 -n 1 -w 10 -u 50000 -e 10 -x 1 +``` +Note: + Means the current machine would be client, and it's +destination address is 192.168.21.181 (server address), +source address is 192.168.21.180(client address) + +# 3. Document description + +(dmm/stacks/vpp/) + +## configure folder +##### module_config.json +- module_config.json is for configuring dmm protocol stack module + +##### rd_config.json +- rd_config.json is to choose which module is better to go through. It will go + through vpp host protocol stack when RD type is nstack-vpp + +## patch folder +- modify the makefile to compile the adapt code. + +## adapt folder +##### dmm_vcl_adpt.c && dmm_vcl.h +- vpp host stack adaptation code, including initialization and adaptation functions. + +# 4. More Information +- https://wiki.fd.io/view/DMM +- https://wiki.fd.io/view/VPP +- https://wiki.fd.io/view/VPP/HostStack diff --git a/stacks/vpp/patch/0001-Fix-modify-makefile-to-adapt-dmm.patch b/stacks/vpp/patch/0001-Fix-modify-makefile-to-adapt-dmm.patch new file mode 100644 index 0000000..bb3eca7 --- /dev/null +++ b/stacks/vpp/patch/0001-Fix-modify-makefile-to-adapt-dmm.patch @@ -0,0 +1,72 @@ +From deb61897f0505a82bd26e7fa35b6923c1455732d Mon Sep 17 00:00:00 2001 +From: Jiang Wenjiang <jiangwenjiang@huawei.com> +Date: Thu, 9 Aug 2018 08:22:24 +0800 +Subject: [PATCH] Fix: modify makefile to adapt dmm + +--- + src/vcl.am | 17 +++++++++++++++-- + src/vcl/ldp.c | 2 +- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/vcl.am b/src/vcl.am +index 89e1841..b09cacb 100644 +--- a/src/vcl.am ++++ b/src/vcl.am +@@ -11,13 +11,18 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-lib_LTLIBRARIES += libvppcom.la libvcl_ldpreload.la ++lib_LTLIBRARIES += libvppcom.la libvcl_ldpreload.la libdmm_vcl.la + + libvppcom_la_SOURCES = + libvcl_ldpreload_la_SOURCES = ++libdmm_vcl_la_SOURCES = + libvppcom_la_DEPENDENCIES = \ + libsvm.la \ + libvlibmemoryclient.la ++libdmm_vcl_la_DEPENDENCIES = \ ++ libsvm.la \ ++ libvlibmemoryclient.la \ ++ libvcl_ldpreload.la + + libvppcom_la_LIBADD = $(libvppcom_la_DEPENDENCIES) -lpthread -lrt -ldl + +@@ -40,12 +45,20 @@ libvcl_ldpreload_la_SOURCES += \ + vcl/ldp.c \ + $(libvppcom_la_SOURCES) + ++libdmm_vcl_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/../../../../release/include ++ ++libdmm_vcl_la_LIBADD = $(libdmm_vcl_la_DEPENDENCIES) -lpthread -lrt -ldl ++ ++libdmm_vcl_la_SOURCES += \ ++ vcl/dmm_vcl_adpt.c \ ++ $(libvcl_ldpreload_la_SOURCES) ++ + nobase_include_HEADERS += \ + vcl/ldp_socket_wrapper.h \ + vcl/ldp_glibc_socket.h \ + vcl/ldp.h + +-noinst_PROGRAMS += \ ++bin_PROGRAMS += \ + vcl_test_server \ + vcl_test_client \ + sock_test_server \ +diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c +index d31cd2c..e386855 100644 +--- a/src/vcl/ldp.c ++++ b/src/vcl/ldp.c +@@ -1669,7 +1669,7 @@ send (int fd, const void *buf, size_t n, int flags) + getpid (), fd, fd, func_str, sid, sid, buf, n, flags); + + size = vppcom_session_sendto (sid, (void *) buf, n, flags, NULL); +- if (size != VPPCOM_OK) ++ if (size <= VPPCOM_OK) + { + errno = -size; + size = -1; +-- +1.8.3.1 + diff --git a/stacks/vpp/patch/0002-Fix-fix-epoll-problem.patch b/stacks/vpp/patch/0002-Fix-fix-epoll-problem.patch new file mode 100644 index 0000000..7975e27 --- /dev/null +++ b/stacks/vpp/patch/0002-Fix-fix-epoll-problem.patch @@ -0,0 +1,62 @@ +From bdb9568fe64c6bdfde17f61dac57a7f54214912c Mon Sep 17 00:00:00 2001 +From: Jiang Wenjiang <jiangwenjiang@huawei.com> +Date: Mon, 10 Sep 2018 03:01:41 +0800 +Subject: [PATCH] Fix: fix epoll problem + +The same fd can add to different epoll. +--- + src/vcl/vppcom.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c +index cab2f60..9cb52cb 100644 +--- a/src/vcl/vppcom.c ++++ b/src/vcl/vppcom.c +@@ -162,6 +162,7 @@ typedef struct + u64 options[16]; + elog_track_t elog_track; + vce_event_handler_reg_t *poll_reg; ++ u32 ep_count; //the count that add to epoll + } session_t; + + typedef struct vppcom_cfg_t_ +@@ -3430,6 +3431,7 @@ vppcom_session_write_ready (session_t * session, u32 session_index) + + if (PREDICT_FALSE (session->state & STATE_LISTEN)) + { ++ return 0; + clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: " + "cannot write to a listen session!", + getpid (), session->vpp_handle, session_index); +@@ -3802,6 +3804,7 @@ vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index, + session_t *vep_session; + session_t *session; + int rv; ++ int ep_cnt = 0; + + if (vep_idx == session_index) + { +@@ -3846,6 +3849,9 @@ vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index, + switch (op) + { + case EPOLL_CTL_ADD: ++ ep_cnt = __sync_add_and_fetch (&(session->ep_count), 1); ++ if (ep_cnt != 1) ++ break; + if (PREDICT_FALSE (!event)) + { + clib_warning ("VCL<%d>: ERROR: EPOLL_CTL_ADD: NULL pointer to " +@@ -3950,6 +3956,10 @@ vppcom_epoll_ctl (uint32_t vep_idx, int op, uint32_t session_index, + break; + + case EPOLL_CTL_DEL: ++ ep_cnt = __sync_sub_and_fetch (&(session->ep_count), 1); ++ if (ep_cnt != 0) ++ break; ++ + if (PREDICT_FALSE (!session->is_vep_session)) + { + clib_warning ("VCL<%d>: ERROR: sid %u EPOLL_CTL_DEL: " +-- +1.8.3.1 + diff --git a/stacks/vpp/vagrant/Vagrantfile b/stacks/vpp/vagrant/Vagrantfile new file mode 100644 index 0000000..5cf102c --- /dev/null +++ b/stacks/vpp/vagrant/Vagrantfile @@ -0,0 +1,63 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + + # Pick the right distro and bootstrap, default is ubuntu1604 + distro = ( ENV['DMM_VAGRANT_DISTRO'] || "ubuntu") + if distro == 'centos7' + config.vm.box = "puppetlabs/centos-7.2-64-nocm" + else + config.vm.box = "puppetlabs/ubuntu-16.04-64-nocm" + end + config.vm.box_check_update = false + + # Create DMM client and server VM's + config.vm.define "dmm-vpp-server" do |server| + server.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"install_prereq.sh") + server.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"build.sh"), :args => "/dmm vagrant" + end + config.vm.define "dmm-vpp-client" do |client| + client.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"install_prereq.sh") + client.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"build.sh"), :args => "/dmm vagrant" + end + + + # vagrant-cachier caches apt/yum etc to speed subsequent + # vagrant up + # to enable, run + # vagrant plugin install vagrant-cachier + # + if Vagrant.has_plugin?("vagrant-cachier") + config.cache.scope = :box + end + + # Define some physical ports for your VMs to be used by DPDK + nics = (ENV['DMM_VAGRANT_NICS'] || "2").to_i(10) + for i in 1..nics + config.vm.network "private_network", type: "dhcp" + # config.vm.network "private_network", ip: "172.28.128.200" + # config.vm.network "private_network", ip: "172.28.128.201" + end + + # use http proxy if avaiable + if ENV['http_proxy'] && Vagrant.has_plugin?("vagrant-proxyconf") + config.proxy.http = ENV['http_proxy'] + config.proxy.https = ENV['https_proxy'] + config.proxy.no_proxy = "localhost,127.0.0.1" + end + + vmcpu=(ENV['DMM_VAGRANT_VMCPU'] || 4) + vmram=(ENV['DMM_VAGRANT_VMRAM'] || 5120) + + config.ssh.forward_agent = true + config.ssh.forward_x11 = true + + config.vm.provider "virtualbox" do |vb| + vb.customize ["modifyvm", :id, "--ioapic", "on"] + vb.memory = "#{vmram}" + vb.cpus = "#{vmcpu}" + + config.vm.synced_folder "../../../", "/dmm", type: "rsync" + end +end diff --git a/stacks/vpp/vagrant/build.sh b/stacks/vpp/vagrant/build.sh new file mode 100644 index 0000000..1ed343b --- /dev/null +++ b/stacks/vpp/vagrant/build.sh @@ -0,0 +1,224 @@ +#!/bin/bash -x +######################################################################### +# 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 -x + +TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) +log_file="/tmp/build_log.txt-$TIMESTAMP" +exec 1> >(tee -a "$log_file") 2>&1 + +# Get Command Line arguements if present +TEMP_DIR=$1 +if [ "x$1" != "x" ]; then + TEMP_DIR=$1 + DMM_BUILD_DIR=${TEMP_DIR}/build + DPDK_BUILD_SCRIPT_DIR=${DMM_BUILD_DIR}/../scripts + VPP_BUILD_DIR=${TEMP_DIR}/stacks/vpp/vpp/ +else + TEMP_DIR=`dirname $(readlink -f $0)`/.. + DMM_BUILD_DIR=${TEMP_DIR}/../../build + DPDK_BUILD_SCRIPT_DIR=${DMM_BUILD_DIR}/../scripts + VPP_BUILD_DIR=${TEMP_DIR} +fi + +echo 0:$0 +echo 1:$1 +echo 2:$2 +echo TEMP_DIR: $TEMP_DIR +echo DMM_BUILD_DIR: $DMM_BUILD_DIR +echo DPDK_BUILD_SCRIPT_DIR: $DPDK_BUILD_SCRIPT_DIR +echo VPP_BUILD_DIR: $VPP_BUILD_DIR + +OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +OS_VERSION_ID=$(grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +KERNEL_OS=`uname -o` +KERNEL_MACHINE=`uname -m` +KERNEL_RELEASE=`uname -r` +KERNEL_VERSION=`uname -v` + +echo KERNEL_OS: $KERNEL_OS +echo KERNEL_MACHINE: $KERNEL_MACHINE +echo KERNEL_RELEASE: $KERNEL_RELEASE +echo KERNEL_VERSION: $KERNEL_VERSION +echo OS_ID: $OS_ID +echo OS_VERSION_ID: $OS_ID + +#DPDK download path +DPDK_DOWNLOAD_PATH=/tmp/dpdk + +#dpdk installation path +DPDK_INSTALL_PATH=/usr + +#set and check the environment for Linux +if [ "$OS_ID" == "ubuntu" ]; then + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + + APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" + sudo apt-get update ${APT_OPTS} + sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim ethtool unzip +elif [ "$OS_ID" == "debian" ]; then + echo "not tested for debian and exit" + exit 1 + export DEBIAN_FRONTEND=noninteractive + export DEBCONF_NONINTERACTIVE_SEEN=true + + APT_OPTS="--assume-yes --no-install-suggests --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" + sudo apt-get update ${APT_OPTS} + sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev vim +elif [ "$OS_ID" == "centos" ]; then + sudo yum install -y git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel +elif [ "$OS_ID" == "opensuse" ]; then + echo "not tested for opensuse and exit" + exit 1 + sudo yum install -y git cmake gcc g++ automake libtool wget lsof lshw pciutils net-tools tcpdump vim sudo yum-utils pcre-devel zlib-devel +fi + +#DPDK will be having dependancy on linux headers +if [ "$OS_ID" == "ubuntu" ]; then + sudo apt-get -y install git build-essential linux-headers-`uname -r` + sudo apt-get -y install libnuma-dev +elif [ "$OS_ID" == "debian" ]; then + sudo apt-get -y install git build-essential linux-headers-`uname -r` +elif [ "$OS_ID" == "centos" ]; then + sudo yum groupinstall -y "Development Tools" + sudo yum install -y kernel-headers + sudo yum install -y numactl-devel +elif [ "$OS_ID" == "opensuse" ]; then + sudo yum groupinstall -y "Development Tools" + sudo yum install -y kernel-headers +fi +#===========build DPDK================ + +if [ ! -d /usr/include/dpdk ] || [ ! -d /usr/share/dpdk ] || [ ! -d /usr/lib/modules/4.4.0-31-generic/extra/dpdk ]; then + mkdir -p $DPDK_DOWNLOAD_PATH + + cd $DPDK_DOWNLOAD_PATH + wget -N https://fast.dpdk.org/rel/dpdk-18.02.tar.xz --no-check-certificate + tar xvf dpdk-18.02.tar.xz + cd dpdk-18.02/ + + + sed -i 's!CONFIG_RTE_EXEC_ENV=.*!CONFIG_RTE_EXEC_ENV=y!1' config/common_base + sed -i 's!CONFIG_RTE_BUILD_SHARED_LIB=.*!CONFIG_RTE_BUILD_SHARED_LIB=y!1' config/common_base + sed -i 's!CONFIG_RTE_LIBRTE_EAL=.*!CONFIG_RTE_LIBRTE_EAL=y!1' config/common_base + sed -i 's!CONFIG_RTE_EAL_PMD_PATH=.*!CONFIG_RTE_EAL_PMD_PATH="/tmp/dpdk/drivers/"!1' config/common_base + + sudo make install T=x86_64-native-linuxapp-gcc DESTDIR=${DPDK_INSTALL_PATH} -j 4 + + mkdir -p /tmp/dpdk/drivers/ + cp -f /usr/lib/librte_mempool_ring.so /tmp/dpdk/drivers/ +fi + +#===========check running env ================= +hugepagesize=$(cat /proc/meminfo | grep Hugepagesize | awk -F " " {'print$2'}) +if [ "$hugepagesize" == "2048" ]; then + pages=2560 +elif [ "$hugepagesize" == "1048576" ]; then + pages=5 +fi +sudo sysctl -w vm.nr_hugepages=$pages +HUGEPAGES=`sysctl -n vm.nr_hugepages` +if [ $HUGEPAGES != $pages ]; then + echo "ERROR: Unable to get $pages hugepages, only got $HUGEPAGES. Cannot finish." + exit +fi + + +hugepageTotal=$(cat /proc/meminfo | grep -c "HugePages_Total: 0") +if [ $hugepageTotal -ne 0 ]; then + echo "HugePages_Total is zero" + exit +fi + +hugepageFree=$(cat /proc/meminfo | grep -c "HugePages_Free: 0") +if [ $hugepageFree -ne 0 ]; then + echo "HugePages_Free is zero" + exit +fi + +hugepageSize=$(cat /proc/meminfo | grep -c "Hugepagesize: 0 kB") +if [ $hugepageSize -ne 0 ]; then + echo "Hugepagesize is zero" + exit +fi + + +sudo mkdir /mnt/nstackhuge -p +if [ "$hugepagesize" == "2048" ]; then +sudo mount -t hugetlbfs -o pagesize=2M none /mnt/nstackhuge/ +elif [ "$hugepagesize" == "1048576" ]; then + sudo mount -t hugetlbfs -o pagesize=1G none /mnt/nstackhuge/ +fi + +#===========build DMM================= +echo "DMM build started....." + +cd $DMM_BUILD_DIR +ldconfig +rm -rf * +cmake .. +make -j 8 +if [ $? -eq 0 ]; then + echo "DMM build is SUCCESS" +else + echo "DMM build has FAILED" + exit 1 +fi +echo "DMM build finished....." + +git config --global http.sslVerify false +#===========build vpp=========== +echo "vpp build started....." +make vpp-stack +if [ $? -eq 0 ]; then + echo "vpp build is SUCCESS" +else + echo "vpp build has FAILED" + exit 1 +fi +echo "vpp build finished....." + +#===========set environment=========== +sudo mkdir -p /etc/vpp/ +cp /dmm/stacks/vpp/configure/startup.conf /etc/vpp/ +cp /dmm/stacks/vpp/configure/vpp_config /etc/vpp/ + +sudo cp -r /dmm/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_plugins/ /usr/lib/ + +sudo modprobe uio +sudo insmod ${DPDK_DOWNLOAD_PATH}/dpdk-18.02/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko + +sudo ifconfig enp0s9 down + +if [ "$OS_ID" == "centos" ]; then + ifaddress1=$(ifconfig enp0s9 | grep 'inet' | cut -d: -f2 | awk '{print $2}') + echo $ifaddress1 + ifaddresscut=$(ifconfig enp0s9 | grep 'inet' | head -n 1 | awk -F " " '{print $2}' | awk -F "." '{print $1"."$2"."$3}') + echo $ifaddresscut +elif [ "$OS_ID" == "ubuntu" ]; then + ifaddress1=$(ifconfig enp0s9 | grep 'inet' | head -n 1 | cut -d: -f2 | awk '{print $1}') + echo $ifaddress1 +fi + +cd /etc/vpp/ + +sudo sed -i 's!192.168.1.1!'$ifaddress1'!1' vpp_config + +cd $DMM_BUILD_DIR/../release/bin +sudo cp ../../stacks/vpp/configure/*.json ./ +sudo cp ../../stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib64/libdmm_vcl.so ../lib64/ +sudo sed -i 's!192.168.1.1!'$ifaddresscut'.0!1' rd_config.json diff --git a/stacks/vpp/vagrant/env.sh b/stacks/vpp/vagrant/env.sh new file mode 100644 index 0000000..96ad346 --- /dev/null +++ b/stacks/vpp/vagrant/env.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +#export DMM_VAGRANT_DISTRO="ubuntu1604" +export DMM_VAGRANT_DISTRO="centos7" +export DMM_VAGRANT_NICS=2 +export DMM_VAGRANT_VMCPU=4 +export DMM_VAGRANT_VMRAM=8192 diff --git a/stacks/vpp/vagrant/install_prereq.sh b/stacks/vpp/vagrant/install_prereq.sh new file mode 100644 index 0000000..2e636c2 --- /dev/null +++ b/stacks/vpp/vagrant/install_prereq.sh @@ -0,0 +1,39 @@ +#!/bin/bash -x +log_file="/tmp/pre_install_log.txt-`date +'%Y-%m-%d_%H-%M-%S'`" +exec 1> >(tee -a "$log_file") 2>&1 + +if [ "$(uname)" <> "Darwin" ]; then + OS_ID=$(grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') + OS_VERSION_ID=$(grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g') +fi + +if [ "$OS_ID" == "ubuntu" ]; then + # Standard update + upgrade dance + cat << EOF >> /etc/apt/sources.list + deb http://in.archive.ubuntu.com/ubuntu/ trusty main restricted + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty main restricted + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates main restricted + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates main restricted + deb http://in.archive.ubuntu.com/ubuntu/ trusty universe + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty universe + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates universe + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates universe + deb http://in.archive.ubuntu.com/ubuntu/ trusty multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty multiverse + deb http://in.archive.ubuntu.com/ubuntu/ trusty-updates multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-updates multiverse + deb http://in.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse + deb-src http://in.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse + deb http://security.ubuntu.com/ubuntu trusty-security main restricted + deb-src http://security.ubuntu.com/ubuntu trusty-security main restricted + deb http://security.ubuntu.com/ubuntu trusty-security universe + deb-src http://security.ubuntu.com/ubuntu trusty-security universe + deb http://security.ubuntu.com/ubuntu trusty-security multiverse + deb-src http://security.ubuntu.com/ubuntu trusty-security multiverse + deb http://extras.ubuntu.com/ubuntu trusty main + deb-src http://extras.ubuntu.com/ubuntu trusty main +EOF +elif [ "$OS_ID" == "centos" ]; then + + echo centos +fi diff --git a/thirdparty/apps/CMakeLists.txt b/thirdparty/apps/CMakeLists.txt index de58120..2cf5240 100644 --- a/thirdparty/apps/CMakeLists.txt +++ b/thirdparty/apps/CMakeLists.txt @@ -1,3 +1,19 @@ +######################################################################### +# +# 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. +######################################################################### + LINK_DIRECTORIES(${LIB_PATH_SHARED}) SET(NGINX_URL http://nginx.org/download/nginx-1.12.2.tar.gz) SET(NGINX_DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR}/nginx/) @@ -10,7 +26,7 @@ else() SET(NGINX_DOWNLOAD_CMD wget --no-check-certificate -O nginx-1.12.2.tar.gz ${NGINX_URL} && tar -xvf ${NGINX_DOWNLOAD_DIR}/nginx-1.12.2.tar.gz -C ${NGINX_DOWNLOAD_DIR}/nginx-1.12.2 --strip-components 1) endif() -INCLUDE(ExternalProject) +INCLUDE(ExternalProject) ExternalProject_Add( NGINX URL ${NGINX_URL} @@ -19,10 +35,44 @@ ExternalProject_Add( BUILD_IN_SOURCE 1 SOURCE_DIR ${NGINX_SRC} PATCH_COMMAND echo "./configure --with-ld-opt=\"-L${LIB_PATH_SHARED}/ -lnStackAPI -Wl,-rpath=${LIB_PATH_SHARED}\" --sbin-path=${NGINX_RELEASE}/nginx --conf-path=${NGINX_RELEASE}/nginx.conf --pid-path=${NGINX_RELEASE}/nginx.pid " > configure.sh + COMMAND sed -i -e "48,49 s/^/#/" ${CMAKE_CURRENT_LIST_DIR}/nginx/nginx-1.12.2/auto/os/linux CONFIGURE_COMMAND sh configure.sh - BUILD_COMMAND make + BUILD_COMMAND make INSTALL_COMMAND make install DEPENDS nStackAPI ) set_target_properties(NGINX PROPERTIES EXCLUDE_FROM_ALL TRUE) + + +SET(IPERF_URL https://iperf.fr/download/source/iperf-3.1.3-source.tar.gz) + +INCLUDE(ExternalProject) +ExternalProject_Add( + IPERF + URL ${IPERF_URL} + DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/iperf-3.1.3 + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND sh -c "LDFLAGS=\"-L${LIB_PATH_SHARED} -Wl,-rpath=${LIB_PATH_SHARED} -lnStackAPI\" ./configure" + BUILD_COMMAND make + DEPENDS nStackAPI +) + +set_target_properties(IPERF PROPERTIES EXCLUDE_FROM_ALL TRUE) + +SET(NETPERF_URL https://github.com/HewlettPackard/netperf/archive/netperf-2.7.0.tar.gz) + +INCLUDE(ExternalProject) +ExternalProject_Add( + NETPERF + URL ${NETPERF_URL} + DOWNLOAD_DIR ${CMAKE_CURRENT_LIST_DIR} + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/netperf-2.7.0 + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND sh -c "LDFLAGS=\"-L${LIB_PATH_SHARED} -Wl,-rpath=${LIB_PATH_SHARED} -lnStackAPI\" ./configure" + BUILD_COMMAND make + DEPENDS nStackAPI +) + +set_target_properties(NETPERF PROPERTIES EXCLUDE_FROM_ALL TRUE) diff --git a/thirdparty/glog/glog-0.3.4/INSTALL b/thirdparty/glog/glog-0.3.4/INSTALL deleted file mode 100644 index 0babe24..0000000 --- a/thirdparty/glog/glog-0.3.4/INSTALL +++ /dev/null @@ -1,297 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Glog-Specific Install Notes -================================ - -*** NOTE FOR 64-BIT LINUX SYSTEMS - -The glibc built-in stack-unwinder on 64-bit systems has some problems -with the glog libraries. (In particular, if you are using -InstallFailureSignalHandler(), the signal may be raised in the middle -of malloc, holding some malloc-related locks when they invoke the -stack unwinder. The built-in stack unwinder may call malloc -recursively, which may require the thread to acquire a lock it already -holds: deadlock.) - -For that reason, if you use a 64-bit system and you need -InstallFailureSignalHandler(), we strongly recommend you install -libunwind before trying to configure or install google glog. -libunwind can be found at - - http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz - -Even if you already have libunwind installed, you will probably still -need to install from the snapshot to get the latest version. - -CAUTION: if you install libunwind from the URL above, be aware that -you may have trouble if you try to statically link your binary with -glog: that is, if you link with 'gcc -static -lgcc_eh ...'. This -is because both libunwind and libgcc implement the same C++ exception -handling APIs, but they implement them differently on some platforms. -This is not likely to be a problem on ia64, but may be on x86-64. - -Also, if you link binaries statically, make sure that you add --Wl,--eh-frame-hdr to your linker options. This is required so that -libunwind can find the information generated by the compiler required -for stack unwinding. - -Using -static is rare, though, so unless you know this will affect you -it probably won't. - -If you cannot or do not wish to install libunwind, you can still try -to use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder -and 2. frame pointer based stack-unwinder. - -1. As we already mentioned, glibc's unwinder has a deadlock issue. -However, if you don't use InstallFailureSignalHandler() or you don't -worry about the rare possibilities of deadlocks, you can use this -stack-unwinder. If you specify no options and libunwind isn't -detected on your system, the configure script chooses this unwinder by -default. - -2. The frame pointer based stack unwinder requires that your -application, the glog library, and system libraries like libc, all be -compiled with a frame pointer. This is *not* the default for x86-64. - -If you are on x86-64 system, know that you have a set of system -libraries with frame-pointers enabled, and compile all your -applications with -fno-omit-frame-pointer, then you can enable the -frame pointer based stack unwinder by passing the ---enable-frame-pointers flag to configure. - - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 6. Often, you can also type `make uninstall' to remove the installed - files again. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/thirdparty/glog/glog-0.3.4/Makefile.in b/thirdparty/glog/glog-0.3.4/Makefile.in deleted file mode 100644 index 82a7c1e..0000000 --- a/thirdparty/glog/glog-0.3.4/Makefile.in +++ /dev/null @@ -1,2080 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ - -# These are good warnings to turn on by default -@GCC_TRUE@am__append_1 = -g -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -Wno-deprecated \ -@GCC_TRUE@ -fstack-protector -Wl,-z,relro -Wl,--disable-new-dtags \ -@GCC_TRUE@ -Wl,-z,noexecstack -fPIC -D_FORTIFY_SOURCE=2 -O2 -z,now -Wformat=2 -Wfloat-equal -Wshadow - - -# These are x86-specific, having to do with frame-pointers -@ENABLE_FRAME_POINTERS_TRUE@@X86_64_TRUE@am__append_2 = -fno-omit-frame-pointer -@ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@am__append_3 = -DNO_FRAME_POINTER -@DISABLE_RTTI_TRUE@am__append_4 = -fno-rtti -TESTS = logging_unittest$(EXEEXT) demangle_unittest$(EXEEXT) \ - stacktrace_unittest$(EXEEXT) symbolize_unittest$(EXEEXT) \ - stl_logging_unittest$(EXEEXT) utilities_unittest$(EXEEXT) \ - $(am__EXEEXT_1) -@HAVE_GMOCK_TRUE@am__append_5 = mock_log_test -noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) -subdir = . -DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ - $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(top_srcdir)/src/config.h.in mkinstalldirs \ - $(top_srcdir)/src/glog/logging.h.in \ - $(top_srcdir)/src/glog/raw_logging.h.in \ - $(top_srcdir)/src/glog/vlog_is_on.h.in \ - $(top_srcdir)/src/glog/stl_logging.h.in \ - $(srcdir)/libglog.pc.in depcomp $(dist_doc_DATA) \ - $(gloginclude_HEADERS) $(noinst_HEADERS) test-driver COPYING \ - compile config.guess config.sub install-sh missing ltmain.sh -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ac_have_attribute.m4 \ - $(top_srcdir)/m4/ac_have_builtin_expect.m4 \ - $(top_srcdir)/m4/ac_have_sync_val_compare_and_swap.m4 \ - $(top_srcdir)/m4/ac_rwlock.m4 $(top_srcdir)/m4/acx_pthread.m4 \ - $(top_srcdir)/m4/google_namespace.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/namespaces.m4 \ - $(top_srcdir)/m4/pc_from_ucontext.m4 \ - $(top_srcdir)/m4/stl_namespace.m4 \ - $(top_srcdir)/m4/using_operator.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = src/glog/logging.h src/glog/raw_logging.h \ - src/glog/vlog_is_on.h src/glog/stl_logging.h libglog.pc -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(glogincludedir)" \ - "$(DESTDIR)$(glogincludedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -libglog_la_DEPENDENCIES = $(am__DEPENDENCIES_2) -am__objects_1 = -am__dirstamp = $(am__leading_dot)dirstamp -am_libglog_la_OBJECTS = $(am__objects_1) src/libglog_la-logging.lo \ - src/libglog_la-raw_logging.lo src/libglog_la-vlog_is_on.lo \ - src/libglog_la-utilities.lo src/libglog_la-demangle.lo \ - src/libglog_la-symbolize.lo src/libglog_la-signalhandler.lo \ - src/libglog_la-nstack_logging.lo -nodist_libglog_la_OBJECTS = $(am__objects_1) -libglog_la_OBJECTS = $(am_libglog_la_OBJECTS) \ - $(nodist_libglog_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libglog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libglog_la_CXXFLAGS) \ - $(CXXFLAGS) $(libglog_la_LDFLAGS) $(LDFLAGS) -o $@ -@HAVE_GMOCK_TRUE@am__EXEEXT_1 = mock_log_test$(EXEEXT) -am__EXEEXT_2 = logging_unittest$(EXEEXT) demangle_unittest$(EXEEXT) \ - stacktrace_unittest$(EXEEXT) symbolize_unittest$(EXEEXT) \ - stl_logging_unittest$(EXEEXT) utilities_unittest$(EXEEXT) \ - $(am__EXEEXT_1) -am__EXEEXT_3 = logging_striptest0$(EXEEXT) logging_striptest2$(EXEEXT) \ - logging_striptest10$(EXEEXT) signalhandler_unittest$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) -am_demangle_unittest_OBJECTS = $(am__objects_1) \ - src/demangle_unittest-demangle_unittest.$(OBJEXT) -nodist_demangle_unittest_OBJECTS = $(am__objects_1) -demangle_unittest_OBJECTS = $(am_demangle_unittest_OBJECTS) \ - $(nodist_demangle_unittest_OBJECTS) -demangle_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -demangle_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(demangle_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(demangle_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am_logging_striptest0_OBJECTS = $(am__objects_1) \ - src/logging_striptest0-logging_striptest_main.$(OBJEXT) -nodist_logging_striptest0_OBJECTS = $(am__objects_1) -logging_striptest0_OBJECTS = $(am_logging_striptest0_OBJECTS) \ - $(nodist_logging_striptest0_OBJECTS) -logging_striptest0_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) -logging_striptest0_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(logging_striptest0_CXXFLAGS) $(CXXFLAGS) \ - $(logging_striptest0_LDFLAGS) $(LDFLAGS) -o $@ -am_logging_striptest10_OBJECTS = $(am__objects_1) \ - src/logging_striptest10-logging_striptest10.$(OBJEXT) -nodist_logging_striptest10_OBJECTS = $(am__objects_1) -logging_striptest10_OBJECTS = $(am_logging_striptest10_OBJECTS) \ - $(nodist_logging_striptest10_OBJECTS) -logging_striptest10_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) -logging_striptest10_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(logging_striptest10_CXXFLAGS) $(CXXFLAGS) \ - $(logging_striptest10_LDFLAGS) $(LDFLAGS) -o $@ -am_logging_striptest2_OBJECTS = $(am__objects_1) \ - src/logging_striptest2-logging_striptest2.$(OBJEXT) -nodist_logging_striptest2_OBJECTS = $(am__objects_1) -logging_striptest2_OBJECTS = $(am_logging_striptest2_OBJECTS) \ - $(nodist_logging_striptest2_OBJECTS) -logging_striptest2_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) -logging_striptest2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(logging_striptest2_CXXFLAGS) $(CXXFLAGS) \ - $(logging_striptest2_LDFLAGS) $(LDFLAGS) -o $@ -am_logging_unittest_OBJECTS = $(am__objects_1) \ - src/logging_unittest-logging_unittest.$(OBJEXT) -nodist_logging_unittest_OBJECTS = $(am__objects_1) -logging_unittest_OBJECTS = $(am_logging_unittest_OBJECTS) \ - $(nodist_logging_unittest_OBJECTS) -logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -logging_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(logging_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(logging_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am__mock_log_test_SOURCES_DIST = src/glog/log_severity.h \ - src/mock-log_test.cc -@HAVE_GMOCK_TRUE@am_mock_log_test_OBJECTS = $(am__objects_1) \ -@HAVE_GMOCK_TRUE@ src/mock_log_test-mock-log_test.$(OBJEXT) -@HAVE_GMOCK_TRUE@nodist_mock_log_test_OBJECTS = $(am__objects_1) -mock_log_test_OBJECTS = $(am_mock_log_test_OBJECTS) \ - $(nodist_mock_log_test_OBJECTS) -@HAVE_GMOCK_TRUE@mock_log_test_DEPENDENCIES = libglog.la \ -@HAVE_GMOCK_TRUE@ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2) -mock_log_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(mock_log_test_CXXFLAGS) $(CXXFLAGS) $(mock_log_test_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_signalhandler_unittest_OBJECTS = $(am__objects_1) \ - src/signalhandler_unittest-signalhandler_unittest.$(OBJEXT) -nodist_signalhandler_unittest_OBJECTS = $(am__objects_1) -signalhandler_unittest_OBJECTS = $(am_signalhandler_unittest_OBJECTS) \ - $(nodist_signalhandler_unittest_OBJECTS) -signalhandler_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -signalhandler_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(signalhandler_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am_stacktrace_unittest_OBJECTS = $(am__objects_1) \ - src/stacktrace_unittest-stacktrace_unittest.$(OBJEXT) -nodist_stacktrace_unittest_OBJECTS = $(am__objects_1) -stacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS) \ - $(nodist_stacktrace_unittest_OBJECTS) -stacktrace_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) -stacktrace_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(stacktrace_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am_stl_logging_unittest_OBJECTS = $(am__objects_1) \ - src/stl_logging_unittest-stl_logging_unittest.$(OBJEXT) -nodist_stl_logging_unittest_OBJECTS = $(am__objects_1) -stl_logging_unittest_OBJECTS = $(am_stl_logging_unittest_OBJECTS) \ - $(nodist_stl_logging_unittest_OBJECTS) -stl_logging_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -stl_logging_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(stl_logging_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am_symbolize_unittest_OBJECTS = $(am__objects_1) \ - src/symbolize_unittest-symbolize_unittest.$(OBJEXT) -nodist_symbolize_unittest_OBJECTS = $(am__objects_1) -symbolize_unittest_OBJECTS = $(am_symbolize_unittest_OBJECTS) \ - $(nodist_symbolize_unittest_OBJECTS) -symbolize_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -symbolize_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(symbolize_unittest_LDFLAGS) $(LDFLAGS) -o $@ -am_utilities_unittest_OBJECTS = $(am__objects_1) \ - src/utilities_unittest-utilities_unittest.$(OBJEXT) -nodist_utilities_unittest_OBJECTS = $(am__objects_1) -utilities_unittest_OBJECTS = $(am_utilities_unittest_OBJECTS) \ - $(nodist_utilities_unittest_OBJECTS) -utilities_unittest_DEPENDENCIES = libglog.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_2) -utilities_unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) \ - $(utilities_unittest_LDFLAGS) $(LDFLAGS) -o $@ -SCRIPTS = $(noinst_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libglog_la_SOURCES) $(nodist_libglog_la_SOURCES) \ - $(demangle_unittest_SOURCES) \ - $(nodist_demangle_unittest_SOURCES) \ - $(logging_striptest0_SOURCES) \ - $(nodist_logging_striptest0_SOURCES) \ - $(logging_striptest10_SOURCES) \ - $(nodist_logging_striptest10_SOURCES) \ - $(logging_striptest2_SOURCES) \ - $(nodist_logging_striptest2_SOURCES) \ - $(logging_unittest_SOURCES) $(nodist_logging_unittest_SOURCES) \ - $(mock_log_test_SOURCES) $(nodist_mock_log_test_SOURCES) \ - $(signalhandler_unittest_SOURCES) \ - $(nodist_signalhandler_unittest_SOURCES) \ - $(stacktrace_unittest_SOURCES) \ - $(nodist_stacktrace_unittest_SOURCES) \ - $(stl_logging_unittest_SOURCES) \ - $(nodist_stl_logging_unittest_SOURCES) \ - $(symbolize_unittest_SOURCES) \ - $(nodist_symbolize_unittest_SOURCES) \ - $(utilities_unittest_SOURCES) \ - $(nodist_utilities_unittest_SOURCES) -DIST_SOURCES = $(libglog_la_SOURCES) $(demangle_unittest_SOURCES) \ - $(logging_striptest0_SOURCES) $(logging_striptest10_SOURCES) \ - $(logging_striptest2_SOURCES) $(logging_unittest_SOURCES) \ - $(am__mock_log_test_SOURCES_DIST) \ - $(signalhandler_unittest_SOURCES) \ - $(stacktrace_unittest_SOURCES) $(stl_logging_unittest_SOURCES) \ - $(symbolize_unittest_SOURCES) $(utilities_unittest_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(dist_doc_DATA) $(pkgconfig_DATA) -HEADERS = $(gloginclude_HEADERS) $(nodist_gloginclude_HEADERS) \ - $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope check recheck -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver -LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GFLAGS_CFLAGS = @GFLAGS_CFLAGS@ -GFLAGS_LIBS = @GFLAGS_LIBS@ -GMOCK_CFLAGS = @GMOCK_CFLAGS@ -GMOCK_CONFIG = @GMOCK_CONFIG@ -GMOCK_LIBS = @GMOCK_LIBS@ -GREP = @GREP@ -GTEST_CFLAGS = @GTEST_CFLAGS@ -GTEST_CONFIG = @GTEST_CONFIG@ -GTEST_LIBS = @GTEST_LIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MINGW_CFLAGS = @MINGW_CFLAGS@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -UNWIND_LIBS = @UNWIND_LIBS@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -ac_cv___attribute___noinline = @ac_cv___attribute___noinline@ -ac_cv___attribute___noreturn = @ac_cv___attribute___noreturn@ -ac_cv___attribute___printf_4_5 = @ac_cv___attribute___printf_4_5@ -ac_cv_cxx_using_operator = @ac_cv_cxx_using_operator@ -ac_cv_have___builtin_expect = @ac_cv_have___builtin_expect@ -ac_cv_have___uint16 = @ac_cv_have___uint16@ -ac_cv_have_inttypes_h = @ac_cv_have_inttypes_h@ -ac_cv_have_libgflags = @ac_cv_have_libgflags@ -ac_cv_have_stdint_h = @ac_cv_have_stdint_h@ -ac_cv_have_systypes_h = @ac_cv_have_systypes_h@ -ac_cv_have_u_int16_t = @ac_cv_have_u_int16_t@ -ac_cv_have_uint16_t = @ac_cv_have_uint16_t@ -ac_cv_have_unistd_h = @ac_cv_have_unistd_h@ -ac_google_end_namespace = @ac_google_end_namespace@ -ac_google_namespace = @ac_google_namespace@ -ac_google_start_namespace = @ac_google_start_namespace@ -acx_pthread_config = @acx_pthread_config@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION) -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = subdir-objects - -# Make sure that when we re-make ./configure, we get the macros we need -ACLOCAL_AMFLAGS = -I m4 - -# This is so we can #include <glog/foo> -AM_CPPFLAGS = -I$(top_srcdir)/src - -# This is mostly based on configure options -AM_CXXFLAGS = $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) -glogincludedir = $(includedir)/glog -gloginclude_HEADERS = src/glog/log_severity.h -nodist_gloginclude_HEADERS = src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h src/glog/nstack_glog_in.h src/glog/nstack_glog.ph src/glog/nstack_adapter.ph -noinst_HEADERS = src/glog/logging.h.in src/glog/raw_logging.h.in src/glog/vlog_is_on.h.in src/glog/stl_logging.h.in -dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \ - doc/designstyle.css doc/glog.html - -lib_LTLIBRARIES = libglog.la - -# The libraries libglog depends on. -COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS) -# Compile switches for our unittest. -TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) \ - $(MINGW_CFLAGS) $(AM_CXXFLAGS) - -# Libraries for our unittest. -TEST_LIBS = $(GTEST_LIBS) $(GMOCK_LIBS) $(GFLAGS_LIBS) -TESTS_ENVIRONMENT = -check_SCRIPTS = logging_striplog_test_sh demangle_unittest_sh \ - signalhandler_unittest_sh -# Every time you add a unittest to check_SCRIPTS, add it here too -noinst_SCRIPTS = src/logging_striplog_test.sh src/demangle_unittest.sh \ - src/signalhandler_unittest.sh -# Binaries used for script-based unittests. -TEST_BINARIES = logging_striptest0 logging_striptest2 \ - logging_striptest10 signalhandler_unittest -logging_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/logging_unittest.cc \ - src/config_for_unittests.h \ - src/mock-log.h - -nodist_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -logging_striptest0_SOURCES = $(gloginclude_HEADERS) \ - src/logging_striptest_main.cc - -nodist_logging_striptest0_SOURCES = $(nodist_gloginclude_HEADERS) -logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS) -logging_striptest0_LDADD = libglog.la $(COMMON_LIBS) -logging_striptest2_SOURCES = $(gloginclude_HEADERS) \ - src/logging_striptest2.cc - -nodist_logging_striptest2_SOURCES = $(nodist_gloginclude_HEADERS) -logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS) -logging_striptest2_LDADD = libglog.la $(COMMON_LIBS) -logging_striptest10_SOURCES = $(gloginclude_HEADERS) \ - src/logging_striptest10.cc - -nodist_logging_striptest10_SOURCES = $(nodist_gloginclude_HEADERS) -logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS) -logging_striptest10_LDADD = libglog.la $(COMMON_LIBS) -demangle_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/demangle_unittest.cc - -nodist_demangle_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -demangle_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/stacktrace_unittest.cc - -nodist_stacktrace_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS) -symbolize_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/symbolize_unittest.cc - -nodist_symbolize_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/stl_logging_unittest.cc - -nodist_stl_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/signalhandler_unittest.cc - -nodist_signalhandler_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -utilities_unittest_SOURCES = $(gloginclude_HEADERS) \ - src/utilities_unittest.cc - -nodist_utilities_unittest_SOURCES = $(nodist_gloginclude_HEADERS) -utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -@HAVE_GMOCK_TRUE@mock_log_test_SOURCES = $(gloginclude_HEADERS) \ -@HAVE_GMOCK_TRUE@ src/mock-log_test.cc - -@HAVE_GMOCK_TRUE@nodist_mock_log_test_SOURCES = $(nodist_gloginclude_HEADERS) -@HAVE_GMOCK_TRUE@mock_log_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -@HAVE_GMOCK_TRUE@mock_log_test_LDFLAGS = $(PTHREAD_CFLAGS) -@HAVE_GMOCK_TRUE@mock_log_test_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS) -libglog_la_SOURCES = $(gloginclude_HEADERS) \ - src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \ - src/utilities.cc src/utilities.h \ - src/demangle.cc src/demangle.h \ - src/stacktrace.h \ - src/stacktrace_generic-inl.h \ - src/stacktrace_libunwind-inl.h \ - src/stacktrace_powerpc-inl.h \ - src/stacktrace_x86-inl.h \ - src/stacktrace_x86_64-inl.h \ - src/symbolize.cc src/symbolize.h \ - src/signalhandler.cc \ - src/base/mutex.h src/base/googleinit.h \ - src/base/commandlineflags.h src/googletest.h \ - src/nstack_logging.cc src/glog/nstack_glog_in.h src/glog/nstack_glog.ph src/glog/nstack_adapter.ph - -nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS) -libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(MINGW_CFLAGS) \ - $(AM_CXXFLAGS) -DNDEBUG - -libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_LDFLAGS) -libglog_la_LIBADD = $(COMMON_LIBS) -WINDOWS_PROJECTS = google-glog.sln vsprojects/libglog/libglog.vcproj \ - vsprojects/logging_unittest/logging_unittest.vcproj \ - vsprojects/libglog_static/libglog_static.vcproj \ - vsprojects/logging_unittest_static/logging_unittest_static.vcproj -EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec \ - packages/deb.sh packages/deb/* \ - $(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt \ - src/windows/config.h src/windows/port.h src/windows/port.cc \ - src/windows/preprocess.sh \ - src/windows/glog/log_severity.h src/windows/glog/logging.h \ - src/windows/glog/raw_logging.h src/windows/glog/stl_logging.h \ - src/windows/glog/vlog_is_on.h \ - src/glog/nstack_glog_in.h src/glog/nstack_glog.ph src/glog/nstack_adapter.ph \ - $(WINDOWS_PROJECTS) - -CLEANFILES = core demangle.dm demangle.nm signalhandler.out* \ - signalhandler_unittest.*.log.INFO.* - - -# Add pkgconfig file -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libglog.pc -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -src/config.h: src/stamp-h1 - @if test ! -f $@; then rm -f src/stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; else :; fi - -src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status - @rm -f src/stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status src/config.h -$(top_srcdir)/src/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f src/stamp-h1 - touch $@ - -distclean-hdr: - -rm -f src/config.h src/stamp-h1 -src/glog/logging.h: $(top_builddir)/config.status $(top_srcdir)/src/glog/logging.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -src/glog/raw_logging.h: $(top_builddir)/config.status $(top_srcdir)/src/glog/raw_logging.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -src/glog/vlog_is_on.h: $(top_builddir)/config.status $(top_srcdir)/src/glog/vlog_is_on.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -src/glog/stl_logging.h: $(top_builddir)/config.status $(top_srcdir)/src/glog/stl_logging.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -libglog.pc: $(top_builddir)/config.status $(srcdir)/libglog.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -src/$(am__dirstamp): - @$(MKDIR_P) src - @: > src/$(am__dirstamp) -src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/$(DEPDIR) - @: > src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-logging.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-raw_logging.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-vlog_is_on.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-utilities.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-demangle.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-symbolize.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-signalhandler.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) -src/libglog_la-nstack_logging.lo: src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -libglog.la: $(libglog_la_OBJECTS) $(libglog_la_DEPENDENCIES) $(EXTRA_libglog_la_DEPENDENCIES) - $(AM_V_CXXLD)$(libglog_la_LINK) -rpath $(libdir) $(libglog_la_OBJECTS) $(libglog_la_LIBADD) $(LIBS) - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -src/demangle_unittest-demangle_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -demangle_unittest$(EXEEXT): $(demangle_unittest_OBJECTS) $(demangle_unittest_DEPENDENCIES) $(EXTRA_demangle_unittest_DEPENDENCIES) - @rm -f demangle_unittest$(EXEEXT) - $(AM_V_CXXLD)$(demangle_unittest_LINK) $(demangle_unittest_OBJECTS) $(demangle_unittest_LDADD) $(LIBS) -src/logging_striptest0-logging_striptest_main.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -logging_striptest0$(EXEEXT): $(logging_striptest0_OBJECTS) $(logging_striptest0_DEPENDENCIES) $(EXTRA_logging_striptest0_DEPENDENCIES) - @rm -f logging_striptest0$(EXEEXT) - $(AM_V_CXXLD)$(logging_striptest0_LINK) $(logging_striptest0_OBJECTS) $(logging_striptest0_LDADD) $(LIBS) -src/logging_striptest10-logging_striptest10.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -logging_striptest10$(EXEEXT): $(logging_striptest10_OBJECTS) $(logging_striptest10_DEPENDENCIES) $(EXTRA_logging_striptest10_DEPENDENCIES) - @rm -f logging_striptest10$(EXEEXT) - $(AM_V_CXXLD)$(logging_striptest10_LINK) $(logging_striptest10_OBJECTS) $(logging_striptest10_LDADD) $(LIBS) -src/logging_striptest2-logging_striptest2.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -logging_striptest2$(EXEEXT): $(logging_striptest2_OBJECTS) $(logging_striptest2_DEPENDENCIES) $(EXTRA_logging_striptest2_DEPENDENCIES) - @rm -f logging_striptest2$(EXEEXT) - $(AM_V_CXXLD)$(logging_striptest2_LINK) $(logging_striptest2_OBJECTS) $(logging_striptest2_LDADD) $(LIBS) -src/logging_unittest-logging_unittest.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -logging_unittest$(EXEEXT): $(logging_unittest_OBJECTS) $(logging_unittest_DEPENDENCIES) $(EXTRA_logging_unittest_DEPENDENCIES) - @rm -f logging_unittest$(EXEEXT) - $(AM_V_CXXLD)$(logging_unittest_LINK) $(logging_unittest_OBJECTS) $(logging_unittest_LDADD) $(LIBS) -src/mock_log_test-mock-log_test.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) - -mock_log_test$(EXEEXT): $(mock_log_test_OBJECTS) $(mock_log_test_DEPENDENCIES) $(EXTRA_mock_log_test_DEPENDENCIES) - @rm -f mock_log_test$(EXEEXT) - $(AM_V_CXXLD)$(mock_log_test_LINK) $(mock_log_test_OBJECTS) $(mock_log_test_LDADD) $(LIBS) -src/signalhandler_unittest-signalhandler_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -signalhandler_unittest$(EXEEXT): $(signalhandler_unittest_OBJECTS) $(signalhandler_unittest_DEPENDENCIES) $(EXTRA_signalhandler_unittest_DEPENDENCIES) - @rm -f signalhandler_unittest$(EXEEXT) - $(AM_V_CXXLD)$(signalhandler_unittest_LINK) $(signalhandler_unittest_OBJECTS) $(signalhandler_unittest_LDADD) $(LIBS) -src/stacktrace_unittest-stacktrace_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -stacktrace_unittest$(EXEEXT): $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_DEPENDENCIES) $(EXTRA_stacktrace_unittest_DEPENDENCIES) - @rm -f stacktrace_unittest$(EXEEXT) - $(AM_V_CXXLD)$(stacktrace_unittest_LINK) $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_LDADD) $(LIBS) -src/stl_logging_unittest-stl_logging_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -stl_logging_unittest$(EXEEXT): $(stl_logging_unittest_OBJECTS) $(stl_logging_unittest_DEPENDENCIES) $(EXTRA_stl_logging_unittest_DEPENDENCIES) - @rm -f stl_logging_unittest$(EXEEXT) - $(AM_V_CXXLD)$(stl_logging_unittest_LINK) $(stl_logging_unittest_OBJECTS) $(stl_logging_unittest_LDADD) $(LIBS) -src/symbolize_unittest-symbolize_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -symbolize_unittest$(EXEEXT): $(symbolize_unittest_OBJECTS) $(symbolize_unittest_DEPENDENCIES) $(EXTRA_symbolize_unittest_DEPENDENCIES) - @rm -f symbolize_unittest$(EXEEXT) - $(AM_V_CXXLD)$(symbolize_unittest_LINK) $(symbolize_unittest_OBJECTS) $(symbolize_unittest_LDADD) $(LIBS) -src/utilities_unittest-utilities_unittest.$(OBJEXT): \ - src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) - -utilities_unittest$(EXEEXT): $(utilities_unittest_OBJECTS) $(utilities_unittest_DEPENDENCIES) $(EXTRA_utilities_unittest_DEPENDENCIES) - @rm -f utilities_unittest$(EXEEXT) - $(AM_V_CXXLD)$(utilities_unittest_LINK) $(utilities_unittest_OBJECTS) $(utilities_unittest_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f src/*.$(OBJEXT) - -rm -f src/*.lo - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/demangle_unittest-demangle_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-demangle.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-logging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-nstack_logging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-raw_logging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-signalhandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-symbolize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-utilities.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libglog_la-vlog_is_on.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging_striptest10-logging_striptest10.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging_striptest2-logging_striptest2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/logging_unittest-logging_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mock_log_test-mock-log_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/utilities_unittest-utilities_unittest.Po@am__quote@ - -.cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cc.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -src/libglog_la-logging.lo: src/logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-logging.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-logging.Tpo -c -o src/libglog_la-logging.lo `test -f 'src/logging.cc' || echo '$(srcdir)/'`src/logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-logging.Tpo src/$(DEPDIR)/libglog_la-logging.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging.cc' object='src/libglog_la-logging.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-logging.lo `test -f 'src/logging.cc' || echo '$(srcdir)/'`src/logging.cc - -src/libglog_la-raw_logging.lo: src/raw_logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-raw_logging.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-raw_logging.Tpo -c -o src/libglog_la-raw_logging.lo `test -f 'src/raw_logging.cc' || echo '$(srcdir)/'`src/raw_logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-raw_logging.Tpo src/$(DEPDIR)/libglog_la-raw_logging.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/raw_logging.cc' object='src/libglog_la-raw_logging.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-raw_logging.lo `test -f 'src/raw_logging.cc' || echo '$(srcdir)/'`src/raw_logging.cc - -src/libglog_la-vlog_is_on.lo: src/vlog_is_on.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-vlog_is_on.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-vlog_is_on.Tpo -c -o src/libglog_la-vlog_is_on.lo `test -f 'src/vlog_is_on.cc' || echo '$(srcdir)/'`src/vlog_is_on.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-vlog_is_on.Tpo src/$(DEPDIR)/libglog_la-vlog_is_on.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/vlog_is_on.cc' object='src/libglog_la-vlog_is_on.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-vlog_is_on.lo `test -f 'src/vlog_is_on.cc' || echo '$(srcdir)/'`src/vlog_is_on.cc - -src/libglog_la-utilities.lo: src/utilities.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-utilities.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-utilities.Tpo -c -o src/libglog_la-utilities.lo `test -f 'src/utilities.cc' || echo '$(srcdir)/'`src/utilities.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-utilities.Tpo src/$(DEPDIR)/libglog_la-utilities.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/utilities.cc' object='src/libglog_la-utilities.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-utilities.lo `test -f 'src/utilities.cc' || echo '$(srcdir)/'`src/utilities.cc - -src/libglog_la-demangle.lo: src/demangle.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-demangle.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-demangle.Tpo -c -o src/libglog_la-demangle.lo `test -f 'src/demangle.cc' || echo '$(srcdir)/'`src/demangle.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-demangle.Tpo src/$(DEPDIR)/libglog_la-demangle.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/demangle.cc' object='src/libglog_la-demangle.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-demangle.lo `test -f 'src/demangle.cc' || echo '$(srcdir)/'`src/demangle.cc - -src/libglog_la-symbolize.lo: src/symbolize.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-symbolize.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-symbolize.Tpo -c -o src/libglog_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-symbolize.Tpo src/$(DEPDIR)/libglog_la-symbolize.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/symbolize.cc' object='src/libglog_la-symbolize.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc - -src/libglog_la-signalhandler.lo: src/signalhandler.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-signalhandler.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-signalhandler.Tpo -c -o src/libglog_la-signalhandler.lo `test -f 'src/signalhandler.cc' || echo '$(srcdir)/'`src/signalhandler.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-signalhandler.Tpo src/$(DEPDIR)/libglog_la-signalhandler.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/signalhandler.cc' object='src/libglog_la-signalhandler.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-signalhandler.lo `test -f 'src/signalhandler.cc' || echo '$(srcdir)/'`src/signalhandler.cc - -src/libglog_la-nstack_logging.lo: src/nstack_logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -MT src/libglog_la-nstack_logging.lo -MD -MP -MF src/$(DEPDIR)/libglog_la-nstack_logging.Tpo -c -o src/libglog_la-nstack_logging.lo `test -f 'src/nstack_logging.cc' || echo '$(srcdir)/'`src/nstack_logging.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libglog_la-nstack_logging.Tpo src/$(DEPDIR)/libglog_la-nstack_logging.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/nstack_logging.cc' object='src/libglog_la-nstack_logging.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libglog_la_CXXFLAGS) $(CXXFLAGS) -c -o src/libglog_la-nstack_logging.lo `test -f 'src/nstack_logging.cc' || echo '$(srcdir)/'`src/nstack_logging.cc - -src/demangle_unittest-demangle_unittest.o: src/demangle_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(demangle_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/demangle_unittest-demangle_unittest.o -MD -MP -MF src/$(DEPDIR)/demangle_unittest-demangle_unittest.Tpo -c -o src/demangle_unittest-demangle_unittest.o `test -f 'src/demangle_unittest.cc' || echo '$(srcdir)/'`src/demangle_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/demangle_unittest-demangle_unittest.Tpo src/$(DEPDIR)/demangle_unittest-demangle_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/demangle_unittest.cc' object='src/demangle_unittest-demangle_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(demangle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/demangle_unittest-demangle_unittest.o `test -f 'src/demangle_unittest.cc' || echo '$(srcdir)/'`src/demangle_unittest.cc - -src/demangle_unittest-demangle_unittest.obj: src/demangle_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(demangle_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/demangle_unittest-demangle_unittest.obj -MD -MP -MF src/$(DEPDIR)/demangle_unittest-demangle_unittest.Tpo -c -o src/demangle_unittest-demangle_unittest.obj `if test -f 'src/demangle_unittest.cc'; then $(CYGPATH_W) 'src/demangle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/demangle_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/demangle_unittest-demangle_unittest.Tpo src/$(DEPDIR)/demangle_unittest-demangle_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/demangle_unittest.cc' object='src/demangle_unittest-demangle_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(demangle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/demangle_unittest-demangle_unittest.obj `if test -f 'src/demangle_unittest.cc'; then $(CYGPATH_W) 'src/demangle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/demangle_unittest.cc'; fi` - -src/logging_striptest0-logging_striptest_main.o: src/logging_striptest_main.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest0_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest0-logging_striptest_main.o -MD -MP -MF src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Tpo -c -o src/logging_striptest0-logging_striptest_main.o `test -f 'src/logging_striptest_main.cc' || echo '$(srcdir)/'`src/logging_striptest_main.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Tpo src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest_main.cc' object='src/logging_striptest0-logging_striptest_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest0_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest0-logging_striptest_main.o `test -f 'src/logging_striptest_main.cc' || echo '$(srcdir)/'`src/logging_striptest_main.cc - -src/logging_striptest0-logging_striptest_main.obj: src/logging_striptest_main.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest0_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest0-logging_striptest_main.obj -MD -MP -MF src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Tpo -c -o src/logging_striptest0-logging_striptest_main.obj `if test -f 'src/logging_striptest_main.cc'; then $(CYGPATH_W) 'src/logging_striptest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest_main.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Tpo src/$(DEPDIR)/logging_striptest0-logging_striptest_main.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest_main.cc' object='src/logging_striptest0-logging_striptest_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest0_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest0-logging_striptest_main.obj `if test -f 'src/logging_striptest_main.cc'; then $(CYGPATH_W) 'src/logging_striptest_main.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest_main.cc'; fi` - -src/logging_striptest10-logging_striptest10.o: src/logging_striptest10.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest10_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest10-logging_striptest10.o -MD -MP -MF src/$(DEPDIR)/logging_striptest10-logging_striptest10.Tpo -c -o src/logging_striptest10-logging_striptest10.o `test -f 'src/logging_striptest10.cc' || echo '$(srcdir)/'`src/logging_striptest10.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest10-logging_striptest10.Tpo src/$(DEPDIR)/logging_striptest10-logging_striptest10.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest10.cc' object='src/logging_striptest10-logging_striptest10.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest10_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest10-logging_striptest10.o `test -f 'src/logging_striptest10.cc' || echo '$(srcdir)/'`src/logging_striptest10.cc - -src/logging_striptest10-logging_striptest10.obj: src/logging_striptest10.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest10_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest10-logging_striptest10.obj -MD -MP -MF src/$(DEPDIR)/logging_striptest10-logging_striptest10.Tpo -c -o src/logging_striptest10-logging_striptest10.obj `if test -f 'src/logging_striptest10.cc'; then $(CYGPATH_W) 'src/logging_striptest10.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest10.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest10-logging_striptest10.Tpo src/$(DEPDIR)/logging_striptest10-logging_striptest10.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest10.cc' object='src/logging_striptest10-logging_striptest10.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest10_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest10-logging_striptest10.obj `if test -f 'src/logging_striptest10.cc'; then $(CYGPATH_W) 'src/logging_striptest10.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest10.cc'; fi` - -src/logging_striptest2-logging_striptest2.o: src/logging_striptest2.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest2_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest2-logging_striptest2.o -MD -MP -MF src/$(DEPDIR)/logging_striptest2-logging_striptest2.Tpo -c -o src/logging_striptest2-logging_striptest2.o `test -f 'src/logging_striptest2.cc' || echo '$(srcdir)/'`src/logging_striptest2.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest2-logging_striptest2.Tpo src/$(DEPDIR)/logging_striptest2-logging_striptest2.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest2.cc' object='src/logging_striptest2-logging_striptest2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest2_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest2-logging_striptest2.o `test -f 'src/logging_striptest2.cc' || echo '$(srcdir)/'`src/logging_striptest2.cc - -src/logging_striptest2-logging_striptest2.obj: src/logging_striptest2.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest2_CXXFLAGS) $(CXXFLAGS) -MT src/logging_striptest2-logging_striptest2.obj -MD -MP -MF src/$(DEPDIR)/logging_striptest2-logging_striptest2.Tpo -c -o src/logging_striptest2-logging_striptest2.obj `if test -f 'src/logging_striptest2.cc'; then $(CYGPATH_W) 'src/logging_striptest2.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest2.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_striptest2-logging_striptest2.Tpo src/$(DEPDIR)/logging_striptest2-logging_striptest2.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_striptest2.cc' object='src/logging_striptest2-logging_striptest2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_striptest2_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_striptest2-logging_striptest2.obj `if test -f 'src/logging_striptest2.cc'; then $(CYGPATH_W) 'src/logging_striptest2.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_striptest2.cc'; fi` - -src/logging_unittest-logging_unittest.o: src/logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/logging_unittest-logging_unittest.o -MD -MP -MF src/$(DEPDIR)/logging_unittest-logging_unittest.Tpo -c -o src/logging_unittest-logging_unittest.o `test -f 'src/logging_unittest.cc' || echo '$(srcdir)/'`src/logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_unittest-logging_unittest.Tpo src/$(DEPDIR)/logging_unittest-logging_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_unittest.cc' object='src/logging_unittest-logging_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_unittest-logging_unittest.o `test -f 'src/logging_unittest.cc' || echo '$(srcdir)/'`src/logging_unittest.cc - -src/logging_unittest-logging_unittest.obj: src/logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/logging_unittest-logging_unittest.obj -MD -MP -MF src/$(DEPDIR)/logging_unittest-logging_unittest.Tpo -c -o src/logging_unittest-logging_unittest.obj `if test -f 'src/logging_unittest.cc'; then $(CYGPATH_W) 'src/logging_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/logging_unittest-logging_unittest.Tpo src/$(DEPDIR)/logging_unittest-logging_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/logging_unittest.cc' object='src/logging_unittest-logging_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(logging_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/logging_unittest-logging_unittest.obj `if test -f 'src/logging_unittest.cc'; then $(CYGPATH_W) 'src/logging_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/logging_unittest.cc'; fi` - -src/mock_log_test-mock-log_test.o: src/mock-log_test.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mock_log_test_CXXFLAGS) $(CXXFLAGS) -MT src/mock_log_test-mock-log_test.o -MD -MP -MF src/$(DEPDIR)/mock_log_test-mock-log_test.Tpo -c -o src/mock_log_test-mock-log_test.o `test -f 'src/mock-log_test.cc' || echo '$(srcdir)/'`src/mock-log_test.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/mock_log_test-mock-log_test.Tpo src/$(DEPDIR)/mock_log_test-mock-log_test.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/mock-log_test.cc' object='src/mock_log_test-mock-log_test.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mock_log_test_CXXFLAGS) $(CXXFLAGS) -c -o src/mock_log_test-mock-log_test.o `test -f 'src/mock-log_test.cc' || echo '$(srcdir)/'`src/mock-log_test.cc - -src/mock_log_test-mock-log_test.obj: src/mock-log_test.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mock_log_test_CXXFLAGS) $(CXXFLAGS) -MT src/mock_log_test-mock-log_test.obj -MD -MP -MF src/$(DEPDIR)/mock_log_test-mock-log_test.Tpo -c -o src/mock_log_test-mock-log_test.obj `if test -f 'src/mock-log_test.cc'; then $(CYGPATH_W) 'src/mock-log_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/mock-log_test.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/mock_log_test-mock-log_test.Tpo src/$(DEPDIR)/mock_log_test-mock-log_test.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/mock-log_test.cc' object='src/mock_log_test-mock-log_test.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mock_log_test_CXXFLAGS) $(CXXFLAGS) -c -o src/mock_log_test-mock-log_test.obj `if test -f 'src/mock-log_test.cc'; then $(CYGPATH_W) 'src/mock-log_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/mock-log_test.cc'; fi` - -src/signalhandler_unittest-signalhandler_unittest.o: src/signalhandler_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/signalhandler_unittest-signalhandler_unittest.o -MD -MP -MF src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Tpo -c -o src/signalhandler_unittest-signalhandler_unittest.o `test -f 'src/signalhandler_unittest.cc' || echo '$(srcdir)/'`src/signalhandler_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Tpo src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/signalhandler_unittest.cc' object='src/signalhandler_unittest-signalhandler_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/signalhandler_unittest-signalhandler_unittest.o `test -f 'src/signalhandler_unittest.cc' || echo '$(srcdir)/'`src/signalhandler_unittest.cc - -src/signalhandler_unittest-signalhandler_unittest.obj: src/signalhandler_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/signalhandler_unittest-signalhandler_unittest.obj -MD -MP -MF src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Tpo -c -o src/signalhandler_unittest-signalhandler_unittest.obj `if test -f 'src/signalhandler_unittest.cc'; then $(CYGPATH_W) 'src/signalhandler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/signalhandler_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Tpo src/$(DEPDIR)/signalhandler_unittest-signalhandler_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/signalhandler_unittest.cc' object='src/signalhandler_unittest-signalhandler_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(signalhandler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/signalhandler_unittest-signalhandler_unittest.obj `if test -f 'src/signalhandler_unittest.cc'; then $(CYGPATH_W) 'src/signalhandler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/signalhandler_unittest.cc'; fi` - -src/stacktrace_unittest-stacktrace_unittest.o: src/stacktrace_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/stacktrace_unittest-stacktrace_unittest.o -MD -MP -MF src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo -c -o src/stacktrace_unittest-stacktrace_unittest.o `test -f 'src/stacktrace_unittest.cc' || echo '$(srcdir)/'`src/stacktrace_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/stacktrace_unittest.cc' object='src/stacktrace_unittest-stacktrace_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/stacktrace_unittest-stacktrace_unittest.o `test -f 'src/stacktrace_unittest.cc' || echo '$(srcdir)/'`src/stacktrace_unittest.cc - -src/stacktrace_unittest-stacktrace_unittest.obj: src/stacktrace_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/stacktrace_unittest-stacktrace_unittest.obj -MD -MP -MF src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo -c -o src/stacktrace_unittest-stacktrace_unittest.obj `if test -f 'src/stacktrace_unittest.cc'; then $(CYGPATH_W) 'src/stacktrace_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stacktrace_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Tpo src/$(DEPDIR)/stacktrace_unittest-stacktrace_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/stacktrace_unittest.cc' object='src/stacktrace_unittest-stacktrace_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stacktrace_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/stacktrace_unittest-stacktrace_unittest.obj `if test -f 'src/stacktrace_unittest.cc'; then $(CYGPATH_W) 'src/stacktrace_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stacktrace_unittest.cc'; fi` - -src/stl_logging_unittest-stl_logging_unittest.o: src/stl_logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/stl_logging_unittest-stl_logging_unittest.o -MD -MP -MF src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Tpo -c -o src/stl_logging_unittest-stl_logging_unittest.o `test -f 'src/stl_logging_unittest.cc' || echo '$(srcdir)/'`src/stl_logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Tpo src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/stl_logging_unittest.cc' object='src/stl_logging_unittest-stl_logging_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/stl_logging_unittest-stl_logging_unittest.o `test -f 'src/stl_logging_unittest.cc' || echo '$(srcdir)/'`src/stl_logging_unittest.cc - -src/stl_logging_unittest-stl_logging_unittest.obj: src/stl_logging_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/stl_logging_unittest-stl_logging_unittest.obj -MD -MP -MF src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Tpo -c -o src/stl_logging_unittest-stl_logging_unittest.obj `if test -f 'src/stl_logging_unittest.cc'; then $(CYGPATH_W) 'src/stl_logging_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stl_logging_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Tpo src/$(DEPDIR)/stl_logging_unittest-stl_logging_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/stl_logging_unittest.cc' object='src/stl_logging_unittest-stl_logging_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stl_logging_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/stl_logging_unittest-stl_logging_unittest.obj `if test -f 'src/stl_logging_unittest.cc'; then $(CYGPATH_W) 'src/stl_logging_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/stl_logging_unittest.cc'; fi` - -src/symbolize_unittest-symbolize_unittest.o: src/symbolize_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/symbolize_unittest-symbolize_unittest.o -MD -MP -MF src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Tpo -c -o src/symbolize_unittest-symbolize_unittest.o `test -f 'src/symbolize_unittest.cc' || echo '$(srcdir)/'`src/symbolize_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Tpo src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/symbolize_unittest.cc' object='src/symbolize_unittest-symbolize_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/symbolize_unittest-symbolize_unittest.o `test -f 'src/symbolize_unittest.cc' || echo '$(srcdir)/'`src/symbolize_unittest.cc - -src/symbolize_unittest-symbolize_unittest.obj: src/symbolize_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/symbolize_unittest-symbolize_unittest.obj -MD -MP -MF src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Tpo -c -o src/symbolize_unittest-symbolize_unittest.obj `if test -f 'src/symbolize_unittest.cc'; then $(CYGPATH_W) 'src/symbolize_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/symbolize_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Tpo src/$(DEPDIR)/symbolize_unittest-symbolize_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/symbolize_unittest.cc' object='src/symbolize_unittest-symbolize_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(symbolize_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/symbolize_unittest-symbolize_unittest.obj `if test -f 'src/symbolize_unittest.cc'; then $(CYGPATH_W) 'src/symbolize_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/symbolize_unittest.cc'; fi` - -src/utilities_unittest-utilities_unittest.o: src/utilities_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/utilities_unittest-utilities_unittest.o -MD -MP -MF src/$(DEPDIR)/utilities_unittest-utilities_unittest.Tpo -c -o src/utilities_unittest-utilities_unittest.o `test -f 'src/utilities_unittest.cc' || echo '$(srcdir)/'`src/utilities_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/utilities_unittest-utilities_unittest.Tpo src/$(DEPDIR)/utilities_unittest-utilities_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/utilities_unittest.cc' object='src/utilities_unittest-utilities_unittest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/utilities_unittest-utilities_unittest.o `test -f 'src/utilities_unittest.cc' || echo '$(srcdir)/'`src/utilities_unittest.cc - -src/utilities_unittest-utilities_unittest.obj: src/utilities_unittest.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -MT src/utilities_unittest-utilities_unittest.obj -MD -MP -MF src/$(DEPDIR)/utilities_unittest-utilities_unittest.Tpo -c -o src/utilities_unittest-utilities_unittest.obj `if test -f 'src/utilities_unittest.cc'; then $(CYGPATH_W) 'src/utilities_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/utilities_unittest.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/utilities_unittest-utilities_unittest.Tpo src/$(DEPDIR)/utilities_unittest-utilities_unittest.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/utilities_unittest.cc' object='src/utilities_unittest-utilities_unittest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(utilities_unittest_CXXFLAGS) $(CXXFLAGS) -c -o src/utilities_unittest-utilities_unittest.obj `if test -f 'src/utilities_unittest.cc'; then $(CYGPATH_W) 'src/utilities_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/utilities_unittest.cc'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf src/.libs src/_libs - -distclean-libtool: - -rm -f libtool config.lt -install-dist_docDATA: $(dist_doc_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-dist_docDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-glogincludeHEADERS: $(gloginclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(gloginclude_HEADERS)'; test -n "$(glogincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(glogincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(glogincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(glogincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(glogincludedir)" || exit $$?; \ - done - -uninstall-glogincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(gloginclude_HEADERS)'; test -n "$(glogincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(glogincludedir)'; $(am__uninstall_files_from_dir) -install-nodist_glogincludeHEADERS: $(nodist_gloginclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(nodist_gloginclude_HEADERS)'; test -n "$(glogincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(glogincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(glogincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(glogincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(glogincludedir)" || exit $$?; \ - done - -uninstall-nodist_glogincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(nodist_gloginclude_HEADERS)'; test -n "$(glogincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(glogincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - else \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_SCRIPTS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -logging_unittest.log: logging_unittest$(EXEEXT) - @p='logging_unittest$(EXEEXT)'; \ - b='logging_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -demangle_unittest.log: demangle_unittest$(EXEEXT) - @p='demangle_unittest$(EXEEXT)'; \ - b='demangle_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -stacktrace_unittest.log: stacktrace_unittest$(EXEEXT) - @p='stacktrace_unittest$(EXEEXT)'; \ - b='stacktrace_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -symbolize_unittest.log: symbolize_unittest$(EXEEXT) - @p='symbolize_unittest$(EXEEXT)'; \ - b='symbolize_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -stl_logging_unittest.log: stl_logging_unittest$(EXEEXT) - @p='stl_logging_unittest$(EXEEXT)'; \ - b='stl_logging_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -utilities_unittest.log: utilities_unittest$(EXEEXT) - @p='utilities_unittest$(EXEEXT)'; \ - b='utilities_unittest'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -mock_log_test.log: mock_log_test$(EXEEXT) - @p='mock_log_test$(EXEEXT)'; \ - b='mock_log_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \ - $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(glogincludedir)" "$(DESTDIR)$(glogincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f src/$(DEPDIR)/$(am__dirstamp) - -rm -f src/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstPROGRAMS mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf src/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-dist_docDATA install-glogincludeHEADERS \ - install-nodist_glogincludeHEADERS install-pkgconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf src/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-dist_docDATA uninstall-glogincludeHEADERS \ - uninstall-libLTLIBRARIES uninstall-nodist_glogincludeHEADERS \ - uninstall-pkgconfigDATA - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ - check-am clean clean-cscope clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-noinstPROGRAMS cscope cscopelist-am ctags \ - ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ - dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \ - distclean distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_docDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-glogincludeHEADERS install-html \ - install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man \ - install-nodist_glogincludeHEADERS install-pdf install-pdf-am \ - install-pkgconfigDATA install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-dist_docDATA uninstall-glogincludeHEADERS \ - uninstall-libLTLIBRARIES uninstall-nodist_glogincludeHEADERS \ - uninstall-pkgconfigDATA - -@ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@ # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS), -@ENABLE_FRAME_POINTERS_FALSE@@X86_64_TRUE@ # before setting this. -logging_striplog_test_sh: logging_striptest0 logging_striptest2 logging_striptest10 - $(top_srcdir)/src/logging_striplog_test.sh -demangle_unittest_sh: demangle_unittest - $(builddir)/demangle_unittest # force to create lt-demangle_unittest - $(top_srcdir)/src/demangle_unittest.sh -signalhandler_unittest_sh: signalhandler_unittest - $(builddir)/signalhandler_unittest # force to create lt-signalhandler_unittest - $(top_srcdir)/src/signalhandler_unittest.sh - -rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec - @cd packages && ./rpm.sh ${PACKAGE} ${VERSION} - -deb: dist-gzip packages/deb.sh packages/deb/* - @cd packages && ./deb.sh ${PACKAGE} ${VERSION} - -# Windows wants write permission to .vcproj files and maybe even sln files. -dist-hook: - test -e "$(distdir)/vsprojects" \ - && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/ - -libtool: $(LIBTOOL_DEPS) - $(SHELL) ./config.status --recheck - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/glog/glog-0.3.4/config.guess b/thirdparty/glog/glog-0.3.4/config.guess deleted file mode 100644 index 3942457..0000000 --- a/thirdparty/glog/glog-0.3.4/config.guess +++ /dev/null @@ -1,1519 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. - -timestamp='2007-07-22' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T | authenticamd) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - xtensa:Linux:*:*) - echo xtensa-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess -and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/thirdparty/glog/glog-0.3.4/config.sub b/thirdparty/glog/glog-0.3.4/config.sub deleted file mode 100644 index 1761d8b..0000000 --- a/thirdparty/glog/glog-0.3.4/config.sub +++ /dev/null @@ -1,1626 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. - -timestamp='2007-06-28' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | score \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/thirdparty/glog/glog-0.3.4/depcomp b/thirdparty/glog/glog-0.3.4/depcomp deleted file mode 100644 index e5f9736..0000000 --- a/thirdparty/glog/glog-0.3.4/depcomp +++ /dev/null @@ -1,589 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2007-03-29.01 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software -# Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to <bug-automake@gnu.org>. -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/thirdparty/glog/glog-0.3.4/install-sh b/thirdparty/glog/glog-0.3.4/install-sh deleted file mode 100644 index a5897de..0000000 --- a/thirdparty/glog/glog-0.3.4/install-sh +++ /dev/null @@ -1,519 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2006-12-25.00 - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/thirdparty/glog/glog-0.3.4/ltmain.sh b/thirdparty/glog/glog-0.3.4/ltmain.sh deleted file mode 100644 index c2852d8..0000000 --- a/thirdparty/glog/glog-0.3.4/ltmain.sh +++ /dev/null @@ -1,9661 +0,0 @@ - -# libtool (GNU libtool) 2.4.2 -# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to <bug-libtool@gnu.org>. -# GNU libtool home page: <http://www.gnu.org/software/libtool/>. -# General help using GNU software: <http://www.gnu.org/gethelp/>. - -PROGRAM=libtool -PACKAGE=libtool -VERSION="2.4.2 Debian-2.4.2-1ubuntu1" -TIMESTAMP="" -package_revision=1.3337 - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" - fi" -done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL - -$lt_unset CDPATH - - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - - - -: ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -dirname="s,/[^/]*$,," -basename="s,^.*/,," - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation - - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation - - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation - - -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' - -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi - - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} - -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result - -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' - -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" -} - -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} - -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 - - # bash bug again: - : -} - -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "$my_tmpdir" -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () -{ - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac - - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac -} - - -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac - - func_quote_for_expand_result="$my_arg" -} - - -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug - - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} - -# func_usage -# Echo short help message to standard output and exit. -func_usage () -{ - $opt_debug - - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? -} - -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () -{ - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi -} - -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $opt_debug - - func_error "missing argument for $1." - exit_cmd=exit -} - - -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' - - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation - - -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () -{ - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' - - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation - -exit_cmd=: - - - - - -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" - -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation - -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation - - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation - - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation - - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation - - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation - - -# func_fatal_configuration arg... -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." -} - - -# func_config -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - -# func_features -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - -# func_enable_tag tagname -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname="$1" - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac - - - -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false - - -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. -{ - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done - - # Validate options: - - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } - - - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE -} - - - - -## ----------- ## -## Main. ## -## ----------- ## - -# func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case "$lalib_p_line" in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test "$lalib_p" = yes -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - func_lalib_p "$1" -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $opt_debug - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$save_ifs - eval cmd=\"$cmd\" - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. -func_source () -{ - $opt_debug - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case "$lt_sysroot:$1" in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $opt_debug - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi - - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T <<EOF -# $write_libobj - a libtool object file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -pic_object=$write_lobj - -# Name of the non-PIC object -non_pic_object=$write_oldobj - -EOF - $MV "${write_libobj}T" "${write_libobj}" - } -} - - -################################################## -# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # -################################################## - -# func_convert_core_file_wine_to_w32 ARG -# Helper function used by file name conversion functions when $build is *nix, -# and $host is mingw, cygwin, or some other w32 environment. Relies on a -# correctly configured wine environment available, with the winepath program -# in $build's $PATH. -# -# ARG is the $build file name to be converted to w32 format. -# Result is available in $func_convert_core_file_wine_to_w32_result, and will -# be empty on error (or when ARG is empty) -func_convert_core_file_wine_to_w32 () -{ - $opt_debug - func_convert_core_file_wine_to_w32_result="$1" - if test -n "$1"; then - # Unfortunately, winepath does not exit with a non-zero error code, so we - # are forced to check the contents of stdout. On the other hand, if the - # command is not found, the shell will set an exit code of 127 and print - # *an error message* to stdout. So we must check for both error code of - # zero AND non-empty stdout, which explains the odd construction: - func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $opt_debug - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $opt_debug - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $opt_debug - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $opt_debug - if test -z "$2" && test -n "$1" ; then - func_error "Could not determine host file name corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result="$1" - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $opt_debug - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " \`$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result="$3" - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $opt_debug - case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via `$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $opt_debug - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $opt_debug - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result="$1" -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via `$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $opt_debug - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $opt_debug - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result="$1" -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_mode_compile arg... -func_mode_compile () -{ - $opt_debug - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - func_append_quoted lastarg "$arg" - done - IFS="$save_ifs" - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with \`-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj="$func_basename_result" - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from \`$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode \`$opt_mode'" - ;; - esac - - echo - $ECHO "Try \`$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test "$opt_help" = :; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | sed -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - sed '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $opt_debug - # The first argument is the command name. - cmd="$nonopt" - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "\`$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir="$func_dirname_result" - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir="$func_dirname_result" - ;; - - *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file="$progdir/$program" - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if test "X$opt_dry_run" = Xfalse; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $opt_debug - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "\`$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument \`$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $opt_debug - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "\`$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir="$func_dirname_result" - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking \`$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname="$1" - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme="$stripme" - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme="" - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - $opt_dry_run || { - if test "$finalize" = yes; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_silent || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink \`$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file="$outputname" - else - func_warning "cannot relink \`$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name="$func_basename_result" - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $tool_oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = install && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $opt_dry_run || { - $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" - func_basename "$dlprefile" - name="$func_basename_result" - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" - else - # no lafile. user explicitly requested -dlpreopen <import library>. - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 </dev/null >/dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' - - # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $opt_debug - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $opt_debug - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $opt_debug - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result="" - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $opt_debug - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib="$func_basename_result" - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result="$my_oldobjs" -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case \" \$* \" in - *\\ --lt-*) - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done ;; - esac - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat <<EOF - -/* $cwrappersource - temporary wrapper executable for $objdir/$outputname - Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION - - The $output program cannot be directly executed until all the libtool - libraries that it depends on are installed. - - This wrapper executable should never be moved out of the build directory. - If it is, it will not operate correctly. -*/ -EOF - cat <<"EOF" -#ifdef _MSC_VER -# define _CRT_SECURE_NO_DEPRECATE 1 -#endif -#include <stdio.h> -#include <stdlib.h> -#ifdef _MSC_VER -# include <direct.h> -# include <process.h> -# include <io.h> -#else -# include <unistd.h> -# include <stdint.h> -# ifdef __CYGWIN__ -# include <io.h> -# endif -#endif -#include <malloc.h> -#include <stdarg.h> -#include <assert.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> - -/* declarations of non-ANSI functions */ -#if defined(__MINGW32__) -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined(__CYGWIN__) -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined (other platforms) ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined(__CYGWIN__) -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ -#endif - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -#if defined(LT_DEBUGWRAPPER) -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <<EOF -volatile const char * MAGIC_EXE = "$magic_exe"; -const char * LIB_PATH_VARNAME = "$shlibpath_var"; -EOF - - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - func_to_host_path "$temp_rpath" - cat <<EOF -const char * LIB_PATH_VALUE = "$func_to_host_path_result"; -EOF - else - cat <<"EOF" -const char * LIB_PATH_VALUE = ""; -EOF - fi - - if test -n "$dllsearchpath"; then - func_to_host_path "$dllsearchpath:" - cat <<EOF -const char * EXE_PATH_VARNAME = "PATH"; -const char * EXE_PATH_VALUE = "$func_to_host_path_result"; -EOF - else - cat <<"EOF" -const char * EXE_PATH_VARNAME = ""; -const char * EXE_PATH_VALUE = ""; -EOF - fi - - if test "$fast_install" = yes; then - cat <<EOF -const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ -EOF - else - cat <<EOF -const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ -EOF - fi - - - cat <<"EOF" - -#define LTWRAPPER_OPTION_PREFIX "--lt-" - -static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; -static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; -static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; - -int -main (int argc, char *argv[]) -{ - char **newargz; - int newargc; - char *tmp_pathspec; - char *actual_cwrapper_path; - char *actual_cwrapper_name; - char *target_name; - char *lt_argv_zero; - intptr_t rval = 127; - - int i; - - program_name = (char *) xstrdup (base_name (argv[0])); - newargz = XMALLOC (char *, argc + 1); - - /* very simple arg parsing; don't want to rely on getopt - * also, copy all non cwrapper options to newargz, except - * argz[0], which is handled differently - */ - newargc=0; - for (i = 1; i < argc; i++) - { - if (strcmp (argv[i], dumpscript_opt) == 0) - { -EOF - case "$host" in - *mingw* | *cygwin* ) - # make stdout use "unix" line endings - echo " setmode(1,_O_BINARY);" - ;; - esac - - cat <<"EOF" - lt_dump_script (stdout); - return 0; - } - if (strcmp (argv[i], debug_opt) == 0) - { - lt_debug = 1; - continue; - } - if (strcmp (argv[i], ltwrapper_option_prefix) == 0) - { - /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX - namespace, but it is not one of the ones we know about and - have already dealt with, above (inluding dump-script), then - report an error. Otherwise, targets might begin to believe - they are allowed to use options in the LTWRAPPER_OPTION_PREFIX - namespace. The first time any user complains about this, we'll - need to make LTWRAPPER_OPTION_PREFIX a configure-time option - or a configure.ac-settable value. - */ - lt_fatal (__FILE__, __LINE__, - "unrecognized %s option: '%s'", - ltwrapper_option_prefix, argv[i]); - } - /* otherwise ... */ - newargz[++newargc] = xstrdup (argv[i]); - } - newargz[++newargc] = NULL; - -EOF - cat <<EOF - /* The GNU banner must be the first non-error debug message */ - lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n"); -EOF - cat <<"EOF" - lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); - lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); - - tmp_pathspec = find_executable (argv[0]); - if (tmp_pathspec == NULL) - lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); - lt_debugprintf (__FILE__, __LINE__, - "(main) found exe (before symlink chase) at: %s\n", - tmp_pathspec); - - actual_cwrapper_path = chase_symlinks (tmp_pathspec); - lt_debugprintf (__FILE__, __LINE__, - "(main) found exe (after symlink chase) at: %s\n", - actual_cwrapper_path); - XFREE (tmp_pathspec); - - actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); - strendzap (actual_cwrapper_path, actual_cwrapper_name); - - /* wrapper name transforms */ - strendzap (actual_cwrapper_name, ".exe"); - tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); - XFREE (actual_cwrapper_name); - actual_cwrapper_name = tmp_pathspec; - tmp_pathspec = 0; - - /* target_name transforms -- use actual target program name; might have lt- prefix */ - target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); - strendzap (target_name, ".exe"); - tmp_pathspec = lt_extend_str (target_name, ".exe", 1); - XFREE (target_name); - target_name = tmp_pathspec; - tmp_pathspec = 0; - - lt_debugprintf (__FILE__, __LINE__, - "(main) libtool target name: %s\n", - target_name); -EOF - - cat <<EOF - newargz[0] = - XMALLOC (char, (strlen (actual_cwrapper_path) + - strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); - strcpy (newargz[0], actual_cwrapper_path); - strcat (newargz[0], "$objdir"); - strcat (newargz[0], "/"); -EOF - - cat <<"EOF" - /* stop here, and copy so we don't have to do this twice */ - tmp_pathspec = xstrdup (newargz[0]); - - /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ - strcat (newargz[0], actual_cwrapper_name); - - /* DO want the lt- prefix here if it exists, so use target_name */ - lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); - XFREE (tmp_pathspec); - tmp_pathspec = NULL; -EOF - - case $host_os in - mingw*) - cat <<"EOF" - { - char* p; - while ((p = strchr (newargz[0], '\\')) != NULL) - { - *p = '/'; - } - while ((p = strchr (lt_argv_zero, '\\')) != NULL) - { - *p = '/'; - } - } -EOF - ;; - esac - - cat <<"EOF" - XFREE (target_name); - XFREE (actual_cwrapper_path); - XFREE (actual_cwrapper_name); - - lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ - lt_setenv ("DUALCASE", "1"); /* for MSK sh */ - /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must - be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) - because on Windows, both *_VARNAMEs are PATH but uninstalled - libraries must come first. */ - lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); - lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); - - lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", - nonnull (lt_argv_zero)); - for (i = 0; i < newargc; i++) - { - lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", - i, nonnull (newargz[i])); - } - -EOF - - case $host_os in - mingw*) - cat <<"EOF" - /* execv doesn't actually work on mingw as expected on unix */ - newargz = prepare_spawn (newargz); - rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); - if (rval == -1) - { - /* failed to start process */ - lt_debugprintf (__FILE__, __LINE__, - "(main) failed to launch target \"%s\": %s\n", - lt_argv_zero, nonnull (strerror (errno))); - return 127; - } - return rval; -EOF - ;; - *) - cat <<"EOF" - execv (lt_argv_zero, newargz); - return rval; /* =127, but avoids unused variable warning */ -EOF - ;; - esac - - cat <<"EOF" -} - -void * -xmalloc (size_t num) -{ - void *p = (void *) malloc (num); - if (!p) - lt_fatal (__FILE__, __LINE__, "memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), - string) : NULL; -} - -const char * -base_name (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha ((unsigned char) name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return base; -} - -int -check_executable (const char *path) -{ - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if ((stat (path, &st) >= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp (str, pat) == 0) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - int len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - int orig_value_len = strlen (orig_value); - int add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - int len = strlen (new_value); - while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[len-1] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -n -e ' -s/^\(.\{79\}\)\(..*\)/\1\ -\2/ -h -s/\([\\"]\)/\\\1/g -s/$/\\n/ -s/\([^\n]*\).*/ fputs ("\1", f);/p -g -D' - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $opt_debug - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $opt_debug - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module="${wl}-single_module" - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir="$arg" - prev= - continue - ;; - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file \`$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" - else - func_fatal_error "need path for \`-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module="${wl}-multi_module" - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs="$tmp_deplibs" - fi - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) - libs="$deplibs %DEPLIBS%" - test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" - ;; - esac - fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs="$dlprefiles" - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test "$linkmode" = lib; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "\`-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - ;; - esac - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib="$l" - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" - fi - ;; - esac - func_basename "$lib" - laname="$func_basename_result" - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" - fi - case "$host" in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test "$installed" = no; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" - break - fi - done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then - echo - if test "$linkmode" = prog; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname="$1" - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc*) - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - func_basename "$soroot" - soname="$func_basename_result" - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from \`$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$opt_mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - elif test -n "$old_library"; then - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$opt_mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path="$deplib" ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" - path= - fi - fi - ;; - *) - path="-L$absdir/$objdir" - ;; - esac - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" - - path="-L$absdir" - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "\`-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" - - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" - - install_libdir="$1" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - shift - IFS="$save_ifs" - - test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$1" - number_minor="$2" - number_revision="$3" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - # correct linux to gnu/linux during the next big refactor - darwin|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - *) - func_fatal_configuration "$modename: unknown library version type \`$version_type'" - ;; - esac - ;; - no) - current="$1" - revision="$2" - age="$3" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current" - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) # correct to gnu/linux during the next big refactor - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - func_append verstring ":${current}.0" - ;; - - qnx) - major=".$current" - versuffix=".$current" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - - *) - func_fatal_configuration "unknown library version type \`$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - - fi - - func_generate_dlsyms "$libname" "$libname" "yes" - func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= - - if test "$opt_mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c <<EOF - int main() { return 0; } -EOF - $opt_dry_run || $RM conftest - if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then - ldd_output=`ldd conftest` - for i in $deplibs; do - case $i in - -l*) - func_stripname -l '' "$i" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $i "*) - func_append newdeplibs " $i" - i="" - ;; - esac - fi - if test -n "$i" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` - set dummy $deplib_matches; shift - deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then - func_append newdeplibs " $i" - else - droppeddeps=yes - echo - $ECHO "*** Warning: dynamic linker does not accept needed library $i." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which I believe you do not have" - echo "*** because a test_compile did reveal that the linker did not use it for" - echo "*** its dynamic dependency list that programs get resolved with at runtime." - fi - fi - ;; - *) - func_append newdeplibs " $i" - ;; - esac - done - else - # Error occurred in the first compile. Let's try to salvage - # the situation: Compile a separate program for each library. - for i in $deplibs; do - case $i in - -l*) - func_stripname -l '' "$i" - name=$func_stripname_result - $opt_dry_run || $RM conftest - if $LTCC $LTCFLAGS -o conftest conftest.c $i; then - ldd_output=`ldd conftest` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $i "*) - func_append newdeplibs " $i" - i="" - ;; - esac - fi - if test -n "$i" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` - set dummy $deplib_matches; shift - deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then - func_append newdeplibs " $i" - else - droppeddeps=yes - echo - $ECHO "*** Warning: dynamic linker does not accept needed library $i." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because a test_compile did reveal that the linker did not use this one" - echo "*** as a dynamic dependency that programs can get resolved with at runtime." - fi - fi - else - droppeddeps=yes - echo - $ECHO "*** Warning! Library $i is needed by this library but I was not able to" - echo "*** make it link in! You will probably need to install it or some" - echo "*** library that it depends on before this library will be fully" - echo "*** functional. Installing it before continuing would be even better." - fi - ;; - *) - func_append newdeplibs " $i" - ;; - esac - done - fi - ;; - file_magic*) - set dummy $deplibs_check_method; shift - file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - if test -n "$file_magic_glob"; then - libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` - else - libnameglob=$libname - fi - test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - if test "$want_nocaseglob" = yes; then - shopt -s nocaseglob - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs="$new_libs" - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. - # FIXME: should test the right _cmds variable. - case $archive_cmds in - *\$LD\ *) wl= ;; - esac - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname="$1" - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols="$export_symbols" - export_symbols= - always_export_symbols=yes - fi - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd1 in $cmds; do - IFS="$save_ifs" - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test "$try_normal_branch" = yes \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=${output_objdir}/${output_la}.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test "$compiler_needs_object" = yes; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test "X$objlist" = X || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - fi - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - if ${skipped_export-false}; then - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - fi - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "\`-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "\`-release' is ignored for programs" - - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=yes - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no - ;; - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac - if test "$wrappers_required" = no; then - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' - fi - - exit $exit_status - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase="$func_basename_result" - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name="$func_basename_result" - func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles="$newdlprefiles" - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $opt_debug - RM="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" - else - odir="$dir/$objdir" - fi - func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" - - # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case "$opt_mode" in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$opt_mode" = clean ; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} - -test -z "$opt_mode" && { - help="$generic_help" - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# vi:sw=2 - diff --git a/thirdparty/glog/glog-0.3.4/m4/libtool.m4 b/thirdparty/glog/glog-0.3.4/m4/libtool.m4 deleted file mode 100644 index 828104c..0000000 --- a/thirdparty/glog/glog-0.3.4/m4/libtool.m4 +++ /dev/null @@ -1,8001 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 57 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to <bug-libtool@gnu.org>." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_REPLACE_SHELLFNS - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -m4_ifndef([AC_PROG_GO], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case "$ECHO" in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([${with_sysroot}]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[23]].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$lt_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -_LT_PATH_LD_GNU -AC_SUBST([LD]) - -_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) -])# LT_PATH_LD - -# Old names: -AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) -AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_LD], []) -dnl AC_DEFUN([AC_PROG_LD], []) - - -# _LT_PATH_LD_GNU -#- -------------- -m4_defun([_LT_PATH_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac]) -with_gnu_ld=$lt_cv_prog_gnu_ld -])# _LT_PATH_LD_GNU - - -# _LT_CMD_RELOAD -# -------------- -# find reload flag for linker -# -- PORTME Some linkers may need a different reload flag. -m4_defun([_LT_CMD_RELOAD], -[AC_CACHE_CHECK([for $LD option to reload object files], - lt_cv_ld_reload_flag, - [lt_cv_ld_reload_flag='-r']) -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then - reload_cmds=false - fi - ;; - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac -_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl -_LT_TAGDECL([], [reload_cmds], [2])dnl -])# _LT_CMD_RELOAD - - -# _LT_CHECK_MAGIC_METHOD -# ---------------------- -# how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_MAGIC_METHOD], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -AC_CACHE_CHECK([how to recognize dependent libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[[4-9]]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[[45]]*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - _LT_TAGVAR(link_all_deplibs, $1)=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine which file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/thirdparty/glog/glog-0.3.4/missing b/thirdparty/glog/glog-0.3.4/missing deleted file mode 100644 index 1c8ff70..0000000 --- a/thirdparty/glog/glog-0.3.4/missing +++ /dev/null @@ -1,367 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2006-05-10.23 - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Send bug reports to <bug-automake@gnu.org>." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). -case $1 in - lex|yacc) - # Not GNU programs, they don't have --version. - ;; - - tar) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $1 in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/thirdparty/glog/glog-0.3.4/mkinstalldirs b/thirdparty/glog/glog-0.3.4/mkinstalldirs deleted file mode 100644 index ef7e16f..0000000 --- a/thirdparty/glog/glog-0.3.4/mkinstalldirs +++ /dev/null @@ -1,161 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2006-05-11.19 - -# Original author: Noah Friedman <friedman@prep.ai.mit.edu> -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to <bug-automake@gnu.org> or send patches to -# <automake-patches@gnu.org>. - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to <bug-automake@gnu.org>." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/thirdparty/glog/glog-0.3.4/test-driver b/thirdparty/glog/glog-0.3.4/test-driver deleted file mode 100644 index 84e7d90..0000000 --- a/thirdparty/glog/glog-0.3.4/test-driver +++ /dev/null @@ -1 +0,0 @@ -/usr/share/automake-1.14/test-driver
\ No newline at end of file |