aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/processor/fib.c
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2019-03-23 14:13:53 +0100
committerAngelo Mantellini <manangel@cisco.com>2019-03-24 14:11:17 +0100
commiteb323e056e747d71867cf965434811c1de925de2 (patch)
tree23a6096823d795efe448559cf0409a18ab47932d /hicn-light/src/processor/fib.c
parent43562f9f02d35e5d540ab4028a0326c0c7cd4898 (diff)
[HICN-141] Definition of a C API for hicn-light
Change-Id: Id861f0abe58b1e3c9ba8cc76701da0f9c6801748 Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com> Signed-off-by: Angelo Mantellini <manangel@cisco.com>
Diffstat (limited to 'hicn-light/src/processor/fib.c')
-rw-r--r--hicn-light/src/processor/fib.c448
1 files changed, 0 insertions, 448 deletions
diff --git a/hicn-light/src/processor/fib.c b/hicn-light/src/processor/fib.c
deleted file mode 100644
index c7b1e2de2..000000000
--- a/hicn-light/src/processor/fib.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * 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 <src/config.h>
-#include <stdio.h>
-
-#include <src/processor/fib.h>
-
-#include <parc/algol/parc_Memory.h>
-#include <parc/algol/parc_Network.h>
-
-#include <parc/assert/parc_Assert.h>
-
-#define NULL_POS 128
-#define MSB_POS 127
-
-struct node;
-typedef struct node FibNode;
-
-struct node {
- FibNode *left;
- FibNode *right;
- FibEntry *entry;
- unsigned pos;
-};
-
-struct fib {
- FibNode *root;
- unsigned size;
-};
-
-// =====================================================
-// Public API
-
-FibNode *_createNode(FibNode *left, FibNode *right, FibEntry *entry,
- unsigned pos) {
- FibNode *n = parcMemory_AllocateAndClear(sizeof(FibNode));
- parcAssertNotNull(n, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(FibNode));
-
- n->left = left;
- n->right = right;
- n->entry = entry;
- n->pos = pos;
-
- return n;
-}
-
-FIB *fib_Create() {
- FIB *hicnFib = parcMemory_AllocateAndClear(sizeof(FIB));
- parcAssertNotNull(hicnFib, "parcMemory_AllocateAndClear(%zu) returned NULL",
- sizeof(FIB));
-
- hicnFib->root =
- _createNode(NULL, NULL, NULL,
- NULL_POS); // the pos will decrease going down in the trie
- hicnFib->root->left = hicnFib->root;
- hicnFib->root->right = hicnFib->root;
-
- hicnFib->size = 0;
-
- return hicnFib;
-}
-
-void _destroyNode(FibNode *n) {
- fibEntry_Release(&n->entry);
- parcMemory_Deallocate((void **)&n);
- n = NULL;
-}
-
-void _destroyFib(FIB *fib) {
- // XXX
- // to be done
- return;
-}
-
-void fib_Destroy(FIB **fibPtr) {
- parcAssertNotNull(fibPtr, "Parameter must be non-null double pointer");
- parcAssertNotNull(*fibPtr, "Parameter must dereference to non-null pointer");
-
- FIB *fib = *fibPtr;
-
- _destroyFib(fib);
- parcMemory_Deallocate((void **)&fib);
- *fibPtr = NULL;
-}
-
-void fib_Add(FIB *fib, FibEntry *entry) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(entry, "Parameter must be non-null");
-
- NameBitvector *name = name_GetContentName(fibEntry_GetPrefix(entry));
-
- // search the name
- FibNode *prev = fib->root;
- FibNode *curr;
-
- if (nameBitvector_testBit(name, MSB_POS)) {
- curr = fib->root->right;
- } else {
- curr = fib->root->left;
- }
-
- while (prev->pos > curr->pos) {
- prev = curr;
- if (nameBitvector_testBit(name, curr->pos)) {
- curr = curr->right;
- } else {
- curr = curr->left;
- }
- }
-
- if (curr->entry != NULL &&
- nameBitvector_Equals(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)))) {
- // there is already an entry with this name
- // do nothing. Before call ADD we should check
- // if the node exists, and, in that case update it
- return;
- }
-
- // if the name is not in the FIB search for the first different bit between
- // the new name to add and the node found in the trie
- uint8_t pos = MSB_POS;
- if (curr->entry != NULL)
- pos = nameBitvector_firstDiff(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)));
-
- // reset pointer and search the insertion point
- prev = fib->root;
- if (nameBitvector_testBit(name, MSB_POS))
- curr = fib->root->right;
- else
- curr = fib->root->left;
-
- while (prev->pos > curr->pos && curr->pos > pos) {
- prev = curr;
- if (nameBitvector_testBit(name, curr->pos)) {
- curr = curr->right;
- } else {
- curr = curr->left;
- }
- }
-
- // insert the node
- fib->size++;
- FibNode *n = _createNode(NULL, NULL, entry, pos);
-
- if (nameBitvector_testBit(name, pos)) {
- n->left = curr;
- n->right = n;
- } else {
- n->left = n;
- n->right = curr;
- }
-
- uint8_t new_pos = prev->pos;
- if (new_pos == NULL_POS) new_pos = MSB_POS;
-
- if (nameBitvector_testBit(name, new_pos)) {
- prev->right = n;
- } else {
- prev->left = n;
- }
-}
-
-FibEntry *fib_Contains(const FIB *fib, const Name *prefix) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(prefix, "Parameter must be non-null");
-
- NameBitvector *name = name_GetContentName(prefix);
-
- // this is the same as the first part of the add function
- // we cannnot call this function inside the add because
- // we need the pointer prev and curr for the insertion
-
- FibNode *prev = fib->root;
- FibNode *curr;
-
- if (nameBitvector_testBit(name, MSB_POS))
- curr = fib->root->right;
- else
- curr = fib->root->left;
-
- while (prev->pos > curr->pos) {
- prev = curr;
-
- if (nameBitvector_testBit(name, curr->pos)) {
- curr = curr->right;
- } else {
- curr = curr->left;
- }
- }
-
- if (curr->entry != NULL &&
- nameBitvector_Equals(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)))) {
- return curr->entry;
- } else {
- return NULL;
- }
-}
-
-void _removeNode(FIB *fib, const Name *prefix) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(prefix, "Parameter must be non-null");
-
- FibNode *grand = NULL; // grandparent
- FibNode *prev =
- fib->root; // parent: it will points to curr of the next hop in the trie
- FibNode *curr; // current node: the node to remove
-
- NameBitvector *name = name_GetContentName(prefix);
-
- if (nameBitvector_testBit(name, MSB_POS)) {
- curr = fib->root->right;
- } else {
- curr = fib->root->left;
- }
-
- // in the first loop we always search the node to remove
- while (prev->pos > curr->pos) {
- grand = prev;
- prev = curr;
-
- if (nameBitvector_testBit(name, curr->pos)) {
- curr = curr->right;
- } else {
- curr = curr->left;
- }
- }
-
- if (!nameBitvector_Equals(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)))) {
- // the node does not exists
- return;
- }
-
- // search for the real parent of curr (*tmpPrev)
- // prev points to curr or next node in the trie
- // this is because of the loopback links
-
- FibNode *tmpPrev = fib->root;
- FibNode *tmpCurr;
-
- if (nameBitvector_testBit(name, MSB_POS)) {
- tmpCurr = fib->root->right;
- } else {
- tmpCurr = fib->root->left;
- }
-
- // here we compare pointer so we are sure to stop at the right potion
- while (tmpCurr != curr) {
- tmpPrev = tmpCurr;
-
- if (nameBitvector_testBit(name, tmpCurr->pos)) {
- tmpCurr = tmpCurr->right;
- } else {
- tmpCurr = tmpCurr->left;
- }
- }
-
- // now curr is the node to remove and tmpPrev is the real parent of curr
-
- if (curr == prev) {
- // this is the case where curr is a leaf node
- FibNode *next; // child of curr (the loopback)
-
- if (nameBitvector_testBit(name, curr->pos)) {
- next = curr->left;
- } else {
- next = curr->right;
- }
-
- if (nameBitvector_testBit(name, tmpPrev->pos)) {
- tmpPrev->right = next;
- } else {
- tmpPrev->left = next;
- }
-
- } else {
- // curr is an internal node
- FibNode *next; // child of prev (loopback)
-
- if (nameBitvector_testBit(name, prev->pos)) {
- next = prev->left;
- } else {
- next = prev->right;
- }
-
- if (nameBitvector_testBit(name, grand->pos)) {
- grand->right = next;
- } else {
- grand->left = next;
- }
-
- if (nameBitvector_testBit(name, tmpPrev->pos)) {
- tmpPrev->right = prev;
- } else {
- tmpPrev->left = prev;
- }
-
- prev->left = curr->left;
- prev->right = curr->right;
- prev->pos = curr->pos;
- }
-
- fib->size--;
- _destroyNode(curr);
-}
-
-void fib_Remove(FIB *fib, const Name *name, unsigned connId) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(name, "Parameter must be non-null");
-
- FibEntry *entry = fib_Contains(fib, name);
-
- if (entry == NULL) {
- return;
- }
-
- fibEntry_RemoveNexthopByConnectionId(entry, connId);
- if (fibEntry_NexthopCount(entry) == 0) {
- _removeNode(fib, name);
- }
-}
-
-void _removeConnectionId(FibNode *n, unsigned pos, unsigned connectionId,
- FibEntryList *list) {
- if (n->pos < pos) {
- fibEntry_RemoveNexthopByConnectionId(n->entry, connectionId);
- if (fibEntry_NexthopCount(n->entry) == 0) {
- fibEntryList_Append(list, n->entry);
- }
- _removeConnectionId(n->left, n->pos, connectionId, list);
- _removeConnectionId(n->right, n->pos, connectionId, list);
- }
-}
-
-void fib_RemoveConnectionId(FIB *fib, unsigned connectionId) {
- parcAssertNotNull(fib, "Parameter must be non-null");
-
- // 1 - we vist the tree to remove the connection id
- // 2 - during the visit we collect the fib entry with 0 nexthop
- // 3 - after the visit we remove this entries
-
- FibEntryList *list = fibEntryList_Create();
-
- _removeConnectionId(fib->root->left, fib->root->pos, connectionId, list);
- _removeConnectionId(fib->root->right, fib->root->pos, connectionId, list);
-
- for (int i = 0; i < fibEntryList_Length(list); i++) {
- _removeNode(fib, fibEntry_GetPrefix(fibEntryList_Get(list, i)));
- }
-
- fibEntryList_Destroy(&list);
-}
-
-size_t fib_Length(const FIB *fib) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- return fib->size;
-}
-
-FibEntry *fib_Match(const FIB *fib, const Message *interestMessage) {
- parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(interestMessage, "Parameter must be non-null");
-
- NameBitvector *name = name_GetContentName(message_GetName(interestMessage));
-
- FibNode *prev = fib->root;
- FibNode *curr;
-
- FibNode *match = NULL;
- unsigned len = 0;
-
- if (nameBitvector_testBit(name, MSB_POS))
- curr = fib->root->right;
- else
- curr = fib->root->left;
-
- while (prev->pos > curr->pos) {
- prev = curr;
-
- if (curr->entry != NULL) {
- if (nameBitvector_StartsWith(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry))) &&
- nameBitvector_GetLength(
- name_GetContentName(fibEntry_GetPrefix(curr->entry))) > len) {
- match = curr;
- len = nameBitvector_GetLength(
- name_GetContentName(fibEntry_GetPrefix(curr->entry)));
- }
- }
-
- if (nameBitvector_testBit(name, curr->pos))
- curr = curr->right;
- else
- curr = curr->left;
- }
-
- if (curr->entry != NULL) {
- if (nameBitvector_StartsWith(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry))) &&
- nameBitvector_GetLength(
- name_GetContentName(fibEntry_GetPrefix(curr->entry))) > len) {
- match = curr;
- len = nameBitvector_GetLength(
- name_GetContentName(fibEntry_GetPrefix(curr->entry)));
- }
- }
-
- if (match != NULL && match->entry != NULL) {
- return match->entry;
- } else {
- return NULL;
- }
-}
-
-void _collectFibEntries(FibNode *n, int pos, FibEntryList *list) {
- if (n->pos < (unsigned)pos) {
- fibEntryList_Append(list, n->entry);
- _collectFibEntries(n->left, n->pos, list);
- _collectFibEntries(n->right, n->pos, list);
- }
-}
-
-FibEntryList *fib_GetEntries(const FIB *fib) {
- parcAssertNotNull(fib, "Parameter must be non-null");
-
- FibEntryList *list = fibEntryList_Create();
-
- _collectFibEntries(fib->root->left, fib->root->pos, list);
- _collectFibEntries(fib->root->right, fib->root->pos, list);
-
- return list;
-}