aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--apps/cmake/Modules/Packaging.cmake10
-rw-r--r--ctrl/libhicnctrl/src/CMakeLists.txt2
-rw-r--r--hicn-light/cmake/Modules/Packaging.cmake6
-rw-r--r--hicn-light/src/hicn/config/controlAddListener.c2
-rw-r--r--hicn-light/src/hicn/core/mapMe.c4
-rw-r--r--hicn-light/src/hicn/core/messageHandler.h133
-rw-r--r--hicn-light/src/hicn/core/name.c28
-rw-r--r--hicn-light/src/hicn/core/name.h18
-rw-r--r--hicn-light/src/hicn/core/nameBitvector.c137
-rw-r--r--hicn-light/src/hicn/core/nameBitvector.h10
-rw-r--r--hicn-light/src/hicn/io/hicnListener.c100
-rw-r--r--hicn-light/src/hicn/io/udpListener.c16
-rw-r--r--hicn-light/src/hicn/processor/fib.c657
-rw-r--r--hicn-light/src/hicn/processor/fib.h8
-rw-r--r--hicn-light/src/hicn/processor/fibEntry.c48
-rw-r--r--hicn-light/src/hicn/processor/messageProcessor.c12
-rw-r--r--hicn-light/src/hicn/strategies/loadBalancerWithPD.c4
-rw-r--r--hicn-light/src/hicn/strategies/loadBalancerWithPD.h4
-rw-r--r--hicn-plugin/CMakeLists.txt16
-rw-r--r--hicn-plugin/README.md11
-rw-r--r--hicn-plugin/src/data_fwd.h4
-rw-r--r--hicn-plugin/src/strategy.c2
-rw-r--r--lib/src/name.c14
-rw-r--r--libtransport/src/hicn/transport/CMakeLists.txt1
-rw-r--r--libtransport/src/hicn/transport/core/memif_connector.cc16
-rw-r--r--libtransport/src/hicn/transport/core/memif_connector.h2
-rw-r--r--libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc25
-rw-r--r--libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h2
-rw-r--r--libtransport/src/hicn/transport/interfaces/socket_producer.h4
-rw-r--r--scripts/build-packages.sh6
-rw-r--r--scripts/build-sysrepo.sh6
-rw-r--r--utils/extras/README.md49
33 files changed, 687 insertions, 672 deletions
diff --git a/README.md b/README.md
index a4afc2435..159ab22a4 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ local namespace (local face management).
https://packagecloud.io/fdio/release
## Release note
-The current master branch provides the 19.01 release which is compatible with the 19.01 VPP stable.
+The current master branch provides the 19.08 release which is compatible with the 19.08 VPP stable.
No other VPP releases are supported nor maintained. At every new VPP release distribution hicn
master branch is updated to work with the latest stable release. All previous stable releases
are discontinued and not maintained. The user who is interested in a specific release can always
diff --git a/apps/cmake/Modules/Packaging.cmake b/apps/cmake/Modules/Packaging.cmake
index 5850af707..6a6e34777 100644
--- a/apps/cmake/Modules/Packaging.cmake
+++ b/apps/cmake/Modules/Packaging.cmake
@@ -15,4 +15,14 @@ set(${HICN_APPS}_DESCRIPTION
"Hicn apps provide the higet application, \
useful for testing and debugging within a hicn network."
CACHE STRING "Description for deb/rpm package."
+)
+
+set(${HICN_APPS}_DEB_DEPENDENCIES
+ "lib${LIBTRANSPORT} (>= stable_version)"
+ CACHE STRING "Dependencies for deb/rpm package."
+)
+
+set(${HICN_APPS}_RPM_DEPENDENCIES
+ "lib${LIBTRANSPORT} >= stable_version"
+ CACHE STRING "Dependencies for deb/rpm package."
) \ No newline at end of file
diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt
index ebccb7ddd..204311c39 100644
--- a/ctrl/libhicnctrl/src/CMakeLists.txt
+++ b/ctrl/libhicnctrl/src/CMakeLists.txt
@@ -55,6 +55,7 @@ if (ANDROID_API)
INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES}
LINK_LIBRARIES ${LIBRARIES}
COMPONENT ${LIBHICNCTRL_COMPONENT}
+ DEPENDS ${LIBHICN_STATIC}
INCLUDE_DIRS ${INCLUDE_DIRS}
INSTALL_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
@@ -66,6 +67,7 @@ else ()
INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES}
LINK_LIBRARIES ${LIBRARIES}
COMPONENT ${LIBHICNCTRL_COMPONENT}
+ DEPENDS ${LIBHICN_SHARED}
INCLUDE_DIRS ${INCLUDE_DIRS}
INSTALL_ROOT_DIR hicn
DEFINITIONS ${COMPILER_DEFINITIONS}
diff --git a/hicn-light/cmake/Modules/Packaging.cmake b/hicn-light/cmake/Modules/Packaging.cmake
index 599238cb6..006261b03 100644
--- a/hicn-light/cmake/Modules/Packaging.cmake
+++ b/hicn-light/cmake/Modules/Packaging.cmake
@@ -15,17 +15,17 @@
# Packages section
######################
-set(${LIBHICN_LIGHT}_DESCRIPTION
+set(${HICN_LIGHT}_DESCRIPTION
"hicn-light is a socket based forwarder"
CACHE STRING "Description for deb/rpm package."
)
-set(${LIBHICN_LIGHT}_DEB_DEPENDENCIES
+set(${HICN_LIGHT}_DEB_DEPENDENCIES
"lib${LIBHICN} (>= stable_version), libparc (>= 1.0)"
CACHE STRING "Dependencies for deb/rpm package."
)
-set(${LIBHICN_LIGHT}_RPM_DEPENDENCIES
+set(${HICN_LIGHT}_RPM_DEPENDENCIES
"lib${LIBHICN} >= stable_version, libparc >= 1.0"
CACHE STRING "Dependencies for deb/rpm package."
) \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/controlAddListener.c b/hicn-light/src/hicn/config/controlAddListener.c
index d84b8049b..c9253425a 100644
--- a/hicn-light/src/hicn/config/controlAddListener.c
+++ b/hicn-light/src/hicn/config/controlAddListener.c
@@ -182,7 +182,7 @@ static CommandReturn _controlAddListener_Execute(CommandParser *parser,
// here we discard the prefix len if it exists, since we don't use it in
// code but we let libhicn to find the right ip address.
#ifdef __linux__
- return _CreateListener(parser, ops, symbolic, host, port, interfaceName, HICN_MODE,
+ return _CreateListener(parser, ops, symbolic, host, port, "hicn", HICN_MODE,
HICN_CONN);
#else
return _CreateListener(parser, ops, symbolic, host, port, HICN_MODE,
diff --git a/hicn-light/src/hicn/core/mapMe.c b/hicn-light/src/hicn/core/mapMe.c
index 865841f67..0f86dfd7e 100644
--- a/hicn-light/src/hicn/core/mapMe.c
+++ b/hicn-light/src/hicn/core/mapMe.c
@@ -583,7 +583,7 @@ static bool mapMe_onSpecialInterest(const MapMe *mapme,
#else
fibEntry = fibEntry_Create(name, fwdStrategy);
#endif /* WITH_POLICY */
- FibEntry *lpm = fib_LPM(fib, name);
+ FibEntry *lpm = fib_MatchName(fib, name);
mapMe_CreateTFIB(fibEntry);
fib_Add(fib, fibEntry);
if (!lpm) {
@@ -755,7 +755,7 @@ void mapMe_onSpecialInterestAck(const MapMe *mapme, const uint8_t *msgBuffer,
const Name * name =
name_CreateFromPacket(msgBuffer, MessagePacketType_ContentObject);
- name_setLen(name, prefix->len);
+ name_setLen((Name*) name, prefix->len);
char * name_str = name_ToString(name);
INFO(mapme, "[MAP-Me] Received ack for name prefix=%s seq=%d on conn id=%d",
name_str, params->seq, conn_in_id);
diff --git a/hicn-light/src/hicn/core/messageHandler.h b/hicn-light/src/hicn/core/messageHandler.h
index 74535d80f..f1f91bc40 100644
--- a/hicn-light/src/hicn/core/messageHandler.h
+++ b/hicn-light/src/hicn/core/messageHandler.h
@@ -17,6 +17,7 @@
#define messageHandler
#include <stdlib.h>
+#include <unistd.h> // close
#include <hicn/hicn.h>
#include <hicn/core/messagePacketType.h>
@@ -175,6 +176,85 @@ static inline uint8_t messageHandler_NextHeaderType(const uint8_t *message) {
static inline void * messageHandler_GetSource(const uint8_t *message);
static inline void *messageHandler_GetDestination(const uint8_t *message);
+static const
+AddressPair *
+_createRecvAddressPairFromPacket(const uint8_t *msgBuffer) {
+ Address *packetSrcAddr = NULL; /* This one is in the packet */
+ Address *localAddr = NULL; /* This one is to be determined */
+
+ if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) {
+ struct sockaddr_in6 addr_in6;
+ addr_in6.sin6_family = AF_INET6;
+ addr_in6.sin6_port = htons(1234);
+ addr_in6.sin6_flowinfo = 0;
+ addr_in6.sin6_scope_id = 0;
+ memcpy(&addr_in6.sin6_addr,
+ (struct in6_addr *)messageHandler_GetSource(msgBuffer), 16);
+ packetSrcAddr = addressCreateFromInet6(&addr_in6);
+
+ /* We now determine the local address used to reach the packet src address */
+ int sock = socket (AF_INET6, SOCK_DGRAM, 0);
+ if (sock < 0)
+ goto ERR;
+
+ struct sockaddr_in6 remote, local;
+ memset(&remote, 0, sizeof(remote));
+ remote.sin6_family = AF_INET6;
+ remote.sin6_addr = addr_in6.sin6_addr;
+ remote.sin6_port = htons(1234);
+
+ socklen_t locallen = sizeof(local);
+ if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
+ goto ERR;
+ if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
+ goto ERR;
+
+ local.sin6_port = htons(1234);
+ localAddr = addressCreateFromInet6(&local);
+
+ close(sock);
+
+ } else if (messageHandler_GetIPPacketType(msgBuffer) == IPv4_TYPE) {
+ struct sockaddr_in addr_in;
+ addr_in.sin_family = AF_INET;
+ addr_in.sin_port = htons(1234);
+ memcpy(&addr_in.sin_addr,
+ (struct in_addr *)messageHandler_GetSource(msgBuffer), 4);
+ packetSrcAddr = addressCreateFromInet(&addr_in);
+
+ /* We now determine the local address used to reach the packet src address */
+
+ int sock = socket (AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("Socket error");
+ goto ERR;
+ }
+
+ struct sockaddr_in remote, local;
+ memset(&remote, 0, sizeof(remote));
+ remote.sin_family = AF_INET;
+ remote.sin_addr = addr_in.sin_addr;
+ remote.sin_port = htons(1234);
+
+ socklen_t locallen = sizeof(local);
+ if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
+ goto ERR;
+ if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
+ goto ERR;
+
+ local.sin_port = htons(1234);
+ localAddr = addressCreateFromInet(&local);
+
+ close(sock);
+ }
+ /* As this is a receive pair, we swap src and dst */
+ return addressPair_Create(localAddr, packetSrcAddr);
+
+ERR:
+ perror("Socket error");
+ return NULL;
+}
+
/* Main hook handler */
/**
@@ -187,21 +267,58 @@ static inline void *messageHandler_GetDestination(const uint8_t *message);
* (successfully or not) processed.
*/
static inline bool messageHandler_handleHooks(Forwarder * forwarder,
- const uint8_t * packet, int conn_id)
+ const uint8_t * packet, ListenerOps * listener, int fd, AddressPair * pair)
{
+ bool is_matched = false;
+
+ /* BEGIN Match */
+
#ifdef WITH_MAPME
- if (mapMe_isMapMe(packet)) {
- forwarder_ProcessMapMe(forwarder, packet, conn_id);
- goto END;
+ bool is_mapme = mapMe_isMapMe(packet);
+ is_matched |= is_mapme;
+#endif /* WITH_MAPME */
+
+ /* ... */
+
+ /* END Match */
+
+ if (!is_matched)
+ return false;
+
+ /*
+ * Find existing connection or create a new one (we assume all processing
+ * requires a valid connection.
+ */
+
+ if (!pair) {
+ /* The hICN listener does not provide any address pair while UDP does */
+ const AddressPair * pair = _createRecvAddressPairFromPacket(packet);
+ if (!pair)
+ return false;
+ }
+
+ /* Find connection and eventually create it */
+ const Connection * conn = connectionTable_FindByAddressPair(
+ forwarder_GetConnectionTable(forwarder), pair);
+ unsigned conn_id;
+ if (conn == NULL) {
+ conn_id = listener->createConnection(listener, fd, pair);
+ } else {
+ conn_id = connection_GetConnectionId(conn);
}
+
+ /* BEGIN Process */
+
+#ifdef WITH_MAPME
+ if (mapMe_isMapMe(packet))
+ forwarder_ProcessMapMe(forwarder, packet, conn_id);
#endif /* WITH_MAPME */
- return false;
+ /* ... */
+
+ /* END Process */
-#if 1 // Enable and jump here when a handler has successfully processed the packet
-END:
return true;
-#endif
}
static inline bool messageHandler_IsTCP(const uint8_t *message) {
diff --git a/hicn-light/src/hicn/core/name.c b/hicn-light/src/hicn/core/name.c
index 8cf8dacbc..f4ea7dbca 100644
--- a/hicn-light/src/hicn/core/name.c
+++ b/hicn-light/src/hicn/core/name.c
@@ -162,6 +162,24 @@ Name *name_Acquire(const Name *original) {
return copy;
}
+Name *name_Copy(const Name *original) {
+ parcAssertNotNull(original, "Parameter must be non-null");
+ Name *copy = parcMemory_AllocateAndClear(sizeof(Name));
+ parcAssertNotNull(copy, "parcMemory_AllocateAndClear(%zu) returned NULL",
+ sizeof(Name));
+
+ copy->content_name = nameBitvector_Copy(original->content_name);
+ copy->segment = original->segment;
+ copy->name_hash = original->name_hash;
+
+ copy->refCountPtr = parcMemory_Allocate(sizeof(unsigned));
+ parcAssertNotNull(copy->refCountPtr, "parcMemory_Allocate(%zu) returned NULL",
+ sizeof(unsigned));
+ *copy->refCountPtr = 1;
+
+ return copy;
+}
+
uint32_t name_HashCode(const Name *name) {
parcAssertNotNull(name, "Parameter must be non-null");
return name->name_hash;
@@ -211,13 +229,6 @@ int name_Compare(const Name *a, const Name *b) {
}
}
-bool name_StartsWith(const Name *name, const Name *prefix) {
- parcAssertNotNull(name, "Parameter name must be non-null");
- parcAssertNotNull(prefix, "Parameter prefix must be non-null");
-
- return nameBitvector_StartsWith(name->content_name, prefix->content_name);
-}
-
char *name_ToString(const Name *name) {
char *output = malloc(128);
@@ -231,8 +242,9 @@ char *name_ToString(const Name *name) {
return output;
}
-void name_setLen(const Name *name, uint8_t len) {
+void name_setLen(Name *name, uint8_t len) {
nameBitvector_setLen(name->content_name, len);
+ name->name_hash = _computeHash(name);
}
#ifdef WITH_POLICY
diff --git a/hicn-light/src/hicn/core/name.h b/hicn-light/src/hicn/core/name.h
index 4eb80cf36..f2ae1f64e 100644
--- a/hicn-light/src/hicn/core/name.h
+++ b/hicn-light/src/hicn/core/name.h
@@ -48,6 +48,11 @@ void name_Release(Name **namePtr);
Name *name_Acquire(const Name *original);
/**
+ * returns a copy of the name
+ */
+Name *name_Copy(const Name *original);
+
+/**
* A hash value for use in hash tables
*
*/
@@ -71,17 +76,6 @@ bool name_Equals(const Name *a, const Name *b);
int name_Compare(const Name *a, const Name *b);
/**
- * @function metsName_StartsWith
- * @abstract Checks if name starts with prefix
- * @discussion
- * Byte-by-byte prefix comparison
- *
- * @return True if the name is equal to or begins with prefix
- */
-
-bool name_StartsWith(const Name *name, const Name *prefix);
-
-/**
* return the name in string format (bitvector + segment number)
*
*/
@@ -93,7 +87,7 @@ char *name_ToString(const Name *name);
* @param [in] message - Interest message
* @param [in] len - Name length
*/
-void name_setLen(const Name *name, uint8_t len);
+void name_setLen(Name *name, uint8_t len);
/**
* Creates a name from a Address
diff --git a/hicn-light/src/hicn/core/nameBitvector.c b/hicn-light/src/hicn/core/nameBitvector.c
index 8078778e3..ad6884d02 100644
--- a/hicn-light/src/hicn/core/nameBitvector.c
+++ b/hicn-light/src/hicn/core/nameBitvector.c
@@ -27,24 +27,21 @@
#include <hicn/utils/commands.h>
-#define BLOCKS 2
+#define NAME_LEN 2
-const uint64_t BLOCK_SIZE = 64;
+const uint64_t BV_SIZE = 64;
const uint64_t WIDTH = 128;
-const uint64_t BLOCK_ONE = 0x1;
-
-// the bits are encoded in the following order:
-// 00100101001---101010 00100011---110100100
-// [bits[0] (uint64_t)] [bits[1] (uint64_t)]
-// ^ ^ ^ ^
-// 0 63 64 127
-// address 2200::0011 is encoded as:
-// 1000 1000 0000 0010 00000 ....0100 0100
-// ^ ^
-// 0 127
+const uint64_t ONE = 0x1;
+
+// address b000:0000:0000:0001:c000:0000:0000:0001 is encodend as follow
+// [bits[0] uint64_t ] [bits[1] unit64_t ]
+// ^ ^ ^ ^
+// 63 0 127 64
+// [1000 0000 ... 0000 1101] [1000 0000 ... 0000 0011] //binary
+// 1 b 1 c //hex
struct name_bitvector {
- uint64_t bits[BLOCKS];
+ uint64_t bits[NAME_LEN];
uint8_t len;
uint8_t IPversion;
};
@@ -62,11 +59,11 @@ NameBitvector *nameBitvector_CreateFromInAddr(uint32_t addr, uint8_t len) {
uint8_t addr_3 = (addr & 0x0000ff00) >> 8;
uint8_t addr_4 = (addr & 0x000000ff);
- bitvector->bits[1] = (bitvector->bits[1] | addr_4) << 8;
- bitvector->bits[1] = (bitvector->bits[1] | addr_3) << 8;
- bitvector->bits[1] = (bitvector->bits[1] | addr_2) << 8;
- bitvector->bits[1] = (bitvector->bits[1] | addr_1);
- bitvector->bits[1] = bitvector->bits[1] << 32;
+ bitvector->bits[0] = (bitvector->bits[0] | addr_4) << 8;
+ bitvector->bits[0] = (bitvector->bits[0] | addr_3) << 8;
+ bitvector->bits[0] = (bitvector->bits[0] | addr_2) << 8;
+ bitvector->bits[0] = (bitvector->bits[0] | addr_1);
+ bitvector->bits[0] = bitvector->bits[0] << 32;
bitvector->len = len;
@@ -87,11 +84,11 @@ NameBitvector *nameBitvector_CreateFromIn6Addr(struct in6_addr *addr,
bitvector->bits[1] = 0;
for (int i = 0; i < 8; ++i) {
- bitvector->bits[1] = (bitvector->bits[1] << 8) | addr->s6_addr[i];
+ bitvector->bits[0] = (bitvector->bits[0] << 8) | addr->s6_addr[i];
}
for (int i = 8; i < 16; ++i) {
- bitvector->bits[0] = (bitvector->bits[0] << 8) | addr->s6_addr[i];
+ bitvector->bits[1] = (bitvector->bits[1] << 8) | addr->s6_addr[i];
}
bitvector->len = len;
@@ -191,38 +188,13 @@ int nameBitvector_Compare(const NameBitvector *a, const NameBitvector *b) {
}
}
-bool nameBitvector_StartsWith(const NameBitvector *name,
- const NameBitvector *prefix) {
- parcAssertNotNull(name, "name cannot be NULL");
- parcAssertNotNull(prefix, "prefix cannot be NULL");
- parcAssertTrue(prefix->len > 0, "prefix length can not be 0");
-
- if (prefix->len > BLOCK_SIZE)
- return (name->bits[1] == prefix->bits[1]) &&
- ((name->bits[0] ^ prefix->bits[0]) >>
- (BLOCK_SIZE - (prefix->len - BLOCK_SIZE)) ==
- 0);
-
- return ((name->bits[1] ^ prefix->bits[1]) >> (BLOCK_SIZE - prefix->len) == 0);
-}
-
-bool nameBitvector_testBit(const NameBitvector *name, uint8_t pos) {
- if (pos == WIDTH) pos = 127;
-
- uint8_t final_pos = (uint8_t)(WIDTH - name->len);
-
- // the bit to test is inside the name/prefix len
- if (pos > final_pos) {
- return (name->bits[pos / BLOCK_SIZE] & (BLOCK_ONE << (pos % BLOCK_SIZE)));
- }
+int nameBitvector_testBit(const NameBitvector *name, uint8_t pos, bool *bit) {
+ if(pos >= name->len || pos > (WIDTH -1))
+ return -1;
- // the bit to test is outside the name/prefix len
- if (pos < final_pos) {
- return false;
- }
+ *bit = (name->bits[pos / BV_SIZE] & (ONE << ((BV_SIZE - 1) - (pos % BV_SIZE))));
- // pos is equal to the name/prefix len
- return true;
+ return 0;
}
uint64_t _diff_bit_log2(uint64_t val) {
@@ -257,31 +229,38 @@ uint64_t _diff_bit_log2(uint64_t val) {
return result;
}
-uint8_t nameBitvector_firstDiff(const NameBitvector *a,
- const NameBitvector *b) {
- uint8_t res = 0;
- uint64_t diff = a->bits[1] ^ b->bits[1];
- if (diff)
- res = (uint8_t)(64 + _diff_bit_log2(diff));
- else
- res = (uint8_t)_diff_bit_log2(a->bits[0] ^ b->bits[0]);
-
- // res is computed over the bitvector which is composed by 128 bit all the
- // times however the prefixes may be diffrent just because the have different
- // lengths example: prefix 1: 0::/30 prefix 2: 0::/20 at this point of the
- // function res would be 0 since both the bitvectors are composed by 0s but
- // the function will return 127-20, which is the position at which the two
- // prefix are different, since prefix 2 has only 20 bits
-
- uint8_t len_diff;
+uint32_t nameBitvector_lpm(const NameBitvector *a,
+ const NameBitvector *b) {
+ uint32_t limit;
+ uint32_t prefix_len;
if (a->len < b->len)
- len_diff = (uint8_t)(WIDTH - a->len);
+ limit = a->len;
else
- len_diff = (uint8_t)(WIDTH - b->len);
+ limit = b->len;
+
+ uint64_t diff = a->bits[0] ^ b->bits[0];
+ if(diff){
+ prefix_len = BV_SIZE - (_diff_bit_log2(diff) + 1);
+ //printf("if 1 diff = %lu plen = %d\n", diff, prefix_len);
+ }else{
+ prefix_len = BV_SIZE;
+ diff = a->bits[1] ^ b->bits[1];
+ if(diff){
+ prefix_len += (BV_SIZE - (_diff_bit_log2(diff) + 1));
+ //printf("if 2 diff = %lu plen = %d\n", diff, prefix_len);
+ }else{
+ prefix_len += BV_SIZE;
+ }
+ }
- if (len_diff > res) res = len_diff;
+ if(prefix_len < limit)
+ return prefix_len;
+ return limit;
+}
- return res;
+void nameBitvector_clear(NameBitvector *a, uint8_t start_from){
+ for(uint8_t pos = start_from; pos < WIDTH; pos++)
+ a->bits[pos / BV_SIZE] &= ~(ONE << ((BV_SIZE - 1) - (pos % BV_SIZE)));
}
int nameBitvector_ToIPAddress(const NameBitvector *name,
@@ -291,7 +270,7 @@ int nameBitvector_ToIPAddress(const NameBitvector *name,
ip_address->family = AF_INET;
ip_address->prefix_len = IPV4_ADDR_LEN_BITS;
- uint32_t tmp_addr = name->bits[1] >> 32ULL;
+ uint32_t tmp_addr = name->bits[0] >> 32ULL;
uint8_t addr_1 = (tmp_addr & 0xff000000) >> 24;
uint8_t addr_2 = (tmp_addr & 0x00ff0000) >> 16;
uint8_t addr_3 = (tmp_addr & 0x0000ff00) >> 8;
@@ -309,12 +288,12 @@ int nameBitvector_ToIPAddress(const NameBitvector *name,
ip_address->prefix_len = name->len; // IPV6_ADDR_LEN_BITS;
for (int i = 0; i < 8; i++) {
- addr->s6_addr[i] = (uint8_t)((name->bits[1] >> 8 * (7 - i)) & 0xFF);
+ addr->s6_addr[i] = (uint8_t)((name->bits[0] >> 8 * (7 - i)) & 0xFF);
}
int x = 0;
for (int i = 8; i < 16; ++i) {
- addr->s6_addr[i] = (uint8_t)((name->bits[0] >> 8 * (7 - x)) & 0xFF);
+ addr->s6_addr[i] = (uint8_t)((name->bits[1] >> 8 * (7 - x)) & 0xFF);
x++;
}
}
@@ -329,7 +308,7 @@ Address *nameBitvector_ToAddress(const NameBitvector *name) {
addr.sin_family = AF_INET;
addr.sin_port = htons(1234);
- uint32_t tmp_addr = name->bits[1] >> 32ULL;
+ uint32_t tmp_addr = name->bits[0] >> 32ULL;
uint8_t addr_1 = (tmp_addr & 0xff000000) >> 24;
uint8_t addr_2 = (tmp_addr & 0x00ff0000) >> 16;
uint8_t addr_3 = (tmp_addr & 0x0000ff00) >> 8;
@@ -354,13 +333,13 @@ Address *nameBitvector_ToAddress(const NameBitvector *name) {
for (int i = 0; i < 8; i++) {
addr.sin6_addr.s6_addr[i] =
- (uint8_t)((name->bits[1] >> 8 * (7 - i)) & 0xFF);
+ (uint8_t)((name->bits[0] >> 8 * (7 - i)) & 0xFF);
}
int x = 0;
for (int i = 8; i < 16; ++i) {
addr.sin6_addr.s6_addr[i] =
- (uint8_t)((name->bits[0] >> 8 * (7 - x)) & 0xFF);
+ (uint8_t)((name->bits[1] >> 8 * (7 - x)) & 0xFF);
x++;
}
@@ -380,4 +359,4 @@ char *nameBitvector_ToString(const NameBitvector *name) {
addressDestroy(&packetAddr);
return output;
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/core/nameBitvector.h b/hicn-light/src/hicn/core/nameBitvector.h
index 6ff859e3b..44cc45662 100644
--- a/hicn-light/src/hicn/core/nameBitvector.h
+++ b/hicn-light/src/hicn/core/nameBitvector.h
@@ -30,9 +30,6 @@ NameBitvector *nameBitvector_CreateFromInAddr(uint32_t addr, uint8_t len);
NameBitvector *nameBitvector_CreateFromIn6Addr(struct in6_addr *addr,
uint8_t len);
-NameBitvector *nameBitvector_CreateFromAddress(const Address *prefix,
- uint8_t len);
-
NameBitvector *nameBitvector_Copy(const NameBitvector *original);
void nameBitvector_Destroy(NameBitvector **bitvectorPtr);
@@ -45,12 +42,11 @@ bool nameBitvector_Equals(const NameBitvector *a, const NameBitvector *b);
int nameBitvector_Compare(const NameBitvector *a, const NameBitvector *b);
-bool nameBitvector_StartsWith(const NameBitvector *name,
- const NameBitvector *prefix);
+int nameBitvector_testBit(const NameBitvector *name, uint8_t pos, bool *bit);
-bool nameBitvector_testBit(const NameBitvector *name, uint8_t pos);
+uint32_t nameBitvector_lpm(const NameBitvector *a, const NameBitvector *b);
-uint8_t nameBitvector_firstDiff(const NameBitvector *a, const NameBitvector *b);
+void nameBitvector_clear(NameBitvector *a, uint8_t start_from);
int nameBitvector_ToIPAddress(const NameBitvector *name,
ip_address_t *ip_address);
diff --git a/hicn-light/src/hicn/io/hicnListener.c b/hicn-light/src/hicn/io/hicnListener.c
index e8cab9aca..d13dc5b4d 100644
--- a/hicn-light/src/hicn/io/hicnListener.c
+++ b/hicn-light/src/hicn/io/hicnListener.c
@@ -19,7 +19,6 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <unistd.h>
@@ -579,84 +578,6 @@ static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer) {
message_Release(&message);
}
-static const
-AddressPair *
-_createRecvAddressPairFromPacket(const uint8_t *msgBuffer) {
- Address *packetSrcAddr = NULL; /* This one is in the packet */
- Address *localAddr = NULL; /* This one is to be determined */
-
- if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) {
- struct sockaddr_in6 addr_in6;
- addr_in6.sin6_family = AF_INET6;
- addr_in6.sin6_port = htons(1234);
- addr_in6.sin6_flowinfo = 0;
- addr_in6.sin6_scope_id = 0;
- memcpy(&addr_in6.sin6_addr,
- (struct in6_addr *)messageHandler_GetSource(msgBuffer), 16);
- packetSrcAddr = addressCreateFromInet6(&addr_in6);
-
- /* We now determine the local address used to reach the packet src address */
- int sock = socket (AF_INET6, SOCK_DGRAM, 0);
- if (sock < 0)
- goto ERR;
-
- struct sockaddr_in6 remote, local;
- memset(&remote, 0, sizeof(remote));
- remote.sin6_family = AF_INET6;
- remote.sin6_addr = addr_in6.sin6_addr;
- remote.sin6_port = htons(1234);
-
- socklen_t locallen = sizeof(local);
- if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
- goto ERR;
- if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
- goto ERR;
-
- local.sin6_port = htons(1234);
- localAddr = addressCreateFromInet6(&local);
-
- close(sock);
-
- } else if (messageHandler_GetIPPacketType(msgBuffer) == IPv4_TYPE) {
- struct sockaddr_in addr_in;
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(1234);
- memcpy(&addr_in.sin_addr,
- (struct in_addr *)messageHandler_GetSource(msgBuffer), 4);
- packetSrcAddr = addressCreateFromInet(&addr_in);
-
- /* We now determine the local address used to reach the packet src address */
-
- int sock = socket (AF_INET, SOCK_DGRAM, 0);
- if (sock < 0) {
- perror("Socket error");
- goto ERR;
- }
-
- struct sockaddr_in remote, local;
- memset(&remote, 0, sizeof(remote));
- remote.sin_family = AF_INET;
- remote.sin_addr = addr_in.sin_addr;
- remote.sin_port = htons(1234);
-
- socklen_t locallen = sizeof(local);
- if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1)
- goto ERR;
- if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1)
- goto ERR;
-
- local.sin_port = htons(1234);
- localAddr = addressCreateFromInet(&local);
-
- close(sock);
- }
- /* As this is a receive pair, we swap src and dst */
- return addressPair_Create(localAddr, packetSrcAddr);
-
-ERR:
- perror("Socket error");
- return NULL;
-}
static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer) {
HicnListener * hicn = (HicnListener*)listener->context;
@@ -721,25 +642,8 @@ static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer)
} else if (messageHandler_IsLoadBalancerProbe(msgBuffer)) {
_handleProbeMessage(listener, msgBuffer);
} else {
- const AddressPair * pair = _createRecvAddressPairFromPacket(msgBuffer);
- if (!pair)
- goto ERR;
-
- /* Find connection and eventually create it */
- const Connection * conn = connectionTable_FindByAddressPair(
- forwarder_GetConnectionTable(hicn->forwarder), pair);
- unsigned conn_id;
- if (conn == NULL) {
- conn_id = listener->createConnection(listener, fd, pair);
- } else {
- conn_id = connection_GetConnectionId(conn);
- }
-
- messageHandler_handleHooks(hicn->forwarder, msgBuffer, conn_id);
-
-ERR:
- parcMemory_Deallocate((void **)&msgBuffer);
-
+ messageHandler_handleHooks(hicn->forwarder, msgBuffer, listener, fd, NULL);
+ parcMemory_Deallocate((void **)&msgBuffer);
}
return message;
diff --git a/hicn-light/src/hicn/io/udpListener.c b/hicn-light/src/hicn/io/udpListener.c
index 32f633984..02deb49d1 100644
--- a/hicn-light/src/hicn/io/udpListener.c
+++ b/hicn-light/src/hicn/io/udpListener.c
@@ -418,16 +418,16 @@ static void _handleWldrNotification(UdpListener *udp, unsigned connId,
message_Release(&message);
}
-static Message *_readMessage(ListenerOps * ops, int fd,
+static Message *_readMessage(ListenerOps * listener, int fd,
AddressPair *pair, uint8_t * packet, bool * processed) {
- UdpListener * udp = (UdpListener *)ops->context;
+ UdpListener * udp = (UdpListener *)listener->context;
Message *message = NULL;
unsigned connid;
bool foundConnection;
- const Connection *conn = _lookupConnection(ops, pair);
+ const Connection *conn = _lookupConnection(listener, pair);
if (conn) {
connid = connection_GetConnectionId(conn);
foundConnection = true;
@@ -449,7 +449,7 @@ static Message *_readMessage(ListenerOps * ops, int fd,
} else if (messageHandler_IsInterest(packet)) {
pktType = MessagePacketType_Interest;
if (!foundConnection) {
- connid = _createNewConnection(ops, fd, pair);
+ connid = _createNewConnection(listener, fd, pair);
}
} else {
printf("Got a packet that is not a data nor an interest, drop it!\n");
@@ -471,11 +471,13 @@ static Message *_readMessage(ListenerOps * ops, int fd,
*processed = true;
_handleProbeMessage(udp, packet);
} else {
- /* Generic hook handler */
+
+#if 0
if (!foundConnection)
- connid = _createNewConnection(ops, fd, pair);
+ connid = _createNewConnection(listener, fd, pair);
+#endif
- *processed = messageHandler_handleHooks(udp->forwarder, packet, connid);
+ *processed = messageHandler_handleHooks(udp->forwarder, packet, listener, fd, pair);
}
return message;
diff --git a/hicn-light/src/hicn/processor/fib.c b/hicn-light/src/hicn/processor/fib.c
index 7cb94d4ba..6489e59e2 100644
--- a/hicn-light/src/hicn/processor/fib.c
+++ b/hicn-light/src/hicn/processor/fib.c
@@ -16,6 +16,7 @@
#include <hicn/hicn-light/config.h>
#include <stdio.h>
+#include <hicn/core/forwarder.h>
#include <hicn/processor/fib.h>
#include <parc/algol/parc_Memory.h>
@@ -23,9 +24,6 @@
#include <parc/assert/parc_Assert.h>
-#define NULL_POS 128
-#define MSB_POS 127
-
struct node;
typedef struct node FibNode;
@@ -33,10 +31,11 @@ struct node {
FibNode *left;
FibNode *right;
FibEntry *entry;
- unsigned pos;
+ bool is_used;
};
struct fib {
+ Forwarder *forwarder;
FibNode *root;
unsigned size;
};
@@ -45,7 +44,7 @@ struct fib {
// Public API
FibNode *_createNode(FibNode *left, FibNode *right, FibEntry *entry,
- unsigned pos) {
+ bool is_used) {
FibNode *n = parcMemory_AllocateAndClear(sizeof(FibNode));
parcAssertNotNull(n, "parcMemory_AllocateAndClear(%zu) returned NULL",
sizeof(FibNode));
@@ -53,22 +52,18 @@ FibNode *_createNode(FibNode *left, FibNode *right, FibEntry *entry,
n->left = left;
n->right = right;
n->entry = entry;
- n->pos = pos;
+ n->is_used = is_used;
return n;
}
-FIB *fib_Create() {
+FIB *fib_Create(Forwarder *forwarder) {
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->forwarder = forwarder;
+ hicnFib->root = NULL;
hicnFib->size = 0;
return hicnFib;
@@ -80,9 +75,12 @@ void _destroyNode(FibNode *n) {
n = NULL;
}
-void _destroyFib(FIB *fib) {
- // to be done
- return;
+void _destroyFib(FibNode *n) {
+ if(n != NULL){
+ _destroyFib(n->right);
+ _destroyFib(n->left);
+ _destroyNode(n);
+ }
}
void fib_Destroy(FIB **fibPtr) {
@@ -90,8 +88,8 @@ void fib_Destroy(FIB **fibPtr) {
parcAssertNotNull(*fibPtr, "Parameter must dereference to non-null pointer");
FIB *fib = *fibPtr;
+ _destroyFib(fib->root);
- _destroyFib(fib);
parcMemory_Deallocate((void **)&fib);
*fibPtr = NULL;
}
@@ -100,239 +98,319 @@ 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));
+ NameBitvector *new_prefix = name_GetContentName(fibEntry_GetPrefix(entry));
+ uint32_t new_prefix_len = nameBitvector_GetLength(new_prefix);
+ FibNode * curr = fib->root;
+ FibNode * last = NULL;
- //if the name len is 0, we add this entry on the root
- if(nameBitvector_GetLength(name) == 0){
- fib->size++;
- fib->root->entry = entry;
- return;
- }
+ NameBitvector *curr_name;
+ uint32_t curr_prefix_len;
+ uint32_t match_len;
- // search the name
- FibNode *prev = fib->root;
- FibNode *curr;
+ while(curr != NULL){
+ curr_name = name_GetContentName(fibEntry_GetPrefix(curr->entry));
- if (nameBitvector_testBit(name, MSB_POS)) {
- curr = fib->root->right;
- } else {
- curr = fib->root->left;
- }
+ match_len = nameBitvector_lpm(new_prefix, curr_name);
+ curr_prefix_len = nameBitvector_GetLength(curr_name);
- while (prev->pos > curr->pos) {
- prev = curr;
- if (nameBitvector_testBit(name, curr->pos)) {
+ if(curr_prefix_len != match_len || //the new entry does not match the curr
+ curr_prefix_len >= new_prefix_len) //in this case we cannot procede anymore
+ break;
+
+ last = curr;
+ bool bit;
+ int res = nameBitvector_testBit(new_prefix, curr_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
+ if(bit)
curr = curr->right;
- } else {
+ else
curr = curr->left;
- }
}
- if (curr->entry != NULL && curr->pos != NULL_POS &&
- 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
+ //this is the root (empty trie) or an empty child
+ if(curr == NULL){
+ FibNode * new_node = _createNode(NULL, NULL, entry, true);
+ if(last == NULL){
+ fib->root = new_node;
+ }else{
+ uint32_t last_prefix_len = nameBitvector_GetLength(
+ name_GetContentName(fibEntry_GetPrefix(last->entry)));
+ bool bit;
+ int res = nameBitvector_testBit(new_prefix, last_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
+ if(bit)
+ last->right = new_node;
+ else
+ last->left = new_node;
+ }
+ fib->size++;
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 && curr->pos != NULL_POS){
- pos = nameBitvector_firstDiff(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)));
+ //curr is not null
+
+ //the node already exist
+ //if is not in use we turn it on and we set the rigth fib entry
+ if(curr_prefix_len == match_len && new_prefix_len == match_len){
+ if(!curr->is_used){
+ curr->is_used = true;
+ curr->entry = entry;
+ fib->size++;
+ return;
+ }else{
+ //this case should never happen beacuse of the way we add
+ //entries in the fib
+ const NumberSet * next_hops = fibEntry_GetNexthops(entry);
+ unsigned size = (unsigned)fibEntry_NexthopCount(entry);
+ for(unsigned i = 0; i < size; i++)
+ fibEntry_AddNexthop(curr->entry,numberSet_GetItem(next_hops, i));
+ }
}
- // 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;
+ //key is prefix of the curr node (so new_prefix_len < curr_prefix_len)
+ if(new_prefix_len == match_len){
+ FibNode * new_node = _createNode(NULL, NULL, entry, true);
+ if(last == NULL){
+ fib->root = new_node;
+ }else{
+ uint32_t last_prefix_len = nameBitvector_GetLength(
+ name_GetContentName(fibEntry_GetPrefix(last->entry)));
+
+ bool bit;
+ int res = nameBitvector_testBit(new_prefix, last_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
+ if(bit)
+ last->right = new_node;
+ else
+ last->left = new_node;
}
+ bool bit;
+ int res = nameBitvector_testBit(curr_name, match_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
+ if(bit)
+ new_node->right = curr;
+ else
+ new_node->left = curr;
+ fib->size++;
+ return;
}
- // 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;
+ //in the last case we need to add an inner node
+ Name * inner_prefix = name_Copy(fibEntry_GetPrefix(entry));
+ nameBitvector_clear(name_GetContentName(inner_prefix), match_len);
+ name_setLen(inner_prefix, match_len);
+
+ FibEntry * inner_entry = fibEntry_Create(inner_prefix, SET_STRATEGY_LOADBALANCER,
+ fib->forwarder);
+
+ FibNode * inner_node = _createNode(NULL, NULL, inner_entry, false);
+ FibNode * new_node = _createNode(NULL, NULL, entry, true);
+
+ if(last == NULL){
+ //we need to place the inner_node at the root
+ fib->root = inner_node;
+ }else{
+ uint32_t last_prefix_len = nameBitvector_GetLength(
+ name_GetContentName(fibEntry_GetPrefix(last->entry)));
+ bool bit;
+ int res = nameBitvector_testBit(name_GetContentName(inner_prefix),
+ last_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
+ if(bit)
+ last->right = inner_node;
+ else
+ last->left = inner_node;
}
- uint8_t new_pos = prev->pos;
- if (new_pos == NULL_POS) new_pos = MSB_POS;
+ bool bit;
+ int res = nameBitvector_testBit(new_prefix, match_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_add)");
- if (nameBitvector_testBit(name, new_pos)) {
- prev->right = n;
- } else {
- prev->left = n;
+ if(bit){
+ inner_node -> left = curr;
+ inner_node ->right = new_node;
+ }else{
+ inner_node -> left = new_node;
+ inner_node ->right = curr;
}
+ fib->size ++;
}
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);
+ NameBitvector *key_name = name_GetContentName(prefix);
+ uint32_t key_prefix_len = nameBitvector_GetLength(key_name);
- //if prefix len is 0 it must be stored in the root.
- //if the root entry is null we need to create it, otherwise
- //we just need to add an other nexthop
- if(nameBitvector_GetLength(name) == 0){
- return fib->root->entry;
- }
+ FibNode * curr = fib->root;
- // 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
+ while(curr != NULL){
+ NameBitvector *curr_name =
+ name_GetContentName(fibEntry_GetPrefix(curr->entry));
+ uint32_t match_len = nameBitvector_lpm(key_name, curr_name);
+ uint32_t curr_prefix_len = nameBitvector_GetLength(curr_name);
- FibNode *prev = fib->root;
- FibNode *curr;
+ if(match_len < curr_prefix_len){
+ //the current node does not match completelly the key, so
+ //the key is not in the trie
+ //this implies curr_prefix_len > key_prefix_len
+ return NULL;
+ }
- if (nameBitvector_testBit(name, MSB_POS))
- curr = fib->root->right;
- else
- curr = fib->root->left;
+ if(curr_prefix_len == key_prefix_len){ //== match_len
+ //this is an exact match
+ if(curr->is_used){
+ //we found the key
+ return curr->entry;
+ }else{
+ //the key does not exists
+ return NULL;
+ }
+ }
- while (prev->pos > curr->pos) {
- prev = curr;
+ bool bit;
+ int res = nameBitvector_testBit(key_name, curr_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_contains)");
- if (nameBitvector_testBit(name, curr->pos)) {
+ if(bit)
curr = curr->right;
- } else {
+ else
curr = curr->left;
- }
}
- if (curr->entry != NULL && curr->pos != NULL_POS &&
- nameBitvector_Equals(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)))) {
- return curr->entry;
- } else {
- return NULL;
- }
+ return NULL;
}
-void _removeNode(FIB *fib, const Name *prefix) {
+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 *key_name = name_GetContentName(prefix);
+ uint32_t key_prefix_len = nameBitvector_GetLength(key_name);
- NameBitvector *name = name_GetContentName(prefix);
+ FibNode * curr = fib->root;
+ FibNode * parent = NULL;
+ FibNode * grandpa = NULL;
- if (nameBitvector_testBit(name, MSB_POS)) {
- curr = fib->root->right;
- } else {
- curr = fib->root->left;
- }
+ uint32_t match_len;
+ uint32_t curr_prefix_len;
+ while(curr != NULL){
+ NameBitvector *curr_name =
+ name_GetContentName(fibEntry_GetPrefix(curr->entry));
+ match_len = nameBitvector_lpm(key_name, curr_name);
+ curr_prefix_len = nameBitvector_GetLength(curr_name);
+
+ if(match_len < curr_prefix_len ||
+ curr_prefix_len == key_prefix_len){
+ break;
+ }
- // in the first loop we always search the node to remove
- while (prev->pos > curr->pos) {
- grand = prev;
- prev = curr;
+ grandpa = parent;
+ parent = curr;
- if (nameBitvector_testBit(name, curr->pos)) {
+ bool bit;
+ int res = nameBitvector_testBit(key_name, curr_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (_removeNode)");
+
+ if(bit)
curr = curr->right;
- } else {
+ else
curr = curr->left;
- }
}
- if (!nameBitvector_Equals(
- name, name_GetContentName(fibEntry_GetPrefix(curr->entry)))) {
- // the node does not exists
+ if(curr == NULL ||
+ !curr->is_used ||
+ (curr_prefix_len != key_prefix_len)){
+ //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;
- }
+ //curr has 2 children, leave it there and mark it as inner
+ if(curr->right != NULL && curr->left != NULL){
+ curr->is_used = false;
+ fib->size--;
+ return;
}
- // 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;
+ //curr has no children
+ if(curr->right == NULL && curr->left == NULL){
+ if (parent == NULL){
+ //curr is the root and is the only node in the fib
+ fib->root = NULL;
+ fib->size--;
+ _destroyNode(curr);
+ return;
}
-
- if (nameBitvector_testBit(name, tmpPrev->pos)) {
- tmpPrev->right = next;
- } else {
- tmpPrev->left = next;
+ if(grandpa == NULL){
+ //parent is the root
+ if(fib->root->left == curr)
+ fib->root->left = NULL;
+ else
+ fib->root->right = NULL;
+ fib->size--;
+ _destroyNode(curr);
+ return;
}
+ if(!parent->is_used){
+ //parent is an inner node
+ //remove curr and inner_node (parent), connect the other child
+ //of the parent to the grandpa
+ FibNode * tmp;
+ if(parent->right == curr)
+ tmp = parent->left;
+ else
+ tmp = parent->right;
+
+ if(grandpa->right == parent)
+ grandpa->right = tmp;
+ else
+ grandpa->left = tmp;
- } 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;
+ fib->size--;
+ _destroyNode(curr);
+ _destroyNode(parent);
+ return;
}
+ //parent is node not an inner_node
+ //just remove curr the node
+ if(parent->right == curr)
+ parent->right = NULL;
+ else
+ parent->left = NULL;
+ fib->size--;
+ _destroyNode(curr);
+ return;
+ }
- if (nameBitvector_testBit(name, grand->pos)) {
- grand->right = next;
- } else {
- grand->left = next;
+ //curr has one child
+ if(curr->right != NULL || curr->left != NULL){
+ if(parent == NULL){
+ //curr is the root
+ if(fib->root->right != NULL)
+ fib->root = fib->root->right;
+ else
+ fib->root = fib->root->left;
+ fib->size--;
+ _destroyNode(curr);
+ return;
}
+ //attach the child of curr to parent
+ FibNode * tmp;
+ if(curr->right != NULL)
+ tmp = curr->right;
+ else
+ tmp = curr->left;
- if (nameBitvector_testBit(name, tmpPrev->pos)) {
- tmpPrev->right = prev;
- } else {
- tmpPrev->left = prev;
- }
+ if(parent->right == curr)
+ parent->right = tmp;
+ else
+ parent->left = tmp;
- prev->left = curr->left;
- prev->right = curr->right;
- prev->pos = curr->pos;
+ fib->size--;
+ _destroyNode(curr);
+ return;
}
-
- fib->size--;
- _destroyNode(curr);
}
void fib_Remove(FIB *fib, const Name *name, unsigned connId) {
@@ -346,60 +424,34 @@ void fib_Remove(FIB *fib, const Name *name, unsigned connId) {
}
fibEntry_RemoveNexthopByConnectionId(entry, connId);
- if (fibEntry_NexthopCount(entry) == 0) {
- //if the len is 0, just release the fibEntry on the root node
- if(nameBitvector_GetLength(
- name_GetContentName(fibEntry_GetPrefix(entry))) == 0){
- parcAssertTrue(entry == fib->root->entry,
- "prefix len == 0, entry is not in the FIB root");
- fib->size--;
- fibEntry_Release(&entry);
- fib->root->entry = NULL;
- } else {
- _removeNode(fib, name);
- }
- }
+ if (fibEntry_NexthopCount(entry) == 0)
+ _removeNode(fib, name);
+
}
-void _removeConnectionId(FibNode *n, unsigned pos, unsigned connectionId,
+void _removeConnectionId(FibNode *n, unsigned connectionId,
FibEntryList *list) {
- if (n->pos < pos) {
- fibEntry_RemoveNexthopByConnectionId(n->entry, connectionId);
- if (fibEntry_NexthopCount(n->entry) == 0) {
- fibEntryList_Append(list, n->entry);
+ if(n != NULL){
+ if(n->is_used){
+ 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);
+ _removeConnectionId(n->right, connectionId, list);
+ _removeConnectionId(n->left, connectionId, list);
}
}
void fib_RemoveConnectionId(FIB *fib, unsigned connectionId) {
parcAssertNotNull(fib, "Parameter must be non-null");
- // 0 - remove the connection id from the root
- // 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
-
- if(fib->root->entry){
- fibEntry_RemoveNexthopByConnectionId(fib->root->entry, connectionId);
- if(fibEntry_NexthopCount(fib->root->entry) == 0){
- fib->size--;
- fibEntry_Release(&fib->root->entry);
- fib->root->entry = NULL;
- }
- }
-
- FibEntryList *list = fibEntryList_Create();
-
- _removeConnectionId(fib->root->left, fib->root->pos, connectionId, list);
- _removeConnectionId(fib->root->right, fib->root->pos, connectionId, list);
+ FibEntryList *list = fibEntryList_Create();
+ _removeConnectionId(fib->root, 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) {
@@ -407,143 +459,82 @@ size_t fib_Length(const FIB *fib) {
return fib->size;
}
-FibEntry *fib_Match(const FIB *fib, const Message *interestMessage) {
+FibEntry *fib_MatchMessage(const FIB *fib, const Message *interestMessage) {
parcAssertNotNull(fib, "Parameter must be non-null");
parcAssertNotNull(interestMessage, "Parameter must be non-null");
+ return fib_MatchBitvector(fib, name_GetContentName(
+ message_GetName(interestMessage)));
+}
- 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 && curr->pos != NULL_POS) {
- 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 && curr->pos != NULL_POS) {
- 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 {
- //if there is a default route, return it.
- //the dafualt route is in the route
- return fib->root->entry;
- }
+FibEntry *fib_MatchName(const FIB *fib, const Name *name) {
+ parcAssertNotNull(fib, "Parameter must be non-null");
+ parcAssertNotNull(name, "Parameter must be non-null");
+ return fib_MatchBitvector(fib, name_GetContentName(name));
}
-#ifdef WITH_MAPME
-FibEntry *fib_LPM(const FIB *fib, const Name * prefix) {
+FibEntry *fib_MatchBitvector(const FIB *fib, const NameBitvector *name){
parcAssertNotNull(fib, "Parameter must be non-null");
- parcAssertNotNull(prefix, "Parameter must be non-null");
+ parcAssertNotNull(name, "Parameter must be non-null");
- NameBitvector *name = name_GetContentName(prefix);
+ uint32_t key_prefix_len = nameBitvector_GetLength(name);
- FibNode *prev = fib->root;
- FibNode *curr;
+ FibNode * curr = fib->root;
+ FibNode * candidate = NULL;
- FibNode *match = NULL;
- unsigned len = 0;
+ while(curr != NULL){
+ NameBitvector *curr_name =
+ name_GetContentName(fibEntry_GetPrefix(curr->entry));
+ uint32_t match_len = nameBitvector_lpm(name, curr_name);
+ uint32_t curr_prefix_len = nameBitvector_GetLength(curr_name);
- if (nameBitvector_testBit(name, MSB_POS))
- curr = fib->root->right;
- else
- curr = fib->root->left;
+ if(match_len < curr_prefix_len){
+ //the current node does not match completelly the key, so
+ //return the parent of this node (saved in candidate)
+ break;
+ }
- while (prev->pos > curr->pos) {
- prev = curr;
+ if(curr->is_used)
+ candidate = curr;
- if (curr->entry != NULL && curr->pos != NULL_POS) {
- 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 we are here match_len == curr_prefix_len (can't be larger)
+ //so this node is actually a good candidate for a match
+ if(curr_prefix_len == key_prefix_len){
+ //this an exact match, do not continue
+ break;
}
- if (nameBitvector_testBit(name, curr->pos))
+ bool bit;
+ int res = nameBitvector_testBit(name, curr_prefix_len, &bit);
+ parcAssertFalse(res < 0, "error testing name bit (fib_MatchBitvector)");
+
+ if(bit)
curr = curr->right;
else
curr = curr->left;
}
- if (curr->entry != NULL && curr->pos != NULL_POS) {
- 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(candidate != NULL){
+ return candidate->entry;
}
- if (match != NULL && match->entry != NULL) {
- return match->entry;
- } else {
- //if there is a default route, return it.
- //the dafualt route is in the route
- return fib->root->entry;
- }
+ return NULL;
}
-#endif /* WITH_MAPME */
-
-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);
+void _collectFibEntries(FibNode *n, FibEntryList *list){
+ if(n != NULL){
+ if(n->is_used)
+ fibEntryList_Append(list, n->entry);
+ _collectFibEntries(n->right, list);
+ _collectFibEntries(n->left, list);
}
}
FibEntryList *fib_GetEntries(const FIB *fib) {
parcAssertNotNull(fib, "Parameter must be non-null");
-
FibEntryList *list = fibEntryList_Create();
- if(fib->root->entry){
- fibEntryList_Append(list, fib->root->entry);
- }
-
- _collectFibEntries(fib->root->left, fib->root->pos, list);
- _collectFibEntries(fib->root->right, fib->root->pos, list);
+ _collectFibEntries(fib->root, list);
return list;
}
diff --git a/hicn-light/src/hicn/processor/fib.h b/hicn-light/src/hicn/processor/fib.h
index 8c03537fe..7507bb85c 100644
--- a/hicn-light/src/hicn/processor/fib.h
+++ b/hicn-light/src/hicn/processor/fib.h
@@ -35,11 +35,9 @@ void fib_Remove(FIB *fib, const Name *prefix, unsigned connId);
void fib_RemoveConnectionId(FIB *fib, unsigned connectionId);
-FibEntry *fib_Match(const FIB *fib, const Message *interestMessage);
-
-#ifdef WITH_MAPME
-FibEntry *fib_LPM(const FIB *fib, const Name * name);
-#endif /* WITH_MAPME */
+FibEntry *fib_MatchMessage(const FIB *fib, const Message *interestMessage);
+FibEntry *fib_MatchName(const FIB *fib, const Name *name);
+FibEntry *fib_MatchBitvector(const FIB *fib, const NameBitvector *name);
size_t fib_Length(const FIB *fib);
diff --git a/hicn-light/src/hicn/processor/fibEntry.c b/hicn-light/src/hicn/processor/fibEntry.c
index 15d754168..9d82b086e 100644
--- a/hicn-light/src/hicn/processor/fibEntry.c
+++ b/hicn-light/src/hicn/processor/fibEntry.c
@@ -72,7 +72,6 @@ struct fib_entry {
#ifdef WITH_POLICY
FibEntry *fibEntry_Create(Name *name, strategy_type fwdStrategy, const Forwarder * forwarder) {
- ConnectionTable * table = forwarder_GetConnectionTable(forwarder);
#else
FibEntry *fibEntry_Create(Name *name, strategy_type fwdStrategy) {
#endif /* WITH_POLICY */
@@ -84,47 +83,31 @@ FibEntry *fibEntry_Create(Name *name, strategy_type fwdStrategy) {
if (fwdStrategy) {
switch (fwdStrategy) {
case SET_STRATEGY_LOADBALANCER:
-#ifdef WITH_POLICY
- fibEntry->fwdStrategy = strategyLoadBalancer_Create(table);
-#else
fibEntry->fwdStrategy = strategyLoadBalancer_Create();
-#endif /* WITH_POLICY */
+ break;
+
+ case SET_STRATEGY_RANDOM:
+ fibEntry->fwdStrategy = strategyRnd_Create();
break;
case SET_STRATEGY_RANDOM_PER_DASH_SEGMENT:
-#ifdef WITH_POLICY
- fibEntry->fwdStrategy = strategyRndSegment_Create(table);
-#else
fibEntry->fwdStrategy = strategyRndSegment_Create();
-#endif /* WITH_POLICY */
break;
case SET_STRATEGY_LOADBALANCER_WITH_DELAY:
-#ifdef WITH_POLICY
- fibEntry->fwdStrategy = strategyLoadBalancerWithPD_Create(table);
-#else
fibEntry->fwdStrategy = strategyLoadBalancerWithPD_Create();
-#endif /* WITH_POLICY */
break;
default:
// LB is the default strategy
-#ifdef WITH_POLICY
- fibEntry->fwdStrategy = strategyLoadBalancer_Create(table);
-#else
fibEntry->fwdStrategy = strategyLoadBalancer_Create();
-#endif /* WITH_POLICY */
// the LB strategy is the default one
// other strategies can be set using the appropiate function
break;
}
} else {
-#ifdef WITH_POLICY
- fibEntry->fwdStrategy = strategyLoadBalancer_Create(table);
-#else
fibEntry->fwdStrategy = strategyLoadBalancer_Create();
-#endif /* WITH_POLICY */
}
fibEntry->refcount = 1;
@@ -173,42 +156,27 @@ void fibEntry_Release(FibEntry **fibEntryPtr) {
void fibEntry_SetStrategy(FibEntry *fibEntry, strategy_type strategy) {
StrategyImpl *fwdStrategyImpl;
-#ifdef WITH_POLICY
- ConnectionTable * table = forwarder_GetConnectionTable(fibEntry->forwarder);
-#endif /* WITH_POLICY */
switch (strategy) {
case SET_STRATEGY_LOADBALANCER:
-#ifdef WITH_POLICY
- fwdStrategyImpl = strategyLoadBalancer_Create(table);
-#else
fwdStrategyImpl = strategyLoadBalancer_Create();
-#endif /* WITH_POLICY */
+ break;
+
+ case SET_STRATEGY_RANDOM:
+ fwdStrategyImpl = strategyRnd_Create();
break;
case SET_STRATEGY_RANDOM_PER_DASH_SEGMENT:
-#ifdef WITH_POLICY
- fwdStrategyImpl = strategyRndSegment_Create(table);
-#else
fwdStrategyImpl = strategyRndSegment_Create();
-#endif /* WITH_POLICY */
break;
case SET_STRATEGY_LOADBALANCER_WITH_DELAY:
-#ifdef WITH_POLICY
- fwdStrategyImpl = strategyLoadBalancerWithPD_Create(table);
-#else
fwdStrategyImpl = strategyLoadBalancerWithPD_Create();
-#endif /* WITH_POLICY */
break;
default:
// LB is the defualt strategy
-#ifdef WITH_POLICY
- fwdStrategyImpl = strategyLoadBalancer_Create(table);
-#else
fwdStrategyImpl = strategyLoadBalancer_Create();
-#endif /* WITH_POLICY */
// the LB strategy is the default one
// other strategies can be set using the appropiate function
break;
diff --git a/hicn-light/src/hicn/processor/messageProcessor.c b/hicn-light/src/hicn/processor/messageProcessor.c
index 7e0ece257..456618269 100644
--- a/hicn-light/src/hicn/processor/messageProcessor.c
+++ b/hicn-light/src/hicn/processor/messageProcessor.c
@@ -34,9 +34,7 @@
#include <hicn/content_store/contentStoreLRU.h>
#include <hicn/strategies/loadBalancer.h>
-#ifndef WITH_POLICY
#include <hicn/strategies/loadBalancerWithPD.h>
-#endif /* ! WITH_POLICY */
#include <hicn/strategies/rnd.h>
#include <hicn/strategies/rndSegment.h>
#include <hicn/strategies/strategyImpl.h>
@@ -311,16 +309,14 @@ bool messageProcessor_AddOrUpdateRoute(MessageProcessor *processor,
Name *prefix = name_CreateFromAddress(control->addressType, control->address,
control->len);
FibEntry *entry = fib_Contains(processor->fib, prefix);
-#ifndef WITH_POLICY
bool newEntry = false;
-#endif /* ! WITH_POLICY */
if (entry != NULL) {
fibEntry_AddNexthop(entry, ifidx);
} else {
+ newEntry = true;
#ifdef WITH_POLICY
entry = fibEntry_Create(prefix, fwdStrategy, processor->forwarder);
#else
- newEntry = true;
entry = fibEntry_Create(prefix, fwdStrategy);
#endif /* WITH_POLICY */
fibEntry_AddNexthop(entry, ifidx);
@@ -329,7 +325,6 @@ bool messageProcessor_AddOrUpdateRoute(MessageProcessor *processor,
name_Release(&prefix);
-#ifndef WITH_POLICY
/* For policy implementation, we need access to the ConnectionTable in all
* Forwarding Strategies, so it is setup during FIB Entry creation */
if (newEntry && (fwdStrategy == SET_STRATEGY_LOADBALANCER_WITH_DELAY)) {
@@ -337,7 +332,6 @@ bool messageProcessor_AddOrUpdateRoute(MessageProcessor *processor,
fibEntry_GetFwdStrategy(entry),
forwarder_GetConnectionTable(processor->forwarder));
}
-#endif /* ! WITH_POLICY */
return true;
}
@@ -421,14 +415,12 @@ void processor_SetStrategy(MessageProcessor *processor, Name *prefix,
strategy_type strategy) {
FibEntry *entry = fib_Contains(processor->fib, prefix);
if (entry != NULL) {
-#ifndef WITH_POLICY
fibEntry_SetStrategy(entry, strategy);
if (strategy == SET_STRATEGY_LOADBALANCER_WITH_DELAY) {
strategyLoadBalancerWithPD_SetConnectionTable(
fibEntry_GetFwdStrategy(entry),
forwarder_GetConnectionTable(processor->forwarder));
}
-#endif /* ! WITH_POLICY */
}
}
@@ -584,7 +576,7 @@ static bool messageProcessor_ForwardViaFib(MessageProcessor *processor,
static bool messageProcessor_ForwardViaFib(MessageProcessor *processor,
Message *interestMessage) {
#endif /* WITH_POLICY */
- FibEntry *fibEntry = fib_Match(processor->fib, interestMessage);
+ FibEntry *fibEntry = fib_MatchMessage(processor->fib, interestMessage);
if (fibEntry == NULL) {
return false;
}
diff --git a/hicn-light/src/hicn/strategies/loadBalancerWithPD.c b/hicn-light/src/hicn/strategies/loadBalancerWithPD.c
index b0aae4cbb..dac759053 100644
--- a/hicn-light/src/hicn/strategies/loadBalancerWithPD.c
+++ b/hicn-light/src/hicn/strategies/loadBalancerWithPD.c
@@ -88,11 +88,7 @@ struct strategy_load_balancer_with_pd {
unsigned int fwdPackets;
};
-#ifdef WITH_POLICY
-StrategyImpl *strategyLoadBalancerWithPD_Create(const ConnectionTable *table) {
-#else
StrategyImpl *strategyLoadBalancerWithPD_Create() {
-#endif /* WITH_POLICY */
StrategyLoadBalancerWithPD *strategy =
parcMemory_AllocateAndClear(sizeof(StrategyLoadBalancerWithPD));
parcAssertNotNull(strategy, "parcMemory_AllocateAndClear(%zu) returned NULL",
diff --git a/hicn-light/src/hicn/strategies/loadBalancerWithPD.h b/hicn-light/src/hicn/strategies/loadBalancerWithPD.h
index e6c9f8271..a6ad94ab8 100644
--- a/hicn-light/src/hicn/strategies/loadBalancerWithPD.h
+++ b/hicn-light/src/hicn/strategies/loadBalancerWithPD.h
@@ -24,11 +24,7 @@
#include <hicn/strategies/strategyImpl.h>
#include <hicn/core/connectionTable.h>
-#ifdef WITH_POLICY
-StrategyImpl *strategyLoadBalancerWithPD_Create(const ConnectionTable * table);
-#else
StrategyImpl *strategyLoadBalancerWithPD_Create();
-#endif /* WITH_POLICY */
void strategyLoadBalancerWithPD_SetConnectionTable(StrategyImpl *strategy,
ConnectionTable *connTable);
diff --git a/hicn-plugin/CMakeLists.txt b/hicn-plugin/CMakeLists.txt
index 8c859cdd9..15df64952 100644
--- a/hicn-plugin/CMakeLists.txt
+++ b/hicn-plugin/CMakeLists.txt
@@ -176,7 +176,7 @@ set(HICN_API_TEST_SOURCE_FILES
src/hicn_api_test.c
src/error.c)
-set(HICN_API_TEST_HEADER_FILES
+set(HICN_API_HEADER_FILES
src/hicn_msg_enum.h
src/hicn_all_api_h.h
src/hicn_api.h
@@ -209,9 +209,9 @@ endif()
execute_process(COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/hicn)
# These files are missing from vpp binary distribution
execute_process(
- COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_json_parser.py?h=stable/1901 -o ${CMAKE_BINARY_DIR}/vapi_json_parser.py
- COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_c_gen.py?h=stable/1901 -o ${CMAKE_BINARY_DIR}/vapi_c_gen.py
- COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_cpp_gen.py?h=stable/1901 -o ${CMAKE_BINARY_DIR}/vapi_cpp_gen.py
+ COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_json_parser.py?h=stable/1908 -o ${CMAKE_BINARY_DIR}/vapi_json_parser.py
+ COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_c_gen.py?h=stable/1908 -o ${CMAKE_BINARY_DIR}/vapi_c_gen.py
+ COMMAND curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_cpp_gen.py?h=stable/1908 -o ${CMAKE_BINARY_DIR}/vapi_cpp_gen.py
)
add_custom_command(
@@ -237,7 +237,7 @@ add_library(hicn_plugin SHARED
${HICN_API_GENERATED_FILES}
${HICN_VAPI_GENERATED_FILES})
-file(COPY ${HICN_API_TEST_HEADER_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn)
+file(COPY ${HICN_API_HEADER_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins)
file(COPY ${LIBHICN_HEADER_FILES_SRC} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn)
@@ -275,10 +275,10 @@ install(TARGETS hicn_api_test_plugin
DESTINATION ${VPP_INSTALL_API_TEST_PLUGIN}
COMPONENT ${HICN_PLUGIN})
-install(FILES ${HICN_API_TEST_HEADER_FILES} ${HICN_API_GENERATED_FILES}
+install(FILES ${HICN_API_HEADER_FILES} ${HICN_API_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn
- COMPONENT ${HICN_PLUGIN})
+ COMPONENT ${HICN_PLUGIN}-dev)
install(FILES ${HICN_VAPI_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vapi
- COMPONENT ${HICN_PLUGIN})
+ COMPONENT ${HICN_PLUGIN}-dev)
diff --git a/hicn-plugin/README.md b/hicn-plugin/README.md
index 2208f5ada..5da8d6a5b 100644
--- a/hicn-plugin/README.md
+++ b/hicn-plugin/README.md
@@ -45,7 +45,6 @@ $ sudo make install
CMAKE variables:
- CMAKE_INSTALL_PREFIX -- set the install directory for the hicn-plugin. This is the common path to the lib folder containing vpp_plugins and vpp_api_test_plugins folders. Default is /usr/local.
- VPP_HOME -- set the directory containing the include and lib directories of vpp.
-- HICN_API_TEST_HEADER_FILES -- set the install directory for the header files. Default is <vpp install dir>/include/vpp_plugins/hicn
```
## Using hICN plugin ##
@@ -65,14 +64,14 @@ hICN-plugin has been tested in:
Build dependencies:
-- VPP 19.04
+- VPP 19.08
- DEB packages (can be found https://packagecloud.io/fdio/release/install):
- libvppinfra-dev
- vpp-dev
Running dependencies:
-- VPP 19.04
+- VPP 19.08
- DEB packages (can be found https://packagecloud.io/fdio/release/install):
- vpp
- vpp-plugin-core
@@ -210,9 +209,9 @@ hicn face app {add intfc <sw_if> {prod prefix <hicn_prefix> cs_size <size_in_pac
`hicn face ip`: manipulates ip application faces in the forwarder.
```
-hicn face ip {add local <src_address> remote <dst_address> intfc <sw_if>} | {del id <face_id>}
- <src_address> :the IPv4 or IPv6 local IP address to bind to
- <dst_address> :the IPv4 or IPv6 address of the remote system
+hicn face ip {add [local <src_address>] remote <dst_address> intfc <sw_if>} | {del id <face_id>}
+ <src_address> :the IPv4 or IPv6 local IP address to bind to (not mandatory, if not specified the local address is one of the address assigned to sw_if)
+ <dst_address> :the IPv4 or IPv6 address of the remote system
<sw_if> :software interface on thop of which we create the face
<face_id> :id of the face to remove
```
diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h
index c001e5af5..55434a024 100644
--- a/hicn-plugin/src/data_fwd.h
+++ b/hicn-plugin/src/data_fwd.h
@@ -83,7 +83,7 @@ vlib_buffer_clone_256_2 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
vlib_buffer_t *d = vlib_get_buffer (vm, buffers[i]);
d->current_data = s->current_data;
d->current_length = head_end_offset;
- d->trace_index = s->trace_index;
+ d->trace_handle = s->trace_handle;
d->total_length_not_including_first_buffer = s->current_length -
head_end_offset;
@@ -94,7 +94,7 @@ vlib_buffer_clone_256_2 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
}
d->flags = s->flags | VLIB_BUFFER_NEXT_PRESENT;
d->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
- d->trace_index = s->trace_index;
+ d->trace_handle = s->trace_handle;
clib_memcpy_fast (d->opaque, s->opaque, sizeof (s->opaque));
clib_memcpy_fast (d->opaque2, s->opaque2, sizeof (s->opaque2));
clib_memcpy_fast (vlib_buffer_get_current (d),
diff --git a/hicn-plugin/src/strategy.c b/hicn-plugin/src/strategy.c
index 747e155b1..a6c058e4f 100644
--- a/hicn-plugin/src/strategy.c
+++ b/hicn-plugin/src/strategy.c
@@ -186,7 +186,7 @@ hicn_forward_interest_fn (vlib_main_t * vm,
vlib_buffer_t *b1;
b1 = vlib_get_buffer (vm, from[1]);
CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (&b1->trace_index, 2 * CLIB_CACHE_LINE_BYTES,
+ CLIB_PREFETCH (&b1->trace_handle, 2 * CLIB_CACHE_LINE_BYTES,
STORE);
}
/* Dequeue a packet buffer */
diff --git a/lib/src/name.c b/lib/src/name.c
index ba5ff85b5..0a0da63cf 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -82,28 +82,22 @@ hicn_name_create_from_ip_address (const ip_address_t * ip_address, u32 id,
switch (ip_address->family)
{
case AF_INET:
- if (name->type == HNT_UNSPEC)
- {
- name->type = HNT_CONTIGUOUS_V4;
- }
+ name->type = HNT_CONTIGUOUS_V4;
break;
case AF_INET6:
- if (name->type == HNT_UNSPEC)
- {
- name->type = HNT_CONTIGUOUS_V6;
- }
+ name->type = HNT_CONTIGUOUS_V6;
break;
default:
return HICN_LIB_ERROR_INVALID_IP_ADDRESS;
}
- name->len = (u8) (ip_address->prefix_len);
+ name->len = (u8) ip_address_len (ip_address);
if ((name->type != HNT_CONTIGUOUS_V4) && (name->type != HNT_CONTIGUOUS_V6))
{
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
}
- memcpy (name->buffer, ip_address->buffer, ip_address_len (ip_address));
+ memcpy (name->buffer, ip_address->buffer, name->len);
*(u32 *) (name->buffer + name->len) = id;
return HICN_LIB_ERROR_NONE;
diff --git a/libtransport/src/hicn/transport/CMakeLists.txt b/libtransport/src/hicn/transport/CMakeLists.txt
index 76fcd072b..5fe101c18 100644
--- a/libtransport/src/hicn/transport/CMakeLists.txt
+++ b/libtransport/src/hicn/transport/CMakeLists.txt
@@ -57,6 +57,7 @@ endif ()
if (ANDROID_API)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -isystem -lm")
endif()
+
if (ANDROID_API)
build_library(${LIBTRANSPORT}
STATIC
diff --git a/libtransport/src/hicn/transport/core/memif_connector.cc b/libtransport/src/hicn/transport/core/memif_connector.cc
index a77f14839..43dfab345 100644
--- a/libtransport/src/hicn/transport/core/memif_connector.cc
+++ b/libtransport/src/hicn/transport/core/memif_connector.cc
@@ -139,14 +139,22 @@ int MemifConnector::createMemif(uint32_t index, uint8_t mode, char *s) {
args.num_m2s_rings = 1;
strncpy((char *)args.interface_name, IF_NAME, strlen(IF_NAME) + 1);
args.mode = memif_interface_mode_t::MEMIF_INTERFACE_MODE_IP;
- args.socket_filename = (uint8_t *)socket_filename_.c_str();
- TRANSPORT_LOGD("Socket filename: %s", args.socket_filename);
+ int err;
+
+ err= memif_create_socket (&args.socket, socket_filename_.c_str(),
+ nullptr);
+
+ if (TRANSPORT_EXPECT_FALSE(err != MEMIF_ERR_SUCCESS)) {
+ throw errors::RuntimeException(memif_strerror(err));
+ }
+
+ TRANSPORT_LOGD("Socket filename: %s", socket_filename_.c_str());
args.interface_id = index;
/* last argument for memif_create (void * private_ctx) is used by user
to identify connection. this context is returned with callbacks */
- int err;
+
/* default interrupt */
if (s == nullptr) {
err = memif_create(&c->conn, &args, onConnect, onDisconnect, onInterrupt,
@@ -204,7 +212,7 @@ int MemifConnector::deleteMemif() {
return 0;
}
-int MemifConnector::controlFdUpdate(int fd, uint8_t events) {
+int MemifConnector::controlFdUpdate(int fd, uint8_t events, void *private_ctx) {
/* convert memif event definitions to epoll events */
if (events & MEMIF_FD_EVENT_DEL) {
return MemifConnector::main_event_reactor_.delFileDescriptor(fd);
diff --git a/libtransport/src/hicn/transport/core/memif_connector.h b/libtransport/src/hicn/transport/core/memif_connector.h
index ef100e3fb..4f43c97ef 100644
--- a/libtransport/src/hicn/transport/core/memif_connector.h
+++ b/libtransport/src/hicn/transport/core/memif_connector.h
@@ -78,7 +78,7 @@ class MemifConnector : public Connector {
int deleteMemif();
- static int controlFdUpdate(int fd, uint8_t events);
+ static int controlFdUpdate(int fd, uint8_t events, void *private_ctx);
static int onConnect(memif_conn_handle_t conn, void *private_ctx);
diff --git a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
index c726dfda8..6a45019a4 100644
--- a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
+++ b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
@@ -24,8 +24,9 @@
#define INIT_PACKET_PRODUCTION_RATE 100 // pps random value (almost 1Mbps)
#define STATS_INTERVAL_DURATION 500 // ms
#define INTEREST_LIFETIME_REDUCTION_FACTOR 0.8
-#define INACTIVE_TIME 500 //ms without producing before the socket
- //is considered inactive
+#define INACTIVE_TIME \
+ 500 // ms without producing before the socket
+ // is considered inactive
#define MILLI_IN_A_SEC 1000 // ms in a second
// NACK HEADER
@@ -113,7 +114,9 @@ void RTCProducerSocket::updateStats(uint32_t packet_size, uint64_t now) {
}
}
-void RTCProducerSocket::produce(const uint8_t *buf, size_t buffer_size) {
+void RTCProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) {
+ auto buffer_size = buffer->length();
+
if (TRANSPORT_EXPECT_FALSE(buffer_size == 0)) {
return;
}
@@ -137,11 +140,11 @@ void RTCProducerSocket::produce(const uint8_t *buf, size_t buffer_size) {
ContentObject content_object(flowName_.setSuffix(currentSeg_));
- auto payload = utils::MemBuf::create(buffer_size + TIMESTAMP_LEN);
+ auto payload = utils::MemBuf::create(TIMESTAMP_LEN);
memcpy(payload->writableData(), &now, TIMESTAMP_LEN);
- memcpy(payload->writableData() + TIMESTAMP_LEN, buf, buffer_size);
- payload->append(buffer_size + TIMESTAMP_LEN);
+ payload->append(TIMESTAMP_LEN);
+ payload->prependChain(std::move(buffer));
content_object.appendPayload(std::move(payload));
content_object.setLifetime(500); // XXX this should be set by the APP
@@ -169,14 +172,14 @@ void RTCProducerSocket::onInterest(Interest::Ptr &&interest) {
{
utils::SpinLock::Acquire locked(lock_);
isActive = active_;
- if(isActive){
+ if (isActive) {
uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count();
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
if ((now - lastProduced_) > INACTIVE_TIME) {
- //socket is inactive
+ // socket is inactive
active_ = false;
- isActive = false;
+ isActive = false;
}
}
}
diff --git a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
index 29fd15a4e..5b9a23dd7 100644
--- a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
+++ b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
@@ -36,7 +36,7 @@ class RTCProducerSocket : public ProducerSocket {
void registerPrefix(const Prefix &producer_namespace) override;
- void produce(const uint8_t *buffer, size_t buffer_size) override;
+ void produce(std::unique_ptr<utils::MemBuf> &&buffer) override;
void onInterest(Interest::Ptr &&interest) override;
diff --git a/libtransport/src/hicn/transport/interfaces/socket_producer.h b/libtransport/src/hicn/transport/interfaces/socket_producer.h
index cd1c5a374..18adbf4a7 100644
--- a/libtransport/src/hicn/transport/interfaces/socket_producer.h
+++ b/libtransport/src/hicn/transport/interfaces/socket_producer.h
@@ -62,6 +62,10 @@ class ProducerSocket : public Socket<BasePortal>,
void produce(ContentObject &content_object);
virtual void produce(const uint8_t *buffer, size_t buffer_size) {
+ produce(utils::MemBuf::copyBuffer(buffer, buffer_size));
+ }
+
+ virtual void produce(std::unique_ptr<utils::MemBuf> &&buffer) {
// This API is meant to be used just with the RTC producer.
// Here it cannot be used since no name for the content is specified.
throw errors::NotImplementedException();
diff --git a/scripts/build-packages.sh b/scripts/build-packages.sh
index aeb356e20..45e2ddf92 100644
--- a/scripts/build-packages.sh
+++ b/scripts/build-packages.sh
@@ -22,10 +22,10 @@ PACKAGECLOUD_RELEASE_REPO_DEB="https://packagecloud.io/install/repositories/fdio
PACKAGECLOUD_RELEASE_REPO_RPM="https://packagecloud.io/install/repositories/fdio/release/script.rpm.sh"
VPP_GIT_REPO="https://git.fd.io/vpp"
-VPP_BRANCH="stable/1904"
+VPP_BRANCH="stable/1908"
-VPP_VERSION_DEB="19.04.2-release"
-VPP_VERSION_RPM="19.04.2-release.x86_64"
+VPP_VERSION_DEB="19.08-release"
+VPP_VERSION_RPM="19.08-release.x86_64"
BUILD_TOOLS_UBUNTU="build-essential doxygen"
LIBSSL_LIBEVENT_UBUNTU="libevent-dev libssl-dev"
diff --git a/scripts/build-sysrepo.sh b/scripts/build-sysrepo.sh
index 4192f7e12..7d83cac14 100644
--- a/scripts/build-sysrepo.sh
+++ b/scripts/build-sysrepo.sh
@@ -23,10 +23,10 @@ PACKAGECLOUD_RELEASE_REPO_DEB="https://packagecloud.io/install/repositories/fdio
PACKAGECLOUD_RELEASE_REPO_RPM="https://packagecloud.io/install/repositories/fdio/release/script.rpm.sh"
VPP_GIT_REPO="https://git.fd.io/vpp"
-VPP_BRANCH="stable/1901"
+VPP_BRANCH="stable/1908"
-VPP_VERSION_DEB="19.04-release"
-VPP_VERSION_RPM="19.04-release.x86_64"
+VPP_VERSION_DEB="19.08-release"
+VPP_VERSION_RPM="19.08-release.x86_64"
BUILD_TOOLS_UBUNTU="build-essential doxygen"
LIBSSL_LIBEVENT_UBUNTU="libevent-dev libssl-dev"
diff --git a/utils/extras/README.md b/utils/extras/README.md
new file mode 100644
index 000000000..40363ef18
--- /dev/null
+++ b/utils/extras/README.md
@@ -0,0 +1,49 @@
+# Configure VPP and FRRouting for OSPF6
+This document describes how to configure the VPP with hicn_router plugin and FRR to enable the OSPF protocol. The VPP and FRR
+are configured in a docker file.
+
+## DPDK configuration on host machine:
+
+- Install and configure dpdk
+ - make install T=x86_64-native-linux-gcc && cd x86_64-native-linux-gcc && sudo make install
+ - modprobe uio
+ - modprobe uio_pci_generic
+ - dpdk-devbind --status
+ - the PCIe number of the desired device can be observed ("xxx")
+ - sudo dpdk-devbind -b uio_pci_generic "xxx"
+## VPP configuration:
+
+- Run and configure the VPP (hICN router plugin is required to be installed in VPP)
+ - set int state TenGigabitEtherneta/0/0 up
+ - set int ip address TenGigabitEtherneta/0/0 a001::1/24
+ - create loopback interface
+ - set interface state loop0 up
+ - set interface ip address loop0 b001::1/128
+ - enable tap-inject # This creates the taps by router plugin
+ - show tap-inject # This shows the created taps
+ - ip mroute add ff02::/64 via local Forward # ff02:: is multicast ip address
+ - ip mroute add ff02::/64 via TenGigabitEtherneta/0/0 Accept
+ - ip mroute add ff02::/64 via loop0 Accept
+
+- Setup the tap interface
+ - ip addr add a001::1/24 dev vpp0
+ - ip addr add b001::1/128 dev vpp1
+ - ip link set dev vpp0 up
+ - ip link set dev vpp1 up
+
+## FRR configuration:
+
+- Run and configure FRRouting (ospf)
+ - /usr/lib/frr/frrinit.sh start &
+ - vtysh
+ - configure terminal
+ - router ospf6
+ - area 0.0.0.0 range a001::1/24
+ - area 0.0.0.0 range b001::1/128
+ - interface vpp0 area 0.0.0.0
+ - interface vpp1 area 0.0.0.0
+ - end
+ - wr
+ - add "no ipv6 nd suppress-ra" to the first configurtion part of the /etc/frr/frr.conf
+After the following configuration, the traffic over tap interface can be observered through "tcpdump- i vpp1".
+The neighborhood and route can be seen by the "show ipv6 ospf6 neighbor/route".