aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/core
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light/src/hicn/core')
-rw-r--r--hicn-light/src/hicn/core/CMakeLists.txt12
-rw-r--r--hicn-light/src/hicn/core/address.c4
-rw-r--r--hicn-light/src/hicn/core/address.h4
-rw-r--r--hicn-light/src/hicn/core/address_pair.c6
-rw-r--r--hicn-light/src/hicn/core/address_pair.h6
-rw-r--r--hicn-light/src/hicn/core/connection.c69
-rw-r--r--hicn-light/src/hicn/core/connection.h34
-rw-r--r--hicn-light/src/hicn/core/connection_table.c30
-rw-r--r--hicn-light/src/hicn/core/connection_table.h5
-rw-r--r--hicn-light/src/hicn/core/connection_vft.h4
-rw-r--r--hicn-light/src/hicn/core/fib.c800
-rw-r--r--hicn-light/src/hicn/core/fib.h42
-rw-r--r--hicn-light/src/hicn/core/fib_entry.c98
-rw-r--r--hicn-light/src/hicn/core/fib_entry.h57
-rw-r--r--hicn-light/src/hicn/core/forwarder.c679
-rw-r--r--hicn-light/src/hicn/core/forwarder.h35
-rw-r--r--hicn-light/src/hicn/core/interest_manifest.c64
-rw-r--r--hicn-light/src/hicn/core/interest_manifest.h40
-rw-r--r--hicn-light/src/hicn/core/listener.c36
-rw-r--r--hicn-light/src/hicn/core/listener_table.c4
-rw-r--r--hicn-light/src/hicn/core/listener_table.h10
-rw-r--r--hicn-light/src/hicn/core/mapme.c95
-rw-r--r--hicn-light/src/hicn/core/mapme.h4
-rw-r--r--hicn-light/src/hicn/core/messageHandler.h660
-rw-r--r--hicn-light/src/hicn/core/msgbuf.c36
-rw-r--r--hicn-light/src/hicn/core/msgbuf.h188
-rw-r--r--hicn-light/src/hicn/core/msgbuf_pool.c19
-rw-r--r--hicn-light/src/hicn/core/name.c195
-rw-r--r--hicn-light/src/hicn/core/name.h106
-rw-r--r--hicn-light/src/hicn/core/nameBitvector.c296
-rw-r--r--hicn-light/src/hicn/core/nameBitvector.h66
-rw-r--r--hicn-light/src/hicn/core/nexthops.c29
-rw-r--r--hicn-light/src/hicn/core/nexthops.h23
-rw-r--r--hicn-light/src/hicn/core/packet_cache.c314
-rw-r--r--hicn-light/src/hicn/core/packet_cache.h100
-rw-r--r--hicn-light/src/hicn/core/policy_stats.c19
-rw-r--r--hicn-light/src/hicn/core/strategy_vft.h6
-rw-r--r--hicn-light/src/hicn/core/subscription.c16
38 files changed, 1866 insertions, 2345 deletions
diff --git a/hicn-light/src/hicn/core/CMakeLists.txt b/hicn-light/src/hicn/core/CMakeLists.txt
index 9516a6a72..94295bdf1 100644
--- a/hicn-light/src/hicn/core/CMakeLists.txt
+++ b/hicn-light/src/hicn/core/CMakeLists.txt
@@ -3,7 +3,7 @@
# 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
+# 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,
@@ -21,7 +21,6 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/fib_entry.h
${CMAKE_CURRENT_SOURCE_DIR}/fib.h
${CMAKE_CURRENT_SOURCE_DIR}/forwarder.h
- ${CMAKE_CURRENT_SOURCE_DIR}/interest_manifest.h
${CMAKE_CURRENT_SOURCE_DIR}/listener.h
${CMAKE_CURRENT_SOURCE_DIR}/listener_table.h
${CMAKE_CURRENT_SOURCE_DIR}/listener_vft.h
@@ -34,13 +33,11 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/strategy_vft.h
${CMAKE_CURRENT_SOURCE_DIR}/subscription.h
${CMAKE_CURRENT_SOURCE_DIR}/ticks.h
-# ${CMAKE_CURRENT_SOURCE_DIR}/system.h
+
+ # ${CMAKE_CURRENT_SOURCE_DIR}/system.h
${CMAKE_CURRENT_SOURCE_DIR}/mapme.h
${CMAKE_CURRENT_SOURCE_DIR}/wldr.h
- ${CMAKE_CURRENT_SOURCE_DIR}/messageHandler.h
- ${CMAKE_CURRENT_SOURCE_DIR}/nameBitvector.h
${CMAKE_CURRENT_SOURCE_DIR}/nexthops.h
- ${CMAKE_CURRENT_SOURCE_DIR}/name.h
)
list(APPEND SOURCE_FILES
@@ -53,15 +50,12 @@ list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/fib.c
${CMAKE_CURRENT_SOURCE_DIR}/fib_entry.c
${CMAKE_CURRENT_SOURCE_DIR}/forwarder.c
- ${CMAKE_CURRENT_SOURCE_DIR}/interest_manifest.c
${CMAKE_CURRENT_SOURCE_DIR}/listener.c
${CMAKE_CURRENT_SOURCE_DIR}/listener_table.c
${CMAKE_CURRENT_SOURCE_DIR}/listener_vft.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme.c
${CMAKE_CURRENT_SOURCE_DIR}/msgbuf.c
${CMAKE_CURRENT_SOURCE_DIR}/msgbuf_pool.c
- ${CMAKE_CURRENT_SOURCE_DIR}/nameBitvector.c
- ${CMAKE_CURRENT_SOURCE_DIR}/name.c
${CMAKE_CURRENT_SOURCE_DIR}/nexthops.c
${CMAKE_CURRENT_SOURCE_DIR}/packet_cache.c
${CMAKE_CURRENT_SOURCE_DIR}/pit.c
diff --git a/hicn-light/src/hicn/core/address.c b/hicn-light/src/hicn/core/address.c
index a4b41c8b5..65664fa17 100644
--- a/hicn-light/src/hicn/core/address.c
+++ b/hicn-light/src/hicn/core/address.c
@@ -21,8 +21,8 @@
#include <hicn/core/address.h>
#include <hicn/util/sstrncpy.h>
-int address_from_ip_port(address_t *address, int family, ip_address_t *addr,
- uint16_t port) {
+int address_from_ip_port(address_t *address, int family,
+ hicn_ip_address_t *addr, uint16_t port) {
switch (family) {
case AF_INET:
*address = ADDRESS4(ntohl(addr->v4.as_inaddr.s_addr), ntohs(port));
diff --git a/hicn-light/src/hicn/core/address.h b/hicn-light/src/hicn/core/address.h
index 7958bd063..38cd1e87c 100644
--- a/hicn-light/src/hicn/core/address.h
+++ b/hicn-light/src/hicn/core/address.h
@@ -63,8 +63,8 @@ static inline bool _address6_is_local(struct sockaddr_in6 *sin6) {
((address)->as_ss.ss_family == AF_INET) ? address4_is_local(address) \
: address6_is_local(address)
-int address_from_ip_port(address_t *address, int family, ip_address_t *addr,
- uint16_t port);
+int address_from_ip_port(address_t *address, int family,
+ hicn_ip_address_t *addr, uint16_t port);
static inline address_t ADDRESS4(in_addr_t in_addr, int port) {
address_t address = {
diff --git a/hicn-light/src/hicn/core/address_pair.c b/hicn-light/src/hicn/core/address_pair.c
index facbb8dc4..c4f8b397b 100644
--- a/hicn-light/src/hicn/core/address_pair.c
+++ b/hicn-light/src/hicn/core/address_pair.c
@@ -30,8 +30,10 @@ address_pair_t address_pair_factory(address_t local, address_t remote) {
}
int address_pair_from_ip_port(address_pair_t* pair, int family,
- ip_address_t* local_addr, uint16_t local_port,
- ip_address_t* remote_addr, uint16_t remote_port) {
+ hicn_ip_address_t* local_addr,
+ uint16_t local_port,
+ hicn_ip_address_t* remote_addr,
+ uint16_t remote_port) {
memset(pair, 0, sizeof(*pair));
if (address_from_ip_port(&pair->local, family, local_addr, local_port) < 0)
return -1;
diff --git a/hicn-light/src/hicn/core/address_pair.h b/hicn-light/src/hicn/core/address_pair.h
index 2fd207d34..b2872ad35 100644
--- a/hicn-light/src/hicn/core/address_pair.h
+++ b/hicn-light/src/hicn/core/address_pair.h
@@ -40,8 +40,10 @@ typedef struct {
address_pair_t address_pair_factory(address_t local, address_t remote);
int address_pair_from_ip_port(address_pair_t* pair, int family,
- ip_address_t* local_addr, uint16_t local_port,
- ip_address_t* remote_addr, uint16_t remote_port);
+ hicn_ip_address_t* local_addr,
+ uint16_t local_port,
+ hicn_ip_address_t* remote_addr,
+ uint16_t remote_port);
static inline int address_pair_equals(const address_pair_t* pair1,
const address_pair_t* pair2) {
diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c
index 2108d30af..ff73a9ae8 100644
--- a/hicn-light/src/hicn/core/connection.c
+++ b/hicn-light/src/hicn/core/connection.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -22,8 +22,9 @@
#include <hicn/core/forwarder.h>
#include <hicn/core/listener.h>
-#include <hicn/util/log.h>
#include <hicn/core/wldr.h>
+#include <hicn/policy.h>
+#include <hicn/util/log.h>
#include "connection.h"
#include "connection_vft.h"
@@ -31,7 +32,7 @@
// This is called by configuration
connection_t *connection_create(face_type_t type, const char *name,
const address_pair_t *pair,
- forwarder_t *forwarder) {
+ const forwarder_t *forwarder) {
assert(face_type_is_valid(type));
assert(pair);
assert(forwarder);
@@ -70,6 +71,38 @@ connection_t *connection_create(face_type_t type, const char *name,
return connection_table_at(table, connection_id);
}
+netdevice_type_t connection_get_netdevice_type(const char *interface_name) {
+ if (strncmp(interface_name, "lo", 2) == 0) {
+ return NETDEVICE_TYPE_LOOPBACK;
+ }
+ if ((strncmp(interface_name, "eth", 3) == 0) ||
+ (strncmp(interface_name, "en", 2) == 0)) {
+ /* eth* en* enx* */
+ return NETDEVICE_TYPE_WIRED;
+ }
+ if (strncmp(interface_name, "wl", 2) == 0) {
+ /* wlan* wlp* wlx* */
+ return NETDEVICE_TYPE_WIFI;
+ }
+ if (strncmp(interface_name, "rmnet_ipa", 9) == 0) {
+ /* Qualcomm IPA driver */
+ return NETDEVICE_TYPE_UNDEFINED;
+ }
+ if ((strncmp(interface_name, "rmnet", 5) == 0) ||
+ (strncmp(interface_name, "rev_rmnet", 9) == 0) ||
+ (strncmp(interface_name, "ccmni", 5) == 0)) {
+ /*
+ * rmnet* (Qualcomm) ccmni* (MediaTek)
+ */
+ return NETDEVICE_TYPE_CELLULAR;
+ }
+ /* usb0 might be cellular (eg Zenfone2) */
+ /* what about tethering */
+ /* tun* dummy* ... */
+ /* bnet* pan* hci* for bluetooth */
+ return NETDEVICE_TYPE_UNDEFINED;
+}
+
/**
* @brief Initializes a connection
*
@@ -122,6 +155,30 @@ int connection_initialize(connection_t *connection, face_type_t type,
.wldr_autostart = true,
};
+ connection->interface_type =
+ connection_get_netdevice_type(connection->interface_name);
+
+#ifdef WITH_POLICY
+ connection_clear_tags(connection);
+ switch (connection->interface_type) {
+#if 0
+ case NETDEVICE_TYPE_LOOPBACK:
+ connection_add_tag(connection, POLICY_TAG_LOOPBACK);
+ break;
+#endif
+ case NETDEVICE_TYPE_WIRED:
+ connection_add_tag(connection, POLICY_TAG_WIRED);
+ break;
+ case NETDEVICE_TYPE_WIFI:
+ connection_add_tag(connection, POLICY_TAG_WIFI);
+ break;
+ case NETDEVICE_TYPE_CELLULAR:
+ connection_add_tag(connection, POLICY_TAG_CELLULAR);
+ default:
+ break;
+ }
+#endif
+
connection->data =
malloc(connection_vft[get_protocol(connection->type)]->data_size);
if (!connection->data) goto ERR_DATA;
@@ -200,8 +257,8 @@ int connection_finalize(connection_t *connection) {
return 0;
}
-int connection_send_packet(const connection_t *connection,
- const uint8_t *packet, size_t size) {
+bool connection_send_packet(const connection_t *connection,
+ const uint8_t *packet, size_t size) {
assert(connection);
assert(face_type_is_valid(connection->type));
assert(packet);
@@ -231,10 +288,12 @@ bool connection_send(connection_t *connection, off_t msgbuf_id, bool queue) {
const msgbuf_pool_t *msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
+#if 0
if (connection->wldr)
wldr_set_label(connection->wldr, msgbuf);
else
msgbuf_reset_wldr_label(msgbuf);
+#endif
return _connection_send(connection, msgbuf, queue);
}
diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h
index ac75428dd..b459a6d81 100644
--- a/hicn-light/src/hicn/core/connection.h
+++ b/hicn-light/src/hicn/core/connection.h
@@ -33,25 +33,30 @@
#define CONNECTION_ID_UNDEFINED ~0
-#ifdef WITH_MAPME
+#define foreach_connection_event \
+ _(UNDEFINED) \
+ _(CREATE) \
+ _(DELETE) \
+ _(UPDATE) \
+ _(SET_UP) \
+ _(SET_DOWN) \
+ _(PRIORITY_CHANGED) \
+ _(TAGS_CHANGED) \
+ _(N)
+
typedef enum {
- CONNECTION_EVENT_CREATE,
- CONNECTION_EVENT_DELETE,
- CONNECTION_EVENT_UPDATE,
- CONNECTION_EVENT_SET_UP,
- CONNECTION_EVENT_SET_DOWN,
- CONNECTION_EVENT_PRIORITY_CHANGED,
- CONNECTION_EVENT_TAGS_CHANGED,
+#define _(x) CONNECTION_EVENT_##x,
+ foreach_connection_event
+#undef _
} connection_event_t;
-#endif /* WITH_MAPME */
-
struct wldr_s;
typedef struct {
unsigned id;
char* name;
char* interface_name;
+ netdevice_type_t interface_type;
face_type_t type;
address_pair_t pair;
// bool up;
@@ -111,6 +116,7 @@ typedef struct {
#define connection_get_admin_state(C) ((C)->admin_state)
#define connection_set_admin_state(C, STATE) (C)->admin_state = STATE
#define connection_get_interface_name(C) ((C)->interface_name)
+#define connection_get_interface_type(C) ((C)->interface_type)
#ifdef WITH_POLICY
#define connection_get_priority(C) ((C)->priority)
@@ -118,7 +124,7 @@ typedef struct {
#define connection_get_tags(C) ((C)->tags)
#define connection_set_tags(C, TAGS) (C)->tags = TAGS
#define connection_has_tag(C, TAG) policy_tags_has(connection_get_tags(C), TAG)
-#define connection_add_tag(C, TAG) policy_tags_add(connection_get_tags(X), TAG)
+#define connection_add_tag(C, TAG) policy_tags_add(&connection_get_tags(C), TAG)
#define connection_remove_tag(C, TAG) \
do { \
policy_tags_t _conn_var(tags); \
@@ -198,7 +204,7 @@ static inline void connection_set_tags(connection_t* connection,
connection_t* connection_create(face_type_t type, const char* name,
const address_pair_t* pair,
- struct forwarder_s* forwarder);
+ const struct forwarder_s* forwarder);
int connection_initialize(connection_t* connection, face_type_t type,
const char* name, const char* interface_name, int fd,
@@ -207,8 +213,8 @@ int connection_initialize(connection_t* connection, face_type_t type,
int connection_finalize(connection_t* connection);
-int connection_send_packet(const connection_t* connection,
- const uint8_t* packet, size_t size);
+bool connection_send_packet(const connection_t* connection,
+ const uint8_t* packet, size_t size);
bool connection_flush(connection_t* connection);
diff --git a/hicn-light/src/hicn/core/connection_table.c b/hicn-light/src/hicn/core/connection_table.c
index c723073a1..7bc0e2f4c 100644
--- a/hicn-light/src/hicn/core/connection_table.c
+++ b/hicn-light/src/hicn/core/connection_table.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -81,6 +81,14 @@ connection_t *connection_table_allocate(const connection_table_t *table,
pool_get(table->connections, conn);
if (!conn) return NULL;
+#ifdef __APPLE__
+ // set __uint8_t sin_len to 0
+ uint8_t *ptr = (uint8_t *)address_pair_get_local(pair);
+ *ptr = 0x0;
+ ptr = (uint8_t *)address_pair_get_remote(pair);
+ *ptr = 0x0;
+#endif /* __APPLE__ */
+
off_t id = conn - table->connections;
int rc;
@@ -106,6 +114,14 @@ void connection_table_deallocate(const connection_table_t *table,
const char *name = connection_get_name(conn);
const address_pair_t *pair = connection_get_pair(conn);
+#ifdef __APPLE__
+ // set __uint8_t sin_len to 0
+ uint8_t *ptr = (uint8_t *)address_pair_get_local(pair);
+ *ptr = 0x0;
+ ptr = (uint8_t *)address_pair_get_remote(pair);
+ *ptr = 0x0;
+#endif /* __APPLE__ */
+
// Remove from name hash table
khiter_t k = kh_get_ct_name(table->id_by_name, name);
assert(k != kh_end(table->id_by_name));
@@ -124,6 +140,14 @@ void connection_table_deallocate(const connection_table_t *table,
connection_t *connection_table_get_by_pair(const connection_table_t *table,
const address_pair_t *pair) {
+#ifdef __APPLE__
+ // set __uint8_t sin_len to 0
+ uint8_t *ptr = (uint8_t *)address_pair_get_local(pair);
+ *ptr = 0x0;
+ ptr = (uint8_t *)address_pair_get_remote(pair);
+ *ptr = 0x0;
+#endif /* __APPLE__ */
+
khiter_t k = kh_get_ct_pair(table->id_by_pair, pair);
if (k == kh_end(table->id_by_pair)) return NULL;
return table->connections + kh_val(table->id_by_pair, k);
@@ -196,7 +220,7 @@ int connection_table_get_random_name(const connection_table_t *table,
int i, n_attempts = 2 * USHRT_MAX;
for (i = 0; i < n_attempts; i++) {
int rc = snprintf(name, SYMBOLIC_NAME_LEN, "conn%u", RAND16());
- if (rc >= SYMBOLIC_NAME_LEN) continue;
+ if (rc < 0 || rc >= SYMBOLIC_NAME_LEN) continue;
// Check if generated connection name is a duplicate
khiter_t k = kh_get_ct_name(table->id_by_name, name);
@@ -209,4 +233,4 @@ int connection_table_get_random_name(const connection_table_t *table,
}
return 0;
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/core/connection_table.h b/hicn-light/src/hicn/core/connection_table.h
index 7d4bad761..566443d93 100644
--- a/hicn-light/src/hicn/core/connection_table.h
+++ b/hicn-light/src/hicn/core/connection_table.h
@@ -160,11 +160,14 @@ connection_t *_connection_table_get_by_id(connection_table_t *table, off_t id);
* @return off_t The index of the specified connection in the connection table.
*/
#define connection_table_get_connection_id(table, conn) \
- (conn - table->connections)
+ (unsigned)(conn - table->connections)
#define connection_table_foreach(table, conn, BODY) \
pool_foreach(table->connections, (conn), BODY)
+#define connection_table_foreach_new(table, CONN, BODY) \
+ pool_foreach_typed(table->connections, connection_t *, CONN, BODY)
+
#define connection_table_enumerate(table, i, conn, BODY) \
pool_enumerate(table->connections, (i), (conn), BODY)
diff --git a/hicn-light/src/hicn/core/connection_vft.h b/hicn-light/src/hicn/core/connection_vft.h
index 1a6ecbb78..cc736905c 100644
--- a/hicn-light/src/hicn/core/connection_vft.h
+++ b/hicn-light/src/hicn/core/connection_vft.h
@@ -30,8 +30,8 @@ typedef struct {
const address_t* remote, const char* interface_name);
bool (*flush)(connection_t* connection);
bool (*send)(connection_t* connection, msgbuf_t* msgbuf, bool queue);
- int (*send_packet)(const connection_t* connection, const uint8_t* packet,
- size_t size);
+ bool (*send_packet)(const connection_t* connection, const uint8_t* packet,
+ size_t size);
// void (*read_callback)(connection_t * connection, int fd, void * data);
size_t data_size;
} connection_ops_t;
diff --git a/hicn-light/src/hicn/core/fib.c b/hicn-light/src/hicn/core/fib.c
index d8d3c7cfa..64dd3fe7d 100644
--- a/hicn-light/src/hicn/core/fib.c
+++ b/hicn-light/src/hicn/core/fib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -19,20 +19,21 @@
#include <hicn/core/fib.h>
typedef struct fib_node_s {
- struct fib_node_s *left;
- struct fib_node_s *right;
+ struct fib_node_s *child[2]; /* 0: left, 1: right */
fib_entry_t *entry;
bool is_used;
} fib_node_t;
+#define ZERO 0
+#define ONE 1
+
static fib_node_t *fib_node_create(fib_node_t *left, fib_node_t *right,
fib_entry_t *entry, bool is_used) {
fib_node_t *node = malloc(sizeof(fib_node_t));
if (!node) return NULL;
*node = (fib_node_t){
- .left = left,
- .right = right,
+ .child = {left, right},
.entry = entry,
.is_used = is_used,
};
@@ -43,8 +44,8 @@ static fib_node_t *fib_node_create(fib_node_t *left, fib_node_t *right,
static void fib_node_free(fib_node_t *node) {
if (!node) return;
- fib_node_free(node->right);
- fib_node_free(node->left);
+ fib_node_free(node->child[ZERO]);
+ fib_node_free(node->child[ONE]);
fib_entry_free(node->entry);
free(node);
@@ -82,293 +83,387 @@ size_t fib_get_size(const fib_t *fib) {
return fib->size;
}
-#define FIB_SET(CURR, NEW_PREFIX, CURR_PREFIX_LEN) \
- do { \
- bool bit; \
- int res = nameBitvector_testBit(NEW_PREFIX, CURR_PREFIX_LEN, &bit); \
- assert(res >= 0); \
- (void)res; /* unused */ \
- CURR = bit ? CURR->right : CURR->left; \
- } while (0)
-
-#define FIB_INSERT(DST, SRC, PREFIX, PREFIX_LEN) \
- do { \
- bool bit; \
- int res = nameBitvector_testBit(PREFIX, PREFIX_LEN, &bit); \
- assert(res >= 0); \
- (void)res; /* unused */ \
- if (bit) \
- DST->right = SRC; \
- else \
- DST->left = SRC; \
- } while (0)
-
-void fib_add(fib_t *fib, fib_entry_t *entry) {
- assert(fib);
- assert(entry);
+/*
+ * This struct will hold various information related to the returned node such
+ * as its parent and grandparent if any, as well as some already computed
+ * information about the prefix.
+ */
+typedef struct {
+ /* Result node ancestors (NULL if not applicable) */
+ fib_node_t *parent;
+ fib_node_t *gparent;
+ /* Information related to the result node */
+ hicn_prefix_t *prefix;
+ uint32_t prefix_len;
+ uint32_t match_len;
+} fib_search_t;
+/*
+ * @brief Search for longest subprefix (helper function)
+ * @param [in] fib - Pointer to the FIB to search
+ * @param [in] prefix - The prefix used for search
+ * @param [out] search - A pointer to a structure that will hold related search
+ * information, that can be NULL if this is not needed.
+ *
+ * @returns The node whose entry corresponds to the longest subprefix of the
+ * prefix passed in parameter, or NULL if not found. The longest prefix match is
+ * thus the resulting node if curr_len == prefix_len, and its parent
+ * otherwise.
+ *
+ * Implementation details:
+ *
+ * This function performs a descent in the tree, following branches
+ * corresponding to the value of the next bit, until reaching past a leaf, or
+ * either the current node prefix:
+ * when one of the two following conditions is met:
+ * - is not a prefix of the searched one (match_len < curr_len), or
+ * - is longer or equal than the inserted one (curr_len >= prefix_len)
+ */
+fib_node_t *fib_search(const fib_t *fib, const hicn_prefix_t *prefix,
+ fib_search_t *search) {
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
+ uint32_t curr_len;
+ uint32_t match_len;
- NameBitvector *new_prefix = name_GetContentName(fib_entry_get_prefix(entry));
- uint32_t new_prefix_len = nameBitvector_GetLength(new_prefix);
+ fib_node_t *parent = NULL;
+ fib_node_t *gparent = NULL;
fib_node_t *curr = fib->root;
- fib_node_t *last = NULL;
+ while (curr) {
+ const hicn_prefix_t *curr_prefix = fib_entry_get_prefix(curr->entry);
+ curr_len = hicn_prefix_get_len(curr_prefix);
+ match_len = hicn_prefix_lpm(prefix, curr_prefix);
+
+ // XXX >= vs == for the second stop condition
+ // curr_len >= prefix_len l >= L
+ // L is a prefix of l
+ // > means we did not find
+ // = means we could have found
+ // leverage this info for contains!
+ // XXX remove this comment when done
+ if (match_len < curr_len || curr_len >= prefix_len) break;
+
+ gparent = parent;
+ parent = curr;
- NameBitvector *curr_name;
- uint32_t curr_prefix_len;
- uint32_t match_len;
+ /* The following lookup won't fail since curr_len < prefix_len */
+ uint8_t next_bit = hicn_prefix_get_bit(prefix, curr_len);
+ curr = curr->child[next_bit];
+ }
- while (curr) {
- curr_name = name_GetContentName(fib_entry_get_prefix(curr->entry));
+ if (search) {
+ search->parent = parent;
+ search->gparent = gparent;
+ if (curr) {
+ search->prefix_len = curr_len;
+ search->match_len = match_len;
+ }
+ }
+ return curr;
+}
- match_len = nameBitvector_lpm(new_prefix, curr_name);
- curr_prefix_len = nameBitvector_GetLength(curr_name);
+/*
+ * Helper: insert a new node between parent and child.
+ *
+ * parent == NULL means we set the root of the FIB
+ * child == NULL means our node has no child
+ */
+fib_node_t *_fib_insert(fib_t *fib, fib_entry_t *entry, fib_node_t *parent,
+ fib_node_t *child, bool is_used) {
+ fib_node_t *new_node = fib_node_create(NULL, NULL, entry, is_used);
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
- 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;
+ if (!parent) {
+ fib->root = new_node;
+ } else {
+ const hicn_prefix_t *parent_prefix = fib_entry_get_prefix(parent->entry);
+ uint32_t parent_prefix_len = hicn_prefix_get_len(parent_prefix);
+ uint8_t next_bit = hicn_prefix_get_bit(prefix, parent_prefix_len);
+ parent->child[next_bit] = new_node;
+ }
- last = curr;
- FIB_SET(curr, new_prefix, curr_prefix_len);
+ if (child) {
+ const hicn_prefix_t *curr_prefix = fib_entry_get_prefix(entry);
+ uint32_t match_len = hicn_prefix_lpm(prefix, curr_prefix);
+ uint8_t next_bit = hicn_prefix_get_bit(curr_prefix, match_len);
+ new_node->child[next_bit] = child;
}
- // this is the root (empty trie) or an empty child
- if (!curr) {
- fib_node_t *new_node = fib_node_create(NULL, NULL, entry, true);
- if (!last) {
- fib->root = new_node;
- } else {
- uint32_t last_prefix_len = nameBitvector_GetLength(
- name_GetContentName(fib_entry_get_prefix(last->entry)));
+ if (is_used) fib->size++;
+ return new_node;
+}
- FIB_INSERT(last, new_node, new_prefix, last_prefix_len);
- }
- fib->size++;
- return;
+/*
+ * Helper: remove a node from parent
+ */
+void _fib_remove(fib_t *fib, fib_node_t *curr, fib_node_t *parent) {
+ /*
+ * If we remove the node, curr has either 0 or 1 child. In the latter case,
+ * we attach it to parent
+ */
+ fib_node_t *child = curr->child[ZERO] ? curr->child[ZERO] : curr->child[ONE];
+ if (!parent) {
+ fib->root = child;
+ } else {
+ if (parent->child[ZERO] == curr)
+ parent->child[ZERO] = child;
+ else
+ parent->child[ONE] = child;
}
+ if (curr->is_used) fib->size--;
+ fib_node_free(curr);
+}
+
+/*
+ * - Stop condition: curr == NULL. This corresponds to:
+ *
+ * (CASE 1) Our parent is a strict prefix and we simply have to create a new
+ * leaf child in the correct branch based on the next bit following the parent
+ * prefix.
+ *
+ * Otherwise, our parent node exist. Based on the stop condition, we
+ * either have:
+ *
+ * - Stop condition 1 : curr_len == match_len AND curr_len >=
+ * prefix_len l == m && l >= L
+ *
+ * 2 sub-cases:
+ * - l = m > L : IMPOSSIBLE L < m since m = LPM(l, L) means L >= m
+ * - l = m = L : insert the current node, either it exists or not
+ *
+ * We thus have:
+ *
+ * (CASE 2) The node already exist. If is not in use we turn it on and we set
+ * the right fib entry.
+ *
+ * The case when it is used should never occur because of the way we add
+ * entries in the FIB... but let's add the nexthops we wish to insert into
+ * the existing FIB entry.
+ *
+ * - Stop condition 2: curr_len != match_len
+ * l != m => l > m
+ *
+ * We have two possibilities:
+ * - Only one is bigger than m (case 3)
+ * - They are both bigger than m (case 4)
+ *
+ * (CASE 3) Only one is bigger than m
+ * L == m => L < l (since l != m and l >= m)
+ * l > L = m
+ *
+ * This means L is a prefix of l.
+ * l'
+ * /
+ * L
+ * /
+ * l
+ *
+ * (CASE 4) They are both bigger than m
+ * - l > L > m
+ * - L > l > m
+ * - L = l > m
+ *
+ * Both share L and l share l' as a common prefix, and this is not l' since
+ * they share the name next bit.
+ *
+ * So this case is impossible and we would have taken the other branch during
+ * the descent:
+ *
+ * l'
+ * / \
+ * l L
+ *
+ * We are in a situation where e need to insert an internal node:
+ *
+ * l'
+ * |
+ * X <------ internal node
+ * / \
+ * l L
+ */
+void fib_add(fib_t *fib, fib_entry_t *entry) {
+ assert(fib);
+ assert(entry);
+
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
+
+ fib_search_t search;
+ fib_node_t *curr = fib_search(fib, prefix, &search);
- // curr is not null
+ /* Case 1 */
+ if (!curr) {
+ _fib_insert(fib, entry, search.parent, NULL, true);
+ return;
+ }
- // 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) {
+ /* Case 2 */
+ if (search.prefix_len == search.match_len && prefix_len == search.match_len) {
if (!curr->is_used) {
curr->is_used = true;
+ if (curr->entry) fib_entry_free(curr->entry);
curr->entry = entry;
fib->size++;
- return;
} else {
- // this case should never happen beacuse of the way we add
- // entries in the fib
const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop,
{ fib_entry_nexthops_add(curr->entry, nexthop); });
+ fib_entry_free(entry);
}
+ return;
}
- // key is prefix of the curr node (so new_prefix_len < curr_prefix_len)
- if (new_prefix_len == match_len) {
- fib_node_t *new_node = fib_node_create(NULL, NULL, entry, true);
- if (!last) {
- fib->root = new_node;
- } else {
- uint32_t last_prefix_len = nameBitvector_GetLength(
- name_GetContentName(fib_entry_get_prefix(last->entry)));
- FIB_INSERT(last, new_node, new_prefix, last_prefix_len);
- }
- FIB_INSERT(new_node, curr, curr_name, match_len);
- fib->size++;
+ /* Case 3 */
+ if (prefix_len == search.match_len) {
+ _fib_insert(fib, entry, search.parent, curr, true);
return;
}
- // in the last case we need to add an inner node
- Name inner_prefix = EMPTY_NAME;
- name_Copy(fib_entry_get_prefix(entry), &inner_prefix);
- nameBitvector_clear(name_GetContentName(&inner_prefix), match_len);
- name_setLen(&inner_prefix, match_len);
-
- // this is an inner node, we don't want an acctive strategy
- // like low_latency that sends probes in this node
+ /* Case 4 */
+ hicn_prefix_t inner_prefix; /* dup'ed in fib_entry_create */
+ hicn_prefix_copy(&inner_prefix, prefix);
+ hicn_prefix_truncate(&inner_prefix, search.match_len);
fib_entry_t *inner_entry = fib_entry_create(
&inner_prefix, STRATEGY_TYPE_UNDEFINED, NULL, fib->forwarder);
-
- fib_node_t *inner_node = fib_node_create(NULL, NULL, inner_entry, false);
- fib_node_t *new_node = fib_node_create(NULL, NULL, entry, true);
-
- if (!last) {
- // we need to place the inner_node at the root
- fib->root = inner_node;
- } else {
- uint32_t last_prefix_len = nameBitvector_GetLength(
- name_GetContentName(fib_entry_get_prefix(last->entry)));
- NameBitvector *inner_name = name_GetContentName(&inner_prefix);
- FIB_INSERT(last, inner_node, inner_name, last_prefix_len);
- }
-
- bool bit;
- int res = nameBitvector_testBit(new_prefix, match_len, &bit);
- assert(res >= 0);
- (void)res; /* unused */
- inner_node->left = bit ? curr : new_node;
- inner_node->right = bit ? new_node : curr;
- fib->size++;
+ fib_node_t *new_node =
+ _fib_insert(fib, inner_entry, search.parent, curr, false);
+ _fib_insert(fib, entry, new_node, NULL, true);
}
-fib_entry_t *fib_contains(const fib_t *fib, const Name *prefix) {
+/*
+ * Implementation details:
+ *
+ * To find whether the fib contains a prefix, we issue a search, and based on
+ * the stopping conditions, we return the entry if and only if curr
+ * is not NULL, and prefix_len == curr_len (== match_len)
+ */
+fib_entry_t *fib_contains(const fib_t *fib, const hicn_prefix_t *prefix) {
assert(fib);
assert(prefix);
- NameBitvector *key_name = name_GetContentName(prefix);
- uint32_t key_prefix_len = nameBitvector_GetLength(key_name);
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
- fib_node_t *curr = fib->root;
+ fib_search_t search;
+ fib_node_t *curr = fib_search(fib, prefix, &search);
- while (curr) {
- NameBitvector *curr_name =
- name_GetContentName(fib_entry_get_prefix(curr->entry));
- uint32_t match_len = nameBitvector_lpm(key_name, curr_name);
- uint32_t curr_prefix_len = nameBitvector_GetLength(curr_name);
-
- 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 (curr_prefix_len == key_prefix_len) { //== match_len
- // this is an exact match
- if (!curr->is_used) {
- // the key does not exists
- return NULL;
- }
- // we found the key
- return curr->entry;
- }
-
- FIB_SET(curr, key_name, curr_prefix_len);
- }
-
- return NULL;
+ if (!curr) return NULL;
+ if (search.prefix_len != prefix_len) return NULL;
+ return curr->is_used ? curr->entry : NULL;
}
-static void fib_node_remove(fib_t *fib, const Name *prefix) {
+/*
+ * @brief Remove a prefix (and the associated node) from FIB
+ *
+ * We search for
+ *
+ * Actions depend on N, the number of children of the node to remove
+ * Examples are build using 'left' children only, but the cases with 'right'
+ * children are symmetrical.
+ *
+ * Legend:
+ * (empty) : no children
+ * * : 0 or more children
+ * + : at least one children
+ *
+ * N == 2 - Mark the node as unused
+ *
+ * parent parent
+ * / \ / \
+ * curr ... ==> (curr) ...
+ * / \ / \
+ * L R L R
+ *
+ * N == 1 - Attach the child to the parent node (whether parent is used or not)
+ *
+ * a) curr has no parent (curr is the root)
+ *
+ * curr +
+ * / ==>
+ * +
+ *
+ * b) curr has a parent
+ * parent parent
+ * / \ / \
+ * curr * ==> L *
+ * / \
+ * L
+ *
+ * (parent) (parent)
+ * / \ / \
+ * curr + ==> L +
+ * / \
+ * L
+ *
+ * N == 0
+ *
+ * a) curr has no parent (curr is the root)
+ *
+ * curr
+ * / \ ==>
+ *
+ * b) parent is unused.
+ *
+ * Assuming curr is the left child, then parent must have a
+ * right child, and the grand-parent must be used.
+ *
+ * gp gp gp
+ * / / /
+ * (parent) ==> (parent) ==> +
+ * / \ / \
+ * curr + +
+ * / \
+ *
+ * c) parent is used.
+ *
+ * Assuming curr is the left child, we simply remove it from
+ * parent, leaving parent unchanged whether it has a right child or not.
+ *
+ * parent parent
+ * / \ / \
+ * curr * ==> *
+ * / \
+ *
+ *
+ */
+static void fib_node_remove(fib_t *fib, const hicn_prefix_t *prefix) {
assert(fib);
assert(prefix);
- NameBitvector *key_name = name_GetContentName(prefix);
- uint32_t key_prefix_len = nameBitvector_GetLength(key_name);
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
- fib_node_t *curr = fib->root;
- fib_node_t *parent = NULL;
- fib_node_t *grandpa = NULL;
+ fib_search_t search;
+ fib_node_t *curr = fib_search(fib, prefix, &search);
- uint32_t match_len;
- uint32_t curr_prefix_len;
+ /*
+ * If we reach a NULL, unused node, or a node not matching, that means the
+ * node does not exist
+ */
+ if (!curr || !curr->is_used || (search.prefix_len != prefix_len)) return;
- while (curr) {
- NameBitvector *curr_name =
- name_GetContentName(fib_entry_get_prefix(curr->entry));
- match_len = nameBitvector_lpm(key_name, curr_name);
- curr_prefix_len = nameBitvector_GetLength(curr_name);
+ uint8_t N = 0;
+ if (curr->child[ZERO]) N++;
+ if (curr->child[ONE]) N++;
- if (match_len < curr_prefix_len || curr_prefix_len == key_prefix_len) {
+ switch (N) {
+ case 2:
+ curr->is_used = false;
break;
- }
-
- grandpa = parent;
- parent = curr;
- FIB_SET(curr, key_name, curr_prefix_len);
- }
-
- if (!curr || !curr->is_used || (curr_prefix_len != key_prefix_len)) {
- // the node does not exists
- return;
- }
-
- // curr has 2 children, leave it there and mark it as inner
- if (curr->right && curr->left) {
- curr->is_used = false;
- fib->size--;
- return;
- }
-
- // curr has no children
- if (!curr->right && !curr->left) {
- if (!parent) {
- // curr is the root and is the only node in the fib
- fib->root = NULL;
- fib->size--;
- fib_node_free(curr);
- return;
- }
- if (!grandpa) {
- // parent is the root
- if (fib->root->left == curr)
- fib->root->left = NULL;
- else
- fib->root->right = NULL;
- fib->size--;
- fib_node_free(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
- fib_node_t *tmp = (parent->right == curr) ? parent->left : parent->right;
-
- if (grandpa->right == parent)
- grandpa->right = tmp;
- else
- grandpa->left = tmp;
-
- fib->size--;
- fib_node_free(curr);
- fib_node_free(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--;
- fib_node_free(curr);
- return;
- }
-
- // curr has one child
- if (curr->right || curr->left) {
- if (!parent) {
- // curr is the root
- fib->root = fib->root->right ? fib->root->right : fib->root->left;
- fib->size--;
- fib_node_free(curr);
- return;
- }
- // attach the child of curr to parent
- fib_node_t *tmp = curr->right ? curr->right : curr->left;
-
- if (parent->right == curr)
- parent->right = tmp;
- else
- parent->left = tmp;
+ case 1:
+ _fib_remove(fib, curr, search.parent);
+ break;
- fib->size--;
- fib_node_free(curr);
- return;
+ case 0:
+ _fib_remove(fib, curr, search.parent);
+ if (!search.parent->is_used)
+ _fib_remove(fib, search.parent, search.gparent);
+ break;
}
}
-void fib_remove(fib_t *fib, const Name *name, unsigned conn_id) {
+void fib_remove(fib_t *fib, const hicn_prefix_t *prefix, unsigned conn_id) {
assert(fib);
- assert(name);
+ assert(prefix);
- fib_entry_t *entry = fib_contains(fib, name);
+ fib_entry_t *entry = fib_contains(fib, prefix);
if (!entry) return;
fib_entry_nexthops_remove(entry, conn_id);
@@ -382,16 +477,24 @@ static size_t fib_node_remove_connection_id(fib_node_t *node, unsigned conn_id,
if (!node) return pos;
if (node->is_used) {
fib_entry_nexthops_remove(node->entry, conn_id);
+
+ /* When using MAP-Me, we keep empty FIB entries */
#ifndef WITH_MAPME
if (fib_entry_nexthops_len(node->entry) == 0) array[pos++] = node->entry;
#endif /* WITH_MAPME */
}
- pos = fib_node_remove_connection_id(node->right, conn_id, array, pos);
- pos = fib_node_remove_connection_id(node->left, conn_id, array, pos);
+ pos = fib_node_remove_connection_id(node->child[ONE], conn_id, array, pos);
+ pos = fib_node_remove_connection_id(node->child[ZERO], conn_id, array, pos);
return pos;
}
-void fib_remove_connection_id(fib_t *fib, unsigned conn_id) {
+void fib_remove_entry(fib_t *fib, fib_entry_t *entry) {
+ fib_node_remove(fib, fib_entry_get_prefix(entry));
+}
+
+void fib_remove_connection(fib_t *fib, unsigned conn_id,
+ fib_entry_t ***removed_entries,
+ size_t *num_removed_entries) {
assert(fib);
fib_entry_t **array = malloc(sizeof(fib_entry_t *) * fib->size);
@@ -399,61 +502,64 @@ void fib_remove_connection_id(fib_t *fib, unsigned conn_id) {
size_t pos = 0;
pos = fib_node_remove_connection_id(fib->root, conn_id, array, pos);
- for (int i = 0; i < pos; i++)
- fib_node_remove(fib, fib_entry_get_prefix(array[i]));
- free(array);
-}
+ if (removed_entries) {
+ /*
+ * The caller is taking charge of releasing entries (as well as the returned
+ * array
+ */
+ assert(num_removed_entries);
-fib_entry_t *fib_match_message(const fib_t *fib,
- const msgbuf_t *interest_msgbuf) {
- assert(fib);
- assert(interest_msgbuf);
+ *removed_entries = array;
+ *num_removed_entries = pos;
- return fib_match_bitvector(
- fib, name_GetContentName(msgbuf_get_name(interest_msgbuf)));
+ } else {
+ for (int i = 0; i < pos; i++)
+ fib_node_remove(fib, fib_entry_get_prefix(array[i]));
+ }
+ free(array);
}
-fib_entry_t *fib_match_name(const fib_t *fib, const Name *name) {
+fib_entry_t *fib_match_msgbuf(const fib_t *fib, const msgbuf_t *msgbuf) {
assert(fib);
- assert(name);
+ assert(msgbuf);
- return fib_match_bitvector(fib, name_GetContentName(name));
+ return fib_match_name(fib, msgbuf_get_name(msgbuf));
}
-fib_entry_t *fib_match_bitvector(const fib_t *fib, const NameBitvector *name) {
+/*
+ * Implementation details:
+ *
+ * fib_search returns the longest non-strict subprefix.
+ * - curr == NULL means no such prefix exist and we can return the parent.
+ * - if we have an exact match (curr_len == key_prefix_len), then we
+ * return curr unless is_used is false, in which case we return the parent.
+ * - otherwise, the parent is the longest prefix match
+ */
+fib_entry_t *fib_match_prefix(const fib_t *fib, const hicn_prefix_t *prefix) {
assert(fib);
- assert(name);
-
- uint32_t key_prefix_len = nameBitvector_GetLength(name);
+ assert(prefix);
- fib_node_t *curr = fib->root;
- fib_node_t *candidate = NULL;
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
- while (curr) {
- NameBitvector *curr_name =
- name_GetContentName(fib_entry_get_prefix(curr->entry));
- uint32_t match_len = nameBitvector_lpm(name, curr_name);
- uint32_t curr_prefix_len = nameBitvector_GetLength(curr_name);
-
- 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;
- }
-
- if (curr->is_used) candidate = curr;
+ fib_search_t search;
+ fib_node_t *curr = fib_search(fib, prefix, &search);
- // 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;
- }
-
- FIB_SET(curr, name, curr_prefix_len);
+ if (!curr) {
+ /* This can happen with an empty FIB for instance */
+ if (!search.parent) return NULL;
+ return search.parent->entry;
}
+ if ((search.prefix_len <= prefix_len) && curr->is_used) return curr->entry;
+ if (search.parent) return search.parent->entry;
+ return NULL;
+}
- return candidate ? candidate->entry : NULL;
+fib_entry_t *fib_match_name(const fib_t *fib, const hicn_name_t *name) {
+ hicn_prefix_t prefix;
+ const hicn_name_prefix_t *name_prefix = hicn_name_get_prefix(name);
+ prefix.name = *name_prefix;
+ prefix.len = hicn_name_prefix_get_len_bits(name_prefix);
+ return fib_match_prefix(fib, &prefix);
}
static size_t fib_node_collect_entries(fib_node_t *node, fib_entry_t **array,
@@ -464,8 +570,8 @@ static size_t fib_node_collect_entries(fib_node_t *node, fib_entry_t **array,
if (node->is_used) array[pos++] = node->entry;
- pos = fib_node_collect_entries(node->right, array, pos);
- pos = fib_node_collect_entries(node->left, array, pos);
+ pos = fib_node_collect_entries(node->child[ONE], array, pos);
+ pos = fib_node_collect_entries(node->child[ZERO], array, pos);
return pos;
}
@@ -476,3 +582,123 @@ size_t fib_get_entry_array(const fib_t *fib, fib_entry_t ***array_p) {
pos = fib_node_collect_entries(fib->root, *array_p, pos);
return pos;
}
+
+bool _fib_is_valid(const fib_node_t *node) {
+ if (!node) return true;
+
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(node->entry);
+ uint32_t prefix_len = hicn_prefix_get_len(prefix);
+
+ for (unsigned i = 0; i < 2; i++) {
+ const fib_node_t *child = node->child[i];
+ if (!child) continue;
+ const hicn_prefix_t *child_prefix = fib_entry_get_prefix(child->entry);
+
+ uint32_t match_len = hicn_prefix_lpm(prefix, child_prefix);
+ if (match_len != prefix_len) return false;
+ if (!node->is_used && !child->is_used) return false;
+ if (hicn_prefix_get_bit(child_prefix, match_len) != i) return false;
+ if (!_fib_is_valid(child)) return false;
+ }
+ return true;
+}
+
+/*
+ * @brief Check that the structure of the FIB is correct : prefixes are
+ * correctly nested, 0 are on the left, 1 on the right, and that we have no
+ * more than 1 unused prefix as parents.
+ */
+bool fib_is_valid(const fib_t *fib) { return _fib_is_valid(fib->root); }
+
+/*
+ * Checks whether the preorder traversal of the sub-tree corresponds to the
+ * prefix and used arrays, starting from pos (helper)
+ */
+bool __fib_check_preorder(const fib_node_t *node,
+ const hicn_prefix_t **prefix_array, bool *used_array,
+ size_t size, size_t *pos) {
+ /* Check left subtree... */
+ fib_node_t *left = node->child[ZERO];
+ if (left && !__fib_check_preorder(left, prefix_array, used_array, size, pos))
+ return false;
+
+ /* ... then current node ... */
+ if (*pos > size) {
+ ERROR("size error");
+ return false;
+ }
+
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(node->entry);
+
+ if (!hicn_prefix_equals(prefix, prefix_array[*pos])) {
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc;
+
+ ERROR("Prefix mismatch in position %d %s != %s", pos);
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ ERROR("Expected: %s", buf);
+
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix_array[*pos]);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ ERROR("Expected: %s", buf);
+ return false;
+ }
+
+ (*pos)++;
+
+ /* ... then right subtree */
+ fib_node_t *right = node->child[ONE];
+ if (right &&
+ !__fib_check_preorder(right, prefix_array, used_array, size, pos))
+ return false;
+
+ return true;
+}
+
+/*
+ * Checks whether the preorder traversal of the trie
+ * corresponds to the prefix and used arrays.
+ */
+bool _fib_check_preorder(const fib_t *fib, const hicn_prefix_t **prefix_array,
+ bool *used_array, size_t size) {
+ if (!fib->root) return true;
+ size_t pos = 0;
+ if (!__fib_check_preorder(fib->root, prefix_array, used_array, size, &pos))
+ return false;
+ /* We need to check that we don't miss elements */
+ return pos == size;
+}
+
+// XXX print empty node but not recurse
+void _fib_dump(const fib_node_t *node, int start, int indent) {
+ char buf[MAXSZ_HICN_PREFIX];
+
+ if (node) {
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(node->entry);
+ int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s %d", "(error)", rc);
+ } else {
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(null)");
+ }
+
+ // Left
+ if (indent > 0) {
+ for (int i = 0; i < start - 1; i++) printf(" ");
+ for (int i = start + 1; i < indent; i++) printf("| ");
+ printf("|");
+ printf("_ %s\n", buf);
+ } else {
+ printf("%s\n", buf);
+ }
+
+ if (!node) return;
+
+ _fib_dump(node->child[ZERO], start, indent + 1);
+ _fib_dump(node->child[ONE], start + 1, indent + 1);
+}
+
+void fib_dump(const fib_t *fib) { _fib_dump(fib->root, 0, 0); }
diff --git a/hicn-light/src/hicn/core/fib.h b/hicn-light/src/hicn/core/fib.h
index c0fda960b..501935b0b 100644
--- a/hicn-light/src/hicn/core/fib.h
+++ b/hicn-light/src/hicn/core/fib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -18,7 +18,7 @@
#include "fib_entry.h"
#include "msgbuf.h"
-#include "name.h"
+#include <hicn/name.h>
#define _fib_var(x) _fib_##x
@@ -32,24 +32,39 @@ size_t fib_get_size(const fib_t *fib);
void fib_add(fib_t *fib, fib_entry_t *node);
-fib_entry_t *fib_contains(const fib_t *fib, const Name *prefix);
+fib_entry_t *fib_contains(const fib_t *fib, const hicn_prefix_t *prefix);
-void fib_remove(fib_t *fib, const Name *prefix, unsigned conn_id);
+void fib_remove(fib_t *fib, const hicn_prefix_t *prefix, unsigned conn_id);
-void fib_remove_connection_id(fib_t *fib, unsigned conn_id);
+void fib_remove_entry_connection(fib_t *fib, fib_entry_t *entry,
+ unsigned conn_id, fib_entry_t **removed_entry);
-fib_entry_t *fib_match_message(const fib_t *fib,
- const msgbuf_t *interest_msgbuf);
-fib_entry_t *fib_match_name(const fib_t *fib, const Name *name);
-fib_entry_t *fib_match_bitvector(const fib_t *fib, const NameBitvector *name);
+void fib_remove_name_connection(fib_t *fib, const hicn_prefix_t *prefix,
+ unsigned conn_id);
+
+void fib_remove_entry(fib_t *fib, fib_entry_t *entry);
+
+void fib_remove_connection(fib_t *fib, unsigned conn_id,
+ fib_entry_t ***removed_entries,
+ size_t *num_removed_entries);
+
+fib_entry_t *fib_match_msgbuf(const fib_t *fib, const msgbuf_t *msgbuf);
+
+fib_entry_t *fib_match_prefix(const fib_t *fib, const hicn_prefix_t *prefix);
+
+fib_entry_t *fib_match_name(const fib_t *fib, const hicn_name_t *name);
size_t fib_get_entry_array(const fib_t *fib, fib_entry_t ***array_p);
+/*
+ * NOTE : do not use return on the loop body to avoid leaking memory
+ */
#define fib_foreach_entry(FIB, ENTRY, BODY) \
do { \
fib_entry_t **_fib_var(array); \
size_t _fib_var(n) = fib_get_entry_array((FIB), &_fib_var(array)); \
size_t _fib_var(i); \
+ fib_entry_t *ENTRY; \
for (_fib_var(i) = 0; _fib_var(i) < _fib_var(n); _fib_var(i)++) { \
ENTRY = _fib_var(array)[_fib_var(i)]; \
do { \
@@ -59,4 +74,13 @@ size_t fib_get_entry_array(const fib_t *fib, fib_entry_t ***array_p);
free(_fib_var(array)); \
} while (0)
+bool fib_is_valid(const fib_t *fib);
+bool _fib_check_preorder(const fib_t *fib, const hicn_prefix_t **prefix_array,
+ bool *used_array, size_t size);
+
+#define fib_check_preorder(F, PA, UA) \
+ _fib_check_preorder(F, PA, UA, sizeof(PA) / sizeof(hicn_prefix_t *))
+
+void fib_dump(const fib_t *fib);
+
#endif /* HICNLIGHT_FIB_H */
diff --git a/hicn-light/src/hicn/core/fib_entry.c b/hicn-light/src/hicn/core/fib_entry.c
index 80d337884..b588e3638 100644
--- a/hicn-light/src/hicn/core/fib_entry.c
+++ b/hicn-light/src/hicn/core/fib_entry.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -18,7 +18,6 @@
#include <hicn/hicn-light/config.h>
#include <hicn/core/fib_entry.h>
#include <hicn/core/strategy.h>
-#include <hicn/core/nameBitvector.h>
#ifdef WITH_MAPME
#include <hicn/core/ticks.h>
@@ -38,17 +37,22 @@
#include <hicn/core/policy_stats.h>
#endif /* WITH_POLICY_STATS */
-fib_entry_t *fib_entry_create(Name *name, strategy_type_t strategy_type,
+fib_entry_t *fib_entry_create(const hicn_prefix_t *prefix,
+ strategy_type_t strategy_type,
strategy_options_t *strategy_options,
const forwarder_t *forwarder) {
- assert(name);
- assert(forwarder);
+ assert(prefix);
+ /*
+ * For tests, we allow forwarder to be NULL, some
+ * functions cannot be called but otherwise we need a main loop, etc.
+ */
+ // assert(forwarder);
fib_entry_t *entry = malloc(sizeof(fib_entry_t));
if (!entry) goto ERR_MALLOC;
memset(entry, 0, sizeof(*entry));
- name_Copy(name, &entry->name);
+ hicn_prefix_copy(&entry->prefix, prefix);
entry->nexthops = NEXTHOPS_EMPTY;
fib_entry_add_strategy_options(entry, STRATEGY_TYPE_BESTPATH, NULL);
@@ -148,8 +152,10 @@ void fib_entry_set_strategy(fib_entry_t *entry, strategy_type_t strategy_type,
strategy_initialize(&entry->strategy, entry->forwarder);
}
-#ifdef WITH_POLICY
-
+/*
+ * Filters the set of nexthops passed as parameters (and not the one stored in
+ * the FIB entry
+ */
nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
unsigned ingress_id, bool prefer_local) {
assert(entry);
@@ -165,7 +171,6 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
const connection_table_t *table =
forwarder_get_connection_table(entry->forwarder);
connection_t *conn;
- unsigned nexthop, i;
uint_fast32_t flags;
hicn_policy_t policy = fib_entry_get_policy(entry);
@@ -205,6 +210,7 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
conn = connection_table_at(table, nexthop);
nexthops_disable_if(nexthops, i, (connection_is_local(conn)));
+#ifdef WITH_POLICY
/* Policy filtering : next hops */
nexthops_disable_if(
nexthops, i,
@@ -238,6 +244,7 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
nexthops, i,
(policy.tags[POLICY_TAG_TRUSTED].state == POLICY_STATE_PROHIBIT) &&
(connection_has_tag(conn, POLICY_TAG_TRUSTED)));
+#endif /* WITH_POLICY */
});
if (nexthops_get_curlen(nexthops) == 0) {
@@ -248,6 +255,7 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
/* We have at least one matching next hop, implement heuristic */
+#ifdef WITH_POLICY
/*
* As VPN connections might trigger duplicate uses of one interface, we start
* by filtering out interfaces based on trust status.
@@ -329,6 +337,8 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
});
if (nexthops_get_curlen(nexthops) == 0) nexthops->flags = flags;
}
+// XXX backup curlen ???
+#endif /* WITH_POLICY */
DEBUG("[fib_entry_filter_nexthops] before face priority num=%d/%d",
nexthops_get_curlen(nexthops), nexthops_get_len(nexthops));
@@ -349,10 +359,63 @@ nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
DEBUG("[fib_entry_filter_nexthops] result num=%d/%d",
nexthops_get_curlen(nexthops), nexthops_get_len(nexthops));
+ /* Nexthop priority */
+
+ /*
+ * Filter out nexthops with lowest strategy priority.
+ * Initializing at 0 allows to disable nexthops with a negative priority
+ */
+ max_priority = 0;
+ nexthops_enumerate(nexthops, i, nexthop, {
+ (void)nexthop;
+ int priority = nexthops->state[i].priority;
+ if (priority > max_priority) max_priority = priority;
+ });
+ nexthops_enumerate(nexthops, i, nexthop, {
+ int priority = nexthops->state[i].priority;
+ nexthops_disable_if(nexthops, i, (priority < max_priority));
+ });
+
+ /*
+ * If multipath is disabled, we don't offer much choice to the forwarding
+ * strategy, but still go through it for accounting purposes.
+ */
+ if ((policy.tags[POLICY_TAG_MULTIPATH].state == POLICY_STATE_PROHIBIT) ||
+ (policy.tags[POLICY_TAG_MULTIPATH].state == POLICY_STATE_AVOID)) {
+ DEBUG(
+ "[fib_entry_get_nexthops_from_strategy] select single nexthops due to "
+ "multipath policy");
+ nexthops_select_first(nexthops);
+ }
+
return nexthops;
}
/*
+ * Retrieve all candidate nexthops for sending mapme updates == all non local
+ * connections. We don't apply the policy at this stage.
+ */
+nexthops_t *fib_entry_get_mapme_nexthops(fib_entry_t *entry,
+ nexthops_t *new_nexthops) {
+ assert(new_nexthops);
+
+ const connection_table_t *table =
+ forwarder_get_connection_table(entry->forwarder);
+
+ /* We create a nexthop structure based on connections */
+ // XXX This should be done close to where it is needed
+ connection_t *connection;
+ connection_table_foreach(table, connection, {
+ if (connection_is_local(connection)) continue;
+ new_nexthops->elts[nexthops_get_len(new_nexthops)] =
+ connection_table_get_connection_id(table, connection);
+ nexthops_inc(new_nexthops);
+ });
+
+ return new_nexthops;
+}
+
+/*
* Update available next hops following policy update.
*
* The last nexthop parameter is only used if needed, otherwise the pointer to
@@ -397,13 +460,20 @@ nexthops_t *fib_entry_get_available_nexthops(fib_entry_t *entry,
#endif
}
+#ifdef WITH_POLICY
+
hicn_policy_t fib_entry_get_policy(const fib_entry_t *entry) {
return entry->policy;
}
void fib_entry_set_policy(fib_entry_t *entry, hicn_policy_t policy) {
+ INFO("fib_entry_set_policy");
entry->policy = policy;
+ forwarder_on_route_event(entry->forwarder, entry);
+
+ // XXX generic mechanism to perform a mapme update
+#if 0
#ifdef WITH_MAPME
/*
* Skip entries that do not correspond to a producer ( / have a locally
@@ -411,8 +481,8 @@ void fib_entry_set_policy(fib_entry_t *entry, hicn_policy_t policy) {
*/
if (!fib_entry_has_local_nexthop(entry)) return;
mapme_t *mapme = forwarder_get_mapme(entry->forwarder);
- mapme_set_all_adjacencies(mapme, entry);
#endif /* WITH_MAPME */
+#endif
}
#endif /* WITH_POLICY */
@@ -475,10 +545,7 @@ nexthops_t *fib_entry_get_nexthops_from_strategy(fib_entry_t *entry,
* Initializing at 0 allows to disable nexthops with a negative priority
*/
unsigned max_priority = 0;
- unsigned i;
- nexthop_t nexthop;
nexthops_enumerate(nexthops, i, nexthop, {
- (void)nexthop;
int priority = nexthops->state[i].priority;
if (priority > max_priority) max_priority = priority;
});
@@ -546,9 +613,9 @@ void fib_entry_on_timeout(fib_entry_t *entry,
strategy_on_timeout(&entry->strategy, &entry->nexthops, timeout_nexthops);
}
-const Name *fib_entry_get_prefix(const fib_entry_t *entry) {
+const hicn_prefix_t *fib_entry_get_prefix(const fib_entry_t *entry) {
assert(entry);
- return &(entry->name);
+ return &(entry->prefix);
}
/*
@@ -557,7 +624,6 @@ const Name *fib_entry_get_prefix(const fib_entry_t *entry) {
bool fib_entry_has_local_nexthop(const fib_entry_t *entry) {
connection_table_t *table = forwarder_get_connection_table(entry->forwarder);
- unsigned nexthop;
nexthops_foreach(fib_entry_get_nexthops(entry), nexthop, {
const connection_t *conn = connection_table_at(table, nexthop);
/* Ignore non-local connections */
diff --git a/hicn-light/src/hicn/core/fib_entry.h b/hicn-light/src/hicn/core/fib_entry.h
index 628c4cd4f..b625a33ef 100644
--- a/hicn-light/src/hicn/core/fib_entry.h
+++ b/hicn-light/src/hicn/core/fib_entry.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -37,16 +37,20 @@
#ifndef fib_entry_h
#define fib_entry_h
-#include "name.h"
+#include <hicn/name.h>
#include "strategy.h"
#include "msgbuf.h"
#include "nexthops.h"
#include "policy_stats.h"
typedef struct {
- Name name;
+ hicn_prefix_t prefix;
unsigned refcount;
nexthops_t nexthops;
+
+ /* This is used for producer prefixes only */
+ uint32_t nexthops_hash;
+
strategy_entry_t strategy;
const void *forwarder;
@@ -59,10 +63,12 @@ typedef struct {
policy_stats_t policy_stats;
#ifdef WITH_MAPME
+#if 0
/* In case of no multipath, this stores the previous decision taken by policy.
* As the list of nexthops is not expected to change, we can simply store the
* flags */
uint_fast32_t prev_nexthops_flags;
+#endif
void *user_data;
void (*user_data_release)(void **user_data);
#endif /* WITH_MAPME */
@@ -73,6 +79,7 @@ typedef struct {
#define fib_entry_strategy_type(fib_entry) ((fib_entry)->strategy.type)
#define fib_entry_get_nexthops(fib_entry) (&(fib_entry)->nexthops)
+
#define fib_entry_nexthops_len(fib_entry) \
(nexthops_get_len(&(fib_entry)->nexthops))
#define fib_entry_nexthops_curlen(fib_entry) \
@@ -81,14 +88,36 @@ typedef struct {
#define fib_entry_foreach_nexthop(fib_entry, nexthop, BODY) \
nexthops_foreach(fib_entry->nexthops, BODY)
-#define fib_entry_nexthops_changed(fib_entry) \
- ((fib_entry)->prev_nexthops_flags == fib_entry_get_nexthops(fib_entry)->flags)
-
-#define fib_entry_set_prev_nexthops(fib_entry) \
- ((fib_entry)->prev_nexthops_flags = fib_entry_get_nexthops(fib_entry)->flags)
+#define fib_entry_get_nexthops_hash(E) ((E)->nexthops_hash)
+#define fib_entry_set_nexthops_hash(E, H) (E)->nexthops_hash = (H)
+
+static inline void fib_entry_set_nexthops(fib_entry_t *entry,
+ nexthops_t *nexthops) {
+ entry->nexthops = *nexthops;
+}
+
+static inline void fib_entry_initialize_nexthops(fib_entry_t *entry) {
+ entry->nexthops = NEXTHOPS_EMPTY;
+}
+
+static inline bool fib_entry_nexthops_changed(fib_entry_t *entry,
+ nexthops_t *nexthops) {
+ uint32_t old_hash = fib_entry_get_nexthops_hash(entry);
+ uint32_t hash = nexthops_get_hash(nexthops);
+ if (hash != old_hash) {
+ fib_entry_set_nexthops_hash(entry, hash);
+ return true;
+ }
+ return false;
+};
struct forwarder_s;
-fib_entry_t *fib_entry_create(Name *name, strategy_type_t strategy_type,
+
+/*
+ * This does a copy of the name passed as parameter
+ */
+fib_entry_t *fib_entry_create(const hicn_prefix_t *prefix,
+ strategy_type_t strategy_type,
strategy_options_t *strategy_options,
const struct forwarder_s *table);
@@ -106,8 +135,6 @@ void fib_entry_nexthops_add(fib_entry_t *fib_entry, unsigned nexthop);
void fib_entry_nexthops_remove(fib_entry_t *fib_entry, unsigned nexthop);
-size_t fib_entry_NexthopCount(const fib_entry_t *fib_entry);
-
/**
* @function fib_entry_nexthops_get
* @abstract Returns the nexthop set of the FIB entry. You must Acquire if it
@@ -132,6 +159,12 @@ void fib_entry_set_policy(fib_entry_t *fib_entry, hicn_policy_t policy);
void fib_entry_update_stats(fib_entry_t *fib_entry, uint64_t now);
#endif /* WITH_POLICY */
+nexthops_t *fib_entry_filter_nexthops(fib_entry_t *entry, nexthops_t *nexthops,
+ unsigned ingress_id, bool prefer_local);
+
+nexthops_t *fib_entry_get_mapme_nexthops(fib_entry_t *entry,
+ nexthops_t *new_nexthops);
+
nexthops_t *fib_entry_get_available_nexthops(fib_entry_t *fib_entry,
unsigned in_connection,
nexthops_t *new_nexthops);
@@ -145,7 +178,7 @@ nexthops_t *fib_entry_get_nexthops_from_strategy(
* @abstract Returns a copy of the prefix.
* @return A reference counted copy that you must destroy
*/
-const Name *fib_entry_get_prefix(const fib_entry_t *fib_entry);
+const hicn_prefix_t *fib_entry_get_prefix(const fib_entry_t *fib_entry);
bool fib_entry_has_local_nexthop(const fib_entry_t *entry);
diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c
index 74be6431a..482e3d6f1 100644
--- a/hicn-light/src/hicn/core/forwarder.c
+++ b/hicn-light/src/hicn/core/forwarder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -69,7 +69,7 @@
#endif /* WITH_POLICY_STATS */
#include <hicn/core/wldr.h>
-#include <hicn/core/interest_manifest.h>
+#include <hicn/interest_manifest.h>
#include <hicn/util/log.h>
struct forwarder_s {
@@ -189,9 +189,10 @@ forwarder_t *forwarder_create(configuration_t *configuration) {
vector_init(forwarder->pending_conn, MAX_MSG, 0);
vector_init(forwarder->acquired_msgbuf_ids, MAX_MSG, 0);
- char *n_suffixes_per_split_str = getenv("N_SUFFIXES_PER_SPIT");
+ char *n_suffixes_per_split_str = getenv("N_SUFFIXES_PER_SPLIT");
if (n_suffixes_per_split_str)
- N_SUFFIXES_PER_SPIT = atoi(n_suffixes_per_split_str);
+ configuration_set_suffixes_per_split(forwarder_get_configuration(forwarder),
+ atoi(n_suffixes_per_split_str));
return forwarder;
@@ -239,6 +240,162 @@ void forwarder_free(forwarder_t *forwarder) {
free(forwarder);
}
+/*
+ * An event occurred that might trigger an update of the FIB cache. It is
+ * possible that the flags have been reset following a connection add or remote.
+ * The objective of this function is to prepare the cache entry, and to alert of
+ * any change for both consumer and producer prefixes.
+ */
+void forwarder_on_route_event(const forwarder_t *forwarder,
+ fib_entry_t *entry) {
+ commands_notify_route(forwarder, entry);
+
+ nexthops_t new_nexthops = NEXTHOPS_EMPTY;
+ nexthops_t *nexthops;
+
+ char *prefix_type_s;
+
+ const connection_table_t *table =
+ forwarder_get_connection_table(entry->forwarder);
+
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
+
+ WITH_INFO({
+ char buf[MAXSZ_HICN_PREFIX];
+ hicn_prefix_snprintf(buf, MAXSZ_HICN_NAME, prefix);
+ INFO("fib_entry_on_event: %s", buf);
+ )};
+
+ if (!fib_entry_has_local_nexthop(entry)) {
+ /* Recompute FIB cache, then check whether it has changed based on hash */
+ prefix_type_s = "consumer";
+ nexthops = fib_entry_get_nexthops(entry);
+ nexthops_reset(nexthops);
+ fib_entry_filter_nexthops(entry, nexthops, ~0, false);
+ } else {
+ /* Check available non-local connections (on which we would send MAP-Me
+ * updates */
+ prefix_type_s = "producer";
+
+ nexthops = fib_entry_get_mapme_nexthops(entry, &new_nexthops);
+ fib_entry_filter_nexthops(entry, nexthops, ~0, true);
+
+#ifdef WITH_MAPME
+ mapme_set_adjacencies(forwarder->mapme, entry, nexthops);
+#endif /* WITH_MAPME */
+ }
+
+ if (!fib_entry_nexthops_changed(entry, nexthops)) return;
+
+ /* Send notification */
+ WITH_INFO({
+ char buf[MAXSZ_HICN_PREFIX];
+ hicn_prefix_snprintf(buf, MAXSZ_HICN_NAME, prefix);
+ INFO("Active interfaces changed for %s prefix %s", prefix_type_s, buf);
+ });
+
+ netdevice_flags_t flags = NETDEVICE_FLAGS_EMPTY;
+ nexthops_foreach(nexthops, nh, {
+ connection_t *connection = connection_table_get_by_id(table, nh);
+ netdevice_flags_add(flags, connection_get_interface_type(connection));
+ });
+
+ hicn_ip_prefix_t ip_prefix;
+ hicn_prefix_get_ip_prefix(prefix, &ip_prefix);
+ commands_notify_active_interface_update(forwarder, &ip_prefix, flags);
+}
+
+int forwarder_add_connection(const forwarder_t *forwarder,
+ const char *symbolic_name, face_type_t type,
+ address_pair_t *pair, policy_tags_t tags,
+ int priority, face_state_t admin_state) {
+ connection_table_t *table = forwarder_get_connection_table(forwarder);
+ connection_t *connection = connection_table_get_by_pair(table, pair);
+
+ if (!connection) {
+ connection = connection_create(type, symbolic_name, pair, forwarder);
+ if (!connection) {
+ ERROR("Failed to create %s connection", face_type_str(type));
+ return -1;
+ }
+
+ } else {
+ WARN("Connection already exists");
+ }
+
+#ifdef WITH_POLICY
+ connection_set_tags(connection, tags);
+ connection_set_priority(connection, priority);
+#endif /* WITH_POLICY */
+
+ connection_set_admin_state(connection, admin_state);
+ return 0;
+}
+
+int forwarder_remove_connection(const forwarder_t *forwarder,
+ unsigned connection_id, bool finalize) {
+ /* Remove connection from the FIB */
+ forwarder_remove_connection_id_from_routes(forwarder, connection_id);
+
+ /* Remove connection */
+ connection_table_t *table = forwarder_get_connection_table(forwarder);
+
+ /* Hook: connection deleted through the control protocol */
+ connection_t *connection = connection_table_at(table, connection_id);
+ forwarder_on_connection_event(forwarder, connection, CONNECTION_EVENT_DELETE);
+
+ connection_table_remove_by_id(table, connection_id);
+ if (finalize) connection_finalize(connection);
+
+ return 0;
+}
+
+/*
+ * This is currently called from commands.c for every command sent to update
+ * a connection.
+ */
+void forwarder_on_connection_event(const forwarder_t *forwarder,
+ const connection_t *connection,
+ connection_event_t event) {
+ assert(connection);
+
+ commands_notify_connection(forwarder, event, connection);
+
+ unsigned conn_id = connection_get_id(connection);
+
+ /* We need to send a MapMe update on the newly selected connections for
+ * each concerned fib_entry : connection is involved, or no more involved */
+ fib_t *fib = forwarder_get_fib(forwarder);
+ fib_foreach_entry(fib, entry, {
+ const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
+
+ if (!fib_entry_has_local_nexthop(entry)) {
+ /* Consumer prefix */
+ /*
+ * A new connection has no impact until it is added to FIB, which will
+ * be handled in a route event
+ */
+ if (event == CONNECTION_EVENT_CREATE) break;
+
+ /*
+ * For each FIB entry, trigger an event only if the connection is part
+ * of nexthops */
+ // XXX Replace this by a function
+ nexthops_foreach(nexthops, nexthop, {
+ if (nexthop != conn_id) continue;
+ forwarder_on_route_event(forwarder, entry);
+ break;
+ });
+ } else {
+ /* Producer prefix */
+ if (connection_is_local(connection)) break;
+
+ // XXX we could optimize event more
+ forwarder_on_route_event(forwarder, entry);
+ }
+ });
+}
+
void forwarder_setup_local_listeners(forwarder_t *forwarder, uint16_t port) {
assert(forwarder);
listener_setup_local(forwarder, port);
@@ -249,7 +406,8 @@ configuration_t *forwarder_get_configuration(forwarder_t *forwarder) {
return forwarder->config;
}
-subscription_table_t *forwarder_get_subscriptions(forwarder_t *forwarder) {
+subscription_table_t *forwarder_get_subscriptions(
+ const forwarder_t *forwarder) {
return forwarder->subscriptions;
}
@@ -259,7 +417,7 @@ connection_table_t *forwarder_get_connection_table(
return forwarder->connection_table;
}
-listener_table_t *forwarder_get_listener_table(forwarder_t *forwarder) {
+listener_table_t *forwarder_get_listener_table(const forwarder_t *forwarder) {
assert(forwarder);
return forwarder->listener_table;
}
@@ -295,7 +453,8 @@ void forwarder_cs_set_size(forwarder_t *forwarder, size_t size) {
if (pkt_cache_set_cs_size(forwarder->pkt_cache, size) < 0) {
ERROR(
"Unable to resize the CS: provided maximum size (%u) is smaller than "
- "the number of elements currently stored in the CS (%u). Clear the CS "
+ "the number of elements currently stored in the CS (%u). Clear the "
+ "CS "
"and retry.",
size, pkt_cache_get_cs_size(forwarder->pkt_cache));
}
@@ -335,11 +494,11 @@ static ssize_t forwarder_drop(forwarder_t *forwarder, off_t msgbuf_id) {
const msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
switch (msgbuf_get_type(msgbuf)) {
- case MSGBUF_TYPE_INTEREST:
+ case HICN_PACKET_TYPE_INTEREST:
forwarder->stats.countInterestsDropped++;
break;
- case MSGBUF_TYPE_DATA:
+ case HICN_PACKET_TYPE_DATA:
forwarder->stats.countObjectsDropped++;
break;
@@ -384,7 +543,7 @@ static ssize_t forwarder_forward_via_connection(forwarder_t *forwarder,
// Here we need to update the path label of a data packet before send
// it. The path label update can be done here because the packet is sent
// directly to the socket
- if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA)
+ if (msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA)
msgbuf_update_pathlabel(msgbuf, connection_get_id(conn));
bool success = connection_send_packet(conn, msgbuf_get_packet(msgbuf),
@@ -415,11 +574,11 @@ static ssize_t forwarder_forward_via_connection(forwarder_t *forwarder,
}
switch (msgbuf_get_type(msgbuf)) {
- case MSGBUF_TYPE_INTEREST:
+ case HICN_PACKET_TYPE_INTEREST:
forwarder->stats.countInterestForwarded++;
break;
- case MSGBUF_TYPE_DATA:
+ case HICN_PACKET_TYPE_DATA:
forwarder->stats.countObjectsForwarded++;
break;
@@ -451,7 +610,6 @@ static unsigned forwarder_forward_to_nexthops(forwarder_t *forwarder,
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
unsigned ingressId = msgbuf_get_connection_id(msgbuf);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
// DEBUG("[forwarder_forward_to_nexthops] - nexthop = %d");
if (nexthop == ingressId) continue;
@@ -469,43 +627,57 @@ static bool forwarder_forward_via_fib(forwarder_t *forwarder, off_t msgbuf_id,
pkt_cache_entry_t *entry) {
assert(forwarder && entry && msgbuf_id_is_valid(msgbuf_id));
+ bool ret = true;
+
const msgbuf_pool_t *msgbuf_pool = forwarder_get_msgbuf_pool(forwarder);
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
- assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
- fib_entry_t *fib_entry = fib_match_message(forwarder->fib, msgbuf);
+ fib_entry_t *fib_entry = fib_match_msgbuf(forwarder->fib, msgbuf);
if (!fib_entry) return false;
- // DEBUG("[forwarder] Getting nexthops from strategy");
- nexthops_t *nexthops = fib_entry_get_nexthops_from_strategy(
- fib_entry, msgbuf, verdict == PKT_CACHE_VERDICT_RETRANSMIT_INTEREST);
+ nexthops_t *nexthops = fib_entry_get_nexthops(fib_entry);
+
+ /* Backup flags and cur_len*/
+ uint_fast32_t flags = nexthops->flags;
+ size_t cur_len = nexthops_get_curlen(nexthops);
+
+ /* This affects the nexthops */
+ nexthops = strategy_lookup_nexthops(&fib_entry->strategy, nexthops, msgbuf);
if (nexthops_get_curlen(nexthops) == 0) {
ERROR("Message %p returned an empty next hop set", msgbuf);
- return false;
+ ret = false;
+ goto END;
}
pit_entry_t *pit_entry = &entry->u.pit_entry;
- if (!pit_entry) return false;
+ if (!pit_entry) {
+ ret = false;
+ goto END;
+ }
pit_entry_set_fib_entry(pit_entry, fib_entry);
// this requires some additional checks. It may happen that some of the output
// faces selected by the forwarding strategy are not usable. So far all the
// forwarding strategy return only valid faces (or an empty list)
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
// DEBUG("Adding egress to PIT for nexthop %d", nexthop);
pit_entry_egress_add(pit_entry, nexthop);
});
if (forwarder_forward_to_nexthops(forwarder, msgbuf_id, nexthops) <= 0) {
- // this should never happen
- ERROR("Message %p returned an empty next hop set", msgbuf);
- return false;
+ ERROR("Error forwarding mMessage %p to next hops", msgbuf);
+ ret = false;
}
- return true;
+END:
+ /* Restore flags & curlen */
+ nexthops->flags = flags;
+ nexthops->cur_elts = cur_len;
+
+ return ret;
}
#endif /* ! BYPASS_FIB */
@@ -519,7 +691,7 @@ int _forwarder_forward_upon_interest(
// - Aggregation can be perfomed, do not forward
if (verdict == PKT_CACHE_VERDICT_AGGREGATE_INTEREST) {
forwarder_drop(forwarder, interest_msgbuf_id);
- return msgbuf_get_len(msgbuf);
+ return (int)msgbuf_get_len(msgbuf);
}
// - Data packet matching the interest was found, forward reply
@@ -532,12 +704,12 @@ int _forwarder_forward_upon_interest(
msgbuf_reset_pathlabel(data_msgbuf);
forwarder_forward_via_connection(forwarder, data_msgbuf_id,
msgbuf_get_connection_id(interest_msgbuf));
- return msgbuf_get_len(msgbuf);
+ return (int)msgbuf_get_len(msgbuf);
}
// - For aggregated interest, the interest forwarding is done in
// `_forwarder_forward_aggregated_interest()`
- if (is_aggregated) return msgbuf_get_len(msgbuf);
+ if (is_aggregated) return (int)msgbuf_get_len(msgbuf);
// - Try to forward the interest
int rc =
@@ -552,7 +724,7 @@ int _forwarder_forward_upon_interest(
return -1;
}
- return msgbuf_get_len(msgbuf);
+ return (int)msgbuf_get_len(msgbuf);
}
static void _forwarder_update_interest_stats(forwarder_t *forwarder,
@@ -601,54 +773,60 @@ static void _forwarder_update_interest_stats(forwarder_t *forwarder,
}
}
+/**
+ * Return the interest manifest from the interest payload
+ */
static interest_manifest_header_t *_forwarder_get_interest_manifest(
msgbuf_t *msgbuf) {
- uint8_t *packet = msgbuf_get_packet(msgbuf);
- hicn_header_t *header = (hicn_header_t *)packet;
- hicn_type_t type = hicn_header_to_type(header);
+ uint8_t *payload;
+ size_t payload_size;
- hicn_payload_type_t payload_type;
- int rc = hicn_ops_vft[type.l1]->get_payload_type(type, &header->protocol,
- &payload_type);
- _ASSERT(rc == HICN_LIB_ERROR_NONE);
- if (payload_type != HPT_MANIFEST) return NULL;
+ hicn_packet_buffer_t *pkbuf = msgbuf_get_pkbuf(msgbuf);
- size_t header_length, payload_length;
- rc = hicn_ops_vft[type.l1]->get_header_length(type, &header->protocol,
- &header_length);
+ hicn_payload_type_t payload_type;
+ HICN_UNUSED(int rc) = hicn_packet_get_payload_type(pkbuf, &payload_type);
assert(rc == HICN_LIB_ERROR_NONE);
- rc = hicn_ops_vft[type.l1]->get_payload_length(type, &header->protocol,
- &payload_length);
- assert(rc == HICN_LIB_ERROR_NONE);
+ if (payload_type != HPT_MANIFEST) return NULL;
- u8 *payload = (u8 *)header + header_length;
- interest_manifest_header_t *int_manifest_header =
- (interest_manifest_header_t *)payload;
- if (!interest_manifest_is_valid(int_manifest_header, payload_length))
- return NULL;
+ rc = hicn_packet_get_payload(pkbuf, &payload, &payload_size, false);
+ _ASSERT(rc == HICN_LIB_ERROR_NONE);
- return int_manifest_header;
+ return (interest_manifest_header_t *)payload;
}
// Manifest is split using splitting strategy, then every
// sub-manifest is sent using the forwarding strategy defined for the prefix
int _forwarder_forward_aggregated_interest(
forwarder_t *forwarder, interest_manifest_header_t *int_manifest_header,
- int n_suffixes_to_fwd, msgbuf_t *msgbuf, off_t msgbuf_id,
- pkt_cache_entry_t **entries) {
+ msgbuf_t *msgbuf, off_t msgbuf_id, pkt_cache_entry_t **entries) {
assert(msgbuf_id_is_valid(msgbuf_id) &&
- msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
+ msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
- fib_entry_t *fib_entry = fib_match_message(forwarder->fib, msgbuf);
- if (!fib_entry) return -1;
+ bool ret = -1;
+
+ fib_entry_t *fib_entry = fib_match_msgbuf(forwarder->fib, msgbuf);
+ if (!fib_entry) goto END;
+
+ nexthops_t *nexthops = fib_entry_get_nexthops(fib_entry);
+ if (nexthops_get_curlen(nexthops) == 0) {
+ ret = 0;
+ goto END;
+ }
- int n_suffixes_per_split = N_SUFFIXES_PER_SPIT;
+ /* Backup flags and cur_len*/
+ uint_fast32_t flags = nexthops->flags;
+ size_t cur_len = nexthops_get_curlen(nexthops);
+
+ size_t n_suffixes_per_split = configuration_get_suffixes_per_split(
+ forwarder_get_configuration(forwarder));
+ int_manifest_split_strategy_t disaggregation_strategy =
+ configuration_get_split_strategy(forwarder_get_configuration(forwarder));
switch (disaggregation_strategy) {
- case INT_MANIFEST_SPLIT_NONE:
+ case INT_MANIFEST_SPLIT_STRATEGY_NONE:
n_suffixes_per_split = int_manifest_header->n_suffixes + 1;
- case INT_MANIFEST_SPLIT_MAX_N_SUFFIXES: {
+ case INT_MANIFEST_SPLIT_STRATEGY_MAX_N_SUFFIXES: {
// Generate sub-manifests: same as original manifest,
// but different suffix in the header and different bitmap
@@ -658,11 +836,11 @@ int _forwarder_forward_aggregated_interest(
// Save copy of original bitmap to use as a reference
// to generate bitmaps for sub-manifests
- u32 original_bitmap[BITMAP_SIZE] = {0};
+ hicn_uword original_bitmap[BITMAP_SIZE] = {0};
memcpy(&original_bitmap, int_manifest_header->request_bitmap,
- BITMAP_SIZE * sizeof(u32));
+ BITMAP_SIZE * sizeof(hicn_uword));
- int suffix_index = 0; // Position of suffix in initial manifest
+ size_t suffix_index = 0; // Position of suffix in initial manifest
while (suffix_index < total_suffixes) {
// If more than one sub-manifest,
// clone original interest manifest and update suffix
@@ -677,38 +855,48 @@ int _forwarder_forward_aggregated_interest(
msgbuf = clone;
}
- u32 curr_bitmap[BITMAP_SIZE] = {0};
- int first_suffix_index_in_submanifest = suffix_index;
+ hicn_uword curr_bitmap[BITMAP_SIZE] = {0};
+ size_t first_suffix_index_in_submanifest = suffix_index;
suffix_index = interest_manifest_update_bitmap(
original_bitmap, curr_bitmap, suffix_index, total_suffixes,
n_suffixes_per_split);
- int first_suffix_index_in_next_submanifest = suffix_index;
+ size_t first_suffix_index_in_next_submanifest = suffix_index;
// Update manifest bitmap in current msgbuf
interest_manifest_header_t *manifest =
_forwarder_get_interest_manifest(msgbuf);
assert(manifest != NULL);
memcpy(manifest->request_bitmap, curr_bitmap,
- BITMAP_SIZE * sizeof(u32));
+ BITMAP_SIZE * sizeof(hicn_uword));
WITH_TRACE({
bitmap_print(manifest->request_bitmap, BITMAP_SIZE);
printf("\n");
});
- // Update PIT entries for suffixes in current sub-manifest
- nexthops_t *nexthops =
- fib_entry_get_nexthops_from_strategy(fib_entry, msgbuf, false);
- if (nexthops_get_curlen(nexthops) == 0) return -1;
+ /*
+ * Update PIT entries for suffixes in current sub-manifest.
+ *
+ * Note that strategy lookup affects the nexthops, and we need to
+ *restore the initial state before every lookup
+ */
+ nexthops->flags = flags;
+ nexthops->cur_elts = cur_len;
+ nexthops =
+ strategy_lookup_nexthops(&fib_entry->strategy, nexthops, msgbuf);
+
+ if (nexthops_get_curlen(nexthops) == 0) {
+ ERROR("Message %p returned an empty next hop set", msgbuf);
+ goto RESTORE;
+ }
- for (int i = first_suffix_index_in_submanifest;
+ for (size_t i = first_suffix_index_in_submanifest;
i < first_suffix_index_in_next_submanifest; i++) {
- if (!is_bit_set(manifest->request_bitmap, i)) continue;
+ if (!bitmap_is_set_no_check(manifest->request_bitmap, i)) continue;
pit_entry_t *pit_entry = &(entries[i]->u.pit_entry);
- if (!pit_entry) return -1;
+ if (!pit_entry) goto RESTORE;
pit_entry_set_fib_entry(pit_entry, fib_entry);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop,
{ pit_entry_egress_add(pit_entry, nexthop); });
}
@@ -722,12 +910,21 @@ int _forwarder_forward_aggregated_interest(
total_len += msgbuf_get_len(msgbuf);
}
- return total_len;
+ ret = total_len;
+ goto END;
}
default:
- return -1;
+ break;
}
+
+RESTORE:
+ /* Restore flags & curlen */
+ nexthops->flags = flags;
+ nexthops->cur_elts = cur_len;
+
+END:
+ return ret;
}
static ssize_t forwarder_process_single_interest(forwarder_t *forwarder,
@@ -742,6 +939,7 @@ static ssize_t forwarder_process_single_interest(forwarder_t *forwarder,
pkt_cache_on_interest(forwarder->pkt_cache, msgbuf_pool, msgbuf_id, &verdict,
&data_msgbuf_id, &entry, msgbuf_get_name(msgbuf),
forwarder->serve_from_cs);
+
_forwarder_update_interest_stats(forwarder, verdict, msgbuf,
entry->has_expire_ts, entry->expire_ts);
@@ -749,9 +947,7 @@ static ssize_t forwarder_process_single_interest(forwarder_t *forwarder,
forwarder, msgbuf_pool, data_msgbuf_id, msgbuf_id, entry, verdict, false);
// No route when trying to forward interest, remove from PIT
- if (rc == -1)
- pkt_cache_pit_remove_entry(forwarder->pkt_cache, entry,
- msgbuf_get_name(msgbuf));
+ if (rc == -1) pkt_cache_pit_remove_entry(forwarder->pkt_cache, entry);
return msgbuf_get_len(msgbuf);
}
@@ -769,15 +965,16 @@ static ssize_t forwarder_process_aggregated_interest(
int pos = 0; // Position of current suffix in manifest
int n_suffixes_to_fwd = 0;
u32 *suffix = (u32 *)(int_manifest_header + 1);
- u32 seq = name_GetSegment(msgbuf_get_name(msgbuf));
+ u32 seq = hicn_name_get_suffix(msgbuf_get_name(msgbuf));
- Name name_copy = EMPTY_NAME;
- name_Copy(msgbuf_get_name(msgbuf), &name_copy);
+ hicn_name_t name_copy = HICN_NAME_EMPTY;
+ hicn_name_copy(&name_copy, msgbuf_get_name(msgbuf));
// The fist loop iteration handles the suffix in the header,
// the following ones handle the suffiexes in the manifest
while (true) {
- if (!is_bit_set(int_manifest_header->request_bitmap, pos)) goto NEXT_SUFFIX;
+ if (!bitmap_is_set_no_check(int_manifest_header->request_bitmap, pos))
+ goto NEXT_SUFFIX;
// Update packet cache
pkt_cache_on_interest(forwarder->pkt_cache, msgbuf_pool, msgbuf_id,
@@ -794,14 +991,13 @@ static ssize_t forwarder_process_aggregated_interest(
msgbuf_id, entry, verdict, true);
// No route when trying to forward interest, remove from PIT
- if (rc == -1)
- pkt_cache_pit_remove_entry(forwarder->pkt_cache, entry, &name_copy);
+ if (rc == -1) pkt_cache_pit_remove_entry(forwarder->pkt_cache, entry);
// Unset in bitmap if no interest forwarding needed,
// otherwise increase count of suffixes to forward
if (rc == -1 || verdict == PKT_CACHE_VERDICT_AGGREGATE_INTEREST ||
verdict == PKT_CACHE_VERDICT_FORWARD_DATA) {
- unset_bit(int_manifest_header->request_bitmap, pos);
+ bitmap_unset_no_check(int_manifest_header->request_bitmap, pos);
} else {
n_suffixes_to_fwd++;
}
@@ -812,12 +1008,15 @@ static ssize_t forwarder_process_aggregated_interest(
// Use next segment in manifest
seq = *suffix;
suffix++;
- name_SetSegment(&name_copy, seq);
+ hicn_name_set_suffix(&name_copy, seq);
WITH_DEBUG({
- char *nameString = name_ToString(&name_copy);
- DEBUG("Next in manifest: %s", nameString);
- free(nameString);
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc =
+ hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
+ DEBUG("Next in manifest: %s", buf);
});
}
@@ -825,8 +1024,7 @@ static ssize_t forwarder_process_aggregated_interest(
if (n_suffixes_to_fwd == 0) return msgbuf_get_len(msgbuf);
return _forwarder_forward_aggregated_interest(forwarder, int_manifest_header,
- n_suffixes_to_fwd, msgbuf,
- msgbuf_id, entries);
+ msgbuf, msgbuf_id, entries);
}
/**
@@ -850,7 +1048,7 @@ static ssize_t forwarder_process_interest(forwarder_t *forwarder,
connection_t *conn =
connection_table_get_by_id(table, msgbuf_get_connection_id(msgbuf));
- assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
u32 n_suffixes = 0;
interest_manifest_header_t *int_manifest_header =
@@ -863,16 +1061,20 @@ static ssize_t forwarder_process_interest(forwarder_t *forwarder,
conn->stats.interests.rx_bytes += msgbuf_get_len(msgbuf);
WITH_DEBUG({
- char *nameString = name_ToString(msgbuf_get_name(msgbuf));
- DEBUG("INTEREST (%s) suffixes=%u msgbuf_id=%lu ingress=%u length=%u",
- nameString, n_suffixes, msgbuf_id, msgbuf_get_connection_id(msgbuf),
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
+ DEBUG("INTEREST (%s) msgbuf_id=%lu ingress=%u length=%u", buf, msgbuf_id,
+ msgbuf_get_connection_id(msgbuf), msgbuf_get_len(msgbuf));
+ DEBUG("INTEREST (%s) suffixes=%u msgbuf_id=%lu ingress=%u length=%u", buf,
+ n_suffixes, msgbuf_id, msgbuf_get_connection_id(msgbuf),
msgbuf_get_len(msgbuf));
- free(nameString);
});
// Cache suffixes for current prefix to (possibly) avoid double lookups
pkt_cache_save_suffixes_for_prefix(
- forwarder->pkt_cache, name_GetContentName(msgbuf_get_name(msgbuf)));
+ forwarder->pkt_cache, hicn_name_get_prefix(msgbuf_get_name(msgbuf)));
if (!int_manifest_header)
return forwarder_process_single_interest(forwarder, msgbuf_pool, msgbuf,
@@ -888,7 +1090,9 @@ static void _forwarder_log_on_data(forwarder_t *forwarder,
DEBUG("Message added to CS from PIT");
break;
case PKT_CACHE_VERDICT_STORE_DATA:
- DEBUG("Message added to CS (expired or no previous interest pending)");
+ DEBUG(
+ "Message added to CS (expired or no previous interest "
+ "pending)");
break;
case PKT_CACHE_VERDICT_CLEAR_DATA:
break;
@@ -921,10 +1125,12 @@ static ssize_t forwarder_process_data(forwarder_t *forwarder, off_t msgbuf_id) {
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
WITH_DEBUG({
- char *nameString = name_ToString(msgbuf_get_name(msgbuf));
- DEBUG("DATA (%s) msgbuf_id=%lu ingress=%u length=%u", nameString, msgbuf_id,
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
+ DEBUG("DATA (%s) msgbuf_id=%lu ingress=%u length=%u", buf, msgbuf_id,
msgbuf_get_connection_id(msgbuf), msgbuf_get_len(msgbuf));
- free(nameString);
});
const connection_table_t *table = forwarder_get_connection_table(forwarder);
@@ -938,7 +1144,7 @@ static ssize_t forwarder_process_data(forwarder_t *forwarder, off_t msgbuf_id) {
// Cache suffixes for current prefix to (possibly) avoid double lookups
pkt_cache_save_suffixes_for_prefix(
- forwarder->pkt_cache, name_GetContentName(msgbuf_get_name(msgbuf)));
+ forwarder->pkt_cache, hicn_name_get_prefix(msgbuf_get_name(msgbuf)));
pkt_cache_verdict_t verdict = PKT_CACHE_VERDICT_ERROR;
bool wrong_egress;
@@ -955,17 +1161,13 @@ static ssize_t forwarder_process_data(forwarder_t *forwarder, off_t msgbuf_id) {
forwarder->stats.countDroppedNoReversePath++;
DEBUG("Message %lu did not match PIT, no reverse path", msgbuf_id);
- // MOVE PROBE HOOK ELSEWHERE
- // XXX relationship with forwarding strategy... insert hooks
- // if the packet is a probe we need to analyze it
// NOTE : probes are not stored in PIT
if (msgbuf_is_probe(msgbuf)) {
- fib_entry_t *entry = fib_match_message(forwarder->fib, msgbuf);
+ fib_entry_t *entry = fib_match_msgbuf(forwarder->fib, msgbuf);
if (entry && fib_entry_strategy_type(entry) == STRATEGY_TYPE_BESTPATH) {
nexthops_t probe_nexthops = NEXTHOPS_EMPTY;
nexthops_add(&probe_nexthops, msgbuf_get_connection_id(msgbuf));
fib_entry_on_data(entry, &probe_nexthops, msgbuf, 0, ticks_now());
- // XXX TODO CONFIRM WE DON'T EXIT HERE ?
}
}
forwarder_drop(forwarder, msgbuf_id);
@@ -982,7 +1184,8 @@ void forwarder_flush_connections(forwarder_t *forwarder) {
// DEBUG("[forwarder_flush_connections]");
const connection_table_t *table = forwarder_get_connection_table(forwarder);
- for (unsigned i = 0; i < vector_len(forwarder->pending_conn); i++) {
+ unsigned num_pending_conn = (unsigned)vector_len(forwarder->pending_conn);
+ for (unsigned i = 0; i < num_pending_conn; i++) {
unsigned conn_id = forwarder->pending_conn[i];
connection_t *conn = connection_table_at(table, conn_id);
if (!connection_flush(conn)) {
@@ -994,14 +1197,15 @@ void forwarder_flush_connections(forwarder_t *forwarder) {
// DEBUG("[forwarder_flush_connections] done");
}
+#if WITH_WLDR
// XXX move to wldr file, worst case in connection.
void forwarder_apply_wldr(const forwarder_t *forwarder, const msgbuf_t *msgbuf,
connection_t *connection) {
- // this are the checks needed to implement WLDR. We set wldr only on the STAs
- // and we let the AP to react according to choice of the client.
- // if the STA enables wldr using the set command, the AP enable wldr as well
- // otherwise, if the STA disable it the AP remove wldr
- // WLDR should be enabled only on the STAs using the command line
+ // this are the checks needed to implement WLDR. We set wldr only on the
+ // STAs and we let the AP to react according to choice of the client. if
+ // the STA enables wldr using the set command, the AP enable wldr as
+ // well otherwise, if the STA disable it the AP remove wldr WLDR should
+ // be enabled only on the STAs using the command line
// TODO
// disable WLDR command line on the AP
if (msgbuf_has_wldr(msgbuf)) {
@@ -1023,8 +1227,10 @@ void forwarder_apply_wldr(const forwarder_t *forwarder, const msgbuf_t *msgbuf,
}
}
}
+#endif
-bool forwarder_add_or_update_route(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_add_or_update_route(forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
unsigned ingress_id) {
assert(forwarder);
assert(prefix);
@@ -1032,7 +1238,7 @@ bool forwarder_add_or_update_route(forwarder_t *forwarder, ip_prefix_t *prefix,
configuration_t *config = forwarder_get_configuration(forwarder);
char prefix_s[MAXSZ_IP_PREFIX];
- int rc = ip_prefix_snprintf(prefix_s, MAXSZ_IP_PREFIX, prefix);
+ int rc = hicn_ip_prefix_snprintf(prefix_s, MAXSZ_IP_PREFIX, prefix);
assert(rc < MAXSZ_IP_PREFIX);
if (rc < 0) return false;
@@ -1041,9 +1247,9 @@ bool forwarder_add_or_update_route(forwarder_t *forwarder, ip_prefix_t *prefix,
// XXX TODO this should store options too
strategy_type_t strategy_type = configuration_get_strategy(config, prefix_s);
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, prefix->family, prefix->address,
- prefix->len);
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&prefix->address, prefix->len,
+ &name_prefix);
fib_entry_t *entry = fib_contains(forwarder->fib, &name_prefix);
if (!entry) {
entry = fib_entry_create(&name_prefix, strategy_type, NULL, forwarder);
@@ -1054,17 +1260,19 @@ bool forwarder_add_or_update_route(forwarder_t *forwarder, ip_prefix_t *prefix,
fib_entry_nexthops_add(entry, ingress_id);
}
+ forwarder_on_route_event(forwarder, entry);
+
return true;
}
-bool forwarder_remove_route(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_remove_route(forwarder_t *forwarder, hicn_ip_prefix_t *prefix,
unsigned ingress_id) {
assert(forwarder);
assert(prefix);
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, prefix->family, prefix->address,
- prefix->len);
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&prefix->address, prefix->len,
+ &name_prefix);
fib_remove(forwarder->fib, &name_prefix, ingress_id);
return true;
@@ -1072,31 +1280,32 @@ bool forwarder_remove_route(forwarder_t *forwarder, ip_prefix_t *prefix,
#ifdef WITH_POLICY
-bool forwarder_add_or_update_policy(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_add_or_update_policy(forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
hicn_policy_t *policy) {
assert(forwarder);
assert(prefix);
assert(policy);
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, prefix->family, prefix->address,
- prefix->len);
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&prefix->address, prefix->len,
+ &name_prefix);
fib_entry_t *entry = fib_contains(forwarder->fib, &name_prefix);
if (!entry) return false;
+
fib_entry_set_policy(entry, *policy);
return true;
}
-bool forwarder_remove_policy(forwarder_t *forwarder, ip_prefix_t *prefix) {
+bool forwarder_remove_policy(forwarder_t *forwarder, hicn_ip_prefix_t *prefix) {
assert(forwarder);
assert(prefix);
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, prefix->family, prefix->address,
- prefix->len);
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&prefix->address, prefix->len,
+ &name_prefix);
fib_entry_t *entry = fib_contains(forwarder->fib, &name_prefix);
-
if (!entry) return false;
fib_entry_set_policy(entry, POLICY_EMPTY);
@@ -1106,14 +1315,30 @@ bool forwarder_remove_policy(forwarder_t *forwarder, ip_prefix_t *prefix) {
#endif /* WITH_POLICY */
-void forwarder_remove_connection_id_from_routes(forwarder_t *forwarder,
+void forwarder_remove_connection_id_from_routes(const forwarder_t *forwarder,
unsigned connection_id) {
+ fib_entry_t **removed_entries = NULL;
+ size_t num_removed_entries;
+
assert(forwarder);
- fib_remove_connection_id(forwarder->fib, connection_id);
+ fib_remove_connection(forwarder->fib, connection_id, &removed_entries,
+ &num_removed_entries);
+
+ if (num_removed_entries > 0) {
+ assert(removed_entries);
+
+ for (int i = 0; i < num_removed_entries; i++) {
+ fib_entry_t *entry = removed_entries[i];
+ forwarder_on_route_event(forwarder, entry);
+ fib_remove_entry(forwarder->fib, entry);
+ }
+ free(removed_entries);
+ }
}
-void forwarder_add_strategy_options(forwarder_t *forwarder, Name *name_prefix,
+void forwarder_add_strategy_options(forwarder_t *forwarder,
+ hicn_prefix_t *name_prefix,
strategy_type_t strategy_type,
strategy_options_t *strategy_options) {
assert(forwarder);
@@ -1127,18 +1352,18 @@ void forwarder_add_strategy_options(forwarder_t *forwarder, Name *name_prefix,
fib_entry_add_strategy_options(entry, strategy_type, strategy_options);
}
-void forwarder_set_strategy(forwarder_t *forwarder, Name *name_prefix,
+void forwarder_set_strategy(forwarder_t *forwarder, hicn_prefix_t *prefix,
strategy_type_t strategy_type,
strategy_options_t *strategy_options) {
assert(forwarder);
- assert(name_prefix);
+ assert(prefix);
assert(STRATEGY_TYPE_VALID(strategy_type));
/* strategy_options might be NULL */
- fib_entry_t *entry = fib_contains(forwarder->fib, name_prefix);
+ fib_entry_t *entry = fib_contains(forwarder->fib, prefix);
if (!entry) {
- // there is no exact match. so if the forwarding strategy is not in the list
- // of strategies that can be set by the transport, return
+ // there is no exact match. so if the forwarding strategy is not in
+ // the list of strategies that can be set by the transport, return
if (strategy_type != STRATEGY_TYPE_BESTPATH &&
strategy_type != STRATEGY_TYPE_REPLICATION) {
return;
@@ -1148,7 +1373,7 @@ void forwarder_set_strategy(forwarder_t *forwarder, Name *name_prefix,
// no knowledge of the length of the prefix. so we apply the strategy at the
// matching fib entry, which later will be the one that will be used to send
// interests with this name
- entry = fib_match_name(forwarder->fib, name_prefix);
+ entry = fib_match_prefix(forwarder->fib, prefix);
if (!entry) {
return; // no fib match, return
}
@@ -1163,10 +1388,11 @@ cs_t *forwarder_get_cs(const forwarder_t *forwarder) {
return pkt_cache_get_cs(forwarder->pkt_cache);
}
-// IMPORTANT: Use this function ONLY for read-only operations since a realloc
-// would otherwise modify the returned copy but not the original msgbuf ids
-// vector in the forwarder. This constraint cannot be enforced by returning a
-// (const off_t *) because the vector_t macros still cast to (void **).
+// IMPORTANT: Use this function ONLY for read-only operations since a
+// realloc would otherwise modify the returned copy but not the original
+// msgbuf ids vector in the forwarder. This constraint cannot be enforced
+// by returning a (const off_t *) because the vector_t macros still cast
+// to (void **).
off_t *forwarder_get_acquired_msgbuf_ids(const forwarder_t *forwarder) {
return forwarder->acquired_msgbuf_ids;
}
@@ -1182,25 +1408,18 @@ void forwarder_acquired_msgbuf_ids_push(const forwarder_t *forwarder,
// =======================================================
-fib_t *forwarder_get_fib(forwarder_t *forwarder) { return forwarder->fib; }
+fib_t *forwarder_get_fib(const forwarder_t *forwarder) {
+ return forwarder->fib;
+}
msgbuf_pool_t *forwarder_get_msgbuf_pool(const forwarder_t *forwarder) {
return forwarder->msgbuf_pool;
}
-#ifdef WITH_MAPME
-void forwarder_on_connection_event(const forwarder_t *forwarder,
- const connection_t *connection,
- connection_event_t event) {
- mapme_on_connection_event(forwarder->mapme, connection, event);
-}
-
mapme_t *forwarder_get_mapme(const forwarder_t *forwarder) {
return forwarder->mapme;
}
-#endif /* WITH_MAPME */
-
#ifdef WITH_POLICY_STATS
const policy_stats_mgr_t *forwarder_get_policy_stats_mgr(
const forwarder_t *forwarder) {
@@ -1209,39 +1428,6 @@ const policy_stats_mgr_t *forwarder_get_policy_stats_mgr(
#endif /* WITH_POLICY_STATS */
/**
- * @brief Process a packet by creating the corresponding message buffer and
- * dispatching it to the forwarder for further processing.
- * @param[in] forwarder Forwarder instance.
- *
- */
-// XXX ??? XXX = process for listener as we are resolving connection id
-//
-
-msgbuf_type_t get_type_from_packet(uint8_t *packet) {
- if (messageHandler_IsTCP(packet)) {
- if (messageHandler_IsData(packet)) {
- return MSGBUF_TYPE_DATA;
- } else if (messageHandler_IsInterest(packet)) {
- return MSGBUF_TYPE_INTEREST;
- } else {
- return MSGBUF_TYPE_UNDEFINED;
- }
-
- } else if (messageHandler_IsWldrNotification(packet)) {
- return MSGBUF_TYPE_WLDR_NOTIFICATION;
-
- } else if (mapme_match_packet(packet)) {
- return MSGBUF_TYPE_MAPME;
-
- } else if (*packet == REQUEST_LIGHT) {
- return MSGBUF_TYPE_COMMAND;
-
- } else {
- return MSGBUF_TYPE_UNDEFINED;
- }
-}
-
-/**
* @brief Finalize (i.e. close fd and free internal data structures)
* the current connection ("SELF") when the command is received.
* The connection cannot be removed inside the command handling
@@ -1268,7 +1454,6 @@ ssize_t forwarder_receive(forwarder_t *forwarder, listener_t *listener,
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
assert(msgbuf);
- uint8_t *packet = msgbuf_get_packet(msgbuf);
size_t size = msgbuf_get_len(msgbuf);
/* Connection lookup */
@@ -1281,81 +1466,128 @@ ssize_t forwarder_receive(forwarder_t *forwarder, listener_t *listener,
assert((conn_id != CONNECTION_ID_UNDEFINED) || listener);
+#if 0
+ /*
+ * We have a msgbuf with payload and size, we nee to populate other
+ * information, including packet type etc.
+ */
msgbuf_type_t type = get_type_from_packet(msgbuf_get_packet(msgbuf));
forwarder->stats.countReceived++;
msgbuf->type = type;
+#endif
+ /* Initialize packet buffer stored in msgbuf through libhicn */
+ msgbuf_initialize_from_packet(msgbuf);
+ hicn_packet_analyze(msgbuf_get_pkbuf(msgbuf));
+
msgbuf->connection_id = conn_id;
msgbuf->recv_ts = now;
- switch (type) {
- case MSGBUF_TYPE_INTEREST:
+ hicn_name_t name;
+
+RETRY:
+
+ switch (msgbuf_get_type(msgbuf)) {
+ case HICN_PACKET_TYPE_INTEREST:
if (!connection_id_is_valid(msgbuf->connection_id)) {
char conn_name[SYMBOLIC_NAME_LEN];
int rc = connection_table_get_random_name(table, conn_name);
- if (rc < 0) return 0;
+ if (rc < 0) {
+ ERROR("Could not create name for new connection");
+ goto DROP;
+ }
unsigned connection_id =
listener_create_connection(listener, conn_name, pair);
+ if (connection_id == CONNECTION_ID_UNDEFINED) {
+ ERROR("Could not create new connection");
+ goto DROP;
+ }
msgbuf->connection_id = connection_id;
connection = connection_table_get_by_id(table, connection_id);
}
msgbuf->path_label = 0; // not used for interest packets
- name_create_from_interest(packet, msgbuf_get_name(msgbuf));
+ hicn_interest_get_name(msgbuf_get_pkbuf(msgbuf), &name);
+ msgbuf_set_name(msgbuf, &name);
+#ifdef WITH_WLDR
forwarder_apply_wldr(forwarder, msgbuf, connection);
+#endif /* WITH_WLDR */
forwarder_process_interest(forwarder, msgbuf_id);
pkt_cache_log(forwarder->pkt_cache);
- return size;
+ break;
- case MSGBUF_TYPE_DATA:
- if (!connection_id_is_valid(msgbuf->connection_id))
- return forwarder_drop(forwarder, msgbuf_id);
+ case HICN_PACKET_TYPE_DATA:
+ /* This include probes */
+ if (!connection_id_is_valid(msgbuf->connection_id)) {
+ ERROR("Invalid connection for data packet");
+ goto DROP;
+ }
msgbuf_init_pathlabel(msgbuf);
- name_create_from_data(packet, msgbuf_get_name(msgbuf));
+ hicn_data_get_name(msgbuf_get_pkbuf(msgbuf), &name);
+ msgbuf_set_name(msgbuf, &name);
+#ifdef WITH_WLDR
forwarder_apply_wldr(forwarder, msgbuf, connection);
+#endif /* WITH_WLDR */
forwarder_process_data(forwarder, msgbuf_id);
pkt_cache_log(forwarder->pkt_cache);
- return size;
+ break;
- case MSGBUF_TYPE_WLDR_NOTIFICATION:
- if (!connection_id_is_valid(msgbuf->connection_id))
- return forwarder_drop(forwarder, msgbuf_id);
+ case HICN_PACKET_TYPE_WLDR_NOTIFICATION:
+ if (!connection_id_is_valid(msgbuf->connection_id)) {
+ ERROR("Invalid connection for WLDR packet");
+ goto DROP;
+ }
connection_wldr_handle_notification(connection, msgbuf);
- return size;
+ break;
- case MSGBUF_TYPE_MAPME:
+ case HICN_PACKET_TYPE_MAPME:
// XXX what about acks ?
if (!connection_id_is_valid(msgbuf->connection_id)) {
char conn_name[SYMBOLIC_NAME_LEN];
int rc = connection_table_get_random_name(table, conn_name);
- if (rc < 0) return 0;
+ if (rc < 0) {
+ ERROR("Could not create name for new connection");
+ goto DROP;
+ }
- msgbuf->connection_id =
+ unsigned connection_id =
listener_create_connection(listener, conn_name, pair);
+ if (connection_id == CONNECTION_ID_UNDEFINED) {
+ ERROR("Could not create new connection");
+ goto DROP;
+ }
+ msgbuf->connection_id = connection_id;
}
mapme_process(forwarder->mapme, msgbuf);
- return size;
+ break;
- case MSGBUF_TYPE_COMMAND:
+ case HICN_PACKET_TYPE_COMMAND:
// Create the connection to send the ack back
if (!connection_id_is_valid(msgbuf->connection_id)) {
char conn_name[SYMBOLIC_NAME_LEN];
int rc = connection_table_get_random_name(table, conn_name);
- if (rc < 0) return 0;
+ if (rc < 0) {
+ ERROR("Could not create name for new connection");
+ goto DROP;
+ }
unsigned connection_id =
listener_create_connection(listener, conn_name, pair);
+ if (connection_id == CONNECTION_ID_UNDEFINED) {
+ ERROR("Could not create new connection");
+ goto DROP;
+ }
msgbuf->connection_id = connection_id;
connection = connection_table_get_by_id(table, connection_id);
}
- msg_header_t *msg = (msg_header_t *)packet;
+ msg_header_t *msg = (msg_header_t *)msgbuf_get_packet(msgbuf);
msgbuf->command.type = msg->header.command_id;
if (!command_type_is_valid(msgbuf->command.type)) {
- ERROR("Invalid command");
- return 0;
+ ERROR("Invalid command %d", msgbuf->command.type);
+ goto DROP;
}
size = command_process_msgbuf(forwarder, msgbuf);
@@ -1364,19 +1596,32 @@ ssize_t forwarder_receive(forwarder_t *forwarder, listener_t *listener,
return size;
default:
- ERROR("Invalid msgbuf type");
- forwarder_drop(forwarder, msgbuf_id);
- return 0;
+ /* Commands are not recognized by the packet parser */
+ if (msgbuf_is_command(msgbuf)) {
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
+ goto RETRY;
+ }
+ goto DROP;
}
+
+ return size;
+
+DROP:
+ forwarder_drop(forwarder, msgbuf_id);
+ return 0;
}
void forwarder_log(forwarder_t *forwarder) {
DEBUG(
"Forwarder: received = %u (interest = %u, data = %u), dropped = %u "
- "(interest = %u, data = %u, other = %u), forwarded = { interests = %u, "
- "data = %u }, dropped = { connection_not_found = %u, send_failure = %u, "
+ "(interest = %u, data = %u, other = %u), forwarded = { interests = "
+ "%u, "
+ "data = %u }, dropped = { connection_not_found = %u, send_failure "
+ "= "
+ "%u, "
"no_route_in_fib = %u }, interest processing = { aggregated = %u, "
- "retransmitted = %u, satisfied_from_cs = %u, expired_interests = %u, "
+ "retransmitted = %u, satisfied_from_cs = %u, expired_interests = "
+ "%u, "
"expired_data = %u }, data processing = { "
"no_reverse_path = %u }\n",
forwarder->stats.countReceived, forwarder->stats.countInterestsReceived,
@@ -1396,4 +1641,4 @@ void forwarder_log(forwarder_t *forwarder) {
forwarder_stats_t forwarder_get_stats(forwarder_t *forwarder) {
return forwarder->stats;
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/core/forwarder.h b/hicn-light/src/hicn/core/forwarder.h
index 2f940cf15..b7ce5ff4d 100644
--- a/hicn-light/src/hicn/core/forwarder.h
+++ b/hicn-light/src/hicn/core/forwarder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -74,7 +74,7 @@ void forwarder_setup_local_listeners(forwarder_t *forwarder, uint16_t port);
configuration_t *forwarder_get_configuration(forwarder_t *forwarder);
-subscription_table_t *forwarder_get_subscriptions(forwarder_t *forwarder);
+subscription_table_t *forwarder_get_subscriptions(const forwarder_t *forwarder);
/**
* Returns the set of currently active listeners
@@ -84,7 +84,7 @@ subscription_table_t *forwarder_get_subscriptions(forwarder_t *forwarder);
* @retval non-null The set of active listeners
* @retval null An error
*/
-listener_table_t *forwarder_get_listener_table(forwarder_t *forwarder);
+listener_table_t *forwarder_get_listener_table(const forwarder_t *forwarder);
/**
* Returns the forwrder's connection table
@@ -122,40 +122,43 @@ void forwarder_cs_clear(forwarder_t *forwarder);
/**
* @brief Adds or updates a route on all the message processors
*/
-bool forwarder_add_or_update_route(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_add_or_update_route(forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
unsigned ingress_id);
/**
* @brief Removes a route from all the message processors
*/
-bool forwarder_remove_route(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_remove_route(forwarder_t *forwarder, hicn_ip_prefix_t *prefix,
unsigned ingress_id);
#ifdef WITH_POLICY
/**
* @brief Adds or updates a policy on the message processor
*/
-bool forwarder_add_or_update_policy(forwarder_t *forwarder, ip_prefix_t *prefix,
+bool forwarder_add_or_update_policy(forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
hicn_policy_t *policy);
/**
* @brief Removes a policy from the message processor
*/
-bool forwarder_remove_policy(forwarder_t *forwarder, ip_prefix_t *prefix);
+bool forwarder_remove_policy(forwarder_t *forwarder, hicn_ip_prefix_t *prefix);
#endif /* WITH_POLICY */
/**
* Removes a connection id from all routes
*/
-void forwarder_remove_connection_id_from_routes(forwarder_t *forwarder,
+void forwarder_remove_connection_id_from_routes(const forwarder_t *forwarder,
unsigned connection_id);
-void forwarder_add_strategy_options(forwarder_t *forwarder, Name *name_prefix,
+void forwarder_add_strategy_options(forwarder_t *forwarder,
+ hicn_prefix_t *name_prefix,
strategy_type_t strategy_type,
strategy_options_t *strategy_options);
-void forwarder_set_strategy(forwarder_t *forwarder, Name *name_prefix,
+void forwarder_set_strategy(forwarder_t *forwarder, hicn_prefix_t *prefix,
strategy_type_t strategy_type,
strategy_options_t *strategy_options);
@@ -178,7 +181,7 @@ void forwarder_acquired_msgbuf_ids_push(const forwarder_t *forwarder,
* @param[in] forwarder - Pointer to the forwarder.
* @returns Pointer to the hICN FIB.
*/
-fib_t *forwarder_get_fib(forwarder_t *forwarder);
+fib_t *forwarder_get_fib(const forwarder_t *forwarder);
/**
* @brief Return the forwarder packet pool.
@@ -190,6 +193,16 @@ msgbuf_pool_t *forwarder_get_msgbuf_pool(const forwarder_t *forwarder);
#ifdef WITH_MAPME
+void forwarder_on_route_event(const forwarder_t *forwarder, fib_entry_t *entry);
+
+int forwarder_add_connection(const forwarder_t *forwarder,
+ const char *symbolic_name, face_type_t type,
+ address_pair_t *pair, policy_tags_t tags,
+ int priority, face_state_t admin_state);
+
+int forwarder_remove_connection(const forwarder_t *forwarder,
+ unsigned connection_id, bool finalize);
+
/**
* @brief Callback fired upon addition of a new connection through the
* control protocol.
diff --git a/hicn-light/src/hicn/core/interest_manifest.c b/hicn-light/src/hicn/core/interest_manifest.c
deleted file mode 100644
index 1be8a3fb5..000000000
--- a/hicn-light/src/hicn/core/interest_manifest.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2022 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 "interest_manifest.h"
-
-int_manifest_split_strategy_t disaggregation_strategy =
- INT_MANIFEST_SPLIT_MAX_N_SUFFIXES;
-unsigned N_SUFFIXES_PER_SPIT = 256;
-
-bool interest_manifest_is_valid(interest_manifest_header_t *int_manifest_header,
- size_t payload_length) {
- if (int_manifest_header->n_suffixes == 0 ||
- int_manifest_header->n_suffixes > MAX_SUFFIXES_IN_MANIFEST) {
- ERROR("Manifest with invalid number of suffixes (%d)",
- int_manifest_header->n_suffixes);
- return false;
- }
-
- uint32_t empty_bitmap[BITMAP_SIZE] = {0};
- if (memcmp(empty_bitmap, int_manifest_header->request_bitmap,
- sizeof(empty_bitmap)) == 0) {
- ERROR("Manifest with empty bitmap");
- return false;
- }
-
- if (payload_length - sizeof(interest_manifest_header_t) !=
- int_manifest_header->n_suffixes * sizeof(u32)) {
- ERROR("Size of suffixes in intereset manifest (%d) is not equal to %d",
- payload_length - sizeof(interest_manifest_header_t),
- int_manifest_header->n_suffixes * sizeof(u32));
- return false;
- }
-
- return true;
-}
-
-int interest_manifest_update_bitmap(const u32 *initial_bitmap,
- u32 *bitmap_to_update, int start, int n,
- int max_suffixes) {
- int i = start, n_ones = 0;
- while (i < n) {
- if (is_bit_set(initial_bitmap, i)) {
- set_bit(bitmap_to_update, i);
- n_ones++;
- }
- i++;
-
- if (n_ones == max_suffixes) break;
- }
-
- return i;
-}
diff --git a/hicn-light/src/hicn/core/interest_manifest.h b/hicn-light/src/hicn/core/interest_manifest.h
deleted file mode 100644
index fcb2b9897..000000000
--- a/hicn-light/src/hicn/core/interest_manifest.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef HICNLIGHT_INTEREST_MANIFEST_H
-#define HICNLIGHT_INTEREST_MANIFEST_H
-
-#include <string.h>
-#include <stdbool.h>
-
-#include <hicn/util/log.h>
-#include <hicn/base.h>
-
-typedef enum {
- INT_MANIFEST_SPLIT_NONE,
- INT_MANIFEST_SPLIT_MAX_N_SUFFIXES
-} int_manifest_split_strategy_t;
-
-extern int_manifest_split_strategy_t disaggregation_strategy;
-extern unsigned N_SUFFIXES_PER_SPIT;
-
-bool interest_manifest_is_valid(interest_manifest_header_t *int_manifest_header,
- size_t payload_length);
-
-int interest_manifest_update_bitmap(const u32 *initial_bitmap,
- u32 *bitmap_to_update, int start, int n,
- int max_suffixes);
-
-#endif /* HICNLIGHT_INTEREST_MANIFEST_H */
diff --git a/hicn-light/src/hicn/core/listener.c b/hicn-light/src/hicn/core/listener.c
index 188f0c317..a3c5c8a12 100644
--- a/hicn-light/src/hicn/core/listener.c
+++ b/hicn-light/src/hicn/core/listener.c
@@ -247,38 +247,8 @@ unsigned listener_create_connection(listener_t *listener,
connection_table_print_by_pair(table);
})
-#if 0
- DEBUG("Notification for new connections");
- // Generate notification message
- flag_interface_type_t interface_type =
- FLAG_INTERFACE_TYPE_WIRED | FLAG_INTERFACE_TYPE_CELLULAR;
- struct {
- cmd_header_t header;
- hc_event_interface_update_t payload;
- } msg = {.header =
- {
- .message_type = NOTIFICATION_LIGHT,
- .command_id = EVENT_INTERFACE_UPDATE,
- .length = 0,
- .seq_num = 0,
- },
- .payload = {.interface_type = interface_type}};
- size_t size = sizeof(msg);
-
- // Retrieve subscribed connections
- subscription_table_t *subscriptions =
- forwarder_get_subscriptions(listener->forwarder);
- unsigned *subscribed_conn_ids = subscription_table_get_connections_for_topic(
- subscriptions, TOPIC_CONNECTION);
-
- // Send notification to subscribed connections
- for (int i = 0; i < vector_len(subscribed_conn_ids); i++) {
- DEBUG("Sending notification to connection: %u", subscribed_conn_ids[i]);
- const connection_t *conn =
- connection_table_at(table, subscribed_conn_ids[i]);
- connection_send_packet(conn, (uint8_t *)&msg, size);
- }
-#endif
+ forwarder_on_connection_event(listener->forwarder, connection,
+ CONNECTION_EVENT_CREATE);
return connection_id;
}
@@ -441,4 +411,4 @@ void listener_setup_local(forwarder_t *forwarder, uint16_t port) {
address_t localhost_ipv6_addr = ADDRESS6_LOCALHOST(port);
listener_create(FACE_TYPE_UDP_LISTENER, &localhost_ipv6_addr, "lo", "lo_udp6",
forwarder);
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/core/listener_table.c b/hicn-light/src/hicn/core/listener_table.c
index 220b738bb..c130399a5 100644
--- a/hicn-light/src/hicn/core/listener_table.c
+++ b/hicn-light/src/hicn/core/listener_table.c
@@ -58,7 +58,7 @@ void listener_table_free(listener_table_t *table) {
kh_foreach(table->id_by_key, k_key, v, {
listener = listener_table_get_by_id(table, v);
name = listener_get_name(listener);
- INFO("Removing listner %s [%d]", name, listener->fd);
+ INFO("Removing listener %s [%d]", name, listener->fd);
listener_finalize(listener);
});
@@ -199,4 +199,4 @@ void listener_table_print_by_name(const listener_table_t *table) {
INFO("%s:%d - %s\t\t\t\t(%u, %s)", addr_str, port, face_type_str(key->type),
v, k);
})
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/core/listener_table.h b/hicn-light/src/hicn/core/listener_table.h
index 7e2e99d7f..27c5daa04 100644
--- a/hicn-light/src/hicn/core/listener_table.h
+++ b/hicn-light/src/hicn/core/listener_table.h
@@ -161,9 +161,13 @@ listener_t *_listener_table_get_by_id(listener_table_t *table, off_t id);
#define listener_table_get_listener_id(table, listener) \
(listener - table->listeners)
-#define listener_table_foreach(table, listener, BODY) \
- pool_foreach( \
- table->listeners, listener, do { BODY } while (0))
+#define listener_table_foreach(table, listener, BODY) \
+ do { \
+ listener_t *listener; \
+ (void)listener; \
+ pool_foreach( \
+ table->listeners, listener, do { BODY } while (0)); \
+ } while (0)
#define listener_table_enumerate(table, i, conn, BODY) \
pool_enumerate(table->listeners, (i), (conn), BODY)
diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c
index dfb30da5c..b151d6cb0 100644
--- a/hicn-light/src/hicn/core/mapme.c
+++ b/hicn-light/src/hicn/core/mapme.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -294,15 +294,6 @@ static void mapme_create_tfib(const mapme_t *mapme, fib_entry_t *entry) {
fib_entry_set_user_data(entry, tfib, (void (*)(void **))mapme_release_tfib);
}
-int hicn_prefix_from_name(const Name *name, hicn_prefix_t *prefix) {
- NameBitvector *bv = name_GetContentName(name);
- ip_prefix_t ip_prefix;
- nameBitvector_ToIPAddress(bv, &ip_prefix);
-
- /* The name length will be equal to ip address' prefix length */
- return hicn_prefix_create_from_ip_prefix(&ip_prefix, prefix);
-}
-
/**
* @brief Update/Notification heuristic:
*
@@ -350,12 +341,14 @@ int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry,
tfib = TFIB(entry);
}
- const Name *name = fib_entry_get_prefix(entry);
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
WITH_DEBUG({
- char *name_str = name_ToString(name);
- DEBUG("sending IU/IN for name %s on all nexthops", name_str);
- free(name_str);
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
+ DEBUG("sending IU/IN for name %s on all nexthops", buf);
})
mapme_params_t params = {
@@ -364,14 +357,8 @@ int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry,
.seq = tfib->seq,
};
- hicn_prefix_t prefix;
- if (hicn_prefix_from_name(name, &prefix) < 0) {
- ERROR("Failed to create lib's name");
- return -1;
- }
-
uint8_t packet[MTU];
- size_t size = hicn_mapme_create_packet(packet, &prefix, &params);
+ size_t size = hicn_mapme_create_packet(packet, prefix, &params);
if (size <= 0) {
ERROR("Could not create MAP-Me packet");
return -1;
@@ -379,7 +366,6 @@ int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry,
connection_table_t *table = forwarder_get_connection_table(mapme->forwarder);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
INFO("sending mapme packet on connection %d", nexthop);
const connection_t *conn = connection_table_get_by_id(table, nexthop);
@@ -389,6 +375,7 @@ int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry,
return 0;
}
+#if 0
/**
*
* Here nexthops is not necessarily FIB nexthops as we might advertise given FIB
@@ -410,6 +397,7 @@ void mapme_maybe_send_to_nexthops(const mapme_t *mapme, fib_entry_t *fib_entry,
mapme_send_to_nexthops(mapme, fib_entry, nexthops);
}
+#endif
/******************************************************************************
* MAPME API
@@ -423,15 +411,16 @@ int mapme_set_all_adjacencies(const mapme_t *mapme, fib_entry_t *entry) {
/* Apply the policy of the fib_entry over all neighbours */
nexthops_t new_nexthops = NEXTHOPS_EMPTY;
- nexthops_t *nexthops =
- fib_entry_get_available_nexthops(entry, ~0, &new_nexthops);
+ nexthops_t *nexthops = fib_entry_get_mapme_nexthops(entry, &new_nexthops);
/* We set force to true to avoid overriding the FIB cache */
- return mapme_set_adjacencies(mapme, entry, nexthops, true);
+ return mapme_set_adjacencies(mapme, entry, nexthops);
}
+// XXX this will change with the FIB cache
+// XXX we are sometimes incrementing tfib seq for nothing
int mapme_set_adjacencies(const mapme_t *mapme, fib_entry_t *entry,
- nexthops_t *nexthops, bool force) {
+ nexthops_t *nexthops) {
if (mapme->enabled == false) {
WARN("MAP-Me is NOT enabled");
return -1;
@@ -449,12 +438,7 @@ int mapme_set_adjacencies(const mapme_t *mapme, fib_entry_t *entry,
nexthops_clear(&tfib->nexthops);
tfib->seq++;
- if (force) {
- mapme_send_to_nexthops(mapme, entry, nexthops);
- return 0;
- }
-
- mapme_maybe_send_to_nexthops(mapme, entry, nexthops);
+ mapme_send_to_nexthops(mapme, entry, nexthops);
return 0;
}
@@ -473,7 +457,7 @@ int mapme_update_adjacencies(const mapme_t *mapme, fib_entry_t *entry,
if (inc_iu_seq) tfib->seq++;
- mapme_maybe_send_to_nexthops(mapme, entry, &tfib->nexthops);
+ mapme_send_to_nexthops(mapme, entry, &tfib->nexthops);
return 0;
}
@@ -490,6 +474,7 @@ int mapme_send_to_nexthop(const mapme_t *mapme, fib_entry_t *entry,
return mapme_send_to_nexthops(mapme, entry, &nexthops);
}
+#if 0
/*
* Callback called everytime a new connection is created by the control protocol
*/
@@ -539,9 +524,9 @@ void mapme_on_connection_event(const mapme_t *mapme,
/* We need to send a MapMe update on the newly selected connections for
* each concerned fib_entry : connection is involved, or no more involved */
const fib_t *fib = forwarder_get_fib(mapme->forwarder);
- fib_entry_t *entry;
fib_foreach_entry(fib, entry, { mapme_set_all_adjacencies(mapme, entry); });
}
+#endif
/*------------------------------------------------------------------------------
* Special Interest handling
@@ -811,30 +796,25 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf,
uint8_t *ack_packet = msgbuf_get_packet(ack);
size_t size = hicn_mapme_create_ack(ack_packet, params);
- if (connection_send_packet(conn_in, ack_packet, size) < 0) {
+ if (!connection_send_packet(conn_in, ack_packet, size)) {
/* We accept the packet knowing we will get a retransmit */
ERROR("Failed to send ACK packet");
}
msgbuf_pool_put(msgbuf_pool, ack);
- /* process received interest */
- uint8_t *packet = msgbuf_get_packet(msgbuf);
- name_create_from_interest(packet, msgbuf_get_name(msgbuf));
- Name name = EMPTY_NAME;
- name_Copy(msgbuf_get_name(msgbuf), &name);
- name_setLen(&name, prefix->len);
-
WITH_DEBUG({
- char *name_str = name_ToString(&name);
- DEBUG("Ack'ed interest : connection=%d prefix=%s seq=%d", ingress_id,
- name_str, params->seq);
- free(name_str);
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ DEBUG("Ack'ed interest : connection=%d prefix=%s seq=%d", ingress_id, buf,
+ params->seq);
});
/* EPM on FIB */
const fib_t *fib = forwarder_get_fib(mapme->forwarder);
- fib_entry_t *entry = fib_contains(fib, &name);
+ fib_entry_t *entry = fib_contains(fib, prefix);
if (!entry) {
#ifdef HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY
if (mapme_create_fib_entry(mapme, &name, ingress_id) < 0) {
@@ -883,7 +863,6 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf,
* This could might optimized for situations where nothing changes, but
* this is very unlikely if not impossible...
* */
- unsigned prevhop;
nexthops_foreach(&entry->nexthops, prevhop,
{ nexthops_add(&tfib->nexthops, prevhop); });
nexthops_remove(&tfib->nexthops, ingress_id);
@@ -943,23 +922,17 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf,
static void mapme_on_data(mapme_t *mapme, msgbuf_t *msgbuf, unsigned ingress_id,
hicn_prefix_t *prefix, mapme_params_t *params) {
- INFO("Receive IU/IN Ack on connection %d", ingress_id);
-
- uint8_t *packet = msgbuf_get_packet(msgbuf);
- name_create_from_data(packet, msgbuf_get_name(msgbuf));
- Name name = EMPTY_NAME;
- name_Copy(msgbuf_get_name(msgbuf), &name);
- name_setLen(&name, prefix->len);
-
WITH_DEBUG({
- char *name_str = name_ToString(&name);
- DEBUG("Received ack for name prefix=%s seq=%d on conn id=%d", name_str,
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "(error)");
+ DEBUG("Received ack for name prefix=%s seq=%d on conn id=%d", buf,
params->seq, ingress_id);
- free(name_str);
})
const fib_t *fib = forwarder_get_fib(mapme->forwarder);
- fib_entry_t *entry = fib_contains(fib, &name);
+ fib_entry_t *entry = fib_contains(fib, prefix);
if (!entry) {
INFO("Ignored ACK with no corresponding FIB entry");
return;
@@ -1031,6 +1004,7 @@ void mapme_process(mapme_t *mapme, msgbuf_t *msgbuf) {
}
}
+#if 0
/*
* Returns true iif the message corresponds to a MAP-Me packet
*/
@@ -1048,6 +1022,7 @@ bool mapme_match_packet(const uint8_t *packet) {
return false;
}
}
+#endif
void mapme_set_enable(mapme_t *mapme, bool enable) { mapme->enabled = enable; }
void mapme_set_discovery(mapme_t *mapme, bool enable) {
diff --git a/hicn-light/src/hicn/core/mapme.h b/hicn-light/src/hicn/core/mapme.h
index 8c2ca477f..188607421 100644
--- a/hicn-light/src/hicn/core/mapme.h
+++ b/hicn-light/src/hicn/core/mapme.h
@@ -26,7 +26,7 @@
#include <stdbool.h>
#include <stdint.h>
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/ctrl/hicn-light.h>
#include <hicn/hicn.h>
#include "connection.h"
@@ -87,7 +87,7 @@ int mapme_set_all_adjacencies(const mapme_t *mapme, fib_entry_t *entry);
* @param [in] nexthops - next hops on which to send the update.
*/
int mapme_set_adjacencies(const mapme_t *mapme, fib_entry_t *entry,
- nexthops_t *nexthops, bool force);
+ nexthops_t *nexthops);
/**
* @function mapme_update_adjacencies
diff --git a/hicn-light/src/hicn/core/messageHandler.h b/hicn-light/src/hicn/core/messageHandler.h
deleted file mode 100644
index fe26d0579..000000000
--- a/hicn-light/src/hicn/core/messageHandler.h
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright (c) 2021 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.
- */
-
-#ifndef HICNLIGHT_MESSAGE_HANDLER_H
-#define HICNLIGHT_MESSAGE_HANDLER_H
-
-#include <stdlib.h>
-#ifndef _WIN32
-#include <unistd.h> // close
-#endif /* _WIN32 */
-
-#include <hicn/hicn.h>
-
-//#include <hicn/core/connection_table.h>
-
-#define H(packet) ((hicn_header_t *)packet)
-#define H6(packet) (H(packet)->v6.ip)
-#define H6T(packet) (H(packet)->v6.tcp)
-#define H4(packet) (H(packet)->v4.ip)
-#define H4T(packet) (H(packet)->v4.tcp)
-
-#define HICN_V6_LEN(packet) (H6(packet).len)
-#define HICN_V4_LEN(packet) (H4(packet).len)
-
-/*** codes and types ***/
-#define IPv6_TYPE 6
-#define IPv4_TYPE 4
-#define ICMP_WLDR_TYPE 42
-#define ICMP_WLDR_CODE 0
-#define ICMP_LB_TYPE 43
-
-/*** masks and constants ***/
-#define PATH_LABEL_MASK 0x8000 // 1000 0000 0000 0000
-#define NOT_PATH_LABEL_MASK 0x7fff // 0111 0000 0000 0000
-#define UINT16_T_MASK 0x0000ffff // 1111 1111 1111 1111
-
-/*** HICN ALLOWED PORTS ***/
-#define CONTROL_PORT 9695
-#define HTTP_PORT 8080
-
-#define MIN_PROBE_SUFFIX 0xefffffff
-#define MAX_PROBE_SUFFIX 0xffffffff - 1
-
-// XXX Hardcoded packet format HF_INET6_TCP
-
-#define IPV6_DEFAULT_VERSION 6
-#define IPV6_DEFAULT_TRAFFIC_CLASS 0
-#define IPV6_DEFAULT_FLOW_LABEL 0
-
-//#include <hicn/core/forwarder.h>
-
-//#ifdef WITH_MAPME
-//#include <hicn/core/mapme.h>
-//#include <hicn/socket/api.h>
-//#endif /* WITH_MAPME */
-
-#define BFD_PORT 3784
-
-static inline uint8_t messageHandler_GetIPPacketType(const uint8_t *message) {
- return HICN_IP_VERSION(message);
-}
-
-static inline void messageHandler_UpdateTCPCheckSum(uint8_t *message,
- uint16_t *old_val,
- uint16_t *new_val,
- uint8_t size) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv4_TYPE:
- for (uint8_t i = 0; i < size; i++) {
- uint16_t old_csum = ~(H4T(message).csum);
- uint16_t not_old_val = ~(*old_val);
- uint32_t sum = (uint32_t)old_csum + not_old_val + *new_val;
-
- while (sum >> 16) {
- sum = (sum >> 16) + (sum & UINT16_T_MASK);
- }
-
- H4T(message).csum = ~sum;
- ++old_val;
- ++new_val;
- }
- break;
- case IPv6_TYPE:
- for (uint8_t i = 0; i < size; i++) {
- uint16_t old_csum = ~(H6T(message).csum);
- uint16_t not_old_val = ~(*old_val);
- uint32_t sum = (uint32_t)old_csum + not_old_val + *new_val;
-
- while (sum >> 16) {
- sum = (sum >> 16) + (sum & UINT16_T_MASK);
- }
-
- H6T(message).csum = ~sum;
- ++old_val;
- ++new_val;
- }
- break;
- default:
- return;
- }
-}
-
-static inline void messageHandler_UpdateIPv4CheckSum(uint8_t *message,
- uint16_t *old_val,
- uint16_t *new_val,
- uint8_t size) {
- for (uint8_t i = 0; i < size; i++) {
- uint16_t old_csum = ~(H4(message).csum);
- uint16_t not_old_val = ~(*old_val);
- uint32_t sum = (uint32_t)old_csum + not_old_val + *new_val;
-
- while (sum >> 16) {
- sum = (sum >> 16) + (sum & UINT16_T_MASK);
- }
-
- H4(message).csum = ~sum;
- ++old_val;
- ++new_val;
- }
-}
-
-static inline size_t messageHandler_GetEmptyTCPPacketSize(unsigned ipVersion) {
- if (ipVersion == IPv4_TYPE)
- return IPV4_HDRLEN + TCP_HDRLEN;
- else if (ipVersion == IPv6_TYPE)
- return IPV6_HDRLEN + TCP_HDRLEN;
- else
- return 0;
-}
-
-static inline size_t messageHandler_GetICMPPacketSize(unsigned ipVersion) {
- if (ipVersion == IPv4_TYPE)
- return IPV4_HDRLEN + ICMP_HDRLEN;
- else if (ipVersion == IPv6_TYPE)
- return IPV6_HDRLEN + ICMP_HDRLEN;
- else
- return 0;
-}
-
-static inline size_t messageHandler_GetIPHeaderLength(unsigned ipVersion) {
- if (ipVersion == IPv4_TYPE)
- return IPV4_HDRLEN;
- else if (ipVersion == IPv6_TYPE)
- return IPV6_HDRLEN;
- else
- return 0;
-}
-
-#if 0
-static inline bool messageHandler_IsValidHicnPacket(const uint8_t *message) {
- uint8_t version = messageHandler_GetIPPacketType(message);
- if (version == IPv6_TYPE || version == IPv4_TYPE) {
- return true;
- }
- return false;
-}
-#endif
-
-static inline uint8_t messageHandler_NextHeaderType(const uint8_t *message) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return (uint8_t)H6(message).nxt;
- case IPv4_TYPE:
- return (uint8_t)H4(message).protocol;
- default:
- return 0;
- }
-}
-
-static inline bool messageHandler_IsTCP(const uint8_t *message) {
- if (messageHandler_NextHeaderType(message) != IPPROTO_TCP) return false;
- return true;
-}
-
-static inline bool messageHandler_IsInterest(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return false;
-
- bool flag;
- hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message,
- &flag); // ECE flag is set to 0 in interest packets
- if (flag == false) return true;
- return false;
-}
-
-static inline bool messageHandler_IsData(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return false;
-
- bool flag;
- hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message,
- &flag); // ECE flag is set to 1 in data packets
- if (flag == true) return true;
- return false;
-}
-
-static inline bool messageHandler_IsWldrNotification(const uint8_t *message) {
- // this function returns true only if the packet is an ICMP packet in Wldr
- // form. type must be equal to ICMP_WLDR_TYPE and code equal to ICMP_WLDR_CODE
- uint8_t next_header = messageHandler_NextHeaderType(message);
-
- const uint8_t *icmp_ptr;
- if (next_header == IPPROTO_ICMP) {
- icmp_ptr = message + IPV4_HDRLEN;
- } else if (next_header == IPPROTO_ICMPV6) {
- icmp_ptr = message + IPV6_HDRLEN;
- } else {
- return false;
- }
-
- uint8_t type = ((_icmp_header_t *)icmp_ptr)->type;
- uint8_t code = ((_icmp_header_t *)icmp_ptr)->code;
- if (type == ICMP_WLDR_TYPE && code == ICMP_WLDR_CODE) {
- return true;
- }
-
- return false;
-}
-
-static inline bool messageHandler_IsLoadBalancerProbe(const uint8_t *message) {
- uint8_t next_header = messageHandler_NextHeaderType(message);
-
- const uint8_t *icmp_ptr;
- if (next_header == IPPROTO_ICMP) {
- icmp_ptr = message + IPV4_HDRLEN;
- } else if (next_header == IPPROTO_ICMPV6) {
- icmp_ptr = message + IPV6_HDRLEN;
- } else {
- return false;
- }
-
- uint8_t type = ((_icmp_header_t *)icmp_ptr)->type;
- if (type == ICMP_LB_TYPE) {
- return true;
- }
-
- return false;
-}
-
-static inline uint16_t messageHandler_GetTotalPacketLength(
- const uint8_t *message) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return ntohs((uint16_t)HICN_V6_LEN(message)) + IPV6_HDRLEN;
- case IPv4_TYPE:
- return ntohs((uint16_t)HICN_V4_LEN(message));
- default:
- return 0;
- }
-}
-
-static inline uint32_t messageHandler_GetSegment(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return 0;
-
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return ntohl((uint32_t)H6T(message).seq);
- case IPv4_TYPE:
- return ntohl((uint32_t)H4T(message).seq);
- default:
- return 0;
- }
-}
-
-static inline uint16_t messageHandler_GetExpectedWldrLabel(
- const uint8_t *message) {
- const uint8_t *icmp_ptr;
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- icmp_ptr = message + IPV6_HDRLEN;
- break;
- case IPv4_TYPE:
- icmp_ptr = message + IPV4_HDRLEN;
- break;
- default:
- return 0;
- }
-
- return ntohs(
- ((_icmp_wldr_header_t *)icmp_ptr)->wldr_notification_lbl.expected_lbl);
-}
-
-static inline uint16_t messageHandler_GetWldrLastReceived(
- const uint8_t *message) {
- const uint8_t *icmp_ptr;
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- icmp_ptr = message + IPV6_HDRLEN;
- break;
- case IPv4_TYPE:
- icmp_ptr = message + IPV4_HDRLEN;
- break;
- default:
- return 0;
- }
-
- return ntohs(
- ((_icmp_wldr_header_t *)icmp_ptr)->wldr_notification_lbl.received_lbl);
-}
-
-static inline uint16_t messageHandler_GetWldrLabel(const uint8_t *message) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return ntohs((uint16_t)H6T(message).window);
- case IPv4_TYPE:
- return ntohs((uint16_t)H4T(message).window);
- default:
- return 0;
- }
-}
-
-static inline void messageHandler_SetWldrLabel(uint8_t *message,
- uint16_t label) {
- uint16_t old_val = messageHandler_GetWldrLabel(message);
-
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- H6T(message).window = htons(label);
- break;
- case IPv4_TYPE:
- H4T(message).window = htons(label);
- break;
- default:
- break;
- }
-
- messageHandler_UpdateTCPCheckSum(message, &old_val, &label, 1);
-}
-
-static inline void messageHandler_ResetWldrLabel(uint8_t *message) {
- messageHandler_SetWldrLabel(message, 0);
-}
-
-static inline bool messageHandler_HasWldr(const uint8_t *message) {
- if (messageHandler_IsTCP(message)) {
- uint16_t lbl = messageHandler_GetWldrLabel(message);
- if (lbl != 0) {
- return true;
- }
- }
- return false;
-}
-
-static inline uint32_t messageHandler_GetPathLabel(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return 0;
-
- uint32_t path_label;
- int res = hicn_data_get_path_label((hicn_header_t *)message, &path_label);
- if (res < 0) return 0;
- return path_label;
-}
-
-static inline void messageHandler_SetPathLabel(uint8_t *message,
- uint32_t old_path_label,
- uint32_t new_path_label) {
- if (!messageHandler_IsTCP(message)) return;
-
- hicn_data_set_path_label((hicn_header_t *)message, new_path_label);
-
- messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&old_path_label,
- (uint16_t *)&new_path_label, 2);
-}
-
-static inline void messageHandler_UpdatePathLabel(uint8_t *message,
- uint8_t outFace) {
- if (!messageHandler_IsTCP(message)) return;
-
- uint32_t pl_old_32bit = messageHandler_GetPathLabel(message);
- uint8_t pl_old_8bit = (uint8_t)(pl_old_32bit >> 24UL);
- uint32_t pl_new_32bit =
- (uint32_t)((((pl_old_8bit << 1) | (pl_old_8bit >> 7)) ^ outFace) << 24UL);
-
- // XXX path label should be 8 bits now ?
- messageHandler_SetPathLabel(message, pl_old_32bit, pl_new_32bit);
-}
-
-static inline void messageHandler_ResetPathLabel(uint8_t *message) {
- messageHandler_SetPathLabel(message, messageHandler_GetPathLabel(message), 0);
-}
-
-static inline uint32_t messageHandler_GetInterestLifetime(
- const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return 0;
-
- hicn_lifetime_t lifetime;
- int res = hicn_interest_get_lifetime((hicn_header_t *)message, &lifetime);
- if (res < 0) return 0;
- return lifetime;
-}
-
-static inline bool messageHandler_SetInterestLifetime(uint8_t *message,
- u32 lifetime) {
- if (!messageHandler_IsTCP(message)) return false;
-
- int res = hicn_interest_set_lifetime((hicn_header_t *)message, lifetime);
- if (res < 0) return false;
- return true;
-}
-
-static inline bool messageHandler_SetDataExpiryTime(uint8_t *message,
- u32 lifetime) {
- if (!messageHandler_IsTCP(message)) return false;
-
- int res = hicn_data_set_expiry_time((hicn_header_t *)message, lifetime);
- if (res < 0) return false;
- return true;
-}
-
-static inline bool messageHandler_HasInterestLifetime(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return false;
-
- if (messageHandler_GetInterestLifetime(message) == 0) return false;
- return true;
-}
-
-static inline uint32_t messageHandler_GetContentExpiryTime(
- const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return 0;
-
- uint32_t expirationTime;
- int res =
- hicn_data_get_expiry_time((hicn_header_t *)message, &expirationTime);
- if (res < 0) return 0;
- return expirationTime;
-}
-
-static inline bool messageHandler_HasContentExpiryTime(const uint8_t *message) {
- if (!messageHandler_IsTCP(message)) return 0;
-
- uint32_t expirationTime;
- int res =
- hicn_data_get_expiry_time((hicn_header_t *)message, &expirationTime);
- if (res < 0) return false;
-
- if (expirationTime == HICN_MAX_LIFETIME) return false;
-
- return true;
-}
-
-static inline void *messageHandler_GetSource(const uint8_t *message) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return &H6(message).saddr;
- break;
- case IPv4_TYPE:
- return &H4(message).saddr;
- break;
- default:
- return NULL;
- }
-}
-
-static inline void *messageHandler_GetDestination(const uint8_t *message) {
- switch (messageHandler_GetIPPacketType(message)) {
- case IPv6_TYPE:
- return &H6(message).daddr;
- break;
- case IPv4_TYPE:
- return &H4(message).daddr;
- break;
- default:
- return NULL;
- }
-}
-
-static inline void messageHandler_SetSource_IPv6(uint8_t *message,
- struct in6_addr *address) {
- if (messageHandler_IsTCP(message)) {
- uint16_t *old_src = (uint16_t *)messageHandler_GetSource(message);
- messageHandler_UpdateTCPCheckSum(message, old_src, (uint16_t *)address, 8);
- }
- H6(message).saddr.as_in6addr = *address;
-}
-
-static inline void messageHandler_SetDestination_IPv6(
- uint8_t *message, struct in6_addr *address) {
- if (messageHandler_IsTCP(message)) {
- uint16_t *old_dst = (uint16_t *)messageHandler_GetDestination(message);
- messageHandler_UpdateTCPCheckSum(message, old_dst, (uint16_t *)address, 8);
- }
- H6(message).daddr.as_in6addr = *address;
-}
-
-static inline void messageHandler_SetSource_IPv4(uint8_t *message,
- uint32_t *address) {
- // update tcp checksum
- uint16_t *old_src = (uint16_t *)messageHandler_GetSource(message);
- if (messageHandler_IsTCP(message)) {
- messageHandler_UpdateTCPCheckSum(message, old_src, (uint16_t *)address, 2);
- }
- // update IPv4 cheksum
- // the IPv4 checksum is not part of the psudo header for TCP checksum
- // calculation we can update them separetelly
- messageHandler_UpdateIPv4CheckSum(message, old_src, (uint16_t *)address, 2);
-
- H4(message).saddr.as_u32 = *address;
-}
-
-static inline void messageHandler_SetDestination_IPv4(uint8_t *message,
- uint32_t *address) {
- uint16_t *old_dst = (uint16_t *)messageHandler_GetDestination(message);
- if (messageHandler_IsTCP(message)) {
- messageHandler_UpdateTCPCheckSum(message, old_dst, (uint16_t *)address, 2);
- }
- messageHandler_UpdateIPv4CheckSum(message, old_dst, (uint16_t *)address, 2);
- H4(message).daddr.as_u32 = *address;
-}
-
-static inline void messageHandler_SetWldrNotification(uint8_t *notification,
- uint8_t *original,
- uint16_t expected,
- uint16_t received) {
- hicn_header_t *h = (hicn_header_t *)notification;
- switch (messageHandler_GetIPPacketType(original)) {
- case IPv6_TYPE: {
- *h = (hicn_header_t){.v6 = {
- .ip =
- (_ipv6_header_t){
- .version_class_flow = htonl(
- (IPV6_DEFAULT_VERSION << 28) |
- (IPV6_DEFAULT_TRAFFIC_CLASS << 20) |
- (IPV6_DEFAULT_FLOW_LABEL & 0xfffff)),
- .len = htons(ICMP_HDRLEN),
- .nxt = IPPROTO_ICMPV6,
- .hlim = 5,
- },
- /*
- .wldr =
- {
- .type = ICMP_WLDR_TYPE,
- .code = ICMP_WLDR_CODE,
- .wldr_notification_lbl =
- {
- .expected_lbl = htons(expected),
- .received_lbl = htons(received),
- },
- },*/
- }};
- messageHandler_SetSource_IPv6(
- notification,
- (struct in6_addr *)messageHandler_GetDestination(original));
- messageHandler_SetDestination_IPv6(
- notification, (struct in6_addr *)messageHandler_GetSource(original));
- break;
- }
- case IPv4_TYPE: {
- break;
- }
- default:
- break;
- }
-}
-
-static inline void messageHandler_ModifySuffix(uint8_t *packet,
- uint32_t new_suffix) {
- hicn_format_t format;
- hicn_name_t name;
- hicn_packet_get_format((hicn_header_t *)packet, &format);
- hicn_interest_get_name(format, (hicn_header_t *)packet, &name);
- hicn_name_set_seq_number(&name, new_suffix);
- hicn_interest_set_name(format, (hicn_header_t *)packet, &name);
-}
-
-static inline uint8_t *messageHandler_CreateProbePacket(
- hicn_format_t format, uint32_t probe_lifetime) {
- size_t header_length;
- hicn_packet_get_header_length_from_format(format, &header_length);
-
- uint8_t *pkt = (uint8_t *)calloc(header_length, 1);
-
- hicn_packet_init_header(format, (hicn_header_t *)pkt);
-
- hicn_packet_set_dst_port(format, (hicn_header_t *)pkt, BFD_PORT);
- hicn_interest_set_lifetime((hicn_header_t *)pkt, probe_lifetime);
-
- return pkt;
-}
-
-static inline void messageHandler_CreateProbeReply(uint8_t *probe,
- hicn_format_t format) {
- hicn_name_t probe_name;
- hicn_interest_get_name(format, (const hicn_header_t *)probe, &probe_name);
- ip_address_t probe_locator;
- hicn_interest_get_locator(format, (const hicn_header_t *)probe,
- &probe_locator);
-
- uint16_t src_prt;
- uint16_t dst_prt;
- hicn_packet_get_src_port(format, (const hicn_header_t *)probe, &src_prt);
- hicn_packet_get_dst_port(format, (const hicn_header_t *)probe, &dst_prt);
- hicn_packet_set_src_port(format, (hicn_header_t *)probe, dst_prt);
- hicn_packet_set_dst_port(format, (hicn_header_t *)probe, src_prt);
-
- hicn_data_set_name(format, (hicn_header_t *)probe, &probe_name);
- hicn_data_set_locator(format, (hicn_header_t *)probe, &probe_locator);
- hicn_data_set_expiry_time((hicn_header_t *)probe, 0);
-}
-
-static inline hicn_name_t *messageHandler_CreateProbeName(
- const ip_prefix_t *address) {
- hicn_name_t *name = (hicn_name_t *)calloc(sizeof(hicn_name_t), 1);
- hicn_name_create_from_ip_prefix(address, 0, name);
- return name;
-}
-
-static inline void messageHandler_SetProbeName(uint8_t *probe,
- hicn_format_t format,
- hicn_name_t *name,
- uint32_t seq) {
- hicn_name_set_seq_number(name, seq);
- hicn_interest_set_name(format, (hicn_header_t *)probe, name);
-}
-
-static inline bool messageHandler_IsAProbe(const uint8_t *packet) {
- hicn_format_t format;
- hicn_name_t name;
- uint32_t seq;
- hicn_packet_get_format((hicn_header_t *)packet, &format);
- hicn_data_get_name(format, (hicn_header_t *)packet, &name);
- hicn_name_get_seq_number(&name, &seq);
- if (seq >= MIN_PROBE_SUFFIX && seq <= MAX_PROBE_SUFFIX) return true;
- return false;
-
-#if 0
- // old probe version
- uint16_t src_prt;
- uint16_t dst_prt;
- hicn_packet_get_src_port (HF_INET6_TCP, (const hicn_header_t *) packet, &src_prt);
- hicn_packet_get_dst_port (HF_INET6_TCP, (const hicn_header_t *) packet, &dst_prt);
-
- if(dst_prt == BFD_PORT){
- //interest probe
- return true;
- }
-
- if(src_prt == BFD_PORT){
- //data (could be a probe)
- uint32_t expiry_time;
- hicn_data_get_expiry_time ((const hicn_header_t *) packet, &expiry_time);
- if(expiry_time == 0){
- //this is a probe
- return true;
- }
- }
-
- return false;
-#endif
-}
-
-#endif /* HICNLIGHT_MESSAGE_HANDLER_H */
diff --git a/hicn-light/src/hicn/core/msgbuf.c b/hicn-light/src/hicn/core/msgbuf.c
index 299b20f9b..c58f7a7dc 100644
--- a/hicn-light/src/hicn/core/msgbuf.c
+++ b/hicn-light/src/hicn/core/msgbuf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -19,3 +19,37 @@
*/
#include "msgbuf.h"
+#include "../strategies/probe_generator.h"
+
+int msgbuf_initialize(msgbuf_t *msgbuf) {
+ /*
+ * We define the format and the storage area of the packet buffer we
+ * manipulate
+ */
+ hicn_packet_buffer_t *pkbuf = msgbuf_get_pkbuf(msgbuf);
+ hicn_packet_set_buffer(pkbuf, msgbuf->packet, MTU, 0);
+ hicn_packet_init_header(pkbuf, 0);
+ return 0;
+}
+
+int msgbuf_initialize_from_packet(msgbuf_t *msgbuf) {
+ hicn_packet_set_buffer(msgbuf_get_pkbuf(msgbuf), msgbuf->packet, MTU,
+ msgbuf_get_len(msgbuf));
+ return 0;
+}
+
+bool msgbuf_is_command(const msgbuf_t *msgbuf) {
+ return (*msgbuf->packet == REQUEST_LIGHT);
+}
+
+bool msgbuf_is_probe(const msgbuf_t *msgbuf) {
+ hicn_name_t name;
+ hicn_name_suffix_t suffix;
+
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA);
+
+ const hicn_packet_buffer_t *pkbuf = msgbuf_get_pkbuf(msgbuf);
+ hicn_data_get_name(pkbuf, &name);
+ suffix = hicn_name_get_suffix(&name);
+ return (suffix >= MIN_PROBE_SUFFIX && suffix <= MAX_PROBE_SUFFIX);
+}
diff --git a/hicn-light/src/hicn/core/msgbuf.h b/hicn-light/src/hicn/core/msgbuf.h
index e437f1d09..26fd47540 100644
--- a/hicn-light/src/hicn/core/msgbuf.h
+++ b/hicn-light/src/hicn/core/msgbuf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -21,10 +21,10 @@
#ifndef HICNLIGHT_MSGBUF
#define HICNLIGHT_MSGBUF
-#include "name.h"
+#include <hicn/name.h>
#include "ticks.h"
-#include "messageHandler.h"
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/hicn.h>
+#include <hicn/ctrl/hicn-light.h>
#define MTU 1500
#define INVALID_MSGBUF_ID ~0ul
@@ -32,33 +32,19 @@
#define msgbuf_id_is_valid(msgbuf_id) \
((unsigned long)msgbuf_id != INVALID_MSGBUF_ID)
-#define foreach_msg_type \
- _(UNDEFINED) \
- _(INTEREST) \
- _(DATA) \
- _(WLDR_NOTIFICATION) \
- _(MAPME) \
- _(COMMAND) \
- _(N)
-
-typedef enum {
-#define _(x) MSGBUF_TYPE_##x,
- foreach_msg_type
-#undef _
-} msgbuf_type_t;
-#undef foreach_msg_type
-
typedef struct {
- unsigned length;
- msgbuf_type_t type;
- unsigned connection_id;
- Ticks recv_ts;
- unsigned refs;
- unsigned path_label;
+ hicn_packet_buffer_t pkbuf;
+ unsigned connection_id; // ingress
+ Ticks recv_ts; // timestamp
+ unsigned refs; // refcount
+ unsigned path_label; // XXX what is this ?
+
+ // XXX Cache storage
union {
/* Interest or data packet */
struct {
- Name name;
+ hicn_name_t name;
+ u32 name_hash; // XXX should be always populate when name is assigned
} id;
/* Command packet */
struct {
@@ -68,53 +54,142 @@ typedef struct {
uint8_t packet[MTU];
} msgbuf_t;
-#define msgbuf_get_name(M) (&((M)->id.name))
+int msgbuf_initialize(msgbuf_t *msgbuf);
+int msgbuf_initialize_from_packet(msgbuf_t *msgbuf);
+
+#define msgbuf_get_pkbuf(M) (&(M)->pkbuf)
+
+static inline hicn_packet_type_t msgbuf_get_type(const msgbuf_t *msgbuf) {
+ return hicn_packet_get_type(msgbuf_get_pkbuf(msgbuf));
+}
+
+static inline void msgbuf_set_type(msgbuf_t *msgbuf, hicn_packet_type_t type) {
+ hicn_packet_set_type(msgbuf_get_pkbuf(msgbuf), type);
+}
+
+static inline const hicn_name_t *msgbuf_get_name(const msgbuf_t *msgbuf) {
+ hicn_packet_type_t type = msgbuf_get_type(msgbuf);
+ assert(type == HICN_PACKET_TYPE_INTEREST || type == HICN_PACKET_TYPE_DATA);
+ (void)type;
+
+ return &msgbuf->id.name;
+}
+
#define msgbuf_get_connection_id(M) ((M)->connection_id)
-#define msgbuf_get_type(M) ((M)->type)
-#define msgbuf_has_wldr(M) (messageHandler_HasWldr((M)->packet))
-#define msgbuf_get_len(M) ((M)->length)
#define msgbuf_get_packet(M) ((M)->packet)
#define msgbuf_get_command_type(M) ((M)->command.type)
+#if WITH_WLDR
+#define msgbuf_has_wldr(M) (messageHandler_HasWldr((M)->packet))
+#endif
+
+static inline void msgbuf_set_name(msgbuf_t *msgbuf, const hicn_name_t *name) {
+ msgbuf->id.name = *name;
+}
+
+static inline size_t msgbuf_get_len(const msgbuf_t *msgbuf) {
+ return hicn_packet_get_len(msgbuf_get_pkbuf(msgbuf));
+}
-// XXX TODO EXPLAIN THE CONSTANT
-#define msgbuf_get_lifetime(M) \
- (NSEC_TO_TICKS(messageHandler_GetInterestLifetime((M)->packet) * 1000000ULL))
+static inline void msgbuf_set_len(msgbuf_t *msgbuf, size_t len) {
+ int rc = hicn_packet_set_len(msgbuf_get_pkbuf(msgbuf), len);
+ assert(rc == HICN_LIB_ERROR_NONE); // XXX
+ _unused(rc);
+}
+
+static inline u32 msgbuf_get_name_hash(const msgbuf_t *msgbuf) {
+ hicn_packet_type_t type = msgbuf_get_type(msgbuf);
+ assert(type == HICN_PACKET_TYPE_INTEREST || type == HICN_PACKET_TYPE_DATA);
+ _unused(type);
+ return msgbuf->id.name_hash;
+}
// Lifetimes/expiry times in milliseconds
-#define msgbuf_get_interest_lifetime(M) \
- (messageHandler_GetInterestLifetime((M)->packet))
-#define msgbuf_get_data_expiry_time(M) \
- (messageHandler_GetContentExpiryTime((M)->packet))
+static inline u32 msgbuf_get_interest_lifetime(const msgbuf_t *msgbuf) {
+ u32 lifetime;
+ int rc = hicn_interest_get_lifetime(msgbuf_get_pkbuf(msgbuf), &lifetime);
+ assert(rc == HICN_LIB_ERROR_NONE); // XXX
+ _unused(rc);
+ return lifetime;
+}
+
+//#define msgbuf_get_lifetime(M)
+// (NSEC_TO_TICKS(messageHandler_GetInterestLifetime((M)->packet) *
+// 1000000ULL))
+#define msgbuf_get_lifetime msgbuf_get_interest_lifetime
static inline bool msgbuf_set_interest_lifetime(msgbuf_t *msgbuf,
u32 lifetime) {
- return messageHandler_SetInterestLifetime(msgbuf->packet, lifetime);
+ int rc = hicn_interest_set_lifetime(msgbuf_get_pkbuf(msgbuf), lifetime);
+ return (rc == HICN_LIB_ERROR_NONE);
}
-static inline bool msgbuf_set_data_expiry_time(msgbuf_t *msgbuf, u32 lifetime) {
- return messageHandler_SetDataExpiryTime(msgbuf->packet, lifetime);
+
+static inline u32 msgbuf_get_data_expiry_time(const msgbuf_t *msgbuf) {
+ u32 lifetime;
+ int rc = hicn_data_get_expiry_time(msgbuf_get_pkbuf(msgbuf), &lifetime);
+ assert(rc == HICN_LIB_ERROR_NONE); // XXX
+ _unused(rc);
+ return lifetime;
}
-#define msgbuf_is_probe(M) messageHandler_IsAProbe((M)->packet)
+static inline bool msgbuf_set_data_expiry_time(msgbuf_t *msgbuf, u32 lifetime) {
+ int rc = hicn_data_set_expiry_time(msgbuf_get_pkbuf(msgbuf), lifetime);
+ return (rc == HICN_LIB_ERROR_NONE);
+}
/* Path label */
-#define msgbuf_init_pathlabel(M) \
- ((M)->path_label = messageHandler_GetPathLabel((M)->packet))
-#define msgbuf_update_pathlabel(M, outface) \
- { \
- messageHandler_SetPathLabel((M)->packet, \
- messageHandler_GetPathLabel((M)->packet), \
- (M)->path_label); \
- messageHandler_UpdatePathLabel((M)->packet, outface); \
- }
-#define msgbuf_reset_pathlabel(M) \
- { \
- (M)->path_label = 0; \
- messageHandler_ResetPathLabel((M)->packet); \
- }
+static inline void msgbuf_init_pathlabel(msgbuf_t *msgbuf) {
+ hicn_path_label_t pl;
+ int rc = hicn_data_get_path_label(msgbuf_get_pkbuf(msgbuf), &pl);
+ assert(rc == HICN_LIB_ERROR_NONE);
+ _unused(rc);
+ msgbuf->path_label = pl;
+}
+
+static inline int msgbuf_get_path_label(const msgbuf_t *msgbuf,
+ hicn_path_label_t *pl) {
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA);
+ return hicn_data_get_path_label(msgbuf_get_pkbuf(msgbuf), pl);
+}
+
+static inline int msgbuf_set_path_label(msgbuf_t *msgbuf,
+ hicn_path_label_t pl) {
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA);
+ return hicn_data_set_path_label(msgbuf_get_pkbuf(msgbuf), pl);
+}
+
+static inline int msgbuf_update_pathlabel(msgbuf_t *msgbuf,
+ hicn_faceid_t outface) {
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA);
+
+ hicn_path_label_t pl, newpl;
+ if (msgbuf_get_path_label(msgbuf, &pl) < 0) return -1;
+
+ update_path_label(pl, outface, &newpl);
+
+ return msgbuf_set_path_label(msgbuf, newpl);
+}
+
+static inline void msgbuf_reset_pathlabel(msgbuf_t *msgbuf) {
+ msgbuf->path_label = 0;
+ hicn_data_set_path_label(msgbuf_get_pkbuf(msgbuf), 0);
+ // ERROR ?
+}
+
+static inline void msgbuf_modify_suffix(msgbuf_t *msgbuf, uint32_t new_suffix) {
+ hicn_name_t name;
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
+ hicn_interest_get_name(msgbuf_get_pkbuf(msgbuf), &name);
+ hicn_name_set_suffix(&name, new_suffix);
+ hicn_interest_set_name(msgbuf_get_pkbuf(msgbuf), &name);
+}
+
+bool msgbuf_is_command(const msgbuf_t *msgbuf);
+bool msgbuf_is_probe(const msgbuf_t *msgbuf);
/* WLDR */
+#if 0
#define msgbuf_reset_wldr_label(M) (messageHandler_ResetWldrLabel((M)->packet))
#define msgbuf_get_wldr_label(M) (messageHandler_GetWldrLabel((M)->packet))
#define msgbuf_get_wldr_expected_label(M) \
@@ -123,5 +198,6 @@ static inline bool msgbuf_set_data_expiry_time(msgbuf_t *msgbuf, u32 lifetime) {
(messageHandler_GetWldrLastReceived((M)->packet))
#define msgbuf_set_wldr_label(M, label) \
(messageHandler_GetWldrLabel((M)->packet, label))
+#endif
#endif /* HICNLIGHT_MSGBUF */
diff --git a/hicn-light/src/hicn/core/msgbuf_pool.c b/hicn-light/src/hicn/core/msgbuf_pool.c
index a2092aaf6..892bd59a1 100644
--- a/hicn-light/src/hicn/core/msgbuf_pool.c
+++ b/hicn-light/src/hicn/core/msgbuf_pool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -19,6 +19,7 @@
*/
#include <hicn/util/pool.h>
+#include <hicn/util/log.h>
#include "msgbuf_pool.h"
msgbuf_pool_t *_msgbuf_pool_create(size_t init_size, size_t max_size) {
@@ -90,16 +91,20 @@ void msgbuf_pool_release(msgbuf_pool_t *msgbuf_pool, msgbuf_t **msgbuf_ptr) {
if (msgbuf->refs == 0) {
WITH_TRACE({
off_t msgbuf_id = msgbuf_pool_get_id(msgbuf_pool, msgbuf);
- if (msgbuf->type != MSGBUF_TYPE_INTEREST &&
- msgbuf->type != MSGBUF_TYPE_DATA) {
+ if (msgbuf_get_type(msgbuf) != HICN_PACKET_TYPE_INTEREST &&
+ msgbuf_get_type(msgbuf) != HICN_PACKET_TYPE_DATA) {
TRACE("Msgbuf %d (%p) - put to msgbuf pool", msgbuf_id, msgbuf);
} else {
- char *name_str = name_ToString(msgbuf_get_name(msgbuf));
+ char buf[MAXSZ_HICN_NAME];
+ int rc =
+ hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ if (rc < 0 || rc >= MAXSZ_HICN_NAME)
+ snprintf(buf, MAXSZ_HICN_NAME, "%s", "(error)");
const char *msgbuf_type_str =
- msgbuf->type == MSGBUF_TYPE_INTEREST ? "interest" : "data";
+ msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST ? "interest"
+ : "data";
TRACE("Msgbuf %d (%p) - %s (%s) put to msgbuf pool", msgbuf_id, msgbuf,
- name_str, msgbuf_type_str);
- free(name_str);
+ buf, msgbuf_type_str);
}
})
diff --git a/hicn-light/src/hicn/core/name.c b/hicn-light/src/hicn/core/name.c
deleted file mode 100644
index d30cebefc..000000000
--- a/hicn-light/src/hicn/core/name.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2021 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 <assert.h>
-#include <limits.h>
-#include <hicn/hicn-light/config.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <hicn/core/messageHandler.h>
-#include <hicn/core/name.h>
-#include <hicn/util/log.h>
-#include <hicn/util/hash.h>
-
-#define IPv6_TYPE 6
-#define IPv4_TYPE 4
-
-static uint32_t _computeHash(Name *name) {
- assert(name);
-
- uint32_t hash1 = nameBitvector_GetHash32(&(name->content_name));
- return hashlittle(&name->segment, sizeof(name->segment), hash1);
-}
-
-// ============================================================================
-
-void name_create_from_interest(const uint8_t *packet, Name *name) {
- assert(packet);
- assert(name);
-
- if (messageHandler_GetIPPacketType(packet) == IPv6_TYPE) {
- nameBitvector_CreateFromIn6Addr(
- &(name->content_name),
- (struct in6_addr *)messageHandler_GetDestination(packet), 128);
- } else if (messageHandler_GetIPPacketType(packet) == IPv4_TYPE) {
- nameBitvector_CreateFromInAddr(
- &(name->content_name),
- *((uint32_t *)messageHandler_GetDestination(packet)), 32);
- } else {
- ERROR("Error: unknown message type\n");
- return;
- }
-
- name->segment = messageHandler_GetSegment(packet);
- name->name_hash = _computeHash(name);
-}
-
-void name_create_from_data(const uint8_t *packet, Name *name) {
- assert(packet);
- assert(name);
-
- if (messageHandler_GetIPPacketType(packet) == IPv6_TYPE) {
- nameBitvector_CreateFromIn6Addr(
- &(name->content_name),
- (struct in6_addr *)messageHandler_GetSource(packet), 128);
- } else if (messageHandler_GetIPPacketType(packet) == IPv4_TYPE) {
- nameBitvector_CreateFromInAddr(
- &(name->content_name), *((uint32_t *)messageHandler_GetSource(packet)),
- 32);
- } else {
- printf("Error: unknown message type\n");
- return;
- }
-
- name->segment = messageHandler_GetSegment(packet);
- name->name_hash = _computeHash(name);
-}
-
-void name_CreateFromAddress(Name *name, int family, ip_address_t addr,
- uint8_t len) {
- assert(name);
-
- switch (family) {
- case AF_INET:
- nameBitvector_CreateFromInAddr(&(name->content_name), addr.v4.as_u32,
- len);
- break;
- case AF_INET6:
- nameBitvector_CreateFromIn6Addr(&(name->content_name),
- &addr.v6.as_in6addr, len);
- break;
- default:
- return;
- }
-
- name->segment = 0;
- name->name_hash = _computeHash(name);
-}
-
-void name_Copy(const Name *original, Name *copy) {
- assert(original);
- assert(copy);
-
- nameBitvector_Copy(&(original->content_name), &(copy->content_name));
- copy->segment = original->segment;
- copy->name_hash = original->name_hash;
-}
-
-uint32_t name_HashCode(const Name *name) {
- assert(name);
- return name->name_hash;
-}
-
-NameBitvector *name_GetContentName(const Name *name) {
- assert(name);
- return (NameBitvector *)&(name->content_name);
-}
-
-uint32_t name_GetSegment(const Name *name) {
- assert(name);
- return name->segment;
-}
-
-void name_SetSegment(Name *name, uint32_t segment) { name->segment = segment; }
-
-bool name_Equals(const Name *a, const Name *b) {
- assert(a);
- assert(b);
-
- if ((nameBitvector_Equals(&(a->content_name), &(b->content_name)) &&
- a->segment == b->segment))
- return true;
- return false;
-}
-
-int name_Compare(const Name *a, const Name *b) {
- assert(a);
- assert(b);
-
- if (a == NULL && b == NULL) {
- return 0;
- }
- if (a == NULL) {
- return -1;
- }
- if (b == NULL) {
- return +1;
- }
-
- int res = nameBitvector_Compare(&(a->content_name), &(b->content_name));
-
- if (res != 0) {
- return res;
- } else {
- if (a->segment < b->segment) {
- return -1;
- } else if (a->segment > b->segment) {
- return +1;
- } else {
- return 0;
- }
- }
-}
-
-char *name_ToString(const Name *name) {
- char *output = malloc(NI_MAXHOST * 2);
- address_t address;
- nameBitvector_ToAddress(name_GetContentName(name), &address);
-
- char addr_str[NI_MAXHOST];
- int err = address_to_string(&address, addr_str, NULL);
- _ASSERT(!err);
-
- int chars_written =
- snprintf(output, NI_MAXHOST * 2, "name=%s|%u", addr_str, name->segment);
- _ASSERT(chars_written > 0);
-
- return output;
-}
-
-void name_setLen(Name *name, uint8_t len) {
- nameBitvector_setLen(&(name->content_name), len);
- name->name_hash = _computeHash(name);
-}
-
-#ifdef WITH_POLICY
-uint32_t name_GetSuffix(const Name *name) { return name->segment; }
-
-uint8_t name_GetLen(const Name *name) {
- return nameBitvector_GetLength(&(name->content_name));
-}
-#endif /* WITH_POLICY */
diff --git a/hicn-light/src/hicn/core/name.h b/hicn-light/src/hicn/core/name.h
deleted file mode 100644
index 23505243b..000000000
--- a/hicn-light/src/hicn/core/name.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2021 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.
- */
-
-#ifndef name_h
-#define name_h
-
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include "nameBitvector.h"
-
-typedef struct {
- NameBitvector content_name;
- uint32_t segment;
- uint32_t name_hash;
-} Name;
-
-#define EMPTY_NAME \
- (Name) { .content_name = EMPTY_NAME_BITVECTOR, .segment = 0, .name_hash = 0, }
-
-/**
- * Creates a name from packet
- *
- */
-void name_create_from_interest(const uint8_t *packet, Name *name);
-void name_create_from_data(const uint8_t *packet, Name *name);
-
-/**
- * returns a copy of the name
- */
-void name_Copy(const Name *original, Name *copy);
-
-/**
- * A hash value for use in hash tables
- *
- */
-uint32_t name_HashCode(const Name *name);
-
-/**
- * Returns the content name without the segment value
- *
- */
-NameBitvector *name_GetContentName(const Name *name);
-
-/**
- * Returns the segment value
- *
- */
-uint32_t name_GetSegment(const Name *name);
-
-/**
- * Set the sequence number of the name provided
- *
- */
-void name_SetSegment(Name *name, uint32_t segment);
-
-/**
- * Determine if two HicnName instances are equal.
- */
-bool name_Equals(const Name *a, const Name *b);
-
-/**
- * Compares two names and returns their ordering
- *
- */
-int name_Compare(const Name *a, const Name *b);
-
-/**
- * return the name in string format (bitvector + segment number)
- *
- */
-char *name_ToString(const Name *name);
-
-/**
- * @function message_setNameLen
- * @abstract Sets a message name length
- * @param [in] message - Interest message
- * @param [in] len - Name length
- */
-void name_setLen(Name *name, uint8_t len);
-
-/**
- * Creates a name from a Address
- *
- */
-void name_CreateFromAddress(Name *name, int family, ip_address_t addr,
- uint8_t len);
-
-#ifdef WITH_POLICY
-uint32_t name_GetSuffix(const Name *name);
-uint8_t name_GetLen(const Name *name);
-#endif /* WITH_POLICY */
-
-#endif // name_h
diff --git a/hicn-light/src/hicn/core/nameBitvector.c b/hicn-light/src/hicn/core/nameBitvector.c
deleted file mode 100644
index aa431879c..000000000
--- a/hicn-light/src/hicn/core/nameBitvector.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2021 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <hicn/core/messageHandler.h>
-#include <hicn/core/nameBitvector.h>
-
-#include <hicn/util/hash.h>
-#include <hicn/ctrl/hicn-light-ng.h>
-
-#define DEFAULT_PORT 1234
-
-const uint64_t BV_SIZE = 64;
-const uint64_t WIDTH = 128;
-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 1011] [1000 0000 ... 0000 0011] //binary
-// 1 b 1 c //hex
-
-void nameBitvector_CreateFromInAddr(NameBitvector *bitvector, uint32_t addr,
- uint8_t len) {
- assert(bitvector);
-
- bitvector->bits[0] = 0;
- bitvector->bits[1] = 0;
-
- uint8_t addr_1 = (addr & 0xff000000) >> 24;
- uint8_t addr_2 = (addr & 0x00ff0000) >> 16;
- uint8_t addr_3 = (addr & 0x0000ff00) >> 8;
- uint8_t addr_4 = (addr & 0x000000ff);
-
- 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;
-
- bitvector->IPversion = IPv4_TYPE;
-}
-
-void nameBitvector_CreateFromIn6Addr(NameBitvector *bitvector,
- struct in6_addr *addr, uint8_t len) {
- assert(addr);
- assert(bitvector);
-
- bitvector->bits[0] = 0;
- bitvector->bits[1] = 0;
-
- for (int i = 0; i < 8; ++i) {
- bitvector->bits[0] = (bitvector->bits[0] << 8) | addr->s6_addr[i];
- }
-
- for (int i = 8; i < 16; ++i) {
- bitvector->bits[1] = (bitvector->bits[1] << 8) | addr->s6_addr[i];
- }
-
- bitvector->len = len;
-
- bitvector->IPversion = IPv6_TYPE;
-}
-
-void nameBitvector_Copy(const NameBitvector *original, NameBitvector *copy) {
- assert(original);
- assert(copy);
-
- copy->bits[0] = original->bits[0];
- copy->bits[1] = original->bits[1];
- copy->len = original->len;
- copy->IPversion = original->IPversion;
-}
-
-uint8_t nameBitvector_GetLength(const NameBitvector *name) { return name->len; }
-
-uint32_t nameBitvector_GetHash32(const NameBitvector *name) {
- return hash(&name->bits, 16);
-}
-
-bool nameBitvector_Equals(const NameBitvector *a, const NameBitvector *b) {
- if (nameBitvector_Compare(a, b) == 0) return true;
- return false;
-}
-
-int nameBitvector_Compare(const NameBitvector *a, const NameBitvector *b) {
- if (a == NULL && b == NULL) {
- return 0;
- }
- if (a == NULL) {
- return -1;
- }
- if (b == NULL) {
- return +1;
- }
-
- if (a->bits[0] < b->bits[0]) {
- return -1;
- } else if (a->bits[0] > b->bits[0]) {
- return +1;
- } else if (a->bits[1] < b->bits[1]) {
- return -1;
- } else if (a->bits[1] > b->bits[1]) {
- return +1;
- } else if (a->len < b->len) {
- return -1;
- } else if (a->len > b->len) {
- return +1;
- } else {
- return 0;
- }
-}
-
-int nameBitvector_testBit(const NameBitvector *name, uint8_t pos, bool *bit) {
- if (pos >= name->len || pos > (WIDTH - 1)) return -1;
-
- *bit =
- (name->bits[pos / BV_SIZE] & (ONE << ((BV_SIZE - 1) - (pos % BV_SIZE))));
-
- return 0;
-}
-
-// TODO XXX use ffs(ll)
-uint64_t _diff_bit_log2(uint64_t val) {
- // base 2 log of an uint64_t. This is the same as get the position of
- // the highest bit set (or most significant bit set, MSB)
- uint64_t result = 0;
-
- if (val & 0xFFFFFFFF00000000) {
- val = val >> 32;
- result = result | 32;
- }
- if (val & 0xFFFF0000) {
- val = val >> 16;
- result = result | 16;
- }
- if (val & 0xFF00) {
- val = val >> 8;
- result = result | 8;
- }
- if (val & 0xF0) {
- val = val >> 4;
- result = result | 4;
- }
- if (val & 0xC) {
- val = val >> 2;
- result = result | 2;
- }
- if (val & 0x2) {
- val = val >> 1;
- result = result | 1;
- }
- return result;
-}
-
-uint32_t nameBitvector_lpm(const NameBitvector *a, const NameBitvector *b) {
- uint32_t limit;
- uint32_t prefix_len;
- if (a->len < b->len)
- limit = a->len;
- else
- limit = b->len;
-
- uint64_t diff = a->bits[0] ^ b->bits[0];
- if (diff) {
- prefix_len = (uint32_t)(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 (prefix_len < limit) return prefix_len;
- return limit;
-}
-
-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, ip_prefix_t *prefix) {
- if (name->IPversion == IPv4_TYPE) {
- struct in_addr *addr = (struct in_addr *)(&prefix->address.v4.buffer);
- prefix->family = AF_INET;
- prefix->len = IPV4_ADDR_LEN_BITS;
-
- 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;
- uint8_t addr_4 = (tmp_addr & 0x000000ff);
-
- addr->s_addr = 0;
- addr->s_addr = (addr->s_addr | addr_4) << 8;
- addr->s_addr = (addr->s_addr | addr_3) << 8;
- addr->s_addr = (addr->s_addr | addr_2) << 8;
- addr->s_addr = (addr->s_addr | addr_1);
-
- } else {
- struct in6_addr *addr = (struct in6_addr *)(&prefix->address.v6.buffer);
- prefix->family = AF_INET6;
- prefix->len = name->len; // IPV6_ADDR_LEN_BITS;
-
- for (int i = 0; i < 8; i++) {
- 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[1] >> 8 * (7 - x)) & 0xFF);
- x++;
- }
- }
- return true;
-}
-
-void nameBitvector_setLen(NameBitvector *name, uint8_t len) { name->len = len; }
-
-void nameBitvector_ToAddress(const NameBitvector *name, address_t *address) {
- if (name->IPversion == IPv4_TYPE) {
- struct sockaddr_in *sin = address4(address);
- sin->sin_family = AF_INET;
- sin->sin_port = htons(DEFAULT_PORT);
-
- 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;
- uint8_t addr_4 = (tmp_addr & 0x000000ff);
-
- sin->sin_addr.s_addr = 0;
- sin->sin_addr.s_addr = (sin->sin_addr.s_addr | addr_4) << 8;
- sin->sin_addr.s_addr = (sin->sin_addr.s_addr | addr_3) << 8;
- sin->sin_addr.s_addr = (sin->sin_addr.s_addr | addr_2) << 8;
- sin->sin_addr.s_addr = (sin->sin_addr.s_addr | addr_1);
- } else {
- struct sockaddr_in6 *sin6 = address6(address);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_port = htons(DEFAULT_PORT);
- sin6->sin6_scope_id = 0;
- sin6->sin6_flowinfo = 0;
-
- for (int i = 0; i < 8; i++) {
- sin6->sin6_addr.s6_addr[i] =
- (uint8_t)((name->bits[0] >> 8 * (7 - i)) & 0xFF);
- }
-
- int x = 0;
- for (int i = 8; i < 16; ++i) {
- sin6->sin6_addr.s6_addr[i] =
- (uint8_t)((name->bits[1] >> 8 * (7 - x)) & 0xFF);
- x++;
- }
- }
-}
-
-char *nameBitvector_ToString(const NameBitvector *name) {
- char *output = malloc(WIDTH);
-
- address_t address;
- nameBitvector_ToAddress(name, &address);
-
- // XXX TODO
-#if 0
- sprintf(output, "prefix: %s len: %u", addressToString(packetAddr), name->len);
-#else
- snprintf(output, WIDTH, "%s", "ENOIMPL");
-#endif
-
- return output;
-}
diff --git a/hicn-light/src/hicn/core/nameBitvector.h b/hicn-light/src/hicn/core/nameBitvector.h
deleted file mode 100644
index 549b26679..000000000
--- a/hicn-light/src/hicn/core/nameBitvector.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021 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.
- */
-
-#ifndef name_bitvector_h
-#define name_bitvector_h
-
-#include <hicn/hicn.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "address.h"
-
-#define NAME_LEN 2
-typedef struct __attribute__((__packed__)) {
- uint64_t bits[NAME_LEN];
- uint32_t len;
- uint32_t IPversion;
-} NameBitvector;
-static_assert(sizeof(NameBitvector) == 24,
- "Name prefix should be stored on 24 bytes");
-
-#define EMPTY_NAME_BITVECTOR \
- (NameBitvector) { .bits[0] = 0, .bits[1] = 0, .len = 0, .IPversion = 0, }
-
-void nameBitvector_CreateFromInAddr(NameBitvector *bitvector, uint32_t addr,
- uint8_t len);
-
-void nameBitvector_CreateFromIn6Addr(NameBitvector *bitvector,
- struct in6_addr *addr, uint8_t len);
-
-void nameBitvector_Copy(const NameBitvector *original, NameBitvector *copy);
-
-uint8_t nameBitvector_GetLength(const NameBitvector *name);
-
-uint32_t nameBitvector_GetHash32(const NameBitvector *name);
-
-bool nameBitvector_Equals(const NameBitvector *a, const NameBitvector *b);
-
-int nameBitvector_Compare(const NameBitvector *a, const NameBitvector *b);
-
-int nameBitvector_testBit(const NameBitvector *name, uint8_t pos, bool *bit);
-
-uint32_t nameBitvector_lpm(const NameBitvector *a, const NameBitvector *b);
-
-void nameBitvector_clear(NameBitvector *a, uint8_t start_from);
-
-int nameBitvector_ToIPAddress(const NameBitvector *name, ip_prefix_t *prefix);
-void nameBitvector_setLen(NameBitvector *name, uint8_t len);
-
-void nameBitvector_ToAddress(const NameBitvector *name, address_t *address);
-
-char *nameBitvector_ToString(const NameBitvector *name);
-
-#endif // name_bitvector_h
diff --git a/hicn-light/src/hicn/core/nexthops.c b/hicn-light/src/hicn/core/nexthops.c
index 190f09ab0..70089399d 100644
--- a/hicn-light/src/hicn/core/nexthops.c
+++ b/hicn-light/src/hicn/core/nexthops.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -18,6 +18,8 @@
* \brief Nexthops implementation
*/
+#include <hicn/util/hash.h>
+
#include "nexthops.h"
int nexthops_disable(nexthops_t *nexthops, off_t offset) {
@@ -34,7 +36,6 @@ void nexthops_reset(nexthops_t *nexthops) {
off_t nexthops_add(nexthops_t *nexthops, nexthop_t nexthop) {
off_t id;
- unsigned i, n;
nexthops_enumerate(nexthops, i, n, {
if (n == nexthop) return i;
});
@@ -45,7 +46,6 @@ off_t nexthops_add(nexthops_t *nexthops, nexthop_t nexthop) {
}
off_t nexthops_remove(nexthops_t *nexthops, nexthop_t nexthop) {
- unsigned i, n;
nexthops_enumerate(nexthops, i, n, {
if (n == nexthop) {
nexthops->num_elts--;
@@ -59,7 +59,6 @@ off_t nexthops_remove(nexthops_t *nexthops, nexthop_t nexthop) {
}
bool nexthops_contains(nexthops_t *nexthops, unsigned nexthop) {
- unsigned n;
nexthops_foreach(nexthops, n, {
if (n == nexthop) return true;
});
@@ -67,7 +66,6 @@ bool nexthops_contains(nexthops_t *nexthops, unsigned nexthop) {
}
off_t nexthops_find(nexthops_t *nexthops, unsigned nexthop) {
- unsigned i, n;
nexthops_enumerate(nexthops, i, n, {
if (n == nexthop) return i;
});
@@ -75,7 +73,6 @@ off_t nexthops_find(nexthops_t *nexthops, unsigned nexthop) {
}
unsigned nexthops_get_one(nexthops_t *nexthops) {
- unsigned n;
nexthops_foreach(nexthops, n, { return n; });
return INVALID_NEXTHOP;
}
@@ -92,8 +89,6 @@ int nexthops_select(nexthops_t *nexthops, off_t i) {
void nexthops_set_priority(nexthops_t *nexthops, nexthop_t nexthop,
int priority) {
- unsigned i;
- nexthop_t nh;
nexthops_enumerate(nexthops, i, nh, {
if (nexthop == nh) nexthops_set_priority_by_id(nexthops, i, priority);
});
@@ -112,8 +107,6 @@ void nexthops_reset_priority_by_id(nexthops_t *nexthops, off_t i) {
}
void nexthops_reset_priorities(nexthops_t *nexthops) {
- unsigned i;
- nexthop_t nh;
nexthops_enumerate(nexthops, i, nh, {
(void)nh;
nexthops_reset_priority(nexthops, i);
@@ -121,7 +114,6 @@ void nexthops_reset_priorities(nexthops_t *nexthops) {
}
bool nexthops_equal(nexthops_t *a, nexthops_t *b) {
- unsigned n;
if (nexthops_get_len(a) != nexthops_get_len(b)) return false;
nexthops_foreach(a, n, {
if (!nexthops_contains(b, n)) return false;
@@ -139,4 +131,19 @@ void nexthops_copy(nexthops_t *src, nexthops_t *dst) {
dst->cur_elts = src->cur_elts;
}
+/* Adapted from Jenkins hash (commutative) */
+uint32_t nexthops_get_hash(nexthops_t *nexthops) {
+ uint32_t hash = 0;
+
+ nexthops_foreach(nexthops, nh, {
+ hash += nh;
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ });
+ hash += hash << 3;
+ hash ^= hash >> 11;
+ hash += hash << 15;
+ return hash;
+}
+
#endif /* WITH_POLICY */
diff --git a/hicn-light/src/hicn/core/nexthops.h b/hicn-light/src/hicn/core/nexthops.h
index 2a7fc0b32..ff83199a6 100644
--- a/hicn-light/src/hicn/core/nexthops.h
+++ b/hicn-light/src/hicn/core/nexthops.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -106,21 +106,24 @@ int nexthops_disable(nexthops_t *nexthops, off_t offset);
void nexthops_reset(nexthops_t *nexthops);
-#define nexthops_enumerate(NH, i, X, BODY) \
+#define nexthops_enumerate(NH, I, X, BODY) \
do { \
- for ((i) = 0; (i) < nexthops_get_len(NH); (i)++) { \
- if (nexthops_is_disabled((NH), (i))) continue; \
- X = (NH)->elts[(i)]; \
+ nexthop_t X; \
+ (void)X; \
+ unsigned I; \
+ (void)I; \
+ for ((I) = 0; (I) < nexthops_get_len(NH); (I)++) { \
+ if (nexthops_is_disabled((NH), (I))) continue; \
+ X = (NH)->elts[(I)]; \
do { \
BODY \
} while (0); \
} \
} while (0)
-#define nexthops_foreach(NH, X, BODY) \
- do { \
- unsigned _nexthops_var(i); \
- nexthops_enumerate((NH), _nexthops_var(i), (X), {BODY}); \
+#define nexthops_foreach(NH, X, BODY) \
+ do { \
+ nexthops_enumerate((NH), _nexthops_var(i), X, {BODY}); \
} while (0)
off_t nexthops_add(nexthops_t *nexthops, nexthop_t nexthop);
@@ -173,4 +176,6 @@ void nexthops_copy(nexthops_t *src, nexthops_t *dst);
#endif /* WITH_POLICY */
+uint32_t nexthops_get_hash(nexthops_t *nexthops);
+
#endif /* HICNLIGHT_NEXTHOPS_H */
diff --git a/hicn-light/src/hicn/core/packet_cache.c b/hicn-light/src/hicn/core/packet_cache.c
index 8bd188c8b..9d0b041c3 100644
--- a/hicn-light/src/hicn/core/packet_cache.c
+++ b/hicn-light/src/hicn/core/packet_cache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -16,48 +16,121 @@
/**
* \file packet_cache.c
* \brief Implementation of hICN packet cache
+ *
+ * _get_suffixes : first level lookup to return the suffixes
+ *
+ * _remove_suffix : Remove suffix from the two level packet cache structure
+ *
+ * __add_suffix : Add a packet cache entry in the second level of the
+ * two-level data structure _add_suffix : Add a packet cache entry in the both
+ * the first and second level of the two-level data tructure (helper)
+ *
+ * __get_suffix : Lookup in the second level of the packet cache
+ *
+ * _get_suffix : Lookup in both the first and second levels of the packet cache
+ *
+ * ----
+ *
+ * pkt_cache_save_suffixes_for_prefix : always done at packet reception to keep
+ * the latest suffixes
+ *
+ * pkt_cache_reset_suffixes_for_prefix
+ *
+ * ----
+ *
+ * pkt_cache_allocate
+ *
+ * pkt_cache_add_to_index
+ *
+ * pkt_cache_remove_from_index
+ *
+ * pkt_cache_pit_remove_entry
+ *
+ * pkt_cache_cs_remove_entry
+ *
+ * pkt_cache_add_to_pit
+ * pkt_cache_add_to_cs
+ *
+ * _pkt_cache_add_to_pit
+ * used by pkt_cache_add_to_pit
+ * plt_cache_update_pit
+ * _pkt_cache_add_to_cs
+ *
+ * pkt_cache_pit_to_cs
+ * pkt_cache_cs_to_pit
+ *
+ * pkt_cache_update_pit : when an interest expired
+ * pkt_cache_update_cs
+ *
+ * pkt_cache_try_aggregate_in_pit
+ *
+ *
+ *
*/
#include "packet_cache.h"
+const char *_pkt_cache_verdict_str[] = {
+#define _(x) [PKT_CACHE_VERDICT_##x] = #x,
+ foreach_kh_verdict
+#undef _
+};
+
/******************************************************************************
* Low-level operations on the hash table
******************************************************************************/
+/**
+ * Free the two level packet cache structure (helper)
+ */
void _prefix_map_free(kh_pkt_cache_prefix_t *prefix_to_suffixes) {
- const NameBitvector *key;
+ const hicn_name_prefix_t *key;
kh_pkt_cache_suffix_t *value;
kh_foreach(prefix_to_suffixes, key, value, {
- free((NameBitvector *)key);
+ //(void)key;
+ free((hicn_name_prefix_t *)key);
kh_destroy_pkt_cache_suffix(value);
});
kh_destroy_pkt_cache_prefix(prefix_to_suffixes);
}
+/**
+ * Perform the first level lookup to return the suffixes (helper)
+ */
kh_pkt_cache_suffix_t *_get_suffixes(kh_pkt_cache_prefix_t *prefix_to_suffixes,
- const NameBitvector *prefix) {
+ const hicn_name_prefix_t *prefix,
+ bool create) {
khiter_t k = kh_get_pkt_cache_prefix(prefix_to_suffixes, prefix);
- // Return suffixes found
+ /* Return suffixes if found... */
if (k != kh_end(prefix_to_suffixes)) {
kh_pkt_cache_suffix_t *suffixes = kh_val(prefix_to_suffixes, k);
return suffixes;
}
+ if (!create) return NULL;
+
+ /* ... otherwise populate the first level and return the newly added entry.
+ */
kh_pkt_cache_suffix_t *suffixes = kh_init_pkt_cache_suffix();
- NameBitvector *nb_copy = (NameBitvector *)malloc(sizeof(NameBitvector));
- *nb_copy = *prefix;
+
+ hicn_name_prefix_t *prefix_copy = malloc(sizeof(hicn_name_prefix_t));
+ *prefix_copy = *prefix;
int rc;
- k = kh_put_pkt_cache_prefix(prefix_to_suffixes, nb_copy, &rc);
+ k = kh_put_pkt_cache_prefix(prefix_to_suffixes, prefix_copy, &rc);
assert(rc == KH_ADDED || rc == KH_RESET);
kh_value(prefix_to_suffixes, k) = suffixes;
return suffixes;
}
+/**
+ * Remove suffix from the two level packet cache structure (helper)
+ */
void _remove_suffix(kh_pkt_cache_prefix_t *prefixes,
- const NameBitvector *prefix, uint32_t suffix) {
- kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix);
+ const hicn_name_prefix_t *prefix,
+ const hicn_name_suffix_t suffix) {
+ kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix, false);
assert(suffixes != NULL);
khiter_t k = kh_get_pkt_cache_suffix(suffixes, suffix);
@@ -67,60 +140,90 @@ void _remove_suffix(kh_pkt_cache_prefix_t *prefixes,
// TODO(eloparco): Remove prefix if no associated suffixes?
}
-void __add_suffix(kh_pkt_cache_suffix_t *suffixes, uint32_t suffix,
+/**
+ * Add a packet cache entry in the second level of the two-level data structure
+ * (helper)
+ */
+void __add_suffix(kh_pkt_cache_suffix_t *suffixes, hicn_name_suffix_t suffix,
unsigned val) {
+ // INFO("suffix add suffixes=%p suffix=%d val=%d", suffixes, suffix, val);
int rc;
khiter_t k = kh_put_pkt_cache_suffix(suffixes, suffix, &rc);
assert(rc == KH_ADDED || rc == KH_RESET);
kh_value(suffixes, k) = val;
}
-void _add_suffix(kh_pkt_cache_prefix_t *prefixes, const NameBitvector *prefix,
- uint32_t suffix, unsigned val) {
- kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix);
+/**
+ * Add a packet cache entry in the both the first and second level of the
+ * two-level data tructure (helper)
+ */
+void _add_suffix(kh_pkt_cache_prefix_t *prefixes,
+ const hicn_name_prefix_t *prefix,
+ const hicn_name_suffix_t suffix, unsigned val) {
+ kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix, true);
assert(suffixes != NULL);
__add_suffix(suffixes, suffix, val);
}
-unsigned __get_suffix(kh_pkt_cache_suffix_t *suffixes, uint32_t suffix,
- int *rc) {
- *rc = KH_FOUND;
+/**
+ * Lookup in the second level of the packet cache (helper)
+ */
+unsigned __get_suffix(kh_pkt_cache_suffix_t *suffixes,
+ hicn_name_suffix_t suffix) {
khiter_t k = kh_get_pkt_cache_suffix(suffixes, suffix);
// Not Found
if (k == kh_end(suffixes)) {
- *rc = KH_NOT_FOUND;
- return -1;
+ return HICN_INVALID_SUFFIX;
}
unsigned index = kh_val(suffixes, k);
return index;
}
+unsigned _get_suffix(kh_pkt_cache_prefix_t *prefixes,
+ const hicn_name_prefix_t *prefix,
+ hicn_name_suffix_t suffix) {
+ /* create is false as this function is always called by lookup */
+ kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix, false);
+ if (!suffixes) {
+ return HICN_INVALID_SUFFIX;
+ }
+ return __get_suffix(suffixes, suffix);
+}
+
+/**
+ * Lookup in both the first and second levels of the packet cache (helper)
+ */
+unsigned _get_suffix_from_name(kh_pkt_cache_prefix_t *prefixes,
+ const hicn_name_t *name) {
+ const hicn_name_prefix_t *prefix = hicn_name_get_prefix(name);
+ const hicn_name_suffix_t suffix = hicn_name_get_suffix(name);
+
+ return _get_suffix(prefixes, prefix, suffix);
+}
+
void pkt_cache_save_suffixes_for_prefix(pkt_cache_t *pkt_cache,
- const NameBitvector *prefix) {
+ const hicn_name_prefix_t *prefix) {
// Cached prefix matches the current one
- if (nameBitvector_Compare(&pkt_cache->cached_prefix, prefix) == 0) return;
+ if (hicn_name_prefix_equals(&pkt_cache->cached_prefix, prefix)) return;
+
+ char buf[MAXSZ_HICN_PREFIX];
+ hicn_name_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, &pkt_cache->cached_prefix);
+ hicn_name_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
// Update cached prefix information
pkt_cache->cached_prefix = *prefix;
pkt_cache->cached_suffixes =
- _get_suffixes(pkt_cache->prefix_to_suffixes, prefix);
+ _get_suffixes(pkt_cache->prefix_to_suffixes, prefix, true); // XXX
+ //
}
void pkt_cache_reset_suffixes_for_prefix(pkt_cache_t *pkt_cache) {
pkt_cache->cached_suffixes = NULL;
}
-unsigned _get_suffix(kh_pkt_cache_prefix_t *prefixes,
- const NameBitvector *prefix, uint32_t suffix, int *rc) {
- kh_pkt_cache_suffix_t *suffixes = _get_suffixes(prefixes, prefix);
- assert(suffixes != NULL);
-
- return __get_suffix(suffixes, suffix, rc);
-}
-
/******************************************************************************
* Public API
******************************************************************************/
@@ -136,7 +239,7 @@ pkt_cache_t *pkt_cache_create(size_t cs_size) {
pkt_cache->prefix_to_suffixes = kh_init_pkt_cache_prefix();
pool_init(pkt_cache->entries, DEFAULT_PKT_CACHE_SIZE, 0);
- pkt_cache->cached_prefix = EMPTY_NAME_BITVECTOR;
+ pkt_cache->cached_prefix = HICN_NAME_PREFIX_EMPTY;
pkt_cache->cached_suffixes = NULL;
return pkt_cache;
@@ -157,50 +260,71 @@ void pkt_cache_free(pkt_cache_t *pkt_cache) {
}
kh_pkt_cache_suffix_t *pkt_cache_get_suffixes(const pkt_cache_t *pkt_cache,
- const NameBitvector *prefix) {
- return _get_suffixes(pkt_cache->prefix_to_suffixes, prefix);
+ const hicn_name_prefix_t *prefix,
+ bool create) {
+ return _get_suffixes(pkt_cache->prefix_to_suffixes, prefix, create);
}
-pkt_cache_entry_t *pkt_cache_allocate(pkt_cache_t *pkt_cache,
- const Name *name) {
+pkt_cache_entry_t *pkt_cache_allocate(pkt_cache_t *pkt_cache) {
pkt_cache_entry_t *entry = NULL;
pool_get(pkt_cache->entries, entry);
- if (!entry) return NULL;
+ assert(entry);
+ return entry;
+}
+void pkt_cache_add_to_index(const pkt_cache_t *pkt_cache,
+ const pkt_cache_entry_t *entry) {
off_t id = entry - pkt_cache->entries;
+ /* It is important that the name used for the index is the one in the packet
+ * cache entry, which is common for PIT and CS
+ */
+ const hicn_name_t *name = &entry->name;
+
if (pkt_cache->cached_suffixes) {
- __add_suffix(pkt_cache->cached_suffixes, name_GetSegment(name),
+ __add_suffix(pkt_cache->cached_suffixes, hicn_name_get_suffix(name),
(unsigned int)id);
} else {
- _add_suffix(pkt_cache->prefix_to_suffixes, name_GetContentName(name),
- name_GetSegment(name), (unsigned int)id);
+ _add_suffix(pkt_cache->prefix_to_suffixes, hicn_name_get_prefix(name),
+ hicn_name_get_suffix(name), (unsigned int)id);
}
+}
- return entry;
+/**
+ * Remove a name pointer to the packet cache index (helper)
+ */
+void pkt_cache_remove_from_index(const pkt_cache_t *pkt_cache,
+ const hicn_name_t *name) {
+ _remove_suffix(pkt_cache->prefix_to_suffixes, hicn_name_get_prefix(name),
+ hicn_name_get_suffix(name));
+
+// TODO
+#if 0
+ khiter_t k = kh_get_pkt_cache_name(pkt_cache->index_by_name, name);
+ assert(k != kh_end(pkt_cache->index_by_name));
+ kh_del(pkt_cache_name, pkt_cache->index_by_name, k);
+#endif
}
pit_t *pkt_cache_get_pit(pkt_cache_t *pkt_cache) { return pkt_cache->pit; }
cs_t *pkt_cache_get_cs(pkt_cache_t *pkt_cache) { return pkt_cache->cs; }
-pkt_cache_entry_t *pkt_cache_lookup(pkt_cache_t *pkt_cache, const Name *name,
+pkt_cache_entry_t *pkt_cache_lookup(pkt_cache_t *pkt_cache,
+ const hicn_name_t *name,
msgbuf_pool_t *msgbuf_pool,
pkt_cache_lookup_t *lookup_result,
off_t *entry_id,
bool is_serve_from_cs_enabled) {
- int rc;
-
- unsigned index = -1;
+ unsigned index = HICN_INVALID_SUFFIX;
if (pkt_cache->cached_suffixes) {
index =
- __get_suffix(pkt_cache->cached_suffixes, name_GetSegment(name), &rc);
+ __get_suffix(pkt_cache->cached_suffixes, hicn_name_get_suffix(name));
} else {
- index = _get_suffix(pkt_cache->prefix_to_suffixes,
- name_GetContentName(name), name_GetSegment(name), &rc);
+ index = _get_suffix_from_name(pkt_cache->prefix_to_suffixes, name);
}
- if (rc == KH_NOT_FOUND) {
+ if (index == HICN_INVALID_SUFFIX) {
*lookup_result = PKT_CACHE_LU_NONE;
return NULL;
}
@@ -237,9 +361,10 @@ void pkt_cache_cs_remove_entry(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
off_t msgbuf_id = entry->u.cs_entry.msgbuf_id;
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
- const Name *name = msgbuf_get_name(msgbuf);
- _remove_suffix(pkt_cache->prefix_to_suffixes, name_GetContentName(name),
- name_GetSegment(name));
+ // XXX const hicn_name_t *name = msgbuf_get_name(msgbuf);
+ _remove_suffix(pkt_cache->prefix_to_suffixes,
+ hicn_name_get_prefix(&entry->name),
+ hicn_name_get_suffix(&entry->name));
// Do not update the LRU cache for evicted entries
if (!is_evicted) cs_vft[pkt_cache->cs->type]->remove_entry(pkt_cache, entry);
@@ -248,28 +373,34 @@ void pkt_cache_cs_remove_entry(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
pool_put(pkt_cache->entries, entry);
WITH_DEBUG({
- char *name_str = name_ToString(msgbuf_get_name(msgbuf));
- DEBUG("Packet %s removed from CS", name_str);
- free(name_str);
+ char buf[MAXSZ_HICN_NAME];
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, &entry->name);
+ if (rc < 0 || rc >= MAXSZ_HICN_NAME)
+ snprintf(buf, MAXSZ_HICN_NAME, "%s", "(error)");
+ DEBUG("Packet %s removed from CS", buf);
})
msgbuf_pool_release(msgbuf_pool, &msgbuf);
}
void pkt_cache_pit_remove_entry(pkt_cache_t *pkt_cache,
- pkt_cache_entry_t *entry, const Name *name) {
+ pkt_cache_entry_t *entry) {
assert(pkt_cache);
assert(entry);
assert(entry->entry_type == PKT_CACHE_PIT_TYPE);
- _remove_suffix(pkt_cache->prefix_to_suffixes, name_GetContentName(name),
- name_GetSegment(name));
+ const hicn_name_t *name = &entry->name;
+ _remove_suffix(pkt_cache->prefix_to_suffixes, hicn_name_get_prefix(name),
+ hicn_name_get_suffix(name));
+
pool_put(pkt_cache->entries, entry);
WITH_DEBUG({
- char *name_str = name_ToString(name);
- DEBUG("Packet %s removed from PIT", name_str);
- free(name_str);
+ char buf[MAXSZ_HICN_NAME];
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, name);
+ if (rc < 0 || rc >= MAXSZ_HICN_NAME)
+ snprintf(buf, MAXSZ_HICN_NAME, "%s", "(error)");
+ DEBUG("Packet %s removed from PIT", buf);
})
}
@@ -279,8 +410,9 @@ void _pkt_cache_add_to_cs(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
entry->u.cs_entry =
(cs_entry_t){.msgbuf_id = msgbuf_id,
.lru = {.prev = INVALID_ENTRY_ID, .next = INVALID_ENTRY_ID}};
- entry->create_ts = ticks_now();
- entry->expire_ts = ticks_now() + msgbuf_get_data_expiry_time(msgbuf);
+ Ticks now = ticks_now();
+ entry->create_ts = now;
+ entry->expire_ts = now + msgbuf_get_data_expiry_time(msgbuf);
entry->has_expire_ts = true;
entry->entry_type = PKT_CACHE_CS_TYPE;
@@ -299,18 +431,21 @@ void _pkt_cache_add_to_cs(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
msgbuf_pool_acquire(msgbuf);
}
-void pkt_cache_pit_to_cs(pkt_cache_t *pkt_cache,
- pkt_cache_entry_t *interest_entry,
- msgbuf_pool_t *msgbuf_pool, msgbuf_t *data_msgbuf,
- off_t data_msgbuf_id, off_t entry_id) {
+void pkt_cache_pit_to_cs(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
+ msgbuf_pool_t *msgbuf_pool, msgbuf_t *msgbuf,
+ off_t msgbuf_id, off_t entry_id) {
assert(pkt_cache);
- assert(interest_entry);
- assert(interest_entry->entry_type == PKT_CACHE_PIT_TYPE);
+ assert(entry);
+ assert(entry->entry_type == PKT_CACHE_PIT_TYPE);
- _pkt_cache_add_to_cs(pkt_cache, interest_entry, msgbuf_pool, data_msgbuf,
- data_msgbuf_id, entry_id);
+ _pkt_cache_add_to_cs(pkt_cache, entry, msgbuf_pool, msgbuf, msgbuf_id,
+ entry_id);
}
+/**
+ * entry : newly allocated cache entry
+ * msgbuf : used for name, ingress connection id and lifetime
+ */
void _pkt_cache_add_to_pit(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
const msgbuf_t *msgbuf) {
entry->u.pit_entry = (pit_entry_t){
@@ -366,11 +501,13 @@ void pkt_cache_update_cs(pkt_cache_t *pkt_cache, msgbuf_pool_t *msgbuf_pool,
pkt_cache_entry_t *pkt_cache_add_to_pit(pkt_cache_t *pkt_cache,
const msgbuf_t *msgbuf,
- const Name *name) {
+ const hicn_name_t *name) {
assert(pkt_cache);
- pkt_cache_entry_t *entry = pkt_cache_allocate(pkt_cache, name);
+ pkt_cache_entry_t *entry = pkt_cache_allocate(pkt_cache);
+ entry->name = *name;
_pkt_cache_add_to_pit(pkt_cache, entry, msgbuf);
+ pkt_cache_add_to_index(pkt_cache, entry);
return entry;
}
@@ -379,12 +516,13 @@ pkt_cache_entry_t *pkt_cache_add_to_cs(pkt_cache_t *pkt_cache,
msgbuf_t *msgbuf, off_t msgbuf_id) {
assert(pkt_cache);
- pkt_cache_entry_t *entry =
- pkt_cache_allocate(pkt_cache, msgbuf_get_name(msgbuf));
+ pkt_cache_entry_t *entry = pkt_cache_allocate(pkt_cache);
+ const hicn_name_t *name = msgbuf_get_name(msgbuf);
+ entry->name = *name;
off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
_pkt_cache_add_to_cs(pkt_cache, entry, msgbuf_pool, msgbuf, msgbuf_id,
entry_id);
-
+ pkt_cache_add_to_index(pkt_cache, entry);
return entry;
}
@@ -404,7 +542,8 @@ void pkt_cache_update_pit(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
bool pkt_cache_try_aggregate_in_pit(pkt_cache_t *pkt_cache,
pkt_cache_entry_t *entry,
- const msgbuf_t *msgbuf, const Name *name) {
+ const msgbuf_t *msgbuf,
+ const hicn_name_t *name) {
assert(pkt_cache);
assert(entry);
assert(entry->entry_type == PKT_CACHE_PIT_TYPE);
@@ -422,15 +561,17 @@ bool pkt_cache_try_aggregate_in_pit(pkt_cache_t *pkt_cache,
if (is_aggregated) pit_entry_ingress_add(pit_entry, connection_id);
WITH_DEBUG({
- char *name_str = name_ToString(name);
+ char buf[MAXSZ_HICN_NAME];
+ int rc = hicn_name_snprintf(buf, MAXSZ_HICN_NAME, msgbuf_get_name(msgbuf));
+ if (rc < 0 || rc >= MAXSZ_HICN_NAME)
+ snprintf(buf, MAXSZ_HICN_NAME, "%s", "(error)");
if (is_aggregated) {
- DEBUG("Interest %s already existing (expiry %lu): aggregate", name_str,
+ DEBUG("Interest %s already existing (expiry %lu): aggregate", buf,
entry->expire_ts);
} else {
- DEBUG("Interest %s already existing (expiry %lu): retransmit", name_str,
+ DEBUG("Interest %s already existing (expiry %lu): retransmit", buf,
entry->expire_ts);
}
- free(name_str);
})
return is_aggregated;
@@ -445,7 +586,7 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
assert(msgbuf_id_is_valid(msgbuf_id));
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
- assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA);
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA);
*wrong_egress = false;
off_t entry_id;
@@ -487,7 +628,7 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
entry_id);
*verdict = PKT_CACHE_VERDICT_FORWARD_DATA;
} else {
- pkt_cache_pit_remove_entry(pkt_cache, entry, msgbuf_get_name(msgbuf));
+ pkt_cache_pit_remove_entry(pkt_cache, entry);
*verdict = PKT_CACHE_VERDICT_CLEAR_DATA;
}
@@ -503,7 +644,7 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
entry_id);
*verdict = PKT_CACHE_VERDICT_STORE_DATA;
} else {
- pkt_cache_pit_remove_entry(pkt_cache, entry, msgbuf_get_name(msgbuf));
+ pkt_cache_pit_remove_entry(pkt_cache, entry);
*verdict = PKT_CACHE_VERDICT_CLEAR_DATA;
}
return NULL;
@@ -543,12 +684,13 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
void pkt_cache_on_interest(pkt_cache_t *pkt_cache, msgbuf_pool_t *msgbuf_pool,
off_t msgbuf_id, pkt_cache_verdict_t *verdict,
off_t *data_msgbuf_id, pkt_cache_entry_t **entry_ptr,
- const Name *name, bool is_serve_from_cs_enabled) {
+ const hicn_name_t *name,
+ bool is_serve_from_cs_enabled) {
assert(pkt_cache);
assert(msgbuf_id_is_valid(msgbuf_id));
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
- assert(msgbuf_get_type(msgbuf) == MSGBUF_TYPE_INTEREST);
+ assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
off_t entry_id;
pkt_cache_lookup_t lookup_result;
@@ -628,7 +770,7 @@ void pkt_cache_cs_clear(pkt_cache_t *pkt_cache) {
});
// Reset cached prefix
- pkt_cache->cached_prefix = EMPTY_NAME_BITVECTOR;
+ pkt_cache->cached_prefix = HICN_NAME_PREFIX_EMPTY;
pkt_cache->cached_suffixes = NULL;
// Re-create CS
diff --git a/hicn-light/src/hicn/core/packet_cache.h b/hicn-light/src/hicn/core/packet_cache.h
index 47926fcdc..dcbc20c7d 100644
--- a/hicn-light/src/hicn/core/packet_cache.h
+++ b/hicn-light/src/hicn/core/packet_cache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -69,6 +69,10 @@ typedef enum {
#undef _
} pkt_cache_verdict_t;
+extern const char *_pkt_cache_verdict_str[];
+
+#define pkt_cache_verdict_str(x) _pkt_cache_verdict_str[x]
+
#define foreach_kh_lookup \
_(INTEREST_NOT_EXPIRED) \
_(INTEREST_EXPIRED) \
@@ -83,10 +87,12 @@ typedef enum {
} pkt_cache_lookup_t;
KHASH_MAP_INIT_INT(pkt_cache_suffix, unsigned);
-KHASH_INIT(pkt_cache_prefix, const NameBitvector *, kh_pkt_cache_suffix_t *, 1,
- nameBitvector_GetHash32, nameBitvector_Equals);
+KHASH_INIT(pkt_cache_prefix, const hicn_name_prefix_t *,
+ kh_pkt_cache_suffix_t *, 1, hicn_name_prefix_get_hash,
+ hicn_name_prefix_equals);
typedef struct {
+ hicn_name_t name;
pkt_cache_entry_type_t entry_type;
Ticks create_ts;
@@ -109,7 +115,7 @@ typedef struct {
// Cached prefix info to avoid double lookups,
// used for both single interest speculation and interest manifest
- NameBitvector cached_prefix;
+ hicn_name_prefix_t cached_prefix;
kh_pkt_cache_suffix_t *cached_suffixes;
} pkt_cache_t;
@@ -123,12 +129,29 @@ pkt_cache_t *pkt_cache_create(size_t cs_size);
/**
* @brief Add an entry with the specified name to the packet cache.
*
- * @param[in] pkt_cache Pointer to the msgbuf pool data structure to use.
+ * @param[in] pkt_cache Pointer to the pool data structure to use.
* @param[in, out] entry Empty entry that will be used to return the
* allocated one from the msgbuf pool.
- * * @param[in] name Name to use
+ * @param[in] name hicn_name_t to use
+ *
+ * NOTE: unlike other pools, PIT and CS entries allocation does not update the
+ * index as the key is a hicn_name_t * which should point to :
+ * - the name inside the PIT entry (which is thus not set during allocation),
+ * - the name inside the msgbuf_t in the CS entry, which is always available
+ * during the lifetime of the cache entry.
+ *
+ * The index is therefore updated in pkt_cache_add_to_pit and
+ * pkt_cache_add_to_cs functions.
+ *
+ *
*/
-pkt_cache_entry_t *pkt_cache_allocate(pkt_cache_t *pkt_cache, const Name *name);
+pkt_cache_entry_t *pkt_cache_allocate(pkt_cache_t *pkt_cache);
+
+void pkt_cache_add_to_index(const pkt_cache_t *pkt_cache,
+ const pkt_cache_entry_t *entry);
+
+void pkt_cache_remove_from_index(const pkt_cache_t *pkt_cache,
+ const hicn_name_t *name);
/**
* @brief Free a packet cache data structure.
@@ -150,8 +173,8 @@ pit_t *pkt_cache_get_pit(pkt_cache_t *pkt_cache);
* @brief Get a reference to the CS data structure contained in the packet
* cache.
*
- * @param[in] pkt_cache Pointer to the packet cache data structure to get the CS
- * from.
+ * @param[in] pkt_cache Pointer to the packet cache data structure to get the
+ * CS from.
*/
cs_t *pkt_cache_get_cs(pkt_cache_t *pkt_cache);
@@ -170,13 +193,13 @@ size_t pkt_cache_get_size(pkt_cache_t *pkt_cache);
size_t pkt_cache_get_num_cs_stale_entries(pkt_cache_t *pkt_cache);
/**
- * @brief Change the maximum capacity of the content store (LRU eviction will be
- * used after reaching the provided size)
+ * @brief Change the maximum capacity of the content store (LRU eviction will
+ * be used after reaching the provided size)
*
* @param[in] pkt_cache Pointer to the packet cache data structure to use
* @param[in] size Maximum size of the content store
- * @return int 0 if success, -1 if the provided maximum size is smaller than the
- * number of elements currently stored in the CS
+ * @return int 0 if success, -1 if the provided maximum size is smaller than
+ * the number of elements currently stored in the CS
*/
int pkt_cache_set_cs_size(pkt_cache_t *pkt_cache, size_t size);
@@ -203,8 +226,8 @@ size_t pkt_cache_get_pit_size(pkt_cache_t *pkt_cache);
#define pkt_cache_at(pkt_cache, i) (pkt_cache->entries + i)
/**
- * @brief Retrieve from the packet cache the entry associated with the specified
- * name.
+ * @brief Retrieve from the packet cache the entry associated with the
+ * specified name.
*
* @param[in] pkt_cache Pointer to the packet cache data structure to retrieve
* the entry from
@@ -217,7 +240,8 @@ size_t pkt_cache_get_pit_size(pkt_cache_t *pkt_cache);
* allowed to serve contents from the CS
* @return pkt_cache_entry_t* Entry retrieved, NULL if none found
*/
-pkt_cache_entry_t *pkt_cache_lookup(pkt_cache_t *pkt_cache, const Name *name,
+pkt_cache_entry_t *pkt_cache_lookup(pkt_cache_t *pkt_cache,
+ const hicn_name_t *name,
msgbuf_pool_t *msgbuf_pool,
pkt_cache_lookup_t *lookup_result,
off_t *entry_id,
@@ -260,11 +284,10 @@ void pkt_cache_cs_remove_entry(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
* @brief Remove a PIT entry from the packet cache.
*
* @param[in] pkt_cache Pointer to the packet cache data structure to use
- * @param[in] entry Pointer to the PITe entry to remove
- * @param[in] name Name associated with the PIT entry to remove
+ * @param[in] entry Pointer to the PIT entry to remove
*/
void pkt_cache_pit_remove_entry(pkt_cache_t *pkt_cache,
- pkt_cache_entry_t *entry, const Name *name);
+ pkt_cache_entry_t *entry);
/**
* @brief Convert a PIT entry to a CS entry.
@@ -311,7 +334,7 @@ void pkt_cache_cs_to_pit(pkt_cache_t *pkt_cache, pkt_cache_entry_t *entry,
*/
pkt_cache_entry_t *pkt_cache_add_to_pit(pkt_cache_t *pkt_cache,
const msgbuf_t *msgbuf,
- const Name *name);
+ const hicn_name_t *name);
/**
* @brief Add CS entry to the packet cache.
@@ -329,7 +352,8 @@ pkt_cache_entry_t *pkt_cache_add_to_cs(pkt_cache_t *pkt_cache,
msgbuf_t *msgbuf, off_t msgbuf_id);
/**
- * @brief Update PIT entry in the packet cache in case of an expired PIT entry.
+ * @brief Update PIT entry in the packet cache in case of an expired PIT
+ * entry.
*
* @param[in] pkt_cache Pointer to the packet cache data structure to use
* @param[in, out] entry Pointer to the PIT entry to update
@@ -371,7 +395,8 @@ void pkt_cache_update_cs(pkt_cache_t *pkt_cache, msgbuf_pool_t *msgbuf_pool,
*/
bool pkt_cache_try_aggregate_in_pit(pkt_cache_t *pkt_cache,
pkt_cache_entry_t *entry,
- const msgbuf_t *msgbuf, const Name *name);
+ const msgbuf_t *msgbuf,
+ const hicn_name_t *name);
/**
* @brief Cache prefix info (prefix + associated suffixes) to speed up lookups.
@@ -380,7 +405,7 @@ bool pkt_cache_try_aggregate_in_pit(pkt_cache_t *pkt_cache,
* @param[in] prefix Name prefix to cache
*/
void pkt_cache_save_suffixes_for_prefix(pkt_cache_t *pkt_cache,
- const NameBitvector *prefix);
+ const hicn_name_prefix_t *prefix);
/**
* @brief Reset cached prefix info to force double lookups.
@@ -393,7 +418,8 @@ void pkt_cache_reset_suffixes_for_prefix(pkt_cache_t *pkt_cache);
/**
* @brief Handle data packet reception.
- * @details Perform packet cache lookup and execute operations based on it. If:
+ * @details Perform packet cache lookup and execute operations based on it.
+ * If:
* - INTEREST not expired: Convert PIT entry to CS entry; return the
* nexthops (that can be used to forward the data
* packet now stored in the CS)
@@ -409,7 +435,8 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
/**
* @brief Handle interest packet reception.
- * @details Perform packet cache lookup and execute operations based on it. If:
+ * @details Perform packet cache lookup and execute operations based on it.
+ * If:
* - No match: Do nothing
* - DATA not expired: get data message from CS
* - INTEREST not expired: Aggregate or retransmit the interest received;
@@ -419,23 +446,28 @@ nexthops_t *pkt_cache_on_data(pkt_cache_t *pkt_cache,
void pkt_cache_on_interest(pkt_cache_t *pkt_cache, msgbuf_pool_t *msgbuf_pool,
off_t msgbuf_id, pkt_cache_verdict_t *verdict,
off_t *data_msgbuf_id, pkt_cache_entry_t **entry_ptr,
- const Name *name, bool is_serve_from_cs_enabled);
+ const hicn_name_t *name,
+ bool is_serve_from_cs_enabled);
/********* Low-level operations on the hash table *********/
#ifdef WITH_TESTS
-unsigned __get_suffix(kh_pkt_cache_suffix_t *suffixes, uint32_t suffix,
- int *rc);
+unsigned __get_suffix(kh_pkt_cache_suffix_t *suffixes,
+ hicn_name_suffix_t suffix);
unsigned _get_suffix(kh_pkt_cache_prefix_t *prefixes,
- const NameBitvector *prefix, uint32_t suffix, int *rc);
-void __add_suffix(kh_pkt_cache_suffix_t *suffixes, uint32_t suffix,
+ const hicn_name_prefix_t *prefix,
+ hicn_name_suffix_t suffix);
+void __add_suffix(kh_pkt_cache_suffix_t *suffixes, hicn_name_suffix_t suffix,
unsigned val);
-void _add_suffix(kh_pkt_cache_prefix_t *prefixes, const NameBitvector *prefix,
- uint32_t suffix, unsigned val);
+void _add_suffix(kh_pkt_cache_prefix_t *prefixes,
+ const hicn_name_prefix_t *prefix, hicn_name_suffix_t suffix,
+ unsigned val);
void _remove_suffix(kh_pkt_cache_prefix_t *prefixes,
- const NameBitvector *prefix, uint32_t suffix);
+ const hicn_name_prefix_t *prefix,
+ hicn_name_suffix_t suffix);
void _prefix_map_free(kh_pkt_cache_prefix_t *prefix_to_suffixes);
kh_pkt_cache_suffix_t *_get_suffixes(kh_pkt_cache_prefix_t *prefix_to_suffixes,
- const NameBitvector *prefix);
+ const hicn_name_prefix_t *prefix,
+ bool create);
#endif
/************** Content Store *****************************/
diff --git a/hicn-light/src/hicn/core/policy_stats.c b/hicn-light/src/hicn/core/policy_stats.c
index 1acbccf69..470e74a24 100644
--- a/hicn-light/src/hicn/core/policy_stats.c
+++ b/hicn-light/src/hicn/core/policy_stats.c
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2022 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.
+ */
+
#ifdef WITH_POLICY_STATS
// This has to be included first because of _GNU_SOURCE
@@ -24,7 +39,6 @@ static int policy_stats_mgr_tick(void* mgr_arg, int fd, void* data) {
/* Loop over FIB entries to compute statistics from counters */
const fib_t* fib = forwarder_get_fib(mgr->forwarder);
- fib_entry_t* entry;
fib_foreach_entry(fib, entry, {
policy_stats_update(&entry->policy_stats, &entry->policy_counters, now);
@@ -59,7 +73,6 @@ void policy_stats_on_retransmission(const policy_stats_mgr_t* mgr,
policy_counters_t* counters,
const nexthops_t* nexthops) {
connection_table_t* table = forwarder_get_connection_table(mgr->forwarder);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
#ifdef WITH_POLICY
const connection_t* conn = connection_table_at(table, nexthop);
@@ -97,7 +110,6 @@ void policy_stats_on_data(const policy_stats_mgr_t* mgr, policy_stats_t* stats,
size_t msg_size = msgbuf_get_len(msgbuf);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
#ifdef WITH_POLICY
const connection_t* conn = connection_table_at(table, nexthop);
@@ -121,7 +133,6 @@ void policy_stats_on_timeout(const policy_stats_mgr_t* mgr,
#ifdef WITH_POLICY
connection_table_t* table = forwarder_get_connection_table(mgr->forwarder);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
const connection_t* conn = connection_table_at(table, nexthop);
if (!conn) continue;
diff --git a/hicn-light/src/hicn/core/strategy_vft.h b/hicn-light/src/hicn/core/strategy_vft.h
index 0256cba57..55e61db17 100644
--- a/hicn-light/src/hicn/core/strategy_vft.h
+++ b/hicn-light/src/hicn/core/strategy_vft.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -24,13 +24,11 @@
#include "../strategies/best_path.h"
#include "../strategies/load_balancer.h"
-#include "../strategies/low_latency.h"
#include "../strategies/random.h"
#include "../strategies/replication.h"
typedef union {
strategy_load_balancer_options_t load_balancer;
- strategy_low_latency_options_t low_latency;
strategy_random_options_t random;
strategy_replication_options_t replication;
strategy_bestpath_options_t bestpath;
@@ -42,7 +40,6 @@ typedef struct {
#endif /* WITH_POLICY */
union {
strategy_load_balancer_nexthop_state_t load_balancer;
- strategy_low_latency_nexthop_state_t low_latency;
strategy_random_nexthop_state_t random;
strategy_replication_nexthop_state_t replication;
strategy_bestpath_nexthop_state_t bestpath;
@@ -58,7 +55,6 @@ typedef struct {
typedef union {
strategy_load_balancer_state_t load_balancer;
- strategy_low_latency_state_t low_latency;
strategy_random_state_t random;
strategy_replication_state_t replication;
strategy_bestpath_state_t bestpath;
diff --git a/hicn-light/src/hicn/core/subscription.c b/hicn-light/src/hicn/core/subscription.c
index ad4006531..fb954a245 100644
--- a/hicn-light/src/hicn/core/subscription.c
+++ b/hicn-light/src/hicn/core/subscription.c
@@ -17,12 +17,6 @@ bool topics_contains(hc_topics_t topic_list, hc_topic_t topic) {
#define topic_is_set(topic_list, topic_index) \
((topic_list) & (1 << (topic_index)))
-const char *event_str[] = {
-#define _(x) [EVENT_##x] = #x,
- foreach_event_type
-#undef _
-};
-
/*----------------------------------------------------------------------------*
* Subscriptions
*----------------------------------------------------------------------------*/
@@ -56,13 +50,13 @@ int subscription_table_add_topics_for_connection(
int ret = vector_push(subscriptions->table[topic_index], connection_id);
if (ret < 0) {
ERROR("Unable to perform subscription for connection %d, topic %s",
- connection_id, object_str(topic_index));
+ connection_id, object_type_str(topic_index));
return -1;
}
if (num_duplicates > 0) {
DEBUG("Connection %d had already a subscription for topic %s",
- connection_id, object_str(topic_index));
+ connection_id, object_type_str(topic_index));
is_subscription_already_present = true;
}
}
@@ -111,14 +105,14 @@ unsigned *subscription_table_get_connections_for_topic(
}
void subscription_table_print(subscription_table_t *subscriptions) {
- for (int topic_index = OBJECT_UNDEFINED + 1; topic_index < NUM_TOPICS;
+ for (int topic_index = OBJECT_TYPE_UNDEFINED + 1; topic_index < NUM_TOPICS;
topic_index++) {
printf("topic %s (%lu subscription/s) from connection/s: [ ",
- object_str(topic_index),
+ object_type_str(topic_index),
(unsigned long)vector_len(subscriptions->table[topic_index]));
unsigned *connection_id;
vector_foreach(subscriptions->table[topic_index], connection_id,
{ printf("%d ", *connection_id); });
printf("]\n");
}
-} \ No newline at end of file
+}