diff options
Diffstat (limited to 'stacks/lwip_stack/lwip_src/ip_module/container_ip.c')
-rw-r--r-- | stacks/lwip_stack/lwip_src/ip_module/container_ip.c | 1117 |
1 files changed, 1117 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/ip_module/container_ip.c b/stacks/lwip_stack/lwip_src/ip_module/container_ip.c new file mode 100644 index 0000000..1cbcfb3 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/container_ip.c @@ -0,0 +1,1117 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> +#include "lwip/inet.h" +#include "trp_rb_tree.h" +#include "container_ip.h" +#include "network.h" +#include "netif.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "config_common.h" +#include "igmp.h" +#include "spl_def.h" +#include "stackx_ip_addr.h" +#include "nsfw_hal_api.h" +#include "spl_hal.h" + +struct container_list g_container_list = { 0 }; +static trp_rb_root_t g_container_ip_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock +static trp_rb_root_t g_container_multicast_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock + +static void free_container_port(struct container_port *port, + bool_t only_free); + +/*unsigned int value is typecasted into void * pointer and passed as argument to +this function. so the value can never be > 0xFFFFFFFF. so can suppress the warning*/ + +static int ip_compare(trp_key_t left, trp_key_t right) +{ + //return (int)((unsigned long)left - (unsigned long)right); + + if (left > right) + { + return 1; + } + else if (left < right) + { + return -1; + } + else + { + return 0; + } +} + +NSTACK_STATIC bool_t is_container_ok(struct container_ip * container) +{ + if (!container->ports_list) + { + return 0; + } + + return 1; +} + +NSTACK_STATIC void +add_port(struct container_ip *container, struct container_port *port) +{ + if (port->ip_cidr_list) + { + port->next = container->ports_list; + container->ports_list = port; + } + else + { + free_container_port(port, IP_MODULE_TRUE); + } +} + +static void +add_ip_cidr(struct container_port *port, + struct container_port_ip_cidr *ip_cidr) +{ + if (!ip_cidr) + { + return; + } + + ip_cidr->next = port->ip_cidr_list; + port->ip_cidr_list = ip_cidr; + return; +} + +NSTACK_STATIC void +add_multilcast_ip(struct container_port *port, + struct container_multicast_id *muticastIP) +{ + if (!muticastIP) + { + return; + } + + muticastIP->next = port->multicast_list; + port->multicast_list = muticastIP; + return; +} + +NSTACK_STATIC void +free_container_port_ip_cidr(struct container_port_ip_cidr *ip_cidr, + bool_t only_free) +{ + output_api *api = get_output_api(); + struct container_port_ip_cidr *ip_cidr_tmp = NULL; + + while (ip_cidr) + { + ip_cidr_tmp = ip_cidr; + ip_cidr = ip_cidr_tmp->next; + if (!only_free) + { + if (api->del_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree(ip_cidr_tmp->ip); + if (network) + { + if (network->phy_net->bond_name[0] != 0) + { + (void) api->del_netif_ip(network->phy_net->bond_name, ip_cidr_tmp->ip); //fails only when netif_name not exist, no side effect so don't check return value. + } + else + { + (void) api->del_netif_ip(network->phy_net-> + header->nic_name, + ip_cidr_tmp->ip); + } + } + else + { + NSOPR_LOGERR("can't find network by]IP=%u", + ip_cidr_tmp->ip); + } + } + + trp_rb_erase((void *) (u64_t) ip_cidr_tmp->ip, + &g_container_ip_root, ip_compare); + } + + free(ip_cidr_tmp); + ip_cidr_tmp = NULL; + } +} + +static void +free_container_multicast(struct container_multicast_id *multicast, + bool_t only_free) +{ + struct container_multicast_id *tmp = NULL; + + while (multicast) + { + tmp = multicast; + multicast = multicast->next; + if (!only_free) + { + trp_rb_erase((void *) (u64_t) tmp->ip, + &g_container_multicast_root, ip_compare); + } + + free(tmp); + tmp = NULL; + } +} + +static void free_container_port(struct container_port *port, bool_t only_free) +{ + struct container_port *port_tmp = NULL; + struct container_port *port_curr = port; + + while (port_curr) + { + port_tmp = port_curr; + port_curr = port_tmp->next; + + free_container_multicast(port_tmp->multicast_list, only_free); + free_container_port_ip_cidr(port_tmp->ip_cidr_list, only_free); + + if (port_tmp->buffer) + { + free_port_buffer(port_tmp->buffer); + port_tmp->buffer = NULL; + } + + free(port_tmp); + port_tmp = NULL; + } +} + +void free_container(struct container_ip *container, bool_t only_free) +{ + struct container_ip *container_tmp = NULL; + struct container_ip *container_curr = container; + + while (container_curr) + { + container_tmp = container_curr; + container_curr = container_tmp->next; + if (container_tmp->ports_list) + { + free_container_port(container_tmp->ports_list, only_free); + } + + free(container_tmp); + container_tmp = NULL; + } +} + +struct container_port *parse_port_obj(struct json_object *port_obj) +{ + int retval; + struct json_object *port_name_obj = NULL; + struct json_object *ip_cidr_list_obj = NULL; + struct json_object *mcIDObj = NULL; + + if (!port_obj) + { + NSOPR_LOGERR("port_obj is null"); + return NULL; + } + + struct container_port *port = malloc(sizeof(struct container_port)); + if (!port) + { + NSOPR_LOGERR("malloc failed"); + return NULL; + } + + retval = + memset_s(port, sizeof(struct container_port), 0, + sizeof(struct container_port)); + if (EOK != retval) + { + NSOPR_LOGERR("MEMSET_S failed]ret=%d", retval); + free(port); + return NULL; + } + + json_object_object_get_ex(port_obj, "port_name", &port_name_obj); + if (port_name_obj) + { + const char *port_name = json_object_get_string(port_name_obj); + if ((NULL == port_name) + || (strlen(port_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR("port name is not ok"); + goto RETURN_ERROR; + } + + retval = + strcpy_s(port->port_name, sizeof(port->port_name), port_name); + + if (EOK != retval) + { + NSOPR_LOGERR("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + + json_object_object_get_ex(port_obj, "ip_cidr", &ip_cidr_list_obj); + if (ip_cidr_list_obj) + { + int j; + int ip_cidr_num = json_object_array_length(ip_cidr_list_obj); + for (j = 0; j < ip_cidr_num; ++j) + { + struct json_object *ip_cidr_obj = + json_object_array_get_idx(ip_cidr_list_obj, j); + if (ip_cidr_obj) + { + char tmp[IP_MODULE_LENGTH_32] = { 0 }; + struct container_port_ip_cidr *port_ip_cidr = + malloc(sizeof(struct container_port_ip_cidr)); + if (NULL == port_ip_cidr) + { + NSOPR_LOGERR("malloc failed"); + goto RETURN_ERROR; + } + + retval = + memset_s(port_ip_cidr, + sizeof(struct container_port_ip_cidr), 0, + sizeof(struct container_port_ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR("MEMSET_S failed]ret=%d", retval); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *ip_cidr = json_object_get_string(ip_cidr_obj); + if ((NULL == ip_cidr) || (ip_cidr[0] == 0)) + { + NSOPR_LOGERR("ip_cidr is not ok"); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *sub = strstr(ip_cidr, "/"); + if ((NULL == sub) + || (sizeof(tmp) - 1 < (unsigned int) (sub - ip_cidr)) + || (strlen(sub) > sizeof(tmp) - 1)) + { + NSOPR_LOGERR + ("Error : Ipaddress notation must be in ip cidr notation!"); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + retval = + strncpy_s(tmp, sizeof(tmp), ip_cidr, + (size_t) (sub - ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR("STRNCPY_S failed]ret=%d", retval); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + struct in_addr addr; + int iRet; + retval = memset_s(&addr, sizeof(addr), 0, sizeof(addr)); + if (EOK != retval) + { + NSOPR_LOGERR("MEMSET_S failed]ret=%d", retval); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + iRet = spl_inet_aton(tmp, &addr); + if (0 == iRet) + { + NSOPR_LOGERR("spl_inet_aton failed"); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->ip = addr.s_addr; + iRet = atoi(sub + 1); + if ((iRet <= 0) || (iRet > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR("IP mask length is not correct"); + free(port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->mask_len = (unsigned int) iRet; + add_ip_cidr(port, port_ip_cidr); + } + } + } + + json_object_object_get_ex(port_obj, "multicast_id", &mcIDObj); + if (mcIDObj) + { + int j; + int arrLen = json_object_array_length(mcIDObj); + if (0 == arrLen) + { + NSOPR_LOGERR("arrLen is 0"); + goto RETURN_ERROR; + } + + for (j = 0; j < arrLen; ++j) + { + struct json_object *elemObj = + json_object_array_get_idx(mcIDObj, j); + + if (elemObj) + { + struct json_object *tObj = NULL; + const char *tStr; + int ret; + struct in_addr addr; + + struct container_multicast_id *mcID = + malloc(sizeof(struct container_multicast_id)); + if (NULL == mcID) + { + NSOPR_LOGERR("Can't alloc container multicast id"); + goto RETURN_ERROR; + } + + json_object_object_get_ex(elemObj, "group_ip", &tObj); + if (NULL == tObj) + { + NSOPR_LOGERR("No group_IP"); + free(mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + tStr = json_object_get_string(tObj); + if (NULL == tStr) + { + NSOPR_LOGERR("Get Multiple cast group IP Failed"); + free(mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + ret = spl_inet_aton(tStr, &addr); + if (0 == ret) + { + NSOPR_LOGERR("Parse group IP Failed"); + free(mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + mcID->ip = addr.s_addr; + add_multilcast_ip(port, mcID); + } + } + } + + const char *port_json = json_object_get_string(port_obj); + if ((NULL == port_json) || (0 == strlen(port_json))) + { + NSOPR_LOGERR("json_object_get_string failed"); + goto RETURN_ERROR; + } + + port->buffer = malloc_port_buffer(); + if (!port->buffer) + { + goto RETURN_ERROR; + } + + retval = + strcpy_s(get_port_json(port), IP_MODULE_PORT_JSON_LEN, port_json); + if (EOK != retval) + { + NSOPR_LOGERR("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + return port; + RETURN_ERROR: + free_container_port(port, IP_MODULE_TRUE); + return NULL; +} + +struct container_ip *parse_container_ip_json(char *param) +{ + int retval; + struct json_object *obj = json_tokener_parse(param); + struct json_object *container_id_obj = NULL; + struct json_object *ports_list_obj = NULL; + + if (!obj) + { + return NULL; + } + + struct container_ip *container = malloc(sizeof(struct container_ip)); + if (container == NULL) + { + json_object_put(obj); + return NULL; + } + + retval = + memset_s(container, sizeof(struct container_ip), 0, + sizeof(struct container_ip)); + if (EOK != retval) + { + NSOPR_LOGERR("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + json_object_object_get_ex(obj, "containerID", &container_id_obj); + if (container_id_obj) + { + const char *container_id = json_object_get_string(container_id_obj); + if ((container_id == NULL) || (container_id[0] == 0) + || (strlen(container_id) >= IP_MODULE_MAX_NAME_LEN)) + { + goto RETURN_ERROR; + } + + retval = + memset_s(container->container_id, sizeof(container->container_id), + 0, sizeof(container->container_id)); + if (EOK != retval) + { + NSOPR_LOGERR("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + retval = + strcpy_s(container->container_id, sizeof(container->container_id), + container_id); + + if (EOK != retval) + { + NSOPR_LOGERR("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + else + { + /* this mandatory parameter */ + NSOPR_LOGWAR("json_object_object_get_ex containerID failed"); + } + + json_object_object_get_ex(obj, "ports_list", &ports_list_obj); + if (ports_list_obj) + { + int i; + int port_num = json_object_array_length(ports_list_obj); + + if (port_num == 0) + { + /* this mandatory parameter */ + goto RETURN_ERROR; + } + + for (i = 0; i < port_num; i++) + { + struct json_object *port_obj = + json_object_array_get_idx(ports_list_obj, i); + struct container_port *port = parse_port_obj(port_obj); + if (!port) + { + goto RETURN_ERROR; + } + + add_port(container, port); + } + } + else + { + /* mandatory parameter */ + goto RETURN_ERROR; + } + + /* Check if this function is required, or needs more check inside this function, + as some of them are alraedy validated + */ + if (!is_container_ok(container)) + { + goto RETURN_ERROR; + } + + json_object_put(obj); + return container; + + RETURN_ERROR: + json_object_put(obj); + free_container(container, IP_MODULE_TRUE); + return NULL; +} + +bool_t is_ip_match_netif(unsigned int ip, char *netif_name) +{ + if (!netif_name) + { + return 0; + } + + if (trp_rb_search((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + struct network_configuration *network = + get_network_by_ip_with_tree(ip); + if (network && network->phy_net && network->phy_net->header) + { + if (0 == + strncmp(netif_name, network->phy_net->header->nic_name, + HAL_MAX_NIC_NAME_LEN)) + { + return 1; + } + } + } + + return 0; +} + +inline bool_t is_ip_exist(unsigned int ip) +{ + if (trp_rb_search((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + return 1; + } + + return 0; +} + +int validate_addcontainerconfig(struct container_ip *container) +{ + struct container_port *port; + struct container_ip *old = + get_container_by_container_id(container->container_id); + struct container_port *tmp = container->ports_list; + + if (old) + { + struct container_port *last = NULL; + + while (tmp) + { + if (get_port(container->container_id, tmp->port_name)) + { + NSOPR_LOGERR("port=%s already exists!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + + (void) last; + } + + /* check if port_name duplicates in one json configuration */ + tmp = container->ports_list; + while (tmp) + { + if (get_port_from_container(tmp)) + { + NSOPR_LOGERR("port=%s duplicates!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + tmp = tmp->next; + } + + bool_t is_nstack_dpdk_port; + struct container_port **ref = &container->ports_list; + while ((port = *ref)) + { + is_nstack_dpdk_port = 1; + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + struct network_configuration *network = + get_network_by_ip_with_tree(ip_cidr->ip); + if (network && (0 == strcmp(network->type_name, "nstack-dpdk"))) + { + struct netif *pnetif; + if (get_netif_by_ip(ip_cidr->ip)) + { + NSOPR_LOGERR("ip exists]IP=0x%08x", ip_cidr->ip); + return NSCRTL_RD_EXIST; + } + + if (network->phy_net->bond_name[0] != 0) + { + pnetif = + find_netif_by_if_name(network->phy_net->bond_name); + } + else + { + pnetif = + find_netif_by_if_name(network->phy_net-> + header->nic_name); + } + + if (!pnetif) + { + NSOPR_LOGERR("can't find netif, network json:%s", + get_network_json(network)); + return NSCRTL_ERR; + } + + if (0 == port->port_name[0]) + { + NSOPR_LOGINF + ("ip=0x%08x is in nstack dpdk network, but port_name is null, json:%s", + ip_cidr->ip, get_port_json(port)); + is_nstack_dpdk_port = 0; + break; + } + } + else + { + NSOPR_LOGINF("port %s is not in nstack dpdk network, json:%s", + port->port_name, get_port_json(port)); + is_nstack_dpdk_port = 0; + break; + } + + ip_cidr = ip_cidr->next; + } + + /* only use nstack dpdk port */ + if (is_nstack_dpdk_port) + { + ref = &port->next; + } + else + { + *ref = port->next; + port->next = NULL; + free_container_port(port, IP_MODULE_TRUE); + } + } + + return (!container->ports_list) ? NSCRTL_FREE_ALL_PORT : NSCRTL_OK; +} + +/* get the num of IPs in a container , which in a certain subnet */ +extern struct network_list g_network_list; +extern inline int is_in_subnet(unsigned int ip, struct ip_subnet *subnet); +NSTACK_STATIC inline int get_network_ip_count + (struct container_ip *container, struct ip_subnet *subnet) +{ + int ip_count = 0; + struct container_port *port_list = NULL; + struct container_ip *ci = container; + + while (ci) + { + port_list = ci->ports_list; + while (port_list) + { + struct container_port_ip_cidr *ip_list = port_list->ip_cidr_list; + while (ip_list) + { + if (!is_in_subnet(ip_list->ip, subnet)) + { + ip_count++; + } + + ip_list = ip_list->next; + } + + port_list = port_list->next; + } + + ci = ci->next; + } + + return ip_count; +} + +int check_ip_count(struct container_ip *container) +{ + int cur_count = 0; + int new_count = 0; + + if (NULL == container) + { + return 1; + } + + struct network_configuration *network = g_network_list.header; + while (network) + { + cur_count = + get_network_ip_count(g_container_list.header, network->ip_subnet); + new_count = get_network_ip_count(container, network->ip_subnet); + + if ((cur_count > MAX_NETWORK_IP_COUNT) + || (new_count > MAX_NETWORK_IP_COUNT) + || (cur_count + new_count > MAX_NETWORK_IP_COUNT)) + { + NSOPR_LOGERR + ("reach ip addr max count]network=%s, max=%d, current=%d, new=%d.", + network->network_name, MAX_NETWORK_IP_COUNT, cur_count, + new_count); + return 0; + } + + network = network->next; + } + + return 1; +} + +int +match_groupaddr(struct container_multicast_id *multi_list, + spl_ip_addr_t * groupaddr) +{ + struct container_multicast_id *group_info = multi_list; + + while (group_info) + { + if (group_info->ip == groupaddr->addr) + { + return 1; + } + + group_info = group_info->next; + } + + return 0; +} + +int add_container(struct container_ip *container) +{ + int retVal = 0; + + /* need to check if any of the netif operation failed, then we should return fail */ + retVal = validate_addcontainerconfig(container); + if (retVal != NSCRTL_OK) + { + free_container(container, IP_MODULE_TRUE); + return (NSCRTL_FREE_ALL_PORT == retVal) ? NSCRTL_OK : retVal; + } + + /* control max network and ipaddress count */ + if (!check_ip_count(container)) + { + free_container(container, IP_MODULE_TRUE); + return NSCRTL_IP_COUNT_EXCEED; + } + + struct container_port *last = NULL; + struct container_ip *old = + get_container_by_container_id(container->container_id); + if (old) + { + struct container_port *tmp = container->ports_list; + while (tmp) + { + /* here we don't need to check "if tmp->port_name == NULL", as validate_addcontainerconfig() has done this. */ + if (get_port(container->container_id, tmp->port_name)) + { + free_container(container, IP_MODULE_TRUE); + NSOPR_LOGERR("port exist!"); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + } + else + { + container->next = g_container_list.header; + g_container_list.header = container; + } + + output_api *api = get_output_api(); + struct container_port *port = container->ports_list; + while (port) + { + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + if (api->add_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree(ip_cidr->ip); + if (network) + { + unsigned int mask = ~0; + mask = + (mask << + (IP_MODULE_SUBNET_MASK_LEN - ip_cidr->mask_len)); + mask = spl_htonl(mask); + if (network->phy_net->bond_name[0] != 0) + { + (void) api->add_netif_ip(network->phy_net->bond_name, ip_cidr->ip, mask); //no need to check return value, validate_addcontainerconfig() has been checked parameters. + } + else + { + (void) api->add_netif_ip(network->phy_net-> + header->nic_name, + ip_cidr->ip, mask); + } + } + else + { + NSOPR_LOGERR("can't find network by]IP=%u,port_name=%s", + ip_cidr->ip, port->port_name); + } + } + + retVal = + trp_rb_insert((void *) (u64_t) ip_cidr->ip, (void *) port, + &g_container_ip_root, ip_compare); + + if (0 != retVal) + { + NSOPR_LOGERR("trp_rb_insert failed]ip_cidr->ip=%u", + ip_cidr->ip); + } + + ip_cidr = ip_cidr->next; + } + port = port->next; + } + + if (old) + { + if (last) + { + last->next = old->ports_list; + old->ports_list = container->ports_list; + } + + container->ports_list = NULL; + free_container(container, IP_MODULE_FALSE); + } + + return NSCRTL_OK; +} + +struct container_ip *get_container_by_container_id(char *container_id) +{ + if (NULL == container_id) + { + NSOPR_LOGERR("Param input container ID is NULL"); + return NULL; + } + + struct container_ip *container = g_container_list.header; + while (container) + { + if (0 == strcmp(container->container_id, container_id)) + { + return container; + } + + container = container->next; + } + + return NULL; +} + +/***************************************************************************** +* Prototype : getIpCfgAll +* Description : Get All ip configurations +* Input : char * +* size_t +* Output : char * patern:[***,***,***] +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int getIpCfgAll(char *jsonBuf, size_t size) +{ + int retval; + + if (NULL == jsonBuf) + { + return NSCRTL_ERR; + } + + if (size < 2) + { + NSOPR_LOGERR("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + char bfirstData = 1; + *jsonBuf = '['; + jsonBuf = jsonBuf + 1; + + /*need another two char to keep [and ] */ + size_t len = size - 2; + size_t strsize = 0; + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + while (container) + { + port = container->ports_list; + while (port) + { + if (NULL == port->buffer) + { + port = port->next; + continue; + } + + strsize = strlen(get_port_json(port)) + 1; + + /*always reserve 1 char */ + if ((strsize > 0) && (strsize < len)) + { + if (bfirstData) + { + bfirstData = 0; + } + else + { + *jsonBuf = ','; + jsonBuf = jsonBuf + 1; + len = len - 1; + } + + retval = strcpy_s(jsonBuf, len, get_port_json(port)); + if (EOK != retval) + { + NSOPR_LOGERR("STRCPY_S failed]ret=%d", retval); + return NSCRTL_ERR; + } + + len = len - strlen(get_port_json(port)); + jsonBuf = jsonBuf + strlen(get_port_json(port)); + } + else + { + NSOPR_LOGERR("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + port = port->next; + } + + container = container->next; + } + + *jsonBuf = ']'; + return 0; +} + +int del_port(char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_port **ref = NULL; + struct container_ip *container = NULL; + struct container_ip **container_ref = &g_container_list.header; + + while ((container = *container_ref)) + { + NSOPR_LOGDBG("container->container_id=%s,container_id=%p", + container->container_id, container_id); + if (strcmp(container->container_id, container_id) == 0) + { + ref = &container->ports_list; + while ((port = *ref)) + { + if (strcmp(port_name, port->port_name) == 0) + { + *ref = port->next; + port->next = NULL; + free_container_port(port, IP_MODULE_FALSE); + return 0; + } + + ref = &port->next; + } + + break; + } + + container_ref = &container->next; + } + + return NSCRTL_RD_NOT_EXIST; +} + +struct container_port *get_port(char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + + while (container) + { + if (strcmp(container->container_id, container_id) == 0) + { + port = container->ports_list; + while (port) + { + if (strcmp(port_name, port->port_name) == 0) + { + return port; + } + + port = port->next; + } + } + + container = container->next; + } + + return NULL; +} + +struct container_port *get_port_from_container(struct container_port *port) +{ + char *port_name = port->port_name; + struct container_port *tmp = port->next; + + while (tmp) + { + if (strcmp(port_name, tmp->port_name) == 0) + { + return tmp; + } + + tmp = tmp->next; + } + + return NULL; +} |