aboutsummaryrefslogtreecommitdiffstats
path: root/src/nSocket/nstack_rd
diff options
context:
space:
mode:
authorQing Chang <qing.chang1@huawei.com>2018-03-13 01:24:25 +0000
committerGerrit Code Review <gerrit@fd.io>2018-03-13 01:24:25 +0000
commiteb88437358ba4021ea4631c1b05a68a05e51d954 (patch)
tree15482c10907c00fa22fc489ea10b850d23c9a4cf /src/nSocket/nstack_rd
parent1b031216ba4cd37943900b8759f50fd0e3a8f1cf (diff)
parentc398e6ec613c1f90ffe33608c511208100e7372f (diff)
Merge "Add the nSocket module for dmm"
Diffstat (limited to 'src/nSocket/nstack_rd')
-rw-r--r--src/nSocket/nstack_rd/nstack_rd.c386
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_init.c202
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_ip.c264
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_ip.h38
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_priv.h112
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_proto.c189
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_proto.h35
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 /* */