diff options
Diffstat (limited to 'stacks/lwip_stack/lwip_src/ip_module/network.c')
-rw-r--r-- | stacks/lwip_stack/lwip_src/ip_module/network.c | 1127 |
1 files changed, 1127 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/ip_module/network.c b/stacks/lwip_stack/lwip_src/ip_module/network.c new file mode 100644 index 0000000..83fbb7c --- /dev/null +++ b/stacks/lwip_stack/lwip_src/ip_module/network.c @@ -0,0 +1,1127 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdio.h> +#include <sys/socket.h> +#include <string.h> +#include "json.h" +#include "trp_rb_tree.h" +#include "network.h" +#include "nstack_log.h" +#include "config_common.h" +#include "stackx_spl_share.h" +#include "stackx/spl_api.h" +#include "sharedmemory.h" +#include "nstack_securec.h" +#include "nstack_rd_mng.h" +#include "spl_hal.h" +#include "inet.h" + +struct network_list g_network_list = { 0 }; + +extern struct stackx_port_zone *p_stackx_port_zone; +extern u32 spl_hal_is_nic_exist (const char *name); + +static bool_t +is_phy_net_ok (struct phy_net *pst_phy_net) +{ + if (!pst_phy_net || !pst_phy_net->header) + { + NSOPR_LOGERR ("phy_net is not ok"); + return 0; + } + + return 1; +} + +static bool_t +is_network_configuration_ok (struct network_configuration *network) +{ + while (network) + { + if (!is_phy_net_ok (network->phy_net)) + { + return 0; + } + + network = network->next; + } + + return 1; +} + +static void +add_ref_nic (struct phy_net *pst_phy_net, struct ref_nic *pst_ref_nic) +{ + pst_ref_nic->next = pst_phy_net->header; + pst_phy_net->header = pst_ref_nic; +} + +static void +free_ref_nic (struct ref_nic *pst_ref_nic) +{ + struct ref_nic *nic = pst_ref_nic; + struct ref_nic *tmp = NULL; + + while (nic) + { + tmp = nic; + nic = tmp->next; + free (tmp); + } +} + +static void +free_phy_net (struct phy_net *pst_phy_net) +{ + if (pst_phy_net) + { + free_ref_nic (pst_phy_net->header); + free (pst_phy_net); + } +} + +static void +free_ip_subnet (struct ip_subnet *subnet, bool_t only_free) +{ + struct ip_subnet *tmp = NULL; + + while (subnet) + { + tmp = subnet; + subnet = subnet->next; + free (tmp); + } +} + +void +free_network_configuration (struct network_configuration *network, + bool_t only_free) +{ + if (network) + { + free_ip_subnet (network->ip_subnet, only_free); + free_phy_net (network->phy_net); + + if (network->buffer) + { + free_network_buffer (network->buffer); + network->buffer = NULL; + } + + free (network); + } +} + +inline int +is_in_subnet (unsigned int ip, struct ip_subnet *subnet) +{ + unsigned int mask = ~0; + unsigned int seg_ip, seg; + + mask = mask << (IP_MODULE_SUBNET_MASK_LEN - subnet->mask_len); + + seg_ip = ip & mask; + seg = subnet->subnet & mask; + + return seg_ip != seg ? 1 : 0; +} + +inline struct network_configuration * +get_network_by_ip_with_tree (unsigned int ip) +{ + unsigned int h_ip = spl_ntohl (ip); + struct network_configuration *p = g_network_list.header; + + while (p) + { + if (!is_in_subnet (h_ip, p->ip_subnet)) + { + return p; + } + + p = p->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_name (char *name) +{ + struct network_configuration *network = g_network_list.header; + + while (network) + { + if (strcasecmp (name, network->network_name) == 0) + { + return network; + } + + network = network->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_nic_name (char *name) +{ + if (NULL == name) + { + return NULL; + } + + struct ref_nic *refnic = NULL; + struct phy_net *phynet = NULL; + struct network_configuration *network = g_network_list.header; + while (network) + { + phynet = network->phy_net; + if (phynet) + { + if ((phynet->bond_mode != -1) + && strcmp (name, phynet->bond_name) == 0) + { + return network; + } + + refnic = phynet->header; + while (refnic) + { + if (strcmp (name, refnic->nic_name) == 0) + { + return network; + } + + refnic = refnic->next; + } + } + + network = network->next; + } + + return NULL; +} + +struct network_configuration * +get_network_by_name_from_json (struct network_configuration *network) +{ + char *name = network->network_name; + struct network_configuration *tmp = network->next; + + while (tmp) + { + if (strcasecmp (name, tmp->network_name) == 0) + { + return tmp; + } + + tmp = tmp->next; + } + + return NULL; +} + +NSTACK_STATIC inline int +get_network_count () +{ + int count = 0; + struct network_configuration *network = g_network_list.header; + + while (network) + { + count++; + network = network->next; + } + + return count; +} + +int +get_network_all (char *jsonBuf, size_t size) +{ + if (NULL == jsonBuf) + { + return NSCRTL_ERR; + } + + if (size < 2) + { + NSOPR_LOGERR ("get all ip cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + int retVal; + char bfirstData = 1; + *jsonBuf = '['; + jsonBuf = jsonBuf + 1; + + size_t len = size - 2; // strlen("[]") + size_t strsize = 0; + struct network_configuration *network = g_network_list.header; + while (network) + { + if (NULL == network->buffer) + { + network = network->next; + continue; + } + + if (bfirstData) + { + bfirstData = 0; + } + else + { + *jsonBuf = ','; + jsonBuf = jsonBuf + 1; + len = len - 1; + } + + strsize = strlen (get_network_json (network)) + 1; + if ((strsize > 0) && (strsize < len)) + { + retVal = STRCPY_S (jsonBuf, len, get_network_json (network)); + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + return NSCRTL_STATUS_ERR; + } + + len = len - strlen (get_network_json (network)); + jsonBuf = jsonBuf + strlen (get_network_json (network)); + } + else + { + NSOPR_LOGERR ("get all network cfg error, buffer is not enough."); + return NSCRTL_STATUS_ERR; + } + + network = network->next; + } + + *jsonBuf = ']'; + return 0; +} + +int +nic_already_bind (const char *nic_name) +{ + struct ref_nic *pnic = NULL; + struct network_configuration *pnetwork = g_network_list.header; + + while (pnetwork) + { + pnic = pnetwork->phy_net->header; + while (pnic) + { + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + + pnic = pnic->next; + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +int +nic_already_init (const char *nic_name) +{ + unsigned int i; + + for (i = 0; i < p_stackx_port_zone->port_num; i++) + { + if (0 == + strcmp (p_stackx_port_zone->stackx_one_port[i].linux_ip.if_name, + nic_name)) + { + return 1; + } + } + + return 0; +} + +extern struct stackx_port_info *head_used_port_list; +int +bonded_nic_already_bind (struct network_configuration *pnetwork, + const char *nic_name) +{ + struct stackx_port_info *p_port_list = head_used_port_list; + + while (p_port_list) + { + if (0 == strcmp (p_port_list->linux_ip.if_name, nic_name)) + { + return 1; + } + + p_port_list = p_port_list->next_use_port; + } + + struct ref_nic *pnic = NULL; + + while (pnetwork) + { + if (pnetwork->phy_net->bond_mode == -1) + { + pnic = pnetwork->phy_net->header; + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +extern struct bond_ports_info bond_ports_array; +int +nic_already_bond (struct network_configuration *pnetwork, + const char *nic_name) +{ + u8_t i, j; + struct bond_set *s; + + for (i = 0; i < bond_ports_array.cnt; i++) + { + s = &bond_ports_array.ports[i]; + for (j = 0; j < s->slave_port_cnt; j++) + { + if (strcmp (s->slave_ports[j], nic_name) == 0) + { + return 1; + } + } + } + + struct ref_nic *pnic = NULL; + + while (pnetwork) + { + if (pnetwork->phy_net->bond_mode != -1) + { + pnic = pnetwork->phy_net->header; + while (pnic) + { + if (0 == strcmp (pnic->nic_name, nic_name)) + { + return 1; + } + + pnic = pnic->next; + } + } + + pnetwork = pnetwork->next; + } + + return 0; +} + +/*add network to rd*/ +void +network_rd_proc (struct network_configuration *network, int op) +{ + struct ip_subnet *ptsubnet = NULL; + struct network_configuration *pn = NULL; + rd_ip_data rd_ip = { 0 }; + int ret = 0; + + pn = network; + + while (pn) + { + if (0 == strcmp ("nstack-dpdk", pn->type_name)) + { + ptsubnet = network->ip_subnet; + while (ptsubnet) + { + rd_ip.addr = ptsubnet->subnet; + rd_ip.masklen = ptsubnet->mask_len; + if (0 == op) + { + ret = nstack_rd_ip_node_insert (network->type_name, &rd_ip); + } + else + { + ret = nstack_rd_ip_node_delete (&rd_ip); + } + + if (0 != ret) + { + NSOPR_LOGERR ("nstack rd subnet:0x%x, masklen:0x%x %s fail", + rd_ip.addr, rd_ip.masklen, + (0 == op ? "insert" : "delete")); + } + else + { + NSOPR_LOGDBG + ("nstack rd subnet:0x%x, masklen:0x%x %s success", + rd_ip.addr, rd_ip.masklen, + (0 == op ? "insert" : "delete")); + } + + ptsubnet = ptsubnet->next; + } + } + + pn = pn->next; + } + + return; +} + +/* add network to list in descending sort */ +void +add_network_to_list (struct network_configuration *network) +{ + struct network_configuration *curr = g_network_list.header; + struct network_configuration *prev = NULL; + + network->next = NULL; + + /*add network to rd */ + network_rd_proc (network, 0); + + while (curr) + { + if (network->ip_subnet->mask_len >= curr->ip_subnet->mask_len) + { + break; + } + + prev = curr; + curr = curr->next; + } + + if (NULL == prev) + { + network->next = curr; + g_network_list.header = network; + } + else + { + network->next = prev->next; + prev->next = network; + } +} + +int +add_network_configuration (struct network_configuration + *pst_network_configuration) +{ + struct network_configuration *tmp = pst_network_configuration; + struct ref_nic *pheader; + + if (tmp) + { + if (get_network_by_name (tmp->network_name) + || get_network_by_name_from_json (tmp)) + { + NSOPR_LOGERR ("network exists or duplicates]network_name=%s", + tmp->network_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_RD_EXIST; + } + + if (strcasecmp ("nstack-dpdk", tmp->type_name) != 0) + { + NSOPR_LOGWAR ("illegal network type]type_name=%s", tmp->type_name); + } + + /* control max network and ipaddress count */ + if (get_network_count () >= MAX_NETWORK_COUNT) + { + NSOPR_LOGERR ("network reach]max_count=%d", MAX_NETWORK_COUNT); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_NETWORK_COUNT_EXCEED; + } + + /* If nic is not existed or not initiated, return error */ + pheader = tmp->phy_net->header; + while (pheader) + { + if (!spl_hal_is_nic_exist (pheader->nic_name) + && !nic_already_init (pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s not exist Error! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_RD_NOT_EXIST; + } + + pheader = pheader->next; + } + + /* if a bonded nic has been inited in a non-bond network, return error */ + if (tmp->phy_net->bond_mode != -1) + { + pheader = tmp->phy_net->header; + while (pheader) + { + if (bonded_nic_already_bind + (pst_network_configuration, pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s already bind! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_INPUT_ERR; + } + + pheader = pheader->next; + } + } + + /* if a non-bond nic has been inited in a bonded network, return error */ + if (tmp->phy_net->bond_mode == -1) + { + pheader = tmp->phy_net->header; + while (pheader) + { + if (nic_already_bond + (pst_network_configuration, pheader->nic_name)) + { + NSOPR_LOGERR ("Invalid configuration %s already bind! ", + pheader->nic_name); + free_network_configuration (pst_network_configuration, + IP_MODULE_TRUE); + return NSCRTL_INPUT_ERR; + } + + pheader = pheader->next; + } + } + } + else + { + NSOPR_LOGERR ("Invalid network configuration!"); + return NSCRTL_INPUT_ERR; + } + + /*looping through each node has move to read_ipmoduleoperateadd_configuration */ + ip_subnet_print (tmp->ip_subnet); + add_network_to_list (tmp); + + return NSCRTL_OK; +} + +struct network_configuration * +parse_network_obj (struct json_object *network_obj) +{ + int retVal; + struct network_configuration *pst_network_configuration = NULL; + struct json_object *network_name_obj = NULL, *args_obj = NULL, *phy_obj = + NULL, *type_name_obj = NULL; + struct json_object *ref_nic_list_obj = NULL, *bond_mode_obj = + NULL, *bond_name_obj = NULL, *ipam_obj = NULL; + struct json_object *subnet_obj = NULL; + + if (!network_obj) + { + NSOPR_LOGERR ("network_obj is null"); + goto RETURN_ERROR; + } + + pst_network_configuration = malloc (sizeof (struct network_configuration)); + if (NULL == pst_network_configuration) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_network_configuration, + sizeof (struct network_configuration), 0, + sizeof (struct network_configuration)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "name", &network_name_obj); + if (network_name_obj) + { + const char *network_name = json_object_get_string (network_name_obj); + if ((NULL == network_name) || (network_name[0] == 0) + || (strlen (network_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("network_name is not ok"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_network_configuration->network_name, + sizeof (pst_network_configuration->network_name), + network_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("name is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "type", &type_name_obj); + if (type_name_obj) + { + const char *type_name = json_object_get_string (type_name_obj); + if ((NULL == type_name) || (type_name[0] == 0) + || (strlen (type_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("type parse error"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_network_configuration->type_name, + sizeof (pst_network_configuration->type_name), type_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d", retVal); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("type is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "args", &args_obj); + if (args_obj) + { + json_object_object_get_ex (args_obj, "phynet", &phy_obj); + if (phy_obj) + { + struct phy_net *pst_phy_net = malloc (sizeof (struct phy_net)); + if (NULL == pst_phy_net) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_phy_net, sizeof (struct phy_net), 0, + sizeof (struct phy_net)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + json_object_object_get_ex (phy_obj, "ref_nic", &ref_nic_list_obj); + if (ref_nic_list_obj) + { + int j; + int ref_nic_num = json_object_array_length (ref_nic_list_obj); + if (0 == ref_nic_num) + { + NSOPR_LOGERR ("ref_nic is empty"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + for (j = ref_nic_num - 1; j >= 0; j--) + { + struct json_object *ref_nic_obj = + json_object_array_get_idx (ref_nic_list_obj, j); + if (ref_nic_obj) + { + const char *nic_name = + json_object_get_string (ref_nic_obj); + if ((NULL == nic_name) || (nic_name[0] == 0) + || (strlen (nic_name) >= HAL_MAX_NIC_NAME_LEN)) + { + NSOPR_LOGERR ("nic_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + struct ref_nic *pst_ref_nic = + malloc (sizeof (struct ref_nic)); + if (NULL == pst_ref_nic) + { + NSOPR_LOGERR ("malloc failed"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_ref_nic, sizeof (struct ref_nic), 0, + sizeof (struct ref_nic)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + free (pst_ref_nic); + pst_ref_nic = NULL; + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (pst_ref_nic->nic_name, + sizeof (pst_ref_nic->nic_name), nic_name); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + free (pst_ref_nic); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + add_ref_nic (pst_phy_net, pst_ref_nic); + } + } + } + else + { + NSOPR_LOGERR ("ref_nic is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + json_object_object_get_ex (phy_obj, "bond_mode", &bond_mode_obj); + if (bond_mode_obj) + { + pst_phy_net->bond_mode = json_object_get_int (bond_mode_obj); + if (pst_phy_net->bond_mode != -1) + { + json_object_object_get_ex (phy_obj, "bond_name", + &bond_name_obj); + if (bond_name_obj) + { + const char *bond_name = + json_object_get_string (bond_name_obj); + if ((NULL == bond_name) + || (strlen (bond_name) >= IP_MODULE_MAX_NAME_LEN)) + { + NSOPR_LOGERR ("bond_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_phy_net->bond_name, + sizeof (pst_phy_net->bond_name), 0, + sizeof (pst_phy_net->bond_name)); + + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + + retVal = + STRNCPY_S (pst_phy_net->bond_name, + sizeof (pst_phy_net->bond_name), bond_name, + strlen (bond_name)); + + if (EOK != retVal) + { + NSOPR_LOGERR ("STRNCPY_S failed]retVal=%d", retVal); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("bond_name is not ok"); + free_phy_net (pst_phy_net); + goto RETURN_ERROR; + } + } + } + else + { + pst_phy_net->bond_mode = -1; + } + + pst_network_configuration->phy_net = pst_phy_net; + } + else + { + NSOPR_LOGERR ("phy_net is not ok"); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("args is not ok"); + goto RETURN_ERROR; + } + + json_object_object_get_ex (network_obj, "ipam", &ipam_obj); + if (ipam_obj) + { + json_object_object_get_ex (ipam_obj, "subnet", &subnet_obj); + if (subnet_obj) + { + int iRet; + char tmp[IP_MODULE_LENGTH_32] = { 0 }; + const char *subnet = json_object_get_string (subnet_obj); + struct in_addr addr; + + retVal = MEMSET_S (&addr, sizeof (addr), 0, sizeof (addr)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + if ((NULL == subnet) || (subnet[0] == 0) + || (strlen (subnet) > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + const char *sub = strstr (subnet, "/"); + if ((NULL == sub) + || (sizeof (tmp) - 1 <= (unsigned int) (sub - subnet)) + || (strlen (sub) >= sizeof (tmp) - 1)) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + iRet = + STRNCPY_S (tmp, sizeof (tmp), subnet, (size_t) (sub - subnet)); + if (EOK != iRet) + { + NSOPR_LOGERR ("STRNCPY_S failed]ret=%d", iRet); + goto RETURN_ERROR; + } + + iRet = spl_inet_aton (tmp, &addr); + if (0 == iRet) + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet = + (struct ip_subnet *) malloc (sizeof (struct ip_subnet)); + if (!pst_network_configuration->ip_subnet) + { + NSOPR_LOGERR ("malloc failed"); + goto RETURN_ERROR; + } + + retVal = + MEMSET_S (pst_network_configuration->ip_subnet, + sizeof (struct ip_subnet), 0, + sizeof (struct ip_subnet)); + if (EOK != retVal) + { + NSOPR_LOGERR ("MEMSET_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet->next = NULL; + pst_network_configuration->ip_subnet->subnet = + spl_ntohl (addr.s_addr); + + iRet = atoi (sub + 1); + if ((iRet < 0) || (iRet > IP_MODULE_LENGTH_32)) + { + NSOPR_LOGERR ("mask is not ok"); + goto RETURN_ERROR; + } + + pst_network_configuration->ip_subnet->mask_len = + (unsigned int) iRet; + } + else + { + NSOPR_LOGERR ("subnet is not ok"); + goto RETURN_ERROR; + } + } + else + { + NSOPR_LOGERR ("ipam is not ok"); + goto RETURN_ERROR; + } + + const char *network_json = json_object_get_string (network_obj); + if ((NULL == network_json) || (network_json[0] == 0)) + { + NSOPR_LOGERR ("json_object_get_string failed"); + goto RETURN_ERROR; + } + + pst_network_configuration->buffer = malloc_network_buffer (); + if (!pst_network_configuration->buffer) + { + NSOPR_LOGERR ("malloc_network_buffer failed"); + goto RETURN_ERROR; + } + + retVal = + STRCPY_S (get_network_json (pst_network_configuration), + IP_MODULE_NETWORK_JSON_LEN, network_json); + if (EOK != retVal) + { + NSOPR_LOGERR ("STRCPY_S failed]ret=%d.", retVal); + goto RETURN_ERROR; + } + + return pst_network_configuration; + +RETURN_ERROR: + if (pst_network_configuration) + { + free_network_configuration (pst_network_configuration, IP_MODULE_TRUE); + pst_network_configuration = NULL; + } + + return NULL; +} + +struct network_configuration * +parse_network_json (char *param, struct network_configuration *pnetwork_list) +{ + struct json_object *obj = json_tokener_parse (param); + struct network_configuration *pst_network_configuration = NULL; + + if (!obj) + { + NSOPR_LOGERR ("parse error"); + return NULL; + } + + int network_num = json_object_array_length (obj); + if (0 == network_num) + { + json_object_put (obj); + return NULL; + } + + int i; + for (i = 0; i < network_num; i++) + { + struct json_object *network_obj = json_object_array_get_idx (obj, i); + if (network_obj) + { + pst_network_configuration = parse_network_obj (network_obj); + if (!pst_network_configuration) + { + NSOPR_LOGERR ("parse_network_obj error"); + goto RETURN_ERROR; + } + + pst_network_configuration->next = pnetwork_list; + pnetwork_list = pst_network_configuration; + pst_network_configuration = NULL; + } + else + { + NSOPR_LOGERR ("network_obj is NULL"); + goto RETURN_ERROR; + } + } + + if (pnetwork_list) + { + if (!is_network_configuration_ok (pnetwork_list)) + { + NSOPR_LOGERR ("network_configuration is not ok"); + goto RETURN_ERROR; + } + } + + json_object_put (obj); + return pnetwork_list; + +RETURN_ERROR: + free_network_configuration (pnetwork_list, IP_MODULE_TRUE); + json_object_put (obj); + return NULL; +} + +int +del_network_by_name (char *name) +{ + struct network_configuration *network = NULL; + struct network_configuration **ref = &g_network_list.header; + + while ((network = *ref)) + { + if (strcasecmp (name, network->network_name) == 0) + { + *ref = network->next; + network->next = NULL; + + /*delete netework from rd */ + network_rd_proc (network, 1); + + free_network_configuration (network, IP_MODULE_FALSE); + return 0; + } + + ref = &network->next; + } + + return NSCRTL_RD_NOT_EXIST; +} + +int +is_in_same_network (unsigned int src_ip, unsigned int dst_ip) +{ + if (src_ip == dst_ip) + { + return 1; + } + + struct network_configuration *src = get_network_by_ip_with_tree (src_ip); + struct network_configuration *dst = get_network_by_ip_with_tree (dst_ip); + if (src && (src == dst)) + { + return 1; + } + + return 0; +} + +struct network_configuration * +get_network_list () +{ + return g_network_list.header; +} |