提交 5dc9a0f1 编写于 作者: Z zhushengle

feat: 支持网络容器

BREAKING CHANGE:
支持网络容器对外变更:
1.支持网络容器
2.setns, clone, unshare接口支持CLONE_NEWNET

Close #I6HPH2
Signed-off-by: Nzhushengle <zhushengle@huawei.com>
Change-Id: Ibaa11056982d465d4006680c8d3fa4ae2b9f25b5
上级 806bd808
......@@ -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",
......
......@@ -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;
}
......
......@@ -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
};
......
......@@ -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"
......
......@@ -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",
......
......@@ -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;
......
/*
* 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 <sched.h>
#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
......@@ -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)) {
......
......@@ -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);
......
/*
* 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 <lwip/net_group.h>
#include <lwip/netif.h>
#include <lwip/ip.h>
#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 */
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -46,7 +46,6 @@ typedef struct ProcIPCLimit {
UINT32 shmSize;
UINT32 shmFailedCount;
UINT32 shmSizeLimit;
UINT64 migrateTime;
} ProcIPCLimit;
enum IPCStatType {
......
......@@ -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)
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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)
......
......@@ -48,8 +48,6 @@ typedef struct ProcSchedLimiter {
UINT64 period;
UINT64 quota;
UINT64 allRuntime;
UINT64 overrunTime;
UINT64 stat;
} ProcSchedLimiter;
VOID OsSchedLimitInit(UINTPTR limit);
......
......@@ -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 */
......
......@@ -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;
......
/*
* 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 <lwip/ip.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_IP_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 <lwip/netif.h>
#undef linkoutput
#if LWIP_DHCPS
......
......@@ -35,6 +35,9 @@
#include <lwip/etharp.h>
#include <lwip/sockets.h>
#include <lwip/ethip6.h>
#ifdef LOSCFG_NET_CONTAINER
#include <lwip/tcpip.h>
#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
......@@ -404,7 +404,11 @@ int get_unused_socket_num(void)
#include <net/route.h>
#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);
......
......@@ -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;
......
......@@ -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
......
......@@ -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
}
......
......@@ -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
......
......@@ -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 */
......@@ -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",
]
}
/*
* 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 <arpa/inet.h>
#include <net/if.h>
#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<struct sockaddr_in *>(&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);
}
/*
* 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 <arpa/inet.h>
#include <net/if.h>
#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<struct sockaddr_in *>(&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);
}
/*
* 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 <string>
#include <iostream>
#include <regex>
#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<char> 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);
}
/*
* 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/stat.h>
#include <iostream>
#include <regex>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#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);
}
/*
* 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 <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h>
#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<struct sockaddr_in *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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<void *>(reinterpret_cast<void *>(&tv)), sizeof(timeval));
/* loop try util server is ready */
while (try_count--) {
ret = sendto(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0,
const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
sizeof(struct sockaddr));
if (ret != 0) {
return EXIT_CODE_ERRNO_2;
}
ret = recvfrom(server, recv_data, DATA_LEN, 0, reinterpret_cast<struct sockaddr *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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);
}
/*
* 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 <netinet/in.h>
#include <arpa/inet.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <poll.h>
#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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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);
}
/*
* 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 <netinet/in.h>
#include <arpa/inet.h>
#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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&addr)),
sizeof(struct sockaddr));
if (ret < 0) {
return EXIT_CODE_ERRNO_2;
}
ret = sendto(sock, MSG, DATA_LEN, 0, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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);
}
/*
* 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 <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <poll.h>
#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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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);
}
/*
* 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 <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h>
#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<struct sockaddr_in *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&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);
}
/*
* 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);
}
/*
* 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 <cstdio>
#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);
}
/*
* 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 <cstdio>
#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);
}
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册