aboutsummaryrefslogtreecommitdiffstats
path: root/src/nSocket/nstack_rd/nstack_rd_ip.c
diff options
context:
space:
mode:
authorYalei Wang <william.wangyalei@huawei.com>2018-03-12 10:07:58 +0800
committerYalei Wang <william.wangyalei@huawei.com>2018-03-12 10:07:58 +0800
commitc398e6ec613c1f90ffe33608c511208100e7372f (patch)
tree554b2bc400e14e9ae8e838582e7433ea71eb499f /src/nSocket/nstack_rd/nstack_rd_ip.c
parent71a4e2f34afa8018426f0e830050e50a1de6d375 (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/nstack_rd_ip.c')
-rw-r--r--src/nSocket/nstack_rd/nstack_rd_ip.c264
1 files changed, 264 insertions, 0 deletions
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);
+}