/* * * 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 #include #include #include #include "nstack_rd.h" #include "nstack_rd_init.h" #include "nstack_rd_priv.h" #include "nstack_rd_ip.h" #include "nstack_rd_proto.h" #include "nstack_log.h" #include "nstack_info_parse.h" #include "nstack_securec.h" typedef struct __rd_data_defaut_ip { char ip[RD_IP_STR_MAX_LEN]; char planename[RD_PLANE_NAMELEN]; int masklent; } rd_data_defaut_ip; typedef struct __rd_data_defaut_protocol { unsigned int proto_type; char planename[RD_PLANE_NAMELEN]; } rd_data_defaut_protocol; extern rd_stack_plane_map g_nstack_plane_info[]; extern int g_rd_map_num; rd_data_proc g_rd_cpy[RD_DATA_TYPE_MAX] = { { nstack_rd_ipdata_cpy, nstack_rd_ip_item_insert, nstack_rd_ip_item_age, nstack_rd_ip_item_find, nstack_rd_ip_spec, nstack_rd_ip_default, }, { nstack_rd_proto_cpy, nstack_rd_proto_item_insert, nstack_rd_proto_item_age, nstack_rd_proto_item_find, nstack_rd_proto_spec, nstack_rd_proto_default, }, }; rd_data_defaut_ip g_defualt_ip_config[] = { {{"127.0.0.1"}, {RD_LINUX_PLANENAME}, 32}, {{"0.0.0.0"}, {RD_LINUX_PLANENAME}, 32}, }; rd_data_defaut_protocol g_defualt_protcol[] = { {0xf001, {RD_STACKX_PLANENAME}}, }; /***************************************************************************** * Prototype : nstack_rd_get_stackid * Description : choose the stack by key, type is the most important * Input : nstack_rd_key* pkey * int *stackid * Output : None * Return Value : int * Calls : * Called By : *****************************************************************************/ int nstack_rd_get_stackid (nstack_rd_key * pkey, int *stackid) { int type = 0; int ret = NSTACK_RD_SUCCESS; rd_data_item item; if ((!pkey) || (!stackid) || (pkey->type >= RD_DATA_TYPE_MAX)) { NSSOC_LOGERR ("input get stackid fail]addr=%p,stackid=%p,addr->type=%d", pkey, stackid, !pkey ? RD_DATA_TYPE_MAX : pkey->type); return NSTACK_RD_FAIL; } int retVal = MEMSET_S (&item, sizeof (item), 0, sizeof (item)); if (EOK != retVal) { NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); return NSTACK_RD_FAIL; } type = pkey->type; /*specfic key find, for ip example: stack-x was chose if the key is multicast ip */ if (g_rd_cpy[type].rd_item_spec) { ret = g_rd_cpy[type].rd_item_spec ((void *) pkey); if (ret >= 0) { *stackid = ret; return NSTACK_RD_SUCCESS; } } /*search the list */ ret = g_rd_cpy[type].rd_item_find (NSTACK_RD_LIST (type), (void *) pkey, &item); if (NSTACK_RD_SUCCESS == ret) { NSSOC_LOGDBG ("item type=%d stackid=%d was found", pkey->type, item.stack_id); *stackid = item.stack_id; return NSTACK_RD_SUCCESS; } if (g_rd_cpy[type].rd_item_defualt) { *stackid = g_rd_cpy[type].rd_item_defualt ((void *) pkey); } else { *stackid = -1; } NSSOC_LOGINF ("item type=%d was not found, return default=%d", pkey->type, *stackid); return NSTACK_RD_SUCCESS; } /***************************************************************************** * Prototype : nstack_rd_sys_default * Description : sys defualt rd info, * Input : None * Output : None * Return Value : int * Calls : * Called By : ******************************************************************************/ void nstack_rd_sys_default () { rd_data_item item; rd_data_defaut_ip *pdata = NULL; rd_data_defaut_protocol *pprotodata = NULL; int icnt = 0, iindex = 0; /*get the ip defualt route */ for (icnt = 0; icnt < sizeof (g_defualt_ip_config) / sizeof (rd_data_defaut_ip); icnt++) { pdata = &g_defualt_ip_config[icnt]; for (iindex = 0; iindex < g_rd_map_num; iindex++) { if (0 == strcmp (g_nstack_plane_info[iindex].planename, pdata->planename)) { item.stack_id = g_nstack_plane_info[iindex].stackid; break; } } if (iindex >= g_rd_map_num) { NSSOC_LOGINF ("default plane name:%s was not fount, ip:%s msklen:%d was dropped", pdata->planename, pdata->ip, pdata->masklent); continue; } item.type = RD_DATA_TYPE_IP; item.ipdata.addr = ntohl (inet_addr (pdata->ip)); item.ipdata.masklen = pdata->masklent; item.ipdata.resev[0] = 0; item.ipdata.resev[1] = 0; item.agetime = NSTACK_RD_AGETIME_MAX; /*insert to the list */ g_rd_cpy[RD_DATA_TYPE_IP].rd_item_inset (NSTACK_RD_LIST (RD_DATA_TYPE_IP), &item); } /*get the protocol defualt route */ (void) MEMSET_S (&item, sizeof (item), 0, sizeof (item)); for (icnt = 0; icnt < sizeof (g_defualt_protcol) / sizeof (rd_data_defaut_ip); icnt++) { pprotodata = &g_defualt_protcol[icnt]; for (iindex = 0; iindex < g_rd_map_num; iindex++) { if (0 == strcmp (g_nstack_plane_info[iindex].planename, pprotodata->planename)) { item.stack_id = g_nstack_plane_info[iindex].stackid; break; } } if (iindex >= g_rd_map_num) { NSSOC_LOGINF ("default plane name:%s was not fount, protocoltype:%d was dropped", pprotodata->planename, pprotodata->proto_type); continue; } item.type = RD_DATA_TYPE_PROTO; item.proto_type = pprotodata->proto_type; /*insert to the list */ g_rd_cpy[RD_DATA_TYPE_PROTO].rd_item_inset (NSTACK_RD_LIST (RD_DATA_TYPE_PROTO), &item); } return; } /***************************************************************************** * Prototype : nstack_rd_save * Description : save the rd data * Input : None * Output : None * Return Value : int * Calls : * Called By : *****************************************************************************/ void nstack_rd_save (rd_route_data * rd_data, int num) { int icnt = 0; int iindex = 0; rd_data_item item; rd_data_type type = RD_DATA_TYPE_MAX; int retVal = MEMSET_S (&item, sizeof (item), 0, sizeof (item)); if (EOK != retVal) { NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); return; } for (iindex = 0; iindex < num; iindex++) { if (rd_data[iindex].type >= RD_DATA_TYPE_MAX) { NSSOC_LOGERR ("rd data type=%d unkown", rd_data[iindex].type); continue; } type = rd_data[iindex].type; if (NSTACK_RD_SUCCESS == g_rd_cpy[type].rd_item_cpy ((void *) &item, (void *) &rd_data[iindex])) { item.agetime = NSTACK_RD_AGETIME_MAX; for (icnt = 0; icnt < g_rd_map_num; icnt++) { if (0 == strcmp (g_nstack_plane_info[icnt].planename, rd_data[iindex].stack_name)) { item.stack_id = g_nstack_plane_info[icnt].stackid; break; } } if (icnt >= g_rd_map_num) { NSSOC_LOGINF ("plane name:%s was not fount, protocoltype:%d was dropped", rd_data[iindex].stack_name); continue; } /*insert to the list */ g_rd_cpy[type].rd_item_inset (NSTACK_RD_LIST (type), &item); continue; } NSSOC_LOGERR ("rd data type=%d cpy fail", rd_data[iindex].type); } return; } /***************************************************************************** * Prototype : nstack_rd_data_get * Description : rd data get, * Input : None * Output : None * Return Value : int * Calls : * Called By : *****************************************************************************/ int nstack_rd_data_get (nstack_get_route_data pfun) { rd_route_data *rd_data = NULL; int iret = NSTACK_RD_FAIL; int inum = 0; /*get rd config */ if (pfun && (NSTACK_RD_SUCCESS == pfun (&rd_data, &inum))) { if (inum > 0) { nstack_rd_save (rd_data, inum); iret = NSTACK_RD_SUCCESS; } else { NSSOC_LOGDBG ("no rd data got"); } if (rd_data) { free (rd_data); rd_data = NULL; } } else { NSSOC_LOGERR ("nstack rd sys rd info fail"); } return iret; } /***************************************************************************** * Prototype : nstack_rd_sys * Description : sys rd data from rd table, * Input : None * Output : None * Return Value : int * Calls : * Called By : *****************************************************************************/ int nstack_rd_sys () { int iret = NSTACK_RD_FAIL; int icnt = 0; if (!g_rd_local_data) { NSSOC_LOGERR ("rd have not been inited"); return NSTACK_RD_FAIL; } /*insert defualt rd info */ nstack_rd_sys_default (); /*get from config file */ for (icnt = 0; icnt < g_rd_local_data->fun_num; icnt++) { if (NSTACK_RD_SUCCESS == nstack_rd_data_get (g_rd_local_data->sys_fun[icnt])) { iret = NSTACK_RD_SUCCESS; } } /*age after sys */ nstack_rd_age (); return iret; } /***************************************************************************** * Prototype : nstack_rd_age * Description : delete all rd item from the list that not been add again for at least one time * Input : None * Output : None * Return Value : int * Calls : * Called By : *****************************************************************************/ int nstack_rd_age () { int icnt = 0; for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) { (void) g_rd_cpy[icnt].rd_item_age (NSTACK_RD_LIST (icnt)); } return NSTACK_RD_SUCCESS; }