From 5dc9a0f1a65037fa87a2329e740f51e4df3aec3d Mon Sep 17 00:00:00 2001 From: zhushengle Date: Fri, 24 Feb 2023 09:45:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: 支持网络容器对外变更: 1.支持网络容器 2.setns, clone, unshare接口支持CLONE_NEWNET Close #I6HPH2 Signed-off-by: zhushengle Change-Id: Ibaa11056982d465d4006680c8d3fa4ae2b9f25b5 --- BUILD.gn | 1 + fs/proc/os_adapt/plimits_proc.c | 4 +- fs/proc/os_adapt/process_proc.c | 10 + kernel/Kconfig | 5 + kernel/base/BUILD.gn | 1 + kernel/base/container/los_container.c | 96 ++++- kernel/base/container/los_net_container.c | 343 ++++++++++++++++++ kernel/base/core/los_process.c | 10 +- kernel/base/include/los_container_pri.h | 12 + kernel/base/include/los_net_container_pri.h | 62 ++++ kernel/base/vm/shm.c | 12 +- kernel/extended/plimit/los_devicelimit.c | 14 +- kernel/extended/plimit/los_ipclimit.c | 6 +- kernel/extended/plimit/los_ipclimit.h | 1 - kernel/extended/plimit/los_memlimit.c | 4 +- kernel/extended/plimit/los_plimits.c | 44 +-- kernel/extended/plimit/los_processlimit.c | 4 +- kernel/extended/plimit/los_schedlimit.c | 4 +- kernel/extended/plimit/los_schedlimit.h | 2 - net/lwip-2.1/enhancement/src/api_shell.c | 54 ++- net/lwip-2.1/enhancement/src/fixme.c | 14 +- net/lwip-2.1/porting/include/lwip/ip.h | 45 +++ net/lwip-2.1/porting/include/lwip/netif.h | 15 + net/lwip-2.1/porting/src/driverif.c | 64 ++++ net/lwip-2.1/porting/src/sockets.c | 99 ++++- syscall/process_syscall.c | 8 + testsuites/unittest/config.gni | 4 + testsuites/unittest/container/BUILD.gn | 3 + .../unittest/container/It_container_test.cpp | 144 ++++++++ .../unittest/container/It_container_test.h | 13 +- testsuites/unittest/container/config.gni | 16 + .../container/smoke/It_net_container_001.cpp | 144 ++++++++ .../container/smoke/It_net_container_002.cpp | 148 ++++++++ .../container/smoke/It_net_container_003.cpp | 78 ++++ .../container/smoke/It_net_container_004.cpp | 121 ++++++ .../container/smoke/It_net_container_005.cpp | 267 ++++++++++++++ .../container/smoke/It_net_container_006.cpp | 181 +++++++++ .../container/smoke/It_net_container_007.cpp | 102 ++++++ .../container/smoke/It_net_container_008.cpp | 119 ++++++ .../container/smoke/It_net_container_009.cpp | 260 +++++++++++++ .../container/smoke/It_net_container_010.cpp | 80 ++++ .../container/smoke/It_net_container_011.cpp | 100 +++++ .../container/smoke/It_net_container_012.cpp | 105 ++++++ .../unittest/process/fs/process_fs_test.cpp | 12 + .../smoke/It_process_plimits_ipc_009.cpp | 2 +- .../smoke/It_process_plimits_ipc_010.cpp | 1 - 46 files changed, 2765 insertions(+), 69 deletions(-) create mode 100644 kernel/base/container/los_net_container.c create mode 100644 kernel/base/include/los_net_container_pri.h create mode 100644 net/lwip-2.1/porting/include/lwip/ip.h create mode 100644 testsuites/unittest/container/smoke/It_net_container_001.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_002.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_003.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_004.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_005.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_006.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_007.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_008.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_009.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_010.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_011.cpp create mode 100644 testsuites/unittest/container/smoke/It_net_container_012.cpp diff --git a/BUILD.gn b/BUILD.gn index c34324ab..a97c49e8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -251,6 +251,7 @@ config("container_config") { "-DLOSCFG_IPC_CONTAINER", "-DLOSCFG_TIME_CONTAINER", "-DLOSCFG_USER_CONTAINER", + "-DLOSCFG_NET_CONTAINER", "-DLOSCFG_PROC_PROCESS_DIR", "-DLOSCFG_KERNEL_PLIMITS", "-DLOSCFG_KERNEL_MEM_PLIMIT", diff --git a/fs/proc/os_adapt/plimits_proc.c b/fs/proc/os_adapt/plimits_proc.c index 81f2f8ef..b18bd84e 100644 --- a/fs/proc/os_adapt/plimits_proc.c +++ b/fs/proc/os_adapt/plimits_proc.c @@ -585,7 +585,7 @@ static ssize_t MemLimitWriteLimit(struct ProcFile *pf, const CHAR *buf, size_t c { (void)ppos; long long int value = GetPidLimitValue(pf, buf, count); - if (value < 0) { + if ((value < 0) || (value > (long long int)OS_NULL_INT)) { return value; } @@ -678,7 +678,7 @@ static ssize_t IPCLimitWriteShmLimit(struct ProcFile *pf, const CHAR *buf, size_ { (void)ppos; long long int value = GetPidLimitValue(pf, buf, count); - if (value < 0) { + if ((value < 0) || (value > (long long int)OS_NULL_INT)) { return value; } diff --git a/fs/proc/os_adapt/process_proc.c b/fs/proc/os_adapt/process_proc.c index fcf9673c..39764dc0 100644 --- a/fs/proc/os_adapt/process_proc.c +++ b/fs/proc/os_adapt/process_proc.c @@ -91,6 +91,8 @@ static ssize_t ProcessContainerLink(unsigned int containerID, ContainerType type count = snprintf_s(buffer, bufLen, bufLen - 1, "'time:[%u]'", containerID); } else if (type == USER_CONTAINER) { count = snprintf_s(buffer, bufLen, bufLen - 1, "'user:[%u]'", containerID); + } else if (type == NET_CONTAINER) { + count = snprintf_s(buffer, bufLen, bufLen - 1, "'net:[%u]'", containerID); } if (count < 0) { @@ -574,6 +576,14 @@ static struct ProcProcess g_procProcess[] = { .fileOps = &UID_GID_MAP_FOPS }, #endif +#ifdef LOSCFG_IPC_CONTAINER + { + .name = "container/net", + .mode = S_IFLNK, + .type = NET_CONTAINER, + .fileOps = &PID_CONTAINER_FOPS + }, +#endif #endif }; diff --git a/kernel/Kconfig b/kernel/Kconfig index 4fcd60f7..197ddb71 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -108,6 +108,11 @@ config USER_CONTAINER default n depends on KERNEL_CONTAINER +config NET_CONTAINER + bool "Enable net container" + default n + depends on KERNEL_CONTAINER + ######################### config options of extended ##################### source "kernel/extended/Kconfig" diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn index cd87af0c..3212a9a3 100644 --- a/kernel/base/BUILD.gn +++ b/kernel/base/BUILD.gn @@ -36,6 +36,7 @@ kernel_module(module_name) { "container/los_credentials.c", "container/los_ipc_container.c", "container/los_mnt_container.c", + "container/los_net_container.c", "container/los_pid_container.c", "container/los_time_container.c", "container/los_user_container.c", diff --git a/kernel/base/container/los_container.c b/kernel/base/container/los_container.c index f0f1e31b..8a06f6fb 100644 --- a/kernel/base/container/los_container.c +++ b/kernel/base/container/los_container.c @@ -85,6 +85,10 @@ UINT32 OsGetContainerLimit(ContainerType type) case TIME_CONTAINER: case TIME_CHILD_CONTAINER: return g_containerLimit.timeLimit; +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return g_containerLimit.netLimit; #endif default: break; @@ -145,6 +149,11 @@ UINT32 OsSetContainerLimit(ContainerType type, UINT32 value) case TIME_CHILD_CONTAINER: g_containerLimit.timeLimit = value; break; +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + g_containerLimit.netLimit = value; + break; #endif default: SCHEDULER_UNLOCK(intSave); @@ -182,6 +191,10 @@ UINT32 OsGetContainerCount(ContainerType type) case TIME_CONTAINER: case TIME_CHILD_CONTAINER: return OsGetTimeContainerCount(); +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return OsGetNetContainerCount(); #endif default: break; @@ -216,6 +229,10 @@ VOID OsInitRootContainer(VOID) g_containerLimit.timeLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; (VOID)OsInitRootTimeContainer(&g_rootContainer.timeContainer); g_rootContainer.timeForChildContainer = g_rootContainer.timeContainer; +#endif +#ifdef LOSCFG_NET_CONTAINER + g_containerLimit.netLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT; + (VOID)OsInitRootNetContainer(&g_rootContainer.netContainer); #endif return; } @@ -272,10 +289,43 @@ STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *p if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsCopyNetContainer(flags, child, parent); + if (ret != LOS_OK) { + return ret; + } #endif return ret; } +STATIC INLINE UINT32 GetContainerFlagsMask(VOID) +{ + UINT32 mask = 0; +#ifdef LOSCFG_PID_CONTAINER + mask |= CLONE_NEWPID; +#endif +#ifdef LOSCFG_MNT_CONTAINER + mask |= CLONE_NEWNS; +#endif +#ifdef LOSCFG_IPC_CONTAINER + mask |= CLONE_NEWIPC; +#endif +#ifdef LOSCFG_USER_CONTAINER + mask |= CLONE_NEWUSER; +#endif +#ifdef LOSCFG_TIME_CONTAINER + mask |= CLONE_NEWTIME; +#endif +#ifdef LOSCFG_NET_CONTAINER + mask |= CLONE_NEWNET; +#endif +#ifdef LOSCFG_UTS_CONTAINER + mask |= CLONE_NEWUTS; +#endif + return mask; +} + /* * called from clone. This now handles copy for Container and all * namespaces therein. @@ -288,7 +338,7 @@ UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent flags &= ~CLONE_NEWTIME; #endif - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWTIME))) { + if (!(flags & GetContainerFlagsMask())) { #ifdef LOSCFG_PID_CONTAINER if (parent->container->pidContainer != parent->container->pidForChildContainer) { goto CREATE_CONTAINER; @@ -327,7 +377,7 @@ VOID OsContainerFree(LosProcessCB *processCB) } } -VOID OsContainersDestroy(LosProcessCB *processCB) +VOID OsOsContainersDestroyEarly(LosProcessCB *processCB) { /* All processes in the container must be destroyed before the container is destroyed. */ #ifdef LOSCFG_PID_CONTAINER @@ -336,6 +386,13 @@ VOID OsContainersDestroy(LosProcessCB *processCB) } #endif +#ifdef LOSCFG_MNT_CONTAINER + OsMntContainerDestroy(processCB->container); +#endif +} + +VOID OsContainersDestroy(LosProcessCB *processCB) +{ #ifdef LOSCFG_USER_CONTAINER OsUserContainerDestroy(processCB); #endif @@ -344,10 +401,6 @@ VOID OsContainersDestroy(LosProcessCB *processCB) OsUtsContainerDestroy(processCB->container); #endif -#ifdef LOSCFG_MNT_CONTAINER - OsMntContainerDestroy(processCB->container); -#endif - #ifdef LOSCFG_IPC_CONTAINER OsIpcContainerDestroy(processCB->container); #endif @@ -356,6 +409,10 @@ VOID OsContainersDestroy(LosProcessCB *processCB) OsTimeContainerDestroy(processCB->container); #endif +#ifdef LOSCFG_NET_CONTAINER + OsNetContainerDestroy(processCB->container); +#endif + #ifndef LOSCFG_PID_CONTAINER UINT32 intSave; SCHEDULER_LOCK(intSave); @@ -395,6 +452,10 @@ STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *p OsTimeContainerDestroy(container); #endif +#ifdef LOSCFG_NET_CONTAINER + OsNetContainerDestroy(container); +#endif + SCHEDULER_LOCK(intSave); LOS_AtomicDec(&container->rc); if (LOS_AtomicRead(&container->rc) == 0) { @@ -438,6 +499,10 @@ UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type) return OsGetTimeContainerID(container->timeContainer); case TIME_CHILD_CONTAINER: return OsGetTimeContainerID(container->timeForChildContainer); +#endif +#ifdef LOSCFG_NET_CONTAINER + case NET_CONTAINER: + return OsGetNetContainerID(container->netContainer); #endif default: break; @@ -477,6 +542,12 @@ STATIC UINT32 UnshareCreateNewContainers(UINT32 flags, LosProcessCB *curr, Conta if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsUnshareNetContainer(flags, curr, newContainer); + if (ret != LOS_OK) { + return ret; + } #endif return ret; } @@ -487,8 +558,7 @@ INT32 OsUnshare(UINT32 flags) UINT32 intSave; LosProcessCB *curr = OsCurrProcessGet(); Container *oldContainer = curr->container; - UINT32 unshareFlags = CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUSER; - + UINT32 unshareFlags = GetContainerFlagsMask(); if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) { return -EINVAL; } @@ -547,6 +617,8 @@ STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType) case TIME_CONTAINER: case TIME_CHILD_CONTAINER: return CLONE_NEWTIME; + case NET_CONTAINER: + return CLONE_NEWNET; default: break; } @@ -585,13 +657,19 @@ STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Co if (ret != LOS_OK) { return ret; } +#endif +#ifdef LOSCFG_NET_CONTAINER + ret = OsSetNsNetContainer(flags, container, newContainer); + if (ret != LOS_OK) { + return ret; + } #endif return LOS_OK; } STATIC UINT32 SetNsParamCheck(INT32 fd, INT32 type, UINT32 *flag, LosProcessCB **target) { - UINT32 typeMask = CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWTIME | CLONE_NEWUSER; + UINT32 typeMask = GetContainerFlagsMask(); *flag = (UINT32)(type & typeMask); UINT32 containerType = 0; diff --git a/kernel/base/container/los_net_container.c b/kernel/base/container/los_net_container.c new file mode 100644 index 00000000..aefe350b --- /dev/null +++ b/kernel/base/container/los_net_container.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include "los_net_container_pri.h" +#include "los_config.h" +#include "los_memory.h" +#include "los_process_pri.h" + +#ifdef LOSCFG_NET_CONTAINER +STATIC UINT32 g_currentNetContainerNum = 0; +STATIC NetContainer *g_rootNetContainer = NULL; + +STATIC struct netif *NetifAlloc(VOID) +{ + UINT32 size = sizeof(struct netif); + struct netif *netif = LOS_MemAlloc(m_aucSysMem1, size); + if (netif == NULL) { + return NULL; + } + (VOID)memset_s(netif, size, 0, size); + + return netif; +} + +STATIC VOID FreeNetif(struct netif *netif) +{ + if (netif != NULL) { + if (netif->peer != NULL) { + netif_remove(netif->peer); + (VOID)LOS_MemFree(m_aucSysMem1, netif->peer); + } + netif_remove(netif); + (VOID)LOS_MemFree(m_aucSysMem1, netif); + } +} + +STATIC UINT32 CreateVethNetif(NetContainer *netContainer, struct netif **veth) +{ + struct netif *netif = NetifAlloc(); + if (netif == NULL) { + return ENOMEM; + } + + veth_init(netif, netContainer->group); + + *veth = netif; + return LOS_OK; +} + +STATIC UINT32 InitVethPair(NetContainer *netContainer) +{ + struct netif *vethOfNetContainer = NULL; + struct netif *vethOfRootNetContainer = NULL; + + UINT32 ret = CreateVethNetif(netContainer, &vethOfNetContainer); + if (ret != LOS_OK) { + return ret; + } + + ret = CreateVethNetif(g_rootNetContainer, &vethOfRootNetContainer); + if (ret != LOS_OK) { + FreeNetif(vethOfNetContainer); + return ret; + } + + vethOfNetContainer->peer = vethOfRootNetContainer; + vethOfRootNetContainer->peer = vethOfNetContainer; + return LOS_OK; +} + +STATIC UINT32 InitLoopNetif(NetContainer *netContainer) +{ + struct netif *loop_netif = NetifAlloc(); + if (loop_netif == NULL) { + return ENOMEM; + } + + netContainer->group->loop_netif = loop_netif; + netif_init(netContainer->group); + return LOS_OK; +} + +STATIC UINT32 InitContainerNetifs(NetContainer *netContainer) +{ + UINT32 ret = InitLoopNetif(netContainer); + if (ret != LOS_OK) { + return ret; + } + return InitVethPair(netContainer); +} + +STATIC UINT32 InitNetGroup(NetContainer *netContainer) +{ + UINT32 size = sizeof(struct net_group); + struct net_group *group = LOS_MemAlloc(m_aucSysMem1, size); + if (group == NULL) { + return ENOMEM; + } + (VOID)memset_s(group, size, 0, size); + + netContainer->group = group; + return LOS_OK; +} + +STATIC VOID FreeNetContainerGroup(struct net_group *group) +{ + if (group == NULL) { + return; + } + + struct netif *freeNetif = group->netif_list; + struct netif *nextNetif = NULL; + + while (freeNetif != NULL) { + nextNetif = freeNetif->next; + FreeNetif(freeNetif); + freeNetif = nextNetif; + } +} + +VOID OsNetContainerDestroy(Container *container) +{ + UINT32 intSave; + if (container == NULL) { + return; + } + + SCHEDULER_LOCK(intSave); + NetContainer *netContainer = container->netContainer; + if (netContainer == NULL) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_AtomicDec(&netContainer->rc); + if (LOS_AtomicRead(&netContainer->rc) > 0) { + SCHEDULER_UNLOCK(intSave); + return; + } + + g_currentNetContainerNum--; + SCHEDULER_UNLOCK(intSave); + FreeNetContainerGroup(netContainer->group); + container->netContainer = NULL; + (VOID)LOS_MemFree(m_aucSysMem1, netContainer->group); + (VOID)LOS_MemFree(m_aucSysMem1, netContainer); + return; +} + +STATIC NetContainer *CreateNewNetContainer(NetContainer *parent) +{ + NetContainer *netContainer = LOS_MemAlloc(m_aucSysMem1, sizeof(NetContainer)); + if (netContainer == NULL) { + return NULL; + } + (VOID)memset_s(netContainer, sizeof(NetContainer), 0, sizeof(NetContainer)); + + netContainer->containerID = OsAllocContainerID(); + + if (parent != NULL) { + LOS_AtomicSet(&netContainer->rc, 1); + } else { + LOS_AtomicSet(&netContainer->rc, 3); /* 3: Three system processes */ + } + return netContainer; +} + +STATIC UINT32 CreateNetContainer(Container *container, NetContainer *parentContainer) +{ + UINT32 intSave, ret; + NetContainer *newNetContainer = CreateNewNetContainer(parentContainer); + if (newNetContainer == NULL) { + return ENOMEM; + } + + ret = InitNetGroup(newNetContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer); + return ret; + } + + ret = InitContainerNetifs(newNetContainer); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer->group); + (VOID)LOS_MemFree(m_aucSysMem1, newNetContainer); + return ret; + } + + SCHEDULER_LOCK(intSave); + g_currentNetContainerNum++; + container->netContainer = newNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent) +{ + UINT32 intSave; + NetContainer *currNetContainer = parent->container->netContainer; + + if (!(flags & CLONE_NEWNET)) { + SCHEDULER_LOCK(intSave); + LOS_AtomicInc(&currNetContainer->rc); + child->container->netContainer = currNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateNetContainer(child->container, currNetContainer); +} + +UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, Container *newContainer) +{ + UINT32 intSave; + NetContainer *parentContainer = curr->container->netContainer; + + if (!(flags & CLONE_NEWNET)) { + SCHEDULER_LOCK(intSave); + newContainer->netContainer = parentContainer; + LOS_AtomicInc(&parentContainer->rc); + SCHEDULER_UNLOCK(intSave); + return LOS_OK; + } + + if (OsContainerLimitCheck(NET_CONTAINER, &g_currentNetContainerNum) != LOS_OK) { + return EPERM; + } + + return CreateNetContainer(newContainer, parentContainer); +} + +UINT32 OsSetNsNetContainer(UINT32 flags, Container *container, Container *newContainer) +{ + if (flags & CLONE_NEWNET) { + newContainer->netContainer = container->netContainer; + LOS_AtomicInc(&container->netContainer->rc); + return LOS_OK; + } + + newContainer->netContainer = OsCurrProcessGet()->container->netContainer; + LOS_AtomicInc(&newContainer->netContainer->rc); + return LOS_OK; +} + +UINT32 OsGetNetContainerID(NetContainer *netContainer) +{ + if (netContainer == NULL) { + return OS_INVALID_VALUE; + } + + return netContainer->containerID; +} + +STATIC struct net_group *DoGetNetGroupFromCurrProcess(VOID) +{ + LosProcessCB *processCB = OsCurrProcessGet(); + NetContainer *netContainer = processCB->container->netContainer; + return netContainer->group; +} + +STATIC VOID DoSetNetifNetGroup(struct netif *netif, struct net_group *group) +{ + netif->group = group; +} + +STATIC struct net_group *DoGetNetGroupFromNetif(struct netif *netif) +{ + return netif != NULL ? netif->group : NULL; +} + +STATIC VOID DoSetIppcbNetGroup(struct ip_pcb *pcb, struct net_group *group) +{ + pcb->group = group; +} + +STATIC struct net_group *DoGetNetGroupFromIppcb(struct ip_pcb *pcb) +{ + return pcb != NULL ? pcb->group : NULL; +} + +struct net_group_ops netGroupOps = { + .get_curr_process_net_group = DoGetNetGroupFromCurrProcess, + .set_netif_net_group = DoSetNetifNetGroup, + .get_net_group_from_netif = DoGetNetGroupFromNetif, + .set_ippcb_net_group = DoSetIppcbNetGroup, + .get_net_group_from_ippcb = DoGetNetGroupFromIppcb, +}; + +UINT32 OsInitRootNetContainer(NetContainer **netContainer) +{ + UINT32 intSave; + NetContainer *newNetContainer = CreateNewNetContainer(NULL); + if (newNetContainer == NULL) { + return ENOMEM; + } + + newNetContainer->group = get_root_net_group(); + set_default_net_group_ops(&netGroupOps); + + SCHEDULER_LOCK(intSave); + g_currentNetContainerNum++; + *netContainer = newNetContainer; + g_rootNetContainer = newNetContainer; + SCHEDULER_UNLOCK(intSave); + return LOS_OK; +} + +UINT32 OsGetNetContainerCount(VOID) +{ + return g_currentNetContainerNum; +} +#endif diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 9b1942d4..b72f6994 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -442,7 +442,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) #endif #ifdef LOSCFG_KERNEL_CONTAINER - OsContainersDestroy(processCB); + OsOsContainersDestroyEarly(processCB); #endif #ifdef LOSCFG_FS_VFS @@ -451,6 +451,11 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB) } processCB->files = NULL; #endif + +#ifdef LOSCFG_KERNEL_CONTAINER + OsContainersDestroy(processCB); +#endif + #ifdef LOSCFG_KERNEL_PLIMITS OsPLimitsDeleteProcess(processCB); #endif @@ -2152,6 +2157,9 @@ LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) #ifdef LOSCFG_USER_CONTAINER cloneFlag |= CLONE_NEWUSER; #endif +#ifdef LOSCFG_NET_CONTAINER + cloneFlag |= CLONE_NEWNET; +#endif #endif if (flags & (~cloneFlag)) { diff --git a/kernel/base/include/los_container_pri.h b/kernel/base/include/los_container_pri.h index f4122bfd..d7b72c70 100644 --- a/kernel/base/include/los_container_pri.h +++ b/kernel/base/include/los_container_pri.h @@ -51,6 +51,9 @@ #ifdef LOSCFG_TIME_CONTAINER #include "los_time_container_pri.h" #endif +#ifdef LOSCFG_NET_CONTAINER +#include "los_net_container_pri.h" +#endif typedef enum { CONTAINER = 0, @@ -62,6 +65,7 @@ typedef enum { USER_CONTAINER, TIME_CONTAINER, TIME_CHILD_CONTAINER, + NET_CONTAINER, CONTAINER_MAX, } ContainerType; @@ -84,6 +88,9 @@ typedef struct Container { struct TimeContainer *timeContainer; struct TimeContainer *timeForChildContainer; #endif +#ifdef LOSCFG_NET_CONTAINER + struct NetContainer *netContainer; +#endif } Container; typedef struct TagContainerLimit { @@ -105,6 +112,9 @@ typedef struct TagContainerLimit { #ifdef LOSCFG_USER_CONTAINER UINT32 userLimit; #endif +#ifdef LOSCFG_NET_CONTAINER + UINT32 netLimit; +#endif } ContainerLimit; VOID OsContainerInitSystemProcess(LosProcessCB *processCB); @@ -113,6 +123,8 @@ VOID OsInitRootContainer(VOID); UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID); +VOID OsOsContainersDestroyEarly(LosProcessCB *processCB); + VOID OsContainersDestroy(LosProcessCB *processCB); VOID OsContainerFree(LosProcessCB *processCB); diff --git a/kernel/base/include/los_net_container_pri.h b/kernel/base/include/los_net_container_pri.h new file mode 100644 index 00000000..3b1d30ed --- /dev/null +++ b/kernel/base/include/los_net_container_pri.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ + +#ifndef _LOS_NET_CONTAINER_PRI_H +#define _LOS_NET_CONTAINER_PRI_H +#include +#include +#include +#include "los_atomic.h" + +#ifdef LOSCFG_NET_CONTAINER +typedef struct ProcessCB LosProcessCB; +struct Container; + +typedef struct NetContainer { + Atomic rc; + struct net_group *group; + UINT32 containerID; +} NetContainer; + +UINT32 OsInitRootNetContainer(NetContainer **ipcContainer); + +UINT32 OsCopyNetContainer(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent); + +UINT32 OsUnshareNetContainer(UINTPTR flags, LosProcessCB *curr, struct Container *newContainer); + +UINT32 OsSetNsNetContainer(UINT32 flags, struct Container *container, struct Container *newContainer); + +VOID OsNetContainerDestroy(struct Container *container); + +UINT32 OsGetNetContainerID(NetContainer *ipcContainer); + +UINT32 OsGetNetContainerCount(VOID); +#endif +#endif /* _LOS_NET_CONTAINER_PRI_H */ diff --git a/kernel/base/vm/shm.c b/kernel/base/vm/shm.c index 9f3f878d..637c6167 100644 --- a/kernel/base/vm/shm.c +++ b/kernel/base/vm/shm.c @@ -206,6 +206,12 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) return -ENOMEM; } +#ifdef LOSCFG_KERNEL_IPC_PLIMIT + if (OsIPCLimitShmAlloc(*size) != LOS_OK) { + return -ENOMEM; + } +#endif + for (i = 0; i < IPC_SHM_INFO.shmmni; i++) { if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) { IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE; @@ -217,12 +223,6 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum) if (*segNum < 0) { return -ENOSPC; } - -#ifdef LOSCFG_KERNEL_IPC_PLIMIT - if (OsIPCLimitShmAlloc(*size) != LOS_OK) { - return -ENOMEM; - } -#endif return 0; } diff --git a/kernel/extended/plimit/los_devicelimit.c b/kernel/extended/plimit/los_devicelimit.c index 00e5930a..b0bda55e 100644 --- a/kernel/extended/plimit/los_devicelimit.c +++ b/kernel/extended/plimit/los_devicelimit.c @@ -51,7 +51,7 @@ VOID OsDevLimitInit(UINTPTR limit) VOID *OsDevLimitAlloc(VOID) { - ProcDevLimit *plimit = (ProcDevLimit *)LOS_KernelMalloc(sizeof(ProcDevLimit)); + ProcDevLimit *plimit = (ProcDevLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcDevLimit)); if (plimit == NULL) { return NULL; } @@ -67,7 +67,7 @@ STATIC VOID DevAccessListDelete(ProcDevLimit *devLimit) DevAccessItem *tmpItem = NULL; LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(delItem, tmpItem, &devLimit->accessList, DevAccessItem, list) { LOS_ListDelete(&delItem->list); - LOS_KernelFree((VOID *)delItem); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)delItem); } } @@ -79,7 +79,7 @@ VOID OsDevLimitFree(UINTPTR limit) } DevAccessListDelete(devLimit); - LOS_KernelFree(devLimit); + (VOID)LOS_MemFree(m_aucSysMem1, devLimit); } STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLimitSrc) @@ -88,7 +88,7 @@ STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLi INT32 itemSize = sizeof(DevAccessItem); devLimitDest->behavior = devLimitSrc->behavior; LOS_DL_LIST_FOR_EACH_ENTRY(tmpItem, &devLimitSrc->accessList, DevAccessItem, list) { - DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(itemSize); + DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, itemSize); if (newItem == NULL) { return ENOMEM; } @@ -326,7 +326,7 @@ STATIC VOID DevLimitAccessListRm(ProcDevLimit *devLimit, DevAccessItem *item) walk->access &= ~item->access; if (!walk->access) { LOS_ListDelete(&walk->list); - LOS_KernelFree((VOID *)walk); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)walk); } } } @@ -338,7 +338,7 @@ STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item) } DevAccessItem *walk = NULL; - DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(sizeof(DevAccessItem)); + DevAccessItem *newItem = (DevAccessItem *)LOS_MemAlloc(m_aucSysMem1, sizeof(DevAccessItem)); if (newItem == NULL) { return ENOMEM; } @@ -351,7 +351,7 @@ STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item) continue; } walk->access |= item->access; - LOS_KernelFree((VOID *)newItem); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)newItem); newItem = NULL; } diff --git a/kernel/extended/plimit/los_ipclimit.c b/kernel/extended/plimit/los_ipclimit.c index dc92ba94..78df3f79 100644 --- a/kernel/extended/plimit/los_ipclimit.c +++ b/kernel/extended/plimit/los_ipclimit.c @@ -33,7 +33,7 @@ #ifdef LOSCFG_KERNEL_IPC_PLIMIT STATIC ProcIPCLimit *g_rootIPCLimit = NULL; -#define PLIMIT_IPC_SHM_LIMIT_MAX 104857600 +#define PLIMIT_IPC_SHM_LIMIT_MAX 0xFFFFFFFF VOID OsIPCLimitInit(UINTPTR limite) { @@ -45,7 +45,7 @@ VOID OsIPCLimitInit(UINTPTR limite) VOID *OsIPCLimitAlloc(VOID) { - ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_KernelMalloc(sizeof(ProcIPCLimit)); + ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIPCLimit)); if (plimite == NULL) { return NULL; } @@ -60,7 +60,7 @@ VOID OsIPCLimitFree(UINTPTR limite) return; } - LOS_KernelFree((VOID *)plimite); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)plimite); } VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src) diff --git a/kernel/extended/plimit/los_ipclimit.h b/kernel/extended/plimit/los_ipclimit.h index 39b967f4..b91da73d 100644 --- a/kernel/extended/plimit/los_ipclimit.h +++ b/kernel/extended/plimit/los_ipclimit.h @@ -46,7 +46,6 @@ typedef struct ProcIPCLimit { UINT32 shmSize; UINT32 shmFailedCount; UINT32 shmSizeLimit; - UINT64 migrateTime; } ProcIPCLimit; enum IPCStatType { diff --git a/kernel/extended/plimit/los_memlimit.c b/kernel/extended/plimit/los_memlimit.c index a1af5bdf..f69064e4 100644 --- a/kernel/extended/plimit/los_memlimit.c +++ b/kernel/extended/plimit/los_memlimit.c @@ -52,7 +52,7 @@ VOID OsMemLimitSetLimit(UINT32 limit) VOID *OsMemLimiterAlloc(VOID) { - ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_KernelMalloc(sizeof(ProcMemLimiter)); + ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcMemLimiter)); if (plimite == NULL) { return NULL; } @@ -67,7 +67,7 @@ VOID OsMemLimiterFree(UINTPTR limite) return; } - LOS_KernelFree((VOID *)limite); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limite); } VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src) diff --git a/kernel/extended/plimit/los_plimits.c b/kernel/extended/plimit/los_plimits.c index 2e420978..93acd506 100644 --- a/kernel/extended/plimit/los_plimits.c +++ b/kernel/extended/plimit/los_plimits.c @@ -121,7 +121,7 @@ ProcLimiterSet *OsRootPLimitsGet(VOID) UINT32 OsProcLimiterSetInit(VOID) { - g_rootPLimite = (ProcLimiterSet *)LOS_KernelMalloc(sizeof(ProcLimiterSet)); + g_rootPLimite = (ProcLimiterSet *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcLimiterSet)); if (g_rootPLimite == NULL) { return ENOMEM; } @@ -145,6 +145,25 @@ UINT32 OsProcLimiterSetInit(VOID) return LOS_OK; } +STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB) +{ + if ((processCB == NULL) || (processCB->plimits == NULL)) { + return; + } + + ProcLimiterSet *plimits = processCB->plimits; + for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { + if (g_limiteOps[limitsID].LimiterDelProcess == NULL) { + continue; + } + g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB); + } + plimits->pidCount--; + LOS_ListDelete(&processCB->plimitsList); + processCB->plimits = NULL; + return; +} + STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB) { UINT32 limitsID; @@ -170,6 +189,8 @@ STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB } } + PLimitsDeleteProcess(processCB); + for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { if (g_limiteOps[limitsID].LimiterAddProcess == NULL) { continue; @@ -215,25 +236,6 @@ UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid) return ret; } -STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB) -{ - if ((processCB == NULL) || (processCB->plimits == NULL)) { - return; - } - - ProcLimiterSet *plimits = processCB->plimits; - for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) { - if (g_limiteOps[limitsID].LimiterDelProcess == NULL) { - continue; - } - g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB); - } - plimits->pidCount--; - LOS_ListDelete(&processCB->plimitsList); - processCB->plimits = NULL; - return; -} - VOID OsPLimitsDeleteProcess(LosProcessCB *processCB) { UINT32 intSave; @@ -318,7 +320,7 @@ UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits) g_limiteOps[limiteID].LimiterFree(procLimiter); } } - LOS_KernelFree(currPLimits); + (VOID)LOS_MemFree(m_aucSysMem1, currPLimits); return LOS_OK; } diff --git a/kernel/extended/plimit/los_processlimit.c b/kernel/extended/plimit/los_processlimit.c index ea21c6f2..5e8a8054 100644 --- a/kernel/extended/plimit/los_processlimit.c +++ b/kernel/extended/plimit/los_processlimit.c @@ -52,7 +52,7 @@ VOID PidLimiterInit(UINTPTR limit) VOID *PidLimiterAlloc(VOID) { - PidLimit *plimite = (PidLimit *)LOS_KernelMalloc(sizeof(PidLimit)); + PidLimit *plimite = (PidLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(PidLimit)); if (plimite == NULL) { return NULL; } @@ -67,7 +67,7 @@ VOID PidLimterFree(UINTPTR limit) return; } - LOS_KernelFree((VOID *)limit); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit); } BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent) diff --git a/kernel/extended/plimit/los_schedlimit.c b/kernel/extended/plimit/los_schedlimit.c index c91359d6..dbba6bb9 100644 --- a/kernel/extended/plimit/los_schedlimit.c +++ b/kernel/extended/plimit/los_schedlimit.c @@ -44,7 +44,7 @@ VOID OsSchedLimitInit(UINTPTR limit) VOID *OsSchedLimitAlloc(VOID) { - ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_KernelMalloc(sizeof(ProcSchedLimiter)); + ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcSchedLimiter)); if (plimit == NULL) { return NULL; } @@ -59,7 +59,7 @@ VOID OsSchedLimitFree(UINTPTR limit) return; } - LOS_KernelFree((VOID *)limit); + (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)limit); } VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src) diff --git a/kernel/extended/plimit/los_schedlimit.h b/kernel/extended/plimit/los_schedlimit.h index 65919a76..7d958bd2 100644 --- a/kernel/extended/plimit/los_schedlimit.h +++ b/kernel/extended/plimit/los_schedlimit.h @@ -48,8 +48,6 @@ typedef struct ProcSchedLimiter { UINT64 period; UINT64 quota; UINT64 allRuntime; - UINT64 overrunTime; - UINT64 stat; } ProcSchedLimiter; VOID OsSchedLimitInit(UINTPTR limit); diff --git a/net/lwip-2.1/enhancement/src/api_shell.c b/net/lwip-2.1/enhancement/src/api_shell.c index 044df974..ebe65624 100644 --- a/net/lwip-2.1/enhancement/src/api_shell.c +++ b/net/lwip-2.1/enhancement/src/api_shell.c @@ -273,7 +273,9 @@ int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len) #if LWIP_IPV6 char *addr = NULL; #endif - +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_net_group_from_netif(netif); +#endif if (buf_len < 1) { goto out; } @@ -348,7 +350,11 @@ int print_netif(struct netif *netif, char *print_buf, unsigned int buf_len) tmp += ret; buf_len -= (unsigned int)ret; +#ifdef LOSCFG_NET_CONTAINER + if ((group->netif_default == netif) && (netif_is_up(netif))) { +#else if (netif_default == netif && netif_is_up(netif)) { +#endif ret = snprintf_s(tmp, buf_len, (buf_len - 1), " %s", "Default"); if ((ret <= 0) || ((unsigned int)ret >= buf_len)) goto out; @@ -432,8 +438,12 @@ void lwip_ifconfig_show_internal(void *arg) struct netif *netif = NULL; struct ifconfig_option *ifconfig_cmd = (struct ifconfig_option *)arg; int ret; - +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); + if (group->netif_list == NULL) { +#else if (netif_list == NULL) { +#endif ret = snprintf_s(ifconfig_cmd->cb_print_buf, PRINT_BUF_LEN - ifconfig_cmd->print_len, ((PRINT_BUF_LEN - ifconfig_cmd->print_len) - 1), "Device not init\n"); if ((ret > 0) && ((unsigned int)ret < (PRINT_BUF_LEN - ifconfig_cmd->print_len))) { @@ -445,7 +455,11 @@ void lwip_ifconfig_show_internal(void *arg) if (ifconfig_cmd->iface[0] == '\0') { /* display all netif */ +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif ret = print_netif(netif, ifconfig_cmd->cb_print_buf + ifconfig_cmd->print_len, PRINT_BUF_LEN - ifconfig_cmd->print_len); ifconfig_cmd->print_len += (unsigned int)ret; @@ -486,7 +500,9 @@ void lwip_ifconfig_internal(void *arg) int ret; s8_t idx; err_t err; - +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); +#endif ifconfig_cmd = (struct ifconfig_option *)arg; netif = netif_find(ifconfig_cmd->iface); if (netif == NULL) { @@ -521,13 +537,22 @@ void lwip_ifconfig_internal(void *arg) /* reset gateway if new and previous ipaddr not in same net */ if (!ip_addr_netcmp_val(&ip_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { ip_addr_set_zero(&netif->gw); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else if (netif == netif_default) { (void)netif_set_default(NULL); +#endif } } /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else loc_netif = netif_list; +#endif while (loc_netif != NULL) { if (loc_netif == netif) { loc_netif = loc_netif->next; @@ -577,7 +602,11 @@ void lwip_ifconfig_internal(void *arg) #endif if (netif_ip4_netmask(netif)->addr != ip_2_ip4(&netmask)->addr) { /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else loc_netif = netif_list; +#endif while (loc_netif != NULL) { if (loc_netif == netif) { loc_netif = loc_netif->next; @@ -594,8 +623,13 @@ void lwip_ifconfig_internal(void *arg) /* check if gateway still reachable */ if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&netmask))) { ip_addr_set_zero(&(netif->gw)); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else if (netif == netif_default) { (void)netif_set_default(NULL); +#endif } } } @@ -630,9 +664,15 @@ void lwip_ifconfig_internal(void *arg) goto out; } +#ifdef LOSCFG_NET_CONTAINER + if (group->netif_default != netif) { + ip_addr_set_zero(&netif->gw); + (void)netif_set_default(netif, group); +#else if (netif_default != netif) { ip_addr_set_zero(&netif->gw); (void)netif_set_default(netif); +#endif } #if LWIP_DHCP @@ -1255,7 +1295,9 @@ void lwip_arp_internal(void *arg) ip4_addr_t ipaddr; err_t ret = 0; int type = 0; - +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); +#endif if (arp_cmd->iface[0] == 'd' && arp_cmd->iface[1] == 'e') { netif = NULL; } else { @@ -1302,7 +1344,11 @@ void lwip_arp_internal(void *arg) if (netif != NULL) { ret = etharp_delete_arp_entry(netif, &ipaddr); } else { +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif ret = etharp_delete_arp_entry(netif, &ipaddr); if (ret == ERR_OK) { /* only can del success one time */ diff --git a/net/lwip-2.1/enhancement/src/fixme.c b/net/lwip-2.1/enhancement/src/fixme.c index 44d8f778..f52b73ef 100644 --- a/net/lwip-2.1/enhancement/src/fixme.c +++ b/net/lwip-2.1/enhancement/src/fixme.c @@ -202,7 +202,11 @@ void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr) (void)err; } +#ifdef LOSCFG_NET_CONTAINER +static struct netif *netif_find_by_name(const char *name, struct net_group *group) +#else static struct netif *netif_find_by_name(const char *name) +#endif { struct netif *netif = NULL; @@ -212,7 +216,11 @@ static struct netif *netif_find_by_name(const char *name) return NULL; } +#ifdef LOSCFG_NET_CONTAINER + NETIF_FOREACH(netif, group) { +#else NETIF_FOREACH(netif) { +#endif if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) { LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found lo\n")); return netif; @@ -234,7 +242,12 @@ static err_t netifapi_do_find_by_name(struct tcpip_api_call_data *m) * We know it works because the structs have been instantiated as struct netifapi_msg */ struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_curr_process_net_group(); + msg->netif = netif_find_by_name(msg->msg.ifs.name, group); +#else msg->netif = netif_find_by_name(msg->msg.ifs.name); +#endif return ERR_OK; } @@ -341,7 +354,6 @@ err_t etharp_delete_arp_entry(struct netif *netif, ip4_addr_t *ipaddr) return 0; } - err_t lwip_dns_setserver(u8_t numdns, ip_addr_t *dnsserver) { (void)numdns; diff --git a/net/lwip-2.1/porting/include/lwip/ip.h b/net/lwip-2.1/porting/include/lwip/ip.h new file mode 100644 index 00000000..4a480c08 --- /dev/null +++ b/net/lwip-2.1/porting/include/lwip/ip.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ + +#ifndef _LWIP_PORTING_IP_H_ +#define _LWIP_PORTING_IP_H_ + +#define IP_PCB_NETGROUP ;struct net_group *group + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_IP_H_ */ diff --git a/net/lwip-2.1/porting/include/lwip/netif.h b/net/lwip-2.1/porting/include/lwip/netif.h index 2633cd71..6109193f 100644 --- a/net/lwip-2.1/porting/include/lwip/netif.h +++ b/net/lwip-2.1/porting/include/lwip/netif.h @@ -41,12 +41,27 @@ #define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \ LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS #endif + +#ifdef LOSCFG_NET_CONTAINER +#include "lwip/net_group.h" +#define VETH_DRIVER_IF 2 +void veth_init(struct netif *netif, struct net_group *group); +#define linkoutput linkoutput; \ + void (*drv_send)(struct netif *netif, struct pbuf *p); \ + u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \ + void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \ + char full_name[IFNAMSIZ]; \ + struct net_group *group; \ + struct netif *peer; \ + u16_t link_layer_type +#else #define linkoutput linkoutput; \ void (*drv_send)(struct netif *netif, struct pbuf *p); \ u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \ void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \ char full_name[IFNAMSIZ]; \ u16_t link_layer_type +#endif #include_next #undef linkoutput #if LWIP_DHCPS diff --git a/net/lwip-2.1/porting/src/driverif.c b/net/lwip-2.1/porting/src/driverif.c index 031d562d..bb387124 100644 --- a/net/lwip-2.1/porting/src/driverif.c +++ b/net/lwip-2.1/porting/src/driverif.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef LOSCFG_NET_CONTAINER +#include +#endif #define LWIP_NETIF_HOSTNAME_DEFAULT "default" #define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps @@ -62,7 +65,11 @@ driverif_init_ifname(struct netif *netif) "%s%d", prefix, i) < 0) { break; } +#ifdef LOSCFG_NET_CONTAINER + NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) { +#else NETIF_FOREACH(tmpnetif) { +#endif if (strcmp(tmpnetif->full_name, netif->full_name) == 0) { break; } @@ -314,3 +321,60 @@ driverif_init(struct netif *netif) LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif)); return ERR_OK; } + +#ifdef LOSCFG_NET_CONTAINER +static err_t netif_veth_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) +{ + LWIP_UNUSED_ARG(addr); + return netif_loop_output(netif->peer, p); +} + +static void veth_init_fullname(struct netif *netif) +{ + struct netif *tmpnetif = NULL; + + for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) { + if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1, + "%s%d", "veth", i) < 0) { + break; + } + NETIF_FOREACH(tmpnetif, get_net_group_from_netif(netif)) { + if (strcmp(tmpnetif->full_name, netif->full_name) == 0) { + break; + } + } + if (tmpnetif == NULL) { + return; + } + } + netif->full_name[0] = '\0'; +} + +static err_t netif_vethif_init(struct netif *netif) +{ + LWIP_ASSERT("netif_vethif_init: invalid netif", netif != NULL); + + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + MIB2_INIT_NETIF(netif, snmp_ifType_other, 0); + netif->link_layer_type = VETH_DRIVER_IF; + + netif->name[0] = 'v'; + netif->name[1] = 'e'; + + veth_init_fullname(netif); + netif->output = netif_veth_output; + + netif_set_flags(netif, NETIF_FLAG_IGMP); + NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_DISABLE_ALL); + return ERR_OK; +} + +void veth_init(struct netif *netif, struct net_group *group) +{ + netif_add_noaddr(netif, group, NULL, netif_vethif_init, tcpip_input); + netif_set_link_up(netif); + netif_set_up(netif); +} +#endif diff --git a/net/lwip-2.1/porting/src/sockets.c b/net/lwip-2.1/porting/src/sockets.c index 9d2fa688..cae2fc7a 100644 --- a/net/lwip-2.1/porting/src/sockets.c +++ b/net/lwip-2.1/porting/src/sockets.c @@ -404,7 +404,11 @@ int get_unused_socket_num(void) #include +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten) +#endif { struct netif *netif = NULL; ip_addr_t rtgw_addr; @@ -429,7 +433,11 @@ static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten) } /* check if reachable */ +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif if (ip_addr_netcmp(&rtgw_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask))) { break; } @@ -450,9 +458,15 @@ static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten) } /* Add validation */ +#ifdef LOSCFG_NET_CONTAINER + if ((group->netif_default != NULL) && (group->netif_default != netif)) { + ip_addr_set_zero(&group->netif_default->gw); + (void)netif_set_default(netif, group); +#else if ((netif_default != NULL) && (netif_default != netif)) { ip_addr_set_zero(&netif_default->gw); (void)netif_set_default(netif); +#endif } netif_set_gw(netif, ip_2_ip4(&rtgw_addr)); @@ -462,8 +476,11 @@ static u8_t lwip_ioctl_internal_SIOCADDRT(struct rtentry *rmten) #endif #if LWIP_IOCTL_IF - +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr) +#endif { struct ifconf *ifc = NULL; struct netif *netif = NULL; @@ -479,7 +496,11 @@ static u8_t lwip_ioctl_internal_SIOCGIFCONF(struct ifreq *ifr) /* Loop over the interfaces, and write an info block for each. */ pos = 0; +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif if (ifc->ifc_buf == NULL) { pos = (pos + (int)sizeof(struct ifreq)); continue; @@ -554,7 +575,11 @@ static u8_t lwip_ioctl_internal_SIOCSIFADDR_6(struct ifreq *ifr) return ENOSYS; } +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr) +#endif { struct netif *netif = NULL; @@ -591,13 +616,22 @@ static u8_t lwip_ioctl_internal_SIOCSIFADDR(struct ifreq *ifr) /* reset gateway if new and previous ipaddr not in same net */ if (ip_addr_netcmp(&taget_addr, &netif->ip_addr, ip_2_ip4(&netif->netmask)) == 0) { ip_addr_set_zero(&netif->gw); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else if (netif == netif_default) { (void)netif_set_default(NULL); +#endif } } /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else loc_netif = netif_list; +#endif while (loc_netif != NULL) { if (loc_netif == netif) { loc_netif = loc_netif->next; @@ -637,7 +671,11 @@ static u8_t lwip_ioctl_internal_SIOCDIFADDR_6(struct ifreq *ifr) return ENOSYS; } +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr) +#endif { struct netif *netif = NULL; @@ -678,8 +716,13 @@ static u8_t lwip_ioctl_internal_SIOCDIFADDR(struct ifreq *ifr) ip_addr_set_zero(&netif->gw); ip_addr_set_zero(&netif->ip_addr); ip_addr_set_zero(&netif->netmask); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else if (netif == netif_default) { (void)netif_set_default(NULL); +#endif } #if LWIP_IPV4 && LWIP_ARP @@ -708,7 +751,11 @@ static u8_t lwip_ioctl_internal_SIOCGIFNETMASK(struct ifreq *ifr) } } +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr) +#endif { struct netif *netif = NULL; @@ -742,12 +789,20 @@ static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr) return 0; } /* check data valid */ +#ifdef LOSCFG_NET_CONTAINER + if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) == 0) { +#else if (ip_addr_netmask_valid(ip_2_ip4(&taget_addr)) != 0) { +#endif return EINVAL; } /* lwip disallow two netif sit in same net at the same time */ +#ifdef LOSCFG_NET_CONTAINER + loc_netif = group->netif_list; +#else loc_netif = netif_list; +#endif while (loc_netif != NULL) { if (loc_netif == netif) { loc_netif = loc_netif->next; @@ -773,8 +828,13 @@ static u8_t lwip_ioctl_internal_SIOCSIFNETMASK(struct ifreq *ifr) /* check if gateway still reachable */ if (!ip_addr_netcmp(&netif->gw, &netif->ip_addr, ip_2_ip4(&taget_addr))) { ip_addr_set_zero(&(netif->gw)); +#ifdef LOSCFG_NET_CONTAINER + if (netif == group->netif_default) { + (void)netif_set_default(NULL, group); +#else if (netif == netif_default) { (void)netif_set_default(NULL); +#endif } } return 0; @@ -1002,12 +1062,19 @@ static u8_t lwip_ioctl_internal_SIOCGIFFLAGS(struct ifreq *ifr) } } +#ifdef LOSCFG_NET_CONTAINER +static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr, struct net_group *group) +#else static u8_t lwip_ioctl_internal_SIOCGIFNAME(struct ifreq *ifr) +#endif { struct netif *netif = NULL; int ret; - +#ifdef LOSCFG_NET_CONTAINER + for (netif = group->netif_list; netif != NULL; netif = netif->next) { +#else for (netif = netif_list; netif != NULL; netif = netif->next) { +#endif if (ifr->ifr_ifindex == netif_get_index(netif)) { break; } @@ -1325,7 +1392,9 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) /* allow it only on IPv6 sockets... */ is_ipv6 = NETCONNTYPE_ISIPV6((unsigned int)(sock->conn->type)); #endif - +#ifdef LOSCFG_NET_CONTAINER + struct net_group *group = get_net_group_from_ippcb(sock->conn->pcb.ip); +#endif switch ((u32_t)cmd) { #if LWIP_IPV6 #if LWIP_IPV6_DUP_DETECT_ATTEMPTS @@ -1371,7 +1440,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) if (is_ipv6 != 0) { err = EINVAL; } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCADDRT(rmten, group); +#else err = lwip_ioctl_internal_SIOCADDRT(rmten); +#endif } break; #endif @@ -1381,7 +1454,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) if (is_ipv6 != 0) { err = EINVAL; } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCGIFCONF(ifr, group); +#else err = lwip_ioctl_internal_SIOCGIFCONF(ifr); +#endif } break; case SIOCGIFADDR: @@ -1395,7 +1472,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) if (is_ipv6 != 0) { err = lwip_ioctl_internal_SIOCSIFADDR_6(ifr); } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCSIFADDR(ifr, group); +#else err = lwip_ioctl_internal_SIOCSIFADDR(ifr); +#endif } break; case SIOCDIFADDR: @@ -1403,7 +1484,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) if (is_ipv6 != 0) { err = lwip_ioctl_internal_SIOCDIFADDR_6(ifr); } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCDIFADDR(ifr, group); +#else err = lwip_ioctl_internal_SIOCDIFADDR(ifr); +#endif } break; case SIOCGIFNETMASK: @@ -1417,7 +1502,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) if (is_ipv6 != 0) { err = EINVAL; } else { +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr, group); +#else err = lwip_ioctl_internal_SIOCSIFNETMASK(ifr); +#endif } break; case SIOCSIFHWADDR: @@ -1433,7 +1522,11 @@ static u8_t lwip_ioctl_impl(const struct lwip_sock *sock, long cmd, void *argp) err = lwip_ioctl_internal_SIOCGIFFLAGS(ifr); break; case SIOCGIFNAME: +#ifdef LOSCFG_NET_CONTAINER + err = lwip_ioctl_internal_SIOCGIFNAME(ifr, group); +#else err = lwip_ioctl_internal_SIOCGIFNAME(ifr); +#endif break; case SIOCSIFNAME: err = lwip_ioctl_internal_SIOCSIFNAME(ifr); diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index 23857e8a..3217b8dd 100644 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -547,6 +547,10 @@ long SysSetUserID(int uid) int retval = -EPERM; unsigned int intSave; + if (uid < 0) { + return -EINVAL; + } + UINT32 kuid = OsMakeKuid(userContainer, uid); if (kuid == (UINT32)-1) { return -EINVAL; @@ -702,6 +706,10 @@ int SysSetGroupID(int gid) unsigned int intSave; int count; + if (gid < 0) { + return -EINVAL; + } + unsigned int kgid = OsMakeKgid(userContainer, gid); if (kgid == (UINT32)-1) { return -EINVAL; diff --git a/testsuites/unittest/config.gni b/testsuites/unittest/config.gni index 50df5755..284e0ae0 100644 --- a/testsuites/unittest/config.gni +++ b/testsuites/unittest/config.gni @@ -143,6 +143,7 @@ LOSCFG_USER_TEST_MNT_CONTAINER = false LOSCFG_USER_TEST_IPC_CONTAINER = false LOSCFG_USER_TEST_TIME_CONTAINER = false LOSCFG_USER_TEST_USER_CONTAINER = false +LOSCFG_USER_TEST_NET_CONTAINER = false if (defined(LOSCFG_KERNEL_CONTAINER) || liteos_container_test_enable == true) { LOSCFG_USER_TEST_CONTAINER = true if (defined(LOSCFG_PID_CONTAINER) || liteos_container_test_enable == true) { @@ -163,6 +164,9 @@ if (defined(LOSCFG_KERNEL_CONTAINER) || liteos_container_test_enable == true) { if (defined(LOSCFG_USER_CONTAINER) || liteos_container_test_enable == true) { LOSCFG_USER_TEST_USER_CONTAINER = true } + if (defined(LOSCFG_NET_CONTAINER) || liteos_container_test_enable == true) { + LOSCFG_USER_TEST_NET_CONTAINER = true + } } LOSCFG_USER_TEST_PROCESS_PLIMITS = false diff --git a/testsuites/unittest/container/BUILD.gn b/testsuites/unittest/container/BUILD.gn index 032e9e97..9fe3d401 100644 --- a/testsuites/unittest/container/BUILD.gn +++ b/testsuites/unittest/container/BUILD.gn @@ -50,6 +50,9 @@ config("container_config") { if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) { cflags += [ "-DLOSCFG_USER_TEST_USER_CONTAINER" ] } + if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) { + cflags += [ "-DLOSCFG_USER_TEST_NET_CONTAINER" ] + } cflags_cc = cflags } diff --git a/testsuites/unittest/container/It_container_test.cpp b/testsuites/unittest/container/It_container_test.cpp index dffb215d..c9d771da 100644 --- a/testsuites/unittest/container/It_container_test.cpp +++ b/testsuites/unittest/container/It_container_test.cpp @@ -181,7 +181,151 @@ HWTEST_F(ContainerTest, ItContainer001, TestSize.Level0) { ItContainer001(); } +#if defined(LOSCFG_USER_TEST_NET_CONTAINER) +/** +* @tc.name: Container_NET_Test_001 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer001, TestSize.Level0) +{ + ItNetContainer001(); +} +/** +* @tc.name: Container_NET_Test_002 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer002, TestSize.Level0) +{ + ItNetContainer002(); +} + +/** +* @tc.name: Container_NET_Test_003 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer003, TestSize.Level0) +{ + ItNetContainer003(); +} + +/** +* @tc.name: Container_NET_Test_004 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer004, TestSize.Level0) +{ + ItNetContainer004(); +} + +/** +* @tc.name: Container_NET_Test_005 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer005, TestSize.Level0) +{ + ItNetContainer005(); +} + +/** +* @tc.name: Container_NET_Test_006 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer006, TestSize.Level0) +{ + ItNetContainer006(); +} + +/** +* @tc.name: Container_NET_Test_007 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer007, TestSize.Level0) +{ + ItNetContainer007(); +} + +/** +* @tc.name: Container_NET_Test_008 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer008, TestSize.Level0) +{ + ItNetContainer008(); +} + +/** +* @tc.name: Container_NET_Test_009 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer009, TestSize.Level0) +{ + ItNetContainer009(); +} + +/** +* @tc.name: Container_NET_Test_010 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer010, TestSize.Level0) +{ + ItNetContainer010(); +} + +/** +* @tc.name: Container_NET_Test_011 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer011, TestSize.Level0) +{ + ItNetContainer011(); +} + +/** +* @tc.name: Container_NET_Test_012 +* @tc.desc: uts container function test case +* @tc.type: FUNC +* @tc.require: issueI6HPH2 +* @tc.author: +*/ +HWTEST_F(ContainerTest, ItNetContainer012, TestSize.Level0) +{ + ItNetContainer012(); +} +#endif #if defined(LOSCFG_USER_TEST_USER_CONTAINER) /** * @tc.name: Container_UTS_Test_001 diff --git a/testsuites/unittest/container/It_container_test.h b/testsuites/unittest/container/It_container_test.h index 0da1c6be..09c7b3af 100644 --- a/testsuites/unittest/container/It_container_test.h +++ b/testsuites/unittest/container/It_container_test.h @@ -220,5 +220,16 @@ void ItPidContainer021(void); void ItPidContainer022(void); void ItPidContainer024(void); void ItUtsContainer003(void); - +void ItNetContainer001(void); +void ItNetContainer002(void); +void ItNetContainer003(void); +void ItNetContainer004(void); +void ItNetContainer005(void); +void ItNetContainer006(void); +void ItNetContainer007(void); +void ItNetContainer008(void); +void ItNetContainer009(void); +void ItNetContainer010(void); +void ItNetContainer011(void); +void ItNetContainer012(void); #endif /* _IT_CONTAINER_TEST_H */ diff --git a/testsuites/unittest/container/config.gni b/testsuites/unittest/container/config.gni index 160a05ba..8dec07ab 100644 --- a/testsuites/unittest/container/config.gni +++ b/testsuites/unittest/container/config.gni @@ -149,3 +149,19 @@ if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) { sources_full += [ "$TEST_UNITTEST_DIR/container/full/It_user_container_005.cpp" ] } +if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) { + sources_smoke += [ + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_001.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_002.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_003.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_004.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_005.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_006.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_007.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_008.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_009.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_010.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_011.cpp", + "$TEST_UNITTEST_DIR/container/smoke/It_net_container_012.cpp", + ] +} diff --git a/testsuites/unittest/container/smoke/It_net_container_001.cpp b/testsuites/unittest/container/smoke/It_net_container_001.cpp new file mode 100644 index 00000000..b145e2ca --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_001.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include "It_container_test.h" + +using namespace std; +const int IpLen = 16; + +static int GetLocalIP(char *ip) +{ + struct ifreq ifr; + int inet_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (inet_sock < 0) { + return -1; + } + int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0"); + if (ret != EOK) { + (void)close(inet_sock); + return -1; + } + ioctl(inet_sock, SIOCGIFADDR, &ifr); + ret = strcpy_s(ip, IpLen, inet_ntoa((reinterpret_cast(&ifr.ifr_addr))->sin_addr)); + if (ret != EOK) { + (void)close(inet_sock); + return -1; + } + ret = close(inet_sock); + if (ret != 0) { + return -1; + } + return 0; +} + +static int SetIP(char *ip) +{ + struct ifreq ifr; + int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ioctl(fd, SIOCSIFADDR, &ifr); + ret = close(fd); + if (ret != 0) { + return -1; + } + return 0; +} + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + ret = GetLocalIP(oldIp); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = SetIP("192.168.1.233"); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = GetLocalIP(newIp); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = strcmp(oldIp, newIp); + if (ret == 0) { + return EXIT_CODE_ERRNO_4; + } + + printf("%s %d\n", __FUNCTION__, __LINE__); + return 0; +} + +void ItNetContainer001(void) +{ + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, NULL); + char *stackTop = stack + STACK_SIZE; + + ret = GetLocalIP(oldIp); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = GetLocalIP(newIp); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldIp, newIp); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_002.cpp b/testsuites/unittest/container/smoke/It_net_container_002.cpp new file mode 100644 index 00000000..4f6b979b --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_002.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include "It_container_test.h" + +using namespace std; +const int IpLen = 16; + +static int GetLocalIP(char *ip) +{ + struct ifreq ifr; + int inet_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (inet_sock < 0) { + return -1; + } + int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0"); + if (ret != EOK) { + (void)close(inet_sock); + return -1; + } + ioctl(inet_sock, SIOCGIFADDR, &ifr); + ret = strcpy_s(ip, IpLen, inet_ntoa((reinterpret_cast(&ifr.ifr_addr))->sin_addr)); + if (ret != EOK) { + (void)close(inet_sock); + return -1; + } + ret = close(inet_sock); + if (ret != 0) { + return -1; + } + return 0; +} + +static int SetIP(char *ip) +{ + struct ifreq ifr; + int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ioctl(fd, SIOCSIFADDR, &ifr); + ret = close(fd); + if (ret != 0) { + return -1; + } + return 0; +} + +static int ChildFunc(void *arg) +{ + (void)arg; + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + ret = GetLocalIP(oldIp); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + ret = unshare(CLONE_NEWNET); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = SetIP("192.168.1.234"); + if (ret != 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = GetLocalIP(newIp); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(oldIp, newIp); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + return 0; +} + +void ItNetContainer002(void) +{ + int ret; + char oldIp[IpLen] = {NULL}; + char newIp[IpLen] = {NULL}; + + char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, NULL); + char *stackTop = stack + STACK_SIZE; + + ret = GetLocalIP(oldIp); + ASSERT_EQ(ret, 0); + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD, &arg); + ASSERT_NE(pid, -1); + + int status; + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = GetLocalIP(newIp); + ASSERT_EQ(ret, 0); + + ret = strcmp(oldIp, newIp); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_003.cpp b/testsuites/unittest/container/smoke/It_net_container_003.cpp new file mode 100644 index 00000000..422a4d34 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_003.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include "It_container_test.h" + +static std::string GenNetLinkPath(int pid) +{ + std::ostringstream buf; + buf << "/proc/" << pid << "/container/net"; + return buf.str(); +} + +static std::string ReadlinkNet(int pid) +{ + auto path = GenNetLinkPath(pid); + struct stat sb; + + int ret = lstat(path.data(), &sb); + if (ret == -1) { + perror("lstat"); + return std::string(); + } + + auto bufsiz = sb.st_size + 1; + if (sb.st_size == 0) { + bufsiz = PATH_MAX; + } + + std::vector buf(bufsiz); + auto nbytes = readlink(path.c_str(), buf.data(), bufsiz); + if (nbytes == -1) { + perror("readlink"); + return std::string(); + } + + return buf.data(); +} + +void ItNetContainer003(void) +{ + std::string zerolink("'net:[0]'"); + auto netlink = ReadlinkNet(getpid()); + int ret = zerolink.compare(netlink); + ASSERT_NE(ret, 0); + + std::regex reg("'net:\\[[0-9]+\\]'"); + ret = std::regex_match(netlink, reg); + ASSERT_EQ(ret, 1); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_004.cpp b/testsuites/unittest/container/smoke/It_net_container_004.cpp new file mode 100644 index 00000000..63b083ac --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_004.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *CONTAINER_TYPE = "net"; +static const int SLEEP_SECONDS = 2; +static const int TEST_PATH_MAX = 100; + +static int NewnetChildFun(void *) +{ + sleep(SLEEP_SECONDS); + return 0; +} + +static int ChildFun(void *p) +{ + (void)p; + int ret; + int status; + char path[TEST_PATH_MAX]; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + auto childPid = clone(NewnetChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + if (childPid == -1) { + return EXIT_CODE_ERRNO_1; + } + auto oldReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE); + + if (sprintf_s(path, TEST_PATH_MAX, "/proc/%d/container/net", childPid) < 0) { + (void)waitpid(childPid, &status, 0); + return EXIT_CODE_ERRNO_8; + } + int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = setns(fd, CLONE_NEWNET); + if (ret != 0) { + (void)close(fd); + return EXIT_CODE_ERRNO_3; + } + + ret = close(fd); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + auto newReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE); + + ret = strcmp(oldReadLink.c_str(), newReadLink.c_str()); + if (ret == 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = waitpid(childPid, &status, 0); + if (ret != childPid) { + return EXIT_CODE_ERRNO_6; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_7; + } + + return 0; +} + +void ItNetContainer004(void) +{ + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + auto childPid = clone(ChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(childPid, -1); + + int ret = waitpid(childPid, &status, 0); + ASSERT_EQ(ret, childPid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_005.cpp b/testsuites/unittest/container/smoke/It_net_container_005.cpp new file mode 100644 index 00000000..9a2d6540 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_005.cpp @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *SERVER_IP = "192.168.100.6"; +static const int SERVER_PORT = 8000; +static const char *PEER_IP = "192.168.100.5"; +static const int PEER_PORT = 8001; +static const int DATA_LEN = 128; +static const char *SERVER_MSG = "===Hi, I'm Server.==="; +static const char *PEER_MSG = "===Hi, I'm Peer.==="; +static const int TRY_COUNT = 5; +static const int OFFSET = 2; + +static int TryResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + struct ifreq ifr; + struct rtentry rt; + + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, IFNAMSIZ); + if (ret != EOK) { + (void)close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + + inet_pton(AF_INET, netmask, ifr.ifr_addr.sa_data + OFFSET); + ret = ioctl(fd, SIOCSIFNETMASK, &ifr); + if (ret == 0) { + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + OFFSET); + ret = ioctl(fd, SIOCSIFADDR, &ifr); + if (ret == 0) { + struct sockaddr_in* addr = reinterpret_cast(&rt.rt_gateway); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(GW); + rt.rt_flags = RTF_GATEWAY; + ret = ioctl(fd, SIOCADDRT, &rt); + } + } + if (ret != 0) { + (void)close(fd); + return ret; + } + ret = close(fd); + return ret; +} + +static int ResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + int try_count = TRY_COUNT; + + while (try_count--) { + ret = TryResetNetaddr(ifname, ip, netmask, gw); + if (ret == 0) { + break; + } + sleep(1); + } + + return ret; +} + +static int UdpClient(void) +{ + int ret = 0; + int peer; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + struct sockaddr_in peer_addr; + + peer = socket(AF_INET, SOCK_DGRAM, 0); + if (peer < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + peer_addr.sin_family = AF_INET; + peer_addr.sin_addr.s_addr = inet_addr(PEER_IP); + peer_addr.sin_port = htons(PEER_PORT); + (void)memset_s(&(peer_addr.sin_zero), sizeof(peer_addr.sin_zero), 0, sizeof(peer_addr.sin_zero)); + + ret = bind(peer, const_cast(reinterpret_cast(&peer_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + timeval tv = {1, 0}; + ret = setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO, const_cast(reinterpret_cast(&tv)), sizeof(timeval)); + + /* loop try util server is ready */ + while (try_count--) { + ret = sendto(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0, + const_cast(reinterpret_cast(&server_addr)), + (socklen_t)sizeof(server_addr)); + if (ret == -1) { + continue; + } + ret = recvfrom(peer, recv_data, DATA_LEN, 0, nullptr, nullptr); + if (ret != -1) { + break; + } + } + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + (void)close(peer); + + ret = strcmp(recv_data, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + return 0; +} + +static int ChildFunc(void *arg) +{ + int ret = ResetNetaddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + return UdpClient(); +} + +static int UdpServer(void) +{ + int ret = 0; + int server; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + struct sockaddr_in peer_addr; + socklen_t peer_addr_len = sizeof(struct sockaddr); + + server = socket(AF_INET, SOCK_DGRAM, 0); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = recvfrom(server, recv_data, DATA_LEN, 0, reinterpret_cast(&peer_addr), &peer_addr_len); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = sendto(server, SERVER_MSG, strlen(SERVER_MSG) + 1, 0, + const_cast(reinterpret_cast(&peer_addr)), peer_addr_len); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + (void)close(server); + + ret = strcmp(recv_data, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + return ret; +} + +static void *UdpServerThread(void *arg) +{ + int ret; + + ret = ResetNetaddr(IFNAME, SERVER_IP, NETMASK, GW); + if (ret != 0) { + return (void *)(intptr_t)ret; + } + + ret = UdpServer(); + + return (void *)(intptr_t)ret; +} + +void ItNetContainer005(void) +{ + int ret = 0; + int status; + void *tret = nullptr; + pthread_t srv; + pthread_attr_t attr; + + ret = pthread_attr_init(&attr); + ASSERT_EQ(ret, 0); + + ret = pthread_create(&srv, &attr, UdpServerThread, nullptr); + ASSERT_EQ(ret, 0); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + ret = pthread_join(srv, &tret); + ASSERT_EQ(ret, 0); + + ret = pthread_attr_destroy(&attr); + ASSERT_EQ(ret, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_006.cpp b/testsuites/unittest/container/smoke/It_net_container_006.cpp new file mode 100644 index 00000000..f195e505 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_006.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *SERVER_IP = "127.0.0.1"; +static const int SERV_PORT = 8002; +static const char *SERVER_MSG = "Hi, I'm Tcp Server!"; +static const char *PEER_MSG = "Hi, I'm Tcp Client!"; +static const int DATA_LEN = 128; + +static int TcpClient(void *arg) +{ + int ret; + int client; + char buffer[DATA_LEN]; + struct sockaddr_in server_addr; + + client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (client < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + server_addr.sin_port = htons(SERV_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = connect(client, const_cast(reinterpret_cast(&server_addr)), + sizeof(server_addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = send(client, PEER_MSG, strlen(PEER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = recv(client, buffer, sizeof(buffer), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(buffer, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)close(client); + + return 0; +} + +static int ChildFunc(void *) +{ + int ret; + int server; + int status; + char *stack = nullptr; + char *stackTop = nullptr; + char buffer[DATA_LEN]; + struct sockaddr_in server_addr; + + server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + server_addr.sin_port = htons(SERV_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(server_addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = listen(server, 1); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(TcpClient, stackTop, SIGCHLD, &arg); + if (pid == -1) { + return EXIT_CODE_ERRNO_4; + } + + int client = accept(server, nullptr, nullptr); + if (ret < 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = recv(client, buffer, sizeof(buffer), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_6; + } + + ret = strcmp(buffer, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_7; + } + + ret = send(client, SERVER_MSG, strlen(SERVER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_8; + } + + (void)close(client); + (void)close(server); + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + return EXIT_CODE_ERRNO_9; + } + + int exitCode = WEXITSTATUS(status); + if (exitCode != 0) { + return EXIT_CODE_ERRNO_10; + } + + return 0; +} + +void ItNetContainer006(void) +{ + int ret = 0; + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_007.cpp b/testsuites/unittest/container/smoke/It_net_container_007.cpp new file mode 100644 index 00000000..69531868 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_007.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include "It_container_test.h" + +static const char *LOCALHOST = "127.0.0.1"; +static const int LOCALPORT = 8003; +static const char *MSG = "Tis is UDP Test!"; +static const int DATA_LEN = 128; + +static int ChildFunc(void *arg) +{ + int ret; + int sock; + int recv_data_len; + char recv_data[DATA_LEN]; + struct sockaddr_in addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + return EXIT_CODE_ERRNO_1; + } + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(LOCALHOST); + addr.sin_port = htons(LOCALPORT); + (void)memset_s(&(addr.sin_zero), sizeof(addr.sin_zero), 0, sizeof(addr.sin_zero)); + + ret = bind(sock, const_cast(reinterpret_cast(&addr)), + sizeof(struct sockaddr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = sendto(sock, MSG, DATA_LEN, 0, const_cast(reinterpret_cast(&addr)), + (socklen_t)sizeof(addr)); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = recvfrom(sock, recv_data, DATA_LEN, 0, nullptr, nullptr); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(recv_data, MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)close(sock); + + return 0; +} + +void ItNetContainer007(void) +{ + int ret = 0; + int status; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_008.cpp b/testsuites/unittest/container/smoke/It_net_container_008.cpp new file mode 100644 index 00000000..c4e8ad6d --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_008.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const int PORT = 8004; +static const char *LOCALHOST = "127.0.0.1"; + +static int UdpTcpBind(int *sock1, int *sock2) +{ + int ret; + int udp_sock; + int tcp_sock; + + udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udp_sock < 0) { + return EXIT_CODE_ERRNO_1; + } + + struct sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr(LOCALHOST); + sa.sin_port = htons(PORT); + + ret = bind(udp_sock, const_cast(reinterpret_cast(&sa)), sizeof(sa)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tcp_sock < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = bind(tcp_sock, const_cast(reinterpret_cast(&sa)), sizeof(sa)); + if (ret != 0) { + return EXIT_CODE_ERRNO_4; + } + + (*sock1) = udp_sock; + (*sock2) = tcp_sock; + + return 0; +} + +static int ClientFunc(void *param) +{ + (void)param; + int ret; + int udp_sock; + int tcp_sock; + + ret = UdpTcpBind(&udp_sock, &tcp_sock); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + (void)close(udp_sock); + (void)close(tcp_sock); + + return ret; +} + +void ItNetContainer008(void) +{ + int ret; + int status; + int udp_sock; + int tcp_sock; + + ret = UdpTcpBind(&udp_sock, &tcp_sock); + ASSERT_EQ(ret, 0); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + int arg = CHILD_FUNC_ARG; + int pid = clone(ClientFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); + + (void)close(udp_sock); + (void)close(tcp_sock); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_009.cpp b/testsuites/unittest/container/smoke/It_net_container_009.cpp new file mode 100644 index 00000000..40b78bd5 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_009.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include +#include +#include +#include +#include "It_container_test.h" + +static const char *NETMASK = "255.255.255.0"; +static const char *GW = "192.168.100.1"; +static const char *IFNAME = "veth0"; +static const char *SERVER_IP = "192.168.100.6"; +static const int SERVER_PORT = 8005; +static const char *PEER_IP = "192.168.100.5"; +static const char *SERVER_MSG = "===Hi, I'm Server.==="; +static const char *PEER_MSG = "===Hi, I'm Peer.==="; +static const int TRY_COUNT = 5; +static const int DATA_LEN = 128; + +static int TryResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + struct ifreq ifr; + struct rtentry rt; + + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (fd < 0) { + return -1; + } + ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, IFNAMSIZ); + if (ret != EOK) { + close(fd); + return -1; + } + ifr.ifr_addr.sa_family = AF_INET; + + inet_pton(AF_INET, netmask, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ret = ioctl(fd, SIOCSIFNETMASK, &ifr); + if (ret == 0) { + inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */ + ret = ioctl(fd, SIOCSIFADDR, &ifr); + if (ret == 0) { + struct sockaddr_in* addr = reinterpret_cast(&rt.rt_gateway); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(GW); + rt.rt_flags = RTF_GATEWAY; + ret = ioctl(fd, SIOCADDRT, &rt); + } + } + + if (ret != 0) { + (void)close(fd); + return ret; + } + ret = close(fd); + return ret; +} + +static int ResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw) +{ + int ret; + int try_count = TRY_COUNT; + + while (try_count--) { + ret = TryResetNetaddr(ifname, ip, netmask, gw); + if (ret == 0) { + break; + } + sleep(1); + } + + return ret; +} + +static int TcpClient(void) +{ + int ret = 0; + int peer; + int try_count = TRY_COUNT; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + + peer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (peer < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + do { + sleep(1); + ret = connect(peer, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + } while (ret !=0 && (try_count--)); + + if (ret < 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = send(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + ret = recv(peer, recv_data, sizeof(recv_data), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_4; + } + + ret = strcmp(recv_data, SERVER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_5; + } + + (void)close(peer); + + return 0; +} + +static int TcpServer(void) +{ + int ret = 0; + int server; + int peer; + char recv_data[DATA_LEN]; + struct sockaddr_in server_addr; + socklen_t client_addr_len = sizeof(struct sockaddr); + + server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (server < 0) { + return EXIT_CODE_ERRNO_1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); + server_addr.sin_port = htons(SERVER_PORT); + (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); + + ret = bind(server, const_cast(reinterpret_cast(&server_addr)), + sizeof(struct sockaddr)); + if (ret != 0) { + return EXIT_CODE_ERRNO_2; + } + + ret = listen(server, 1); + if (ret < 0) { + return EXIT_CODE_ERRNO_3; + } + + peer = accept(server, nullptr, nullptr); + if (peer < 0) { + return EXIT_CODE_ERRNO_4; + } + + (void)close(server); + + ret = recv(peer, recv_data, sizeof(recv_data), 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_5; + } + + ret = strcmp(recv_data, PEER_MSG); + if (ret != 0) { + return EXIT_CODE_ERRNO_6; + } + + ret = send(peer, SERVER_MSG, strlen(SERVER_MSG) + 1, 0); + if (ret < 0) { + return EXIT_CODE_ERRNO_7; + } + + (void)close(peer); + + return 0; +} + +static void *TcpClientThread(void *arg) +{ + int ret = ResetNetaddr(IFNAME, PEER_IP, NETMASK, GW); + if (ret == 0) { + ret = TcpClient(); + } + + return (void *)(intptr_t)ret; +} + +static int ChildFunc(void *arg) +{ + int ret = ret = ResetNetaddr(IFNAME, SERVER_IP, NETMASK, GW); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + + return TcpServer(); +} + +VOID ItNetContainer009(void) +{ + int ret = 0; + int status; + void *tret = nullptr; + pthread_t srv; + pthread_attr_t attr; + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0); + EXPECT_STRNE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + int arg = CHILD_FUNC_ARG; + int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = pthread_attr_init(&attr); + ASSERT_EQ(ret, 0); + + ret = pthread_create(&srv, &attr, TcpClientThread, nullptr); + ASSERT_EQ(ret, 0); + + ret = pthread_join(srv, &tret); + ASSERT_EQ(ret, 0); + + ret = pthread_attr_destroy(&attr); + ASSERT_EQ(ret, 0); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + + int exitCode = WEXITSTATUS(status); + ASSERT_EQ(exitCode, 0); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_010.cpp b/testsuites/unittest/container/smoke/It_net_container_010.cpp new file mode 100644 index 00000000..f4690256 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_010.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ +#include "sys/resource.h" +#include "sys/wait.h" +#include "pthread.h" +#include "sched.h" +#include "It_container_test.h" + +const int MAX_PID_RANGE = 100000; +const int SLEEP_TIME_US = 1000; +const int LOOP_NUM = 100; + +static int ChildFunc(void *arg) +{ + usleep(SLEEP_TIME_US); + exit(EXIT_CODE_ERRNO_5); +} + +static int GroupProcess(void *arg) +{ + (void)arg; + int ret; + int status = 0; + + for (int i = 0; i < LOOP_NUM; i++) { + int argTmp = CHILD_FUNC_ARG; + auto pid = CloneWrapper(ChildFunc, CLONE_NEWNET, &argTmp); + if (pid == -1) { + return EXIT_CODE_ERRNO_1; + } + ret = waitpid(pid, &status, 0); + status = WEXITSTATUS(status); + if (status != EXIT_CODE_ERRNO_5) { + return EXIT_CODE_ERRNO_2; + } + } + + exit(EXIT_CODE_ERRNO_5); +} + +void ItNetContainer010(void) +{ + int ret; + int status = 0; + int arg = CHILD_FUNC_ARG; + auto pid = CloneWrapper(GroupProcess, CLONE_NEWNET, &arg); + ASSERT_NE(pid, -1); + + ret = waitpid(pid, &status, 0); + ASSERT_EQ(ret, pid); + status = WEXITSTATUS(status); + ASSERT_EQ(status, EXIT_CODE_ERRNO_5); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_011.cpp b/testsuites/unittest/container/smoke/It_net_container_011.cpp new file mode 100644 index 00000000..8b327787 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_011.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + sleep(2); /* 2: delay 2s */ + + return 0; +} + +void ItNetContainer011(void) +{ + std::string path = "/proc/sys/user/max_net_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_NE(pid1, -1); + + auto pid2 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_EQ(pid2, -1); + + ret = waitpid(pid1, NULL, 0); + ASSERT_EQ(ret, pid1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/testsuites/unittest/container/smoke/It_net_container_012.cpp b/testsuites/unittest/container/smoke/It_net_container_012.cpp new file mode 100644 index 00000000..a6f24c18 --- /dev/null +++ b/testsuites/unittest/container/smoke/It_net_container_012.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 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. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER OR + * CONTRIBUTORS 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. + */ + +#include +#include "It_container_test.h" + +static int const configLen = 16; +static const int MAX_CONTAINER = 10; +static const int g_buffSize = 512; +static const int g_arryLen = 4; +static const int g_readLen = 254; + +static int childFunc(void *arg) +{ + (void)arg; + + int ret = unshare(CLONE_NEWNET); + if (ret != 0) { + return EXIT_CODE_ERRNO_1; + } + return 0; +} + +void ItNetContainer012(void) +{ + std::string path = "/proc/sys/user/max_net_container"; + char *array[g_arryLen] = { nullptr }; + char buf[g_buffSize] = { 0 }; + int status = 0; + + int ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + int value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); + + int usedCount = atoi(array[2] + strlen("count: ")); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", usedCount + 1); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + ASSERT_NE(stack, nullptr); + char *stackTop = stack + STACK_SIZE; + + auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL); + ASSERT_NE(pid1, -1); + + ret = waitpid(pid1, &status, 0); + ASSERT_EQ(ret, pid1); + ret = WIFEXITED(status); + ASSERT_NE(ret, 0); + ret = WEXITSTATUS(status); + ASSERT_EQ(ret, EXIT_CODE_ERRNO_1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = sprintf_s(buf, configLen, "%d", value); + ASSERT_GT(ret, 0); + + ret = WriteFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + (void)memset_s(buf, configLen, 0, configLen); + ret = ReadFile(path.c_str(), buf); + ASSERT_NE(ret, -1); + + GetLine(buf, g_arryLen, g_readLen, array); + + value = atoi(array[1] + strlen("limit: ")); + ASSERT_EQ(value, MAX_CONTAINER); +} diff --git a/testsuites/unittest/process/fs/process_fs_test.cpp b/testsuites/unittest/process/fs/process_fs_test.cpp index 3a001b3c..fc12de19 100644 --- a/testsuites/unittest/process/fs/process_fs_test.cpp +++ b/testsuites/unittest/process/fs/process_fs_test.cpp @@ -165,6 +165,18 @@ HWTEST_F(ProcessFsTest, ItProcessFs010, TestSize.Level0) ItProcessFs010(); } +/** +* @tc.name: Process_fs_Test_011 +* @tc.desc: Process mount directory test +* @tc.type: FUNC +* @tc.require: issueI6E2LG +* @tc.author: +*/ +HWTEST_F(ProcessFsTest, ItProcessFs011, TestSize.Level0) +{ + ItProcessFs011(); +} + /** * @tc.name: Process_fs_Test_012 * @tc.desc: Process mount directory test diff --git a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp b/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp index 938d06ed..0f2ada8b 100644 --- a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp +++ b/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_009.cpp @@ -56,7 +56,7 @@ void ItProcessPlimitsIpc009(void) ASSERT_EQ(ret, 0); ret = ReadFile("/proc/plimits/test/ipc.shm_limit", buf); - ASSERT_STREQ(buf, "104857600\n"); + ASSERT_STREQ(buf, "4294967295\n"); shmid = shmget(IPC_PRIVATE, PAGE_SIZE, acessMode | IPC_CREAT); ASSERT_NE(shmid, -1); diff --git a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp b/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp index 4c0abd35..fefc8d2e 100644 --- a/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp +++ b/testsuites/unittest/process/plimits/smoke/It_process_plimits_ipc_010.cpp @@ -92,7 +92,6 @@ void ItProcessPlimitsIpc010(void) ret = shmctl(shmid, IPC_RMID, nullptr); ASSERT_NE(ret, -1); shmctl(shmid_1, IPC_RMID, nullptr); - shmctl(shmid, IPC_RMID, nullptr); ret = rmdir(subPlimitsPath.c_str()); ASSERT_EQ(ret, 0);