diff options
author | sharath <sharathkumarboyanapally@gmail.com> | 2018-08-13 19:28:26 +0530 |
---|---|---|
committer | sharath <sharathkumarboyanapally@gmail.com> | 2018-08-13 19:29:13 +0530 |
commit | 7b1e219c80f5fe44a8f015a369e57ba7d2bc39cc (patch) | |
tree | 9fa3ee1ce324478711dfce73425e16e6bcb429a9 /stacks/lwip_stack/lwip_src/ip_module/container_ip.c | |
parent | bd6e75c243db1b384ba0882ecaf9063ec4cd70bd (diff) |
Feat : LWIP integration part2
Change-Id: I2431581d611659beb9b9b4d6d95d6985e53a8061
Signed-off-by: sharath <sharathkumarboyanapally@gmail.com>
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 | 1168 |
1 files changed, 1168 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..3cbe9b9 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/container_ip.c @@ -0,0 +1,1168 @@ +/* +* +* 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 "nstack_rd_mng.h" +#include "config_common.h" +#include "igmp.h" +#include "spl_def.h" +#include "stackx_ip_addr.h" +#include "hal_api.h" +#include "spl_hal.h" + +struct container_list g_container_list = { 0 }; +static trp_rb_root_t g_container_ip_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock +static trp_rb_root_t g_container_multicast_root = { 0 }; //only handled in tcpip thread, no need protect it with a lock + +static void free_container_port (struct container_port *port, + bool_t only_free); + +/*unsigned int value is typecasted into void * pointer and passed as argument to +this function. so the value can never be > 0xFFFFFFFF. so can suppress the warning*/ + +static int +ip_compare (trp_key_t left, trp_key_t right) +{ + //return (int)((unsigned long)left - (unsigned long)right); + + if (left > right) + { + return 1; + } + else if (left < right) + { + return -1; + } + else + { + return 0; + } +} + +NSTACK_STATIC bool_t +is_container_ok (struct container_ip * container) +{ + if (!container->ports_list) + { + return 0; + } + + return 1; +} + +NSTACK_STATIC void +add_port (struct container_ip *container, struct container_port *port) +{ + if (port->ip_cidr_list) + { + port->next = container->ports_list; + container->ports_list = port; + } + else + { + free_container_port (port, IP_MODULE_TRUE); + } +} + +static void +add_ip_cidr (struct container_port *port, + struct container_port_ip_cidr *ip_cidr) +{ + if (!ip_cidr) + { + return; + } + + ip_cidr->next = port->ip_cidr_list; + port->ip_cidr_list = ip_cidr; + return; +} + +NSTACK_STATIC void +add_multilcast_ip (struct container_port *port, + struct container_multicast_id *muticastIP) +{ + if (!muticastIP) + { + return; + } + + muticastIP->next = port->multicast_list; + port->multicast_list = muticastIP; + return; +} + +NSTACK_STATIC void +free_container_port_ip_cidr (struct container_port_ip_cidr *ip_cidr, + bool_t only_free) +{ + output_api *api = get_output_api (); + struct container_port_ip_cidr *ip_cidr_tmp = NULL; + + while (ip_cidr) + { + ip_cidr_tmp = ip_cidr; + ip_cidr = ip_cidr_tmp->next; + if (!only_free) + { + if (api->del_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr_tmp->ip); + if (network) + { + if (network->phy_net->bond_name[0] != 0) + { + (void) api->del_netif_ip (network->phy_net->bond_name, ip_cidr_tmp->ip); //fails only when netif_name not exist, no side effect so don't check return value. + } + else + { + (void) api->del_netif_ip (network->phy_net-> + header->nic_name, + ip_cidr_tmp->ip); + } + } + else + { + NSOPR_LOGERR ("can't find network by]IP=%u", + ip_cidr_tmp->ip); + } + } + + trp_rb_erase ((void *) (u64_t) ip_cidr_tmp->ip, + &g_container_ip_root, ip_compare); + } + + free (ip_cidr_tmp); + ip_cidr_tmp = NULL; + } +} + +/*note:::the ip must be local order*/ +void +container_multicast_rd (unsigned int ip, int op) +{ + rd_ip_data rd_ip = { 0 }; + int ret = 0; + + rd_ip.addr = ip; + rd_ip.masklen = 32; + if (0 == op) + { + ret = nstack_rd_ip_node_insert ("nstack-dpdk", &rd_ip); + } + else + { + ret = nstack_rd_ip_node_delete (&rd_ip); + } + + if (0 != ret) + { + NSOPR_LOGERR ("nstack rd multicast ip:0x%x %s fail", ip, + (0 == op ? "insert" : "delete")); + } + else + { + NSOPR_LOGDBG ("nstack rd multicast ip:0x%x %s success", ip, + (0 == op ? "insert" : "delete")); + } + + return; +} + +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) + { + /*note:::multicast ip is network, need to change to local order, delete multicast ip from rd. */ + container_multicast_rd (spl_ntohl (tmp->ip), 1); + + trp_rb_erase ((void *) (u64_t) tmp->ip, &g_container_multicast_root, + ip_compare); + } + + free (tmp); + tmp = NULL; + } +} + +static void +free_container_port (struct container_port *port, bool_t only_free) +{ + struct container_port *port_tmp = NULL; + struct container_port *port_curr = port; + + while (port_curr) + { + port_tmp = port_curr; + port_curr = port_tmp->next; + + free_container_multicast (port_tmp->multicast_list, only_free); + free_container_port_ip_cidr (port_tmp->ip_cidr_list, only_free); + + if (port_tmp->buffer) + { + free_port_buffer (port_tmp->buffer); + port_tmp->buffer = NULL; + } + + free (port_tmp); + port_tmp = NULL; + } +} + +void +free_container (struct container_ip *container, bool_t only_free) +{ + struct container_ip *container_tmp = NULL; + struct container_ip *container_curr = container; + + while (container_curr) + { + container_tmp = container_curr; + container_curr = container_tmp->next; + if (container_tmp->ports_list) + { + free_container_port (container_tmp->ports_list, only_free); + } + + free (container_tmp); + container_tmp = NULL; + } +} + +struct container_port * +parse_port_obj (struct json_object *port_obj) +{ + int retval; + struct json_object *port_name_obj = NULL; + struct json_object *ip_cidr_list_obj = NULL; + struct json_object *mcIDObj = NULL; + + if (!port_obj) + { + NSOPR_LOGERR ("port_obj is null"); + return NULL; + } + + struct container_port *port = malloc (sizeof (struct container_port)); + if (!port) + { + NSOPR_LOGERR ("malloc failed"); + return NULL; + } + + retval = + MEMSET_S (port, sizeof (struct container_port), 0, + sizeof (struct container_port)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port); + return NULL; + } + + json_object_object_get_ex (port_obj, "port_name", &port_name_obj); + if (port_name_obj) + { + const char *port_name = json_object_get_string (port_name_obj); + if ((NULL == port_name) + || (strlen (port_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("port name is not ok"); + goto RETURN_ERROR; + } + + retval = + STRCPY_S (port->port_name, sizeof (port->port_name), port_name); + + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + + json_object_object_get_ex (port_obj, "ip_cidr", &ip_cidr_list_obj); + if (ip_cidr_list_obj) + { + int j; + int ip_cidr_num = json_object_array_length (ip_cidr_list_obj); + for (j = 0; j < ip_cidr_num; ++j) + { + struct json_object *ip_cidr_obj = + json_object_array_get_idx (ip_cidr_list_obj, j); + if (ip_cidr_obj) + { + char tmp[IP_MODULE_LENGTH_32] = { 0 }; + struct container_port_ip_cidr *port_ip_cidr = + malloc (sizeof (struct container_port_ip_cidr)); + if (NULL == port_ip_cidr) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retval = + MEMSET_S (port_ip_cidr, + sizeof (struct container_port_ip_cidr), 0, + sizeof (struct container_port_ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *ip_cidr = json_object_get_string (ip_cidr_obj); + if ((NULL == ip_cidr) || (ip_cidr[0] == 0)) + { + NSOPR_LOGERR ("ip_cidr is not ok"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + const char *sub = strstr (ip_cidr, "/"); + if ((NULL == sub) + || (sizeof (tmp) - 1 < (unsigned int) (sub - ip_cidr)) + || (strlen (sub) > sizeof (tmp) - 1)) + { + NSOPR_LOGERR + ("Error : Ipaddress notation must be in ip cidr notation!"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + retval = + STRNCPY_S (tmp, sizeof (tmp), ip_cidr, + (size_t) (sub - ip_cidr)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRNCPY_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + struct in_addr addr; + int iRet; + retval = MEMSET_S (&addr, sizeof (addr), 0, sizeof (addr)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + iRet = spl_inet_aton (tmp, &addr); + if (0 == iRet) + { + NSOPR_LOGERR ("spl_inet_aton failed"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->ip = addr.s_addr; + iRet = atoi (sub + 1); + if ((iRet <= 0) || (iRet > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("IP mask length is not correct"); + free (port_ip_cidr); + port_ip_cidr = NULL; + goto RETURN_ERROR; + } + + port_ip_cidr->mask_len = (unsigned int) iRet; + add_ip_cidr (port, port_ip_cidr); + } + } + } + + json_object_object_get_ex (port_obj, "multicast_id", &mcIDObj); + if (mcIDObj) + { + int j; + int arrLen = json_object_array_length (mcIDObj); + if (0 == arrLen) + { + NSOPR_LOGERR ("arrLen is 0"); + goto RETURN_ERROR; + } + + for (j = 0; j < arrLen; ++j) + { + struct json_object *elemObj = + json_object_array_get_idx (mcIDObj, j); + + if (elemObj) + { + struct json_object *tObj = NULL; + const char *tStr; + int ret; + struct in_addr addr; + + struct container_multicast_id *mcID = + malloc (sizeof (struct container_multicast_id)); + if (NULL == mcID) + { + NSOPR_LOGERR ("Can't alloc container multicast id"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (elemObj, "group_ip", &tObj); + if (NULL == tObj) + { + NSOPR_LOGERR ("No group_IP"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + tStr = json_object_get_string (tObj); + if (NULL == tStr) + { + NSOPR_LOGERR ("Get Multiple cast group IP Failed"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + ret = spl_inet_aton (tStr, &addr); + if (0 == ret) + { + NSOPR_LOGERR ("Parse group IP Failed"); + free (mcID); + mcID = NULL; + goto RETURN_ERROR; + } + + mcID->ip = addr.s_addr; + add_multilcast_ip (port, mcID); + } + } + } + + const char *port_json = json_object_get_string (port_obj); + if ((NULL == port_json) || (0 == strlen (port_json))) + { + NSOPR_LOGERR ("json_object_get_string failed"); + goto RETURN_ERROR; + } + + port->buffer = malloc_port_buffer (); + if (!port->buffer) + { + goto RETURN_ERROR; + } + + retval = + STRCPY_S (get_port_json (port), IP_MODULE_PORT_JSON_LEN, port_json); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + return port; +RETURN_ERROR: + free_container_port (port, IP_MODULE_TRUE); + return NULL; +} + +struct container_ip * +parse_container_ip_json (char *param) +{ + int retval; + struct json_object *obj = json_tokener_parse (param); + struct json_object *container_id_obj = NULL; + struct json_object *ports_list_obj = NULL; + + if (!obj) + { + return NULL; + } + + struct container_ip *container = malloc (sizeof (struct container_ip)); + if (container == NULL) + { + json_object_put (obj); + return NULL; + } + + retval = + MEMSET_S (container, sizeof (struct container_ip), 0, + sizeof (struct container_ip)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + json_object_object_get_ex (obj, "containerID", &container_id_obj); + if (container_id_obj) + { + const char *container_id = json_object_get_string (container_id_obj); + if ((container_id == NULL) || (container_id[0] == 0) + || (strlen (container_id) >= IP_MODULE_MAX_NAME_LEN)) + { + goto RETURN_ERROR; + } + + retval = + MEMSET_S (container->container_id, sizeof (container->container_id), + 0, sizeof (container->container_id)); + if (EOK != retval) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + + retval = + STRCPY_S (container->container_id, sizeof (container->container_id), + container_id); + + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + goto RETURN_ERROR; + } + } + else + { + /* this mandatory parameter */ + goto RETURN_ERROR; + } + + json_object_object_get_ex (obj, "ports_list", &ports_list_obj); + if (ports_list_obj) + { + int i; + int port_num = json_object_array_length (ports_list_obj); + + if (port_num == 0) + { + /* this mandatory parameter */ + goto RETURN_ERROR; + } + + for (i = 0; i < port_num; i++) + { + struct json_object *port_obj = + json_object_array_get_idx (ports_list_obj, i); + struct container_port *port = parse_port_obj (port_obj); + if (!port) + { + goto RETURN_ERROR; + } + + add_port (container, port); + } + } + else + { + /* mandatory parameter */ + goto RETURN_ERROR; + } + + /* Check if this function is required, or needs more check inside this function, + as some of them are alraedy validated + */ + if (!is_container_ok (container)) + { + goto RETURN_ERROR; + } + + json_object_put (obj); + return container; + +RETURN_ERROR: + json_object_put (obj); + free_container (container, IP_MODULE_TRUE); + return NULL; +} + +bool_t +is_ip_match_netif (unsigned int ip, char *netif_name) +{ + if (!netif_name) + { + return 0; + } + + if (trp_rb_search ((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip); + if (network && network->phy_net && network->phy_net->header) + { + if (0 == + strncmp (netif_name, network->phy_net->header->nic_name, + HAL_MAX_NIC_NAME_LEN)) + { + return 1; + } + } + } + + return 0; +} + +inline bool_t +is_ip_exist (unsigned int ip) +{ + if (trp_rb_search ((void *) (u64_t) ip, &g_container_ip_root, ip_compare)) + { + return 1; + } + + return 0; +} + +int +validate_addcontainerconfig (struct container_ip *container) +{ + struct container_port *port; + struct container_ip *old = + get_container_by_container_id (container->container_id); + struct container_port *tmp = container->ports_list; + + if (old) + { + struct container_port *last = NULL; + + while (tmp) + { + if (get_port (container->container_id, tmp->port_name)) + { + NSOPR_LOGERR ("port=%s already exists!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + + (void) last; + } + + /* check if port_name duplicates in one json configuration */ + tmp = container->ports_list; + while (tmp) + { + if (get_port_from_container (tmp)) + { + NSOPR_LOGERR ("port=%s duplicates!", tmp->port_name); + return NSCRTL_RD_EXIST; + } + + tmp = tmp->next; + } + + bool_t is_nstack_dpdk_port; + struct container_port **ref = &container->ports_list; + while ((port = *ref)) + { + is_nstack_dpdk_port = 1; + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr->ip); + if (network && (0 == strcmp (network->type_name, "nstack-dpdk"))) + { + struct netif *pnetif; + if (get_netif_by_ip (ip_cidr->ip)) + { + NSOPR_LOGERR ("ip exists]IP=0x%08x", ip_cidr->ip); + return NSCRTL_RD_EXIST; + } + + if (network->phy_net->bond_name[0] != 0) + { + pnetif = + find_netif_by_if_name (network->phy_net->bond_name); + } + else + { + pnetif = + find_netif_by_if_name (network->phy_net-> + header->nic_name); + } + + if (!pnetif) + { + NSOPR_LOGERR ("can't find netif, network json:%s", + get_network_json (network)); + return NSCRTL_ERR; + } + + if (0 == port->port_name[0]) + { + NSOPR_LOGINF + ("ip=0x%08x is in nstack dpdk network, but port_name is null, json:%s", + ip_cidr->ip, get_port_json (port)); + is_nstack_dpdk_port = 0; + break; + } + } + else + { + NSOPR_LOGINF ("port %s is not in nstack dpdk network, json:%s", + port->port_name, get_port_json (port)); + is_nstack_dpdk_port = 0; + break; + } + + ip_cidr = ip_cidr->next; + } + + /* only use nstack dpdk port */ + if (is_nstack_dpdk_port) + { + ref = &port->next; + } + else + { + *ref = port->next; + port->next = NULL; + free_container_port (port, IP_MODULE_TRUE); + } + } + + return (!container->ports_list) ? NSCRTL_FREE_ALL_PORT : NSCRTL_OK; +} + +/* get the num of IPs in a container , which in a certain subnet */ +extern struct network_list g_network_list; +extern inline int is_in_subnet (unsigned int ip, struct ip_subnet *subnet); +NSTACK_STATIC inline int get_network_ip_count + (struct container_ip *container, struct ip_subnet *subnet) +{ + int ip_count = 0; + struct container_port *port_list = NULL; + struct container_ip *ci = container; + + while (ci) + { + port_list = ci->ports_list; + while (port_list) + { + struct container_port_ip_cidr *ip_list = port_list->ip_cidr_list; + while (ip_list) + { + if (!is_in_subnet (ip_list->ip, subnet)) + { + ip_count++; + } + + ip_list = ip_list->next; + } + + port_list = port_list->next; + } + + ci = ci->next; + } + + return ip_count; +} + +int +check_ip_count (struct container_ip *container) +{ + int cur_count = 0; + int new_count = 0; + + if (NULL == container) + { + return 1; + } + + struct network_configuration *network = g_network_list.header; + while (network) + { + cur_count = + get_network_ip_count (g_container_list.header, network->ip_subnet); + new_count = get_network_ip_count (container, network->ip_subnet); + + if ((cur_count > MAX_NETWORK_IP_COUNT) + || (new_count > MAX_NETWORK_IP_COUNT) + || (cur_count + new_count > MAX_NETWORK_IP_COUNT)) + { + NSOPR_LOGERR + ("reach ip addr max count]network=%s, max=%d, current=%d, new=%d.", + network->network_name, MAX_NETWORK_IP_COUNT, cur_count, + new_count); + return 0; + } + + network = network->next; + } + + return 1; +} + +int +match_groupaddr (struct container_multicast_id *multi_list, + spl_ip_addr_t * groupaddr) +{ + struct container_multicast_id *group_info = multi_list; + + while (group_info) + { + if (group_info->ip == groupaddr->addr) + { + return 1; + } + + group_info = group_info->next; + } + + return 0; +} + +int +add_container (struct container_ip *container) +{ + int retVal = 0; + + /* need to check if any of the netif operation failed, then we should return fail */ + retVal = validate_addcontainerconfig (container); + if (retVal != NSCRTL_OK) + { + free_container (container, IP_MODULE_TRUE); + return (NSCRTL_FREE_ALL_PORT == retVal) ? NSCRTL_OK : retVal; + } + + /* control max network and ipaddress count */ + if (!check_ip_count (container)) + { + free_container (container, IP_MODULE_TRUE); + return NSCRTL_IP_COUNT_EXCEED; + } + + struct container_port *last = NULL; + struct container_ip *old = + get_container_by_container_id (container->container_id); + if (old) + { + struct container_port *tmp = container->ports_list; + while (tmp) + { + /* here we don't need to check "if tmp->port_name == NULL", as validate_addcontainerconfig() has done this. */ + if (get_port (container->container_id, tmp->port_name)) + { + free_container (container, IP_MODULE_TRUE); + NSOPR_LOGERR ("port exist!"); + return NSCRTL_RD_EXIST; + } + + last = tmp; + tmp = tmp->next; + } + } + else + { + container->next = g_container_list.header; + g_container_list.header = container; + } + + output_api *api = get_output_api (); + struct container_port *port = container->ports_list; + while (port) + { + struct container_port_ip_cidr *ip_cidr = port->ip_cidr_list; + while (ip_cidr) + { + if (api->add_netif_ip) + { + struct network_configuration *network = + get_network_by_ip_with_tree (ip_cidr->ip); + if (network) + { + unsigned int mask = ~0; + mask = + (mask << (IP_MODULE_SUBNET_MASK_LEN - ip_cidr->mask_len)); + mask = spl_htonl (mask); + if (network->phy_net->bond_name[0] != 0) + { + (void) api->add_netif_ip (network->phy_net->bond_name, ip_cidr->ip, mask); //no need to check return value, validate_addcontainerconfig() has been checked parameters. + } + else + { + (void) api->add_netif_ip (network->phy_net-> + header->nic_name, ip_cidr->ip, + mask); + } + } + else + { + NSOPR_LOGERR ("can't find network by]IP=%u,port_name=%s", + ip_cidr->ip, port->port_name); + } + } + + retVal = + trp_rb_insert ((void *) (u64_t) ip_cidr->ip, (void *) port, + &g_container_ip_root, ip_compare); + + if (0 != retVal) + { + NSOPR_LOGERR ("trp_rb_insert failed]ip_cidr->ip=%u", + ip_cidr->ip); + } + + ip_cidr = ip_cidr->next; + } + port = port->next; + } + + if (old) + { + if (last) + { + last->next = old->ports_list; + old->ports_list = container->ports_list; + } + + container->ports_list = NULL; + free_container (container, IP_MODULE_FALSE); + } + + return NSCRTL_OK; +} + +struct container_ip * +get_container_by_container_id (char *container_id) +{ + if (NULL == container_id) + { + NSOPR_LOGERR ("Param input container ID is NULL"); + return NULL; + } + + struct container_ip *container = g_container_list.header; + while (container) + { + if (0 == strcmp (container->container_id, container_id)) + { + return container; + } + + container = container->next; + } + + return NULL; +} + +/***************************************************************************** +* Prototype : getIpCfgAll +* Description : Get All ip configurations +* Input : char * +* size_t +* Output : char * patern:[***,***,***] +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +getIpCfgAll (char *jsonBuf, size_t size) +{ + int retval; + + if (NULL == jsonBuf) + { + return NSCRTL_ERR; + } + + if (size < 2) + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + char bfirstData = 1; + *jsonBuf = '['; + jsonBuf = jsonBuf + 1; + + /*need another two char to keep [and ] */ + size_t len = size - 2; + size_t strsize = 0; + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + while (container) + { + port = container->ports_list; + while (port) + { + if (NULL == port->buffer) + { + port = port->next; + continue; + } + + strsize = strlen (get_port_json (port)) + 1; + + /*always reserve 1 char */ + if ((strsize > 0) && (strsize < len)) + { + if (bfirstData) + { + bfirstData = 0; + } + else + { + *jsonBuf = ','; + jsonBuf = jsonBuf + 1; + len = len - 1; + } + + retval = STRCPY_S (jsonBuf, len, get_port_json (port)); + if (EOK != retval) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retval); + return NSCRTL_ERR; + } + + len = len - strlen (get_port_json (port)); + jsonBuf = jsonBuf + strlen (get_port_json (port)); + } + else + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + port = port->next; + } + + container = container->next; + } + + *jsonBuf = ']'; + return 0; +} + +int +del_port (char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_port **ref = NULL; + struct container_ip *container = NULL; + struct container_ip **container_ref = &g_container_list.header; + + while ((container = *container_ref)) + { + NSOPR_LOGDBG ("container->container_id=%s,container_id=%p", + container->container_id, container_id); + if (strcmp (container->container_id, container_id) == 0) + { + ref = &container->ports_list; + while ((port = *ref)) + { + if (strcmp (port_name, port->port_name) == 0) + { + *ref = port->next; + port->next = NULL; + free_container_port (port, IP_MODULE_FALSE); + return 0; + } + + ref = &port->next; + } + + break; + } + + container_ref = &container->next; + } + + return NSCRTL_RD_NOT_EXIST; +} + +struct container_port * +get_port (char *container_id, char *port_name) +{ + struct container_port *port = NULL; + struct container_ip *container = g_container_list.header; + + while (container) + { + if (strcmp (container->container_id, container_id) == 0) + { + port = container->ports_list; + while (port) + { + if (strcmp (port_name, port->port_name) == 0) + { + return port; + } + + port = port->next; + } + } + + container = container->next; + } + + return NULL; +} + +struct container_port * +get_port_from_container (struct container_port *port) +{ + char *port_name = port->port_name; + struct container_port *tmp = port->next; + + while (tmp) + { + if (strcmp (port_name, tmp->port_name) == 0) + { + return tmp; + } + + tmp = tmp->next; + } + + return NULL; +} |