diff options
author | Yalei Wang <william.wangyalei@huawei.com> | 2018-03-12 10:07:58 +0800 |
---|---|---|
committer | Yalei Wang <william.wangyalei@huawei.com> | 2018-03-12 10:07:58 +0800 |
commit | c398e6ec613c1f90ffe33608c511208100e7372f (patch) | |
tree | 554b2bc400e14e9ae8e838582e7433ea71eb499f /src/nSocket/nstack_rd | |
parent | 71a4e2f34afa8018426f0e830050e50a1de6d375 (diff) |
Add the nSocket module for dmm
Change-Id: I8b97fbe50c9c1c479072510b8d799fe711360da7
Signed-off-by: Yalei Wang <william.wangyalei@huawei.com>
Diffstat (limited to 'src/nSocket/nstack_rd')
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd.c | 386 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_init.c | 202 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_ip.c | 264 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_ip.h | 38 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_priv.h | 112 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_proto.c | 189 | ||||
-rw-r--r-- | src/nSocket/nstack_rd/nstack_rd_proto.h | 35 |
7 files changed, 1226 insertions, 0 deletions
diff --git a/src/nSocket/nstack_rd/nstack_rd.c b/src/nSocket/nstack_rd/nstack_rd.c new file mode 100644 index 0000000..ee598ad --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd.c @@ -0,0 +1,386 @@ +/* +* +* 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 <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#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; +} diff --git a/src/nSocket/nstack_rd/nstack_rd_init.c b/src/nSocket/nstack_rd/nstack_rd_init.c new file mode 100644 index 0000000..3025e88 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_init.c @@ -0,0 +1,202 @@ +/* +* +* 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 <stdlib.h> +#include "nstack_rd.h" +#include "nstack_rd_data.h" +#include "nstack_rd_init.h" +#include "nstack_rd_priv.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +#define NSTACK_RD_ERR_CHECK_GOTO(ret, desc, lab) \ +if (NSTACK_RD_SUCCESS != (ret))\ +{ \ + NSSOC_LOGERR("%s fail, return:%d", desc, ret); \ + goto lab; \ +} + +#define NSTACK_RD_POINT_CHECK_GOTO(ptr, desc, lab) \ +if (!ptr)\ +{ \ + NSSOC_LOGERR("%s fail", desc); \ + goto lab; \ +} + +/* *INDENT-OFF* */ +rd_stack_plane_map g_nstack_plane_info[] = { + {{RD_LINUX_NAME}, {RD_LINUX_PLANENAME}, -1}, + {{RD_STACKX_NAME}, {RD_STACKX_PLANENAME}, -1}, +}; +/* *INDENT-ON* */ + +int g_rd_map_num = sizeof (g_nstack_plane_info) / sizeof (rd_stack_plane_map); + +rd_local_data *g_rd_local_data = NULL; + +/***************************************************************************** +* Prototype : nstack_rd_init +* Description : nstack rd init +* Input : nstack_stack_info *pstack +* int num +* nstack_get_route_data pfun +* Output : None +* Return Value : int +* Calls : +* Called By : +* pstack : 1. priority 0: when router not fund, the first will be chose +* 2. if have many same 0 priority, fist input will be chose, +* 3. if none 0 priority, the last input will be choose +*****************************************************************************/ +int +nstack_rd_init (nstack_stack_info * pstack, int num, + nstack_get_route_data * pfun, int fun_num) +{ + int icnt = 0; + int itemp = 0; + int hindex = 0; + int tindex = num - 1; + int iindex = 0; + int ret = NSTACK_RD_SUCCESS; + nstack_rd_stack_info *ptemstack = NULL; + + if ((!pstack) || (!pfun)) + { + NSSOC_LOGERR ("input err pstack:%p, pfun:%p", pstack, pfun); + return NSTACK_RD_FAIL; + } + g_rd_local_data = (rd_local_data *) malloc (sizeof (rd_local_data)); + if (!g_rd_local_data) + { + NSSOC_LOGERR ("g_rd_local_data alloc fail"); + return NSTACK_RD_FAIL; + } + + if (EOK != + MEMSET_S ((void *) g_rd_local_data, sizeof (rd_local_data), 0, + sizeof (rd_local_data))) + { + NSSOC_LOGERR ("MEMSET_S fail"); + goto ERR; + } + for (icnt = 0; icnt < fun_num; icnt++) + { + g_rd_local_data->sys_fun[icnt] = pfun[icnt]; + } + g_rd_local_data->fun_num = fun_num; + ptemstack = + (nstack_rd_stack_info *) malloc (sizeof (nstack_rd_stack_info) * num); + NSTACK_RD_POINT_CHECK_GOTO (ptemstack, "rd stack info malloc fail", ERR); + + /*save stack info in priority order */ + for (icnt = 0; icnt < num; icnt++) + { + if (0 == pstack[icnt].priority) + { + iindex = hindex; + hindex++; + } + else + { + iindex = tindex; + tindex--; + } + + /* modify destMax from RD_PLANE_NAMELEN to STACK_NAME_MAX */ + ret = + STRCPY_S (ptemstack[iindex].stack.stackname, STACK_NAME_MAX, + pstack[icnt].name); + if (ret != EOK) + { + NSSOC_LOGERR ("STRCPY_S failed"); + goto ERR; + } + + for (itemp = 0; itemp < g_rd_map_num; itemp++) + { + if (0 == + strcmp (pstack[icnt].name, + g_nstack_plane_info[itemp].stackname)) + { + ret = + STRCPY_S (ptemstack[iindex].stack.planename, RD_PLANE_NAMELEN, + g_nstack_plane_info[itemp].planename); + g_nstack_plane_info[itemp].stackid = pstack[icnt].stack_id; + NSTACK_RD_ERR_CHECK_GOTO (ret, "plane name copy fail", ERR); + break; + } + } + + if (itemp >= g_rd_map_num) + { + NSSOC_LOGERR ("rd route info not found"); + goto ERR; + } + ptemstack[iindex].priority = pstack[icnt].priority; + ptemstack[iindex].stack_id = pstack[icnt].stack_id; + NSSOC_LOGDBG + ("nstack rd init]stackname=%s,planename=%s,priority=%d,stackid=%d was added", + ptemstack[iindex].stack.stackname, ptemstack[iindex].stack.planename, + ptemstack[iindex].priority, ptemstack[iindex].stack_id); + } + + g_rd_local_data->pstack_info = ptemstack; + g_rd_local_data->stack_num = num; + + for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) + { + INIT_HLIST_HEAD (&(g_rd_local_data->route_list[icnt].headlist)); + } + return NSTACK_RD_SUCCESS; + +ERR: + if (g_rd_local_data) + { + free (g_rd_local_data); + g_rd_local_data = NULL; + } + if (ptemstack) + { + free (ptemstack); + } + return NSTACK_RD_FAIL; +} + +/***************************************************************************** +* Prototype : nstack_get_stackid_byname +* Description : get stack ip by stack name +* Input : char *name +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nstack_get_stackid_byname (char *name) +{ + int stacknum = g_rd_local_data->stack_num; + int iindex = 0; + nstack_rd_stack_info *pstack = NULL; + for (iindex = 0; iindex < stacknum; iindex++) + { + pstack = &(g_rd_local_data->pstack_info[iindex]); + if (0 == strcmp (pstack->stack.stackname, name)) + { + return pstack->stack_id; + } + } + return -1; +} diff --git a/src/nSocket/nstack_rd/nstack_rd_ip.c b/src/nSocket/nstack_rd/nstack_rd_ip.c new file mode 100644 index 0000000..bcbe731 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_ip.c @@ -0,0 +1,264 @@ +/* +* +* 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 <stdlib.h> +#include <arpa/inet.h> +#include "nstack_rd_data.h" +#include "nstack_rd.h" +#include "nstack_rd_init.h" +#include "nstack_rd_priv.h" +#include "nstack_rd_ip.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +#include "nstack_ip_addr.h" + +#define NSTACK_IP_MLSTACKID RD_STACKX_NAME + +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) + +#define rd_ismulticast(addr)(((unsigned int)(addr) & 0xf0000000UL) == 0xe0000000UL) + +int g_multi_stackid = -1; + +/*copy rd data*/ +int +nstack_rd_ipdata_cpy (void *destdata, void *srcdata) +{ + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + + pitem->type = pdata->type; + pitem->ipdata.addr = pdata->ipdata.addr; + pitem->ipdata.masklen = pdata->ipdata.masklen; + pitem->ipdata.resev[0] = pdata->ipdata.resev[0]; + pitem->ipdata.resev[1] = pdata->ipdata.resev[1]; + return NSTACK_RD_SUCCESS; +} + +/* + * Add an ip segment to the list and sort it in descending order of ip mask length + * If the list already exists in the same list of ip side, then stack_id update + *ip is local byteorder + */ +int +nstack_rd_ip_item_insert (nstack_rd_list * hlist, void *rditem) +{ + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + struct hlist_node *tem = NULL; + unsigned int ip_addr = 0; + unsigned int ip_masklen = 0; + unsigned int ip_maskv = MASK_V (ip_addr, ip_masklen); + unsigned int tempip_addr = 0; + unsigned int tempip_masklen = 0; + rd_data_item *pitem = (rd_data_item *) rditem; + + ip_masklen = pitem->ipdata.masklen; + NSSOC_LOGDBG ("stackid:%d, ipaddr:%u.%u.%u.%u masklen:0x%x was inserted", + pitem->stack_id, ip4_addr4_16 (&pitem->ipdata.addr), + ip4_addr3_16 (&pitem->ipdata.addr), + ip4_addr2_16 (&pitem->ipdata.addr), + ip4_addr1_16 (&pitem->ipdata.addr), pitem->ipdata.masklen); + + pdatanode = (nstack_rd_node *) malloc (sizeof (nstack_rd_node)); + if (!pdatanode) + { + NSSOC_LOGERR ("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; + } + int retVal = + MEMSET_S (pdatanode, sizeof (nstack_rd_node), 0, sizeof (nstack_rd_node)); + if (EOK != retVal) + { + NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); + free (pdatanode); + return NSTACK_RD_FAIL; + } + INIT_HLIST_NODE (&pdatanode->rdnode); + NSTACK_RD_IP_ITEM_COPY (&(pdatanode->item), pitem); + + if (hlist_empty (&(hlist->headlist))) + { + hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); + return NSTACK_RD_SUCCESS; + } + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + tem = tempnode; + tempip_addr = tempdata->item.ipdata.addr; + tempip_masklen = tempdata->item.ipdata.masklen; + if (ip_masklen < tempip_masklen) + { + continue; + } + + /*if already exist, just return success */ + if (ip_maskv == MASK_V (tempip_addr, tempip_masklen)) + { + NSSOC_LOGDBG + ("insert ip:%u.%u.%u.%u, mask:0x%x, stack_id:%d, exist orgid:%d", + ip4_addr4_16 (&pitem->ipdata.addr), + ip4_addr3_16 (&pitem->ipdata.addr), + ip4_addr2_16 (&pitem->ipdata.addr), + ip4_addr1_16 (&pitem->ipdata.addr), pitem->ipdata.masklen, + pitem->stack_id, tempdata->item.stack_id); + + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free (pdatanode); + return NSTACK_RD_SUCCESS; + } + hlist_add_before (&(pdatanode->rdnode), tempnode); + return NSTACK_RD_SUCCESS; + } + hlist_add_after (tem, &(pdatanode->rdnode)); + return NSTACK_RD_SUCCESS; +} + +/* + *find stackid by ip + *input ip must netorder + */ +int +nstack_rd_ip_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + unsigned int tempip_addr = 0; + unsigned int tempip_masklen = 0; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + rd_data_item *pitem = (rd_data_item *) outitem; + unsigned int ip_addr = 0; + /*need to convert to local order */ + ip_addr = ntohl (key->ip_addr); + + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + tempip_addr = tempdata->item.ipdata.addr; + tempip_masklen = tempdata->item.ipdata.masklen; + /*if already exist, just return success */ + if (MASK_V (ip_addr, tempip_masklen) == + MASK_V (tempip_addr, tempip_masklen)) + { + NSTACK_RD_IP_ITEM_COPY (pitem, &(tempdata->item)); + return NSTACK_RD_SUCCESS; + } + } + + NSSOC_LOGDBG ("ip=%u.%u.%u.%u item not found", ip4_addr4_16 (&ip_addr), + ip4_addr3_16 (&ip_addr), + ip4_addr2_16 (&ip_addr), ip4_addr1_16 (&ip_addr)); + + return NSTACK_RD_FAIL; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_item_age +* Description : delete the ip item that have not been add again for one time +* Input : nstack_rd_list *hlist +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nstack_rd_ip_item_age (nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF ("nstack rd ip age begin"); + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + NSSOC_LOGDBG + ("stackid:%d, addrip:%u.%u.%u.%u, masklen:0x%x was aged", + tempdata->item.stack_id, + ip4_addr4_16 (&tempdata->item.ipdata.addr), + ip4_addr3_16 (&tempdata->item.ipdata.addr), + ip4_addr2_16 (&tempdata->item.ipdata.addr), + ip4_addr1_16 (&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); + + hlist_del_init (prevnode); + free (prevdata); + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + NSSOC_LOGDBG + ("stackid:%d, addrip:%u.%u.%u.%u, masklen:0x%x was last aged", + tempdata->item.stack_id, + ip4_addr4_16 (&tempdata->item.ipdata.addr), + ip4_addr3_16 (&tempdata->item.ipdata.addr), + ip4_addr2_16 (&tempdata->item.ipdata.addr), + ip4_addr1_16 (&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); + } + hlist_del_init (prevnode); + free (prevdata); + } + NSSOC_LOGINF ("nstack rd ip age end"); + return NSTACK_RD_SUCCESS; +} + +/* + *find stackid by spec ip(multicast ip) + *input ip must netorder + */ +int +nstack_rd_ip_spec (void *rdkey) +{ + nstack_rd_key *key = (nstack_rd_key *) rdkey; + unsigned int ip_addr = 0; + + ip_addr = ntohl (key->ip_addr); + + if (rd_ismulticast (ip_addr)) + { + if (-1 == g_multi_stackid) + { + g_multi_stackid = nstack_get_stackid_byname (NSTACK_IP_MLSTACKID); + } + return g_multi_stackid; + } + return -1; +} + +int +nstack_rd_ip_default (void *rdkey) +{ + return NSTACK_GET_STACK (0); +} diff --git a/src/nSocket/nstack_rd/nstack_rd_ip.h b/src/nSocket/nstack_rd/nstack_rd_ip.h new file mode 100644 index 0000000..d64956d --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_ip.h @@ -0,0 +1,38 @@ +/* +* +* 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. +*/ + +#ifndef __NSTACK_RD_IP_H +#define __NSTACK_RD_IP_H + +#define NSTACK_RD_IP_ITEM_COPY(destitem, srcitem){ \ + (destitem)->agetime = (srcitem)->agetime; \ + (destitem)->stack_id = (srcitem)->stack_id; \ + (destitem)->type = (srcitem)->type; \ + (destitem)->ipdata.addr = (srcitem)->ipdata.addr; \ + (destitem)->ipdata.masklen = (srcitem)->ipdata.masklen; \ + (destitem)->ipdata.resev[0] = (srcitem)->ipdata.resev[0]; \ + (destitem)->ipdata.resev[1] = (srcitem)->ipdata.resev[1]; \ +} + +int nstack_rd_ipdata_cpy (void *destdata, void *srcdata); +int nstack_rd_ip_item_insert (nstack_rd_list * hlist, void *rditem); +int nstack_rd_ip_item_find (nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_ip_item_age (nstack_rd_list * hlist); +int nstack_rd_ip_spec (void *rdkey); +int nstack_rd_ip_default (void *rdkey); + +#endif diff --git a/src/nSocket/nstack_rd/nstack_rd_priv.h b/src/nSocket/nstack_rd/nstack_rd_priv.h new file mode 100644 index 0000000..217f1d3 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_priv.h @@ -0,0 +1,112 @@ +/* +* +* 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. +*/ + +#ifndef __NSTACK_RD_PRIV_H +#define __NSTACK_RD_PRIV_H +#include "list.h" + +#define NSTACK_RD_SUCCESS (0) +#define NSTACK_RD_FAIL (-1) +#define NSTACK_RD_ITEM_MAX (1024) + +#define NSTACK_RD_AGETIME_MAX (1) +#define NSTACK_SYS_FUN_MAX (16) + +#define RD_STACKX_NAME "stackx" +#define RD_LINUX_NAME "kernel" + +#define RD_STACKX_PLANENAME "nstack-dpdk" +#define RD_LINUX_PLANENAME "nstack-kernel" +#define RD_LINUX_PLANENULL "null" + +#define NSTACK_RD_INDEX_BYIP(ip) (((ip) & 0xff) \ + + (((ip) >> 8)&0xff) \ + + (((ip) >> 16)&0xff) \ + + (((ip) >> 24)&0xff)) + +typedef struct __rd_stack_plane_map +{ + char stackname[STACK_NAME_MAX]; + char planename[RD_PLANE_NAMELEN]; + int stackid; +} rd_stack_plane_map; + +/*route data*/ +typedef struct __rd_data_item +{ + /*route info type , for example base on ip */ + rd_data_type type; + int stack_id; + int agetime; + union + { + rd_ip_data ipdata; + unsigned int proto_type; + }; +} rd_data_item; + +/*stack rd node*/ +typedef struct __nstack_rd_node +{ + struct hlist_node rdnode; + rd_data_item item; +} nstack_rd_node; + +typedef struct __nstack_rd_list +{ + struct hlist_head headlist; +} nstack_rd_list; + +typedef struct __nstack_rd_stack_info +{ + /*stack name */ + rd_stack_plane_map stack; + /*stack id */ + int stack_id; + /*when route info not found, high priority stack was chose, same priority chose fist input one */ + int priority; /*0: highest: route info not found choose first */ +} nstack_rd_stack_info; + +/*rd local data*/ +typedef struct __rd_local_data +{ + nstack_rd_stack_info *pstack_info; + int stack_num; + nstack_rd_list route_list[RD_DATA_TYPE_MAX]; /*route table */ + nstack_get_route_data sys_fun[NSTACK_SYS_FUN_MAX]; /*rd data sys proc function list */ + int fun_num; +} rd_local_data; + +typedef struct __rd_data_proc +{ + int (*rd_item_cpy) (void *destdata, void *srcdata); + int (*rd_item_inset) (nstack_rd_list * hlist, void *rditem); + int (*rd_item_age) (nstack_rd_list * hlist); + int (*rd_item_find) (nstack_rd_list * hlist, void *rdkey, void *outitem); + int (*rd_item_spec) (void *rdkey); + int (*rd_item_defualt) (void *rdkey); +} rd_data_proc; + +extern rd_local_data *g_rd_local_data; +extern rd_data_proc g_rd_cpy[RD_DATA_TYPE_MAX]; + +#define NSTACK_NUM (g_rd_local_data->stack_num) +#define NSTACK_RD_LIST(type) (&(g_rd_local_data->route_list[(type)])) +#define NSTACK_GET_STACK(idx) ((g_rd_local_data->pstack_info)[idx].stack_id) + +int nstack_get_stackid_byname (char *name); + +#endif diff --git a/src/nSocket/nstack_rd/nstack_rd_proto.c b/src/nSocket/nstack_rd/nstack_rd_proto.c new file mode 100644 index 0000000..16f4e1f --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_proto.c @@ -0,0 +1,189 @@ +/* +* +* 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 <stdlib.h> +#include <arpa/inet.h> +#include "nstack_rd_data.h" +#include "nstack_rd.h" +#include "nstack_rd_init.h" +#include "nstack_rd_priv.h" +#include "nstack_rd_proto.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +/*copy rd data*/ +int +nstack_rd_proto_cpy (void *destdata, void *srcdata) +{ + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + pitem->type = pdata->type; + pitem->proto_type = pdata->proto_type; + return NSTACK_RD_SUCCESS; +} + +/* + * Add an ip segment to the list and sort it in descending order of ip mask length + * If the list already exists in the same list of ip side, then stack_id update + *ip is local byteorder + */ +int +nstack_rd_proto_item_insert (nstack_rd_list * hlist, void *rditem) +{ + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + rd_data_item *pitem = (rd_data_item *) rditem; + + NSSOC_LOGDBG ("stackid:%d, protocol type:%d was inserted", pitem->stack_id, + pitem->proto_type); + + pdatanode = (nstack_rd_node *) malloc (sizeof (nstack_rd_node)); + if (!pdatanode) + { + NSSOC_LOGERR ("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; + } + int retVal = + MEMSET_S (pdatanode, sizeof (nstack_rd_node), 0, sizeof (nstack_rd_node)); + if (EOK != retVal) + { + NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); + free (pdatanode); + return NSTACK_RD_FAIL; + } + INIT_HLIST_NODE (&pdatanode->rdnode); + NSTACK_RD_PROTO_ITEM_COPY (&(pdatanode->item), pitem); + if (hlist_empty (&(hlist->headlist))) + { + hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + + } + + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (tempdata->item.proto_type == pitem->proto_type) + + { + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free (pdatanode); + return NSTACK_RD_SUCCESS; + } + } + hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + +} + +/* + *find stackid by ip + *input ip must netorder + */ +int +nstack_rd_proto_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + rd_data_item *pitem = (rd_data_item *) outitem; + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + + /*if already exist, just return success */ + if (tempdata->item.proto_type == key->proto_type) + + { + NSTACK_RD_PROTO_ITEM_COPY (pitem, &(tempdata->item)); + return NSTACK_RD_SUCCESS; + } + } + + NSSOC_LOGDBG ("protocol type item not found", key->proto_type); + + return NSTACK_RD_FAIL; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_item_age +* Description : delete the ip item that have not been add again for one time +* Input : nstack_rd_list *hlist +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nstack_rd_proto_item_age (nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF ("nstack rd ip age begin"); + hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + NSSOC_LOGDBG ("stackid:%d, protocol type was aged", + tempdata->item.stack_id, tempdata->item.proto_type); + + hlist_del_init (prevnode); + free (prevdata); + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + NSSOC_LOGDBG ("stackid:%d, protocol type was aged", + tempdata->item.stack_id, tempdata->item.proto_type); + } + hlist_del_init (prevnode); + free (prevdata); + } + NSSOC_LOGINF ("nstack rd ip age end"); + return NSTACK_RD_SUCCESS; +} + +/* + *find stackid by spec ip(multicast ip) + *input ip must netorder + */ +int +nstack_rd_proto_spec (void *rdkey) +{ + return -1; +} + +int +nstack_rd_proto_default (void *rdkey) +{ + return -1; +} diff --git a/src/nSocket/nstack_rd/nstack_rd_proto.h b/src/nSocket/nstack_rd/nstack_rd_proto.h new file mode 100644 index 0000000..f3b0311 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_proto.h @@ -0,0 +1,35 @@ +/* +* +* 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. +*/ + +#ifndef __NSTACK_RD_PROTO_H +#define __NSTACK_RD_PROTO_H +/* *INDENT-OFF* */ +#define NSTACK_RD_PROTO_ITEM_COPY(destitem, srcitem){ \ + (destitem)->agetime = (srcitem)->agetime; \ + (destitem)->stack_id = (srcitem)->stack_id; \ + (destitem)->type = (srcitem)->type; \ + (destitem)->proto_type = (srcitem)->proto_type; \ +} +/* *INDENT-ON* */ +int nstack_rd_proto_cpy (void *destdata, void *srcdata); +int nstack_rd_proto_item_insert (nstack_rd_list * hlist, void *rditem); +int nstack_rd_proto_item_find (nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_proto_item_age (nstack_rd_list * hlist); +int nstack_rd_proto_spec (void *rdkey); +int nstack_rd_proto_default (void *rdkey); + +#endif /* */ |