aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-light')
-rw-r--r--hicn-light/CMakeLists.txt1
-rw-r--r--hicn-light/src/hicn/CMakeLists.txt3
-rw-r--r--hicn-light/src/hicn/cli/hicnc.c380
-rw-r--r--hicn-light/src/hicn/cli/hicns.c6
-rw-r--r--hicn-light/src/hicn/config/CMakeLists.txt34
-rw-r--r--hicn-light/src/hicn/config/command.c119
-rw-r--r--hicn-light/src/hicn/config/command.h179
-rw-r--r--hicn-light/src/hicn/config/command_cache.c54
-rw-r--r--hicn-light/src/hicn/config/command_connection.c128
-rw-r--r--hicn-light/src/hicn/config/command_face.c16
-rw-r--r--hicn-light/src/hicn/config/command_listener.c111
-rw-r--r--hicn-light/src/hicn/config/command_mapme.c59
-rw-r--r--hicn-light/src/hicn/config/command_policy.c52
-rw-r--r--hicn-light/src/hicn/config/command_punting.c40
-rw-r--r--hicn-light/src/hicn/config/command_route.c53
-rw-r--r--hicn-light/src/hicn/config/command_strategy.c47
-rw-r--r--hicn-light/src/hicn/config/command_subscription.c23
-rw-r--r--hicn-light/src/hicn/config/commands.c445
-rw-r--r--hicn-light/src/hicn/config/commands.h16
-rw-r--r--hicn-light/src/hicn/config/configuration.c26
-rw-r--r--hicn-light/src/hicn/config/configuration.h15
-rw-r--r--hicn-light/src/hicn/config/configuration_file.c62
-rw-r--r--hicn-light/src/hicn/config/configuration_file.h1
-rw-r--r--hicn-light/src/hicn/config/parse.c402
-rw-r--r--hicn-light/src/hicn/config/parse.h15
-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
-rw-r--r--hicn-light/src/hicn/io/base.c17
-rw-r--r--hicn-light/src/hicn/io/hicn.c4
-rw-r--r--hicn-light/src/hicn/io/tcp.c7
-rw-r--r--hicn-light/src/hicn/io/udp.c25
-rw-r--r--hicn-light/src/hicn/socket/api.c33
-rw-r--r--hicn-light/src/hicn/socket/api.h6
-rw-r--r--hicn-light/src/hicn/socket/ops.h18
-rw-r--r--hicn-light/src/hicn/socket/ops_linux.c100
-rw-r--r--hicn-light/src/hicn/strategies/CMakeLists.txt2
-rw-r--r--hicn-light/src/hicn/strategies/best_path.c25
-rw-r--r--hicn-light/src/hicn/strategies/load_balancer.c9
-rw-r--r--hicn-light/src/hicn/strategies/local_prefixes.c27
-rw-r--r--hicn-light/src/hicn/strategies/local_prefixes.h7
-rw-r--r--hicn-light/src/hicn/strategies/low_latency.c776
-rw-r--r--hicn-light/src/hicn/strategies/low_latency.h101
-rw-r--r--hicn-light/src/hicn/strategies/probe_generator.c5
-rw-r--r--hicn-light/src/hicn/strategies/probe_generator.h5
-rw-r--r--hicn-light/src/hicn/strategies/random.c1
-rw-r--r--hicn-light/src/hicn/test/CMakeLists.txt15
-rw-r--r--hicn-light/src/hicn/test/test-bitmap.cc144
-rw-r--r--hicn-light/src/hicn/test/test-connection_table.cc3
-rw-r--r--hicn-light/src/hicn/test/test-ctrl.cc11
-rw-r--r--hicn-light/src/hicn/test/test-fib.cc85
-rw-r--r--hicn-light/src/hicn/test/test-interest_manifest.cc79
-rw-r--r--hicn-light/src/hicn/test/test-khash.cc154
-rw-r--r--hicn-light/src/hicn/test/test-listener_table.cc2
-rw-r--r--hicn-light/src/hicn/test/test-local_prefixes.cc195
-rw-r--r--hicn-light/src/hicn/test/test-msgbuf_pool.cc12
-rw-r--r--hicn-light/src/hicn/test/test-packet_cache.cc240
-rw-r--r--hicn-light/src/hicn/test/test-parser.cc4
-rw-r--r--hicn-light/src/hicn/test/test-pool.cc196
-rw-r--r--hicn-light/src/hicn/test/test-ring.cc99
-rw-r--r--hicn-light/src/hicn/test/test-strategy-replication.cc1
-rw-r--r--hicn-light/src/hicn/test/test-subscription.cc6
-rw-r--r--hicn-light/src/hicn/test/test-vector.cc232
-rw-r--r--hicn-light/src/hicn/test/test_hash.cc (renamed from hicn-light/src/hicn/test/test-hash.cc)3
99 files changed, 2835 insertions, 6312 deletions
diff --git a/hicn-light/CMakeLists.txt b/hicn-light/CMakeLists.txt
index 241cae7f2..337e22b7f 100644
--- a/hicn-light/CMakeLists.txt
+++ b/hicn-light/CMakeLists.txt
@@ -93,7 +93,6 @@ else()
${LIBHICNCTRL_STATIC}
)
else ()
- message("qui2!!!")
set(HICN_LIBRARIES
${LIBHICN_SHARED}
${LIBHICNCTRL_SHARED}
diff --git a/hicn-light/src/hicn/CMakeLists.txt b/hicn-light/src/hicn/CMakeLists.txt
index 401ae84eb..feaac5c39 100644
--- a/hicn-light/src/hicn/CMakeLists.txt
+++ b/hicn-light/src/hicn/CMakeLists.txt
@@ -61,7 +61,8 @@ endif()
# Compiler options
##############################################################
set(COMPILER_OPTIONS
- ${DEFAULT_COMPILER_OPTIONS}
+ PRIVATE ${DEFAULT_COMPILER_OPTIONS}
+ #PRIVATE "-Wno-address-of-packed-member"
)
##############################################################
diff --git a/hicn-light/src/hicn/cli/hicnc.c b/hicn-light/src/hicn/cli/hicnc.c
index 3074016c5..b4a6e8191 100644
--- a/hicn-light/src/hicn/cli/hicnc.c
+++ b/hicn-light/src/hicn/cli/hicnc.c
@@ -22,13 +22,23 @@
#endif
#include "color.h"
-#include "../config/parse.h"
+#include <hicn/ctrl/parse.h>
+#include <hicn/ctrl/hicn-light.h>
#include <hicn/util/log.h>
#include <hicn/util/sstrncpy.h>
-#include <hicn/ctrl/hicn-light-ng.h>
#define PORT 9695
+/*
+ * Duplicated from hicn_light_ng_api.c while is only available as a module in
+ * libhicnctrl
+ */
+const char *command_type_str[] = {
+#define _(l, u) [COMMAND_TYPE_##u] = STRINGIZE(u),
+ foreach_command_type
+#undef _
+};
+
static struct option longFormOptions[] = {{"help", no_argument, 0, 'h'},
{"server", required_argument, 0, 'S'},
{"port", required_argument, 0, 'P'},
@@ -50,6 +60,55 @@ void signal_handler(int sig) {
stop = true;
}
+#if 0
+int hc_active_interface_snprintf(char *buf, size_t size,
+ hc_event_active_interface_update_t *event) {
+ int rc;
+ char *pos = buf;
+
+ rc = ip_prefix_snprintf(pos, size, &event->prefix);
+ if ((rc < 0) || (rc >= size)) return rc;
+ pos += rc;
+ size -= rc;
+
+ for (netdevice_type_t type = NETDEVICE_TYPE_UNDEFINED + 1;
+ type < NETDEVICE_TYPE_N; type++) {
+ if (!netdevice_flags_has(event->interface_type, type)) continue;
+ rc = snprintf(pos, size, " %s", netdevice_type_str(type));
+ if ((rc < 0) || (rc >= size)) return pos - buf + rc;
+
+ pos += rc;
+ size -= rc;
+ }
+ return pos - buf;
+}
+
+// XXX hc_object_snprintf
+void hc_subscription_display(command_type_t command_type,
+ const uint8_t *buffer) {
+ char buf[65535];
+
+ switch (command_type) {
+ case COMMAND_TYPE_CONNECTION_ADD:
+ case COMMAND_TYPE_CONNECTION_REMOVE:
+ case COMMAND_TYPE_CONNECTION_UPDATE:
+ hc_connection_snprintf(buf, sizeof(buf), (hc_connection_t *)buffer);
+ break;
+ case COMMAND_TYPE_ACTIVE_INTERFACE_UPDATE:
+ hc_active_interface_snprintf(
+ buf, sizeof(buf), (hc_event_active_interface_update_t *)buffer);
+ break;
+ case COMMAND_TYPE_ROUTE_LIST:
+ hc_route_snprintf(buf, sizeof(buf), (hc_route_t *)buffer);
+ break;
+ default:
+ INFO("Unknown event received");
+ return;
+ }
+ INFO("%s %s", command_type_str(command_type), buf);
+}
+#endif
+
int main(int argc, char *const *argv) {
log_conf.log_level = LOG_INFO;
@@ -149,13 +208,13 @@ int main(int argc, char *const *argv) {
#define BUFSIZE 255
char url[BUFSIZE];
snprintf(url, BUFSIZE, "tcp://%s:%d/", server_ip, server_port);
- s = hc_sock_create_forwarder_url(HICNLIGHT_NG, url);
+ s = hc_sock_create(FORWARDER_TYPE_HICNLIGHT, url);
} else {
- s = hc_sock_create_forwarder(HICNLIGHT_NG);
+ s = hc_sock_create(FORWARDER_TYPE_HICNLIGHT, NULL);
}
if (!s) {
fprintf(stderr, "Could not create socket.\n");
- goto ERR_SOCK;
+ goto ERR_SOCKET;
}
if (hc_sock_connect(s) < 0) {
@@ -163,7 +222,7 @@ int main(int argc, char *const *argv) {
goto ERR_CONNECT;
}
- if (!IS_VALID_OBJECT_TYPE(command.object.type) ||
+ if (!IS_VALID_OBJECT_TYPE(command.object_type) ||
!IS_VALID_ACTION(command.action)) {
fprintf(stderr, "Unsupported command");
goto ERR_PARAM;
@@ -171,285 +230,54 @@ int main(int argc, char *const *argv) {
int rc = UNSUPPORTED_CMD_ERROR;
hc_data_t *data = NULL;
- char buf_listener[MAXSZ_HC_LISTENER];
- char buf_connection[MAXSZ_HC_CONNECTION];
- char buf_route[MAXSZ_HC_ROUTE];
- char buf[MAX_LEN];
- switch (command.object.type) {
- case OBJECT_ROUTE:
- switch (command.action) {
- case ACTION_CREATE:
- rc = hc_route_create(s, &command.object.route);
- break;
-
- case ACTION_DELETE:
- rc = hc_route_delete(s, &command.object.route);
- break;
-
- case ACTION_LIST:
- rc = hc_route_list(s, &data);
- if (rc < 0) break;
-
- INFO("Routes:");
- foreach_route(r, data) {
- if (hc_route_snprintf(buf_route, MAXSZ_HC_ROUTE, r) >=
- MAXSZ_HC_ROUTE)
- ERROR("Display error");
- INFO("%s", buf_route);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_LISTENER:
- switch (command.action) {
- case ACTION_CREATE:
- rc = hc_listener_create(s, &command.object.listener);
- break;
-
- case ACTION_DELETE:
- rc = hc_listener_delete(s, &command.object.listener);
- break;
-
- case ACTION_LIST:
- rc = hc_listener_list(s, &data);
- if (rc < 0) break;
-
- INFO("Listeners:");
- foreach_listener(l, data) {
- if (hc_listener_snprintf(buf_listener, MAXSZ_HC_LISTENER + 17, l) >=
- MAXSZ_HC_LISTENER)
- ERROR("Display error");
- INFO("[%d] %s", l->id, buf_listener);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_CONNECTION:
- switch (command.action) {
- case ACTION_CREATE:
- rc = hc_connection_create(s, &command.object.connection);
- break;
-
- case ACTION_DELETE:
- rc = hc_connection_delete(s, &command.object.connection);
- break;
-
- case ACTION_LIST:
- rc = hc_connection_list(s, &data);
- if (rc < 0) break;
-
- INFO("Connections:");
- foreach_connection(c, data) {
- if (hc_connection_snprintf(buf_connection, MAXSZ_HC_CONNECTION,
- c) >= MAXSZ_HC_CONNECTION)
- ERROR("Display error");
- INFO("[%d] %s", c->id, buf_connection);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_CACHE:
- switch (command.action) {
- case ACTION_SERVE:
- rc = hc_cache_set_serve(s, &command.object.cache);
- break;
-
- case ACTION_STORE:
- rc = hc_cache_set_store(s, &command.object.cache);
- break;
-
- case ACTION_CLEAR:
- rc = hc_cache_clear(s, &command.object.cache);
- break;
-
- case ACTION_LIST:
- rc = hc_cache_list(s, &data);
- if (rc < 0) break;
-
- hc_cache_snprintf(buf, MAX_LEN, (hc_cache_info_t *)data->buffer);
- printf("%s\n", buf);
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_STRATEGY:
- switch (command.action) {
- case ACTION_SET:
- rc = hc_strategy_set(s, &command.object.strategy);
- break;
-
- default:
- break;
- }
- break;
- case OBJECT_MAPME:
- switch (command.action) {
- case ACTION_UPDATE:
- rc = hc_mapme_send_update(s, &command.object.mapme);
- break;
- case ACTION_SET:
- if (command.object.mapme.target == MAPME_TARGET_ENABLE) {
- rc = hc_mapme_set(s, &command.object.mapme);
- } else if (command.object.mapme.target == MAPME_TARGET_DISCOVERY) {
- rc = hc_mapme_set_discovery(s, &command.object.mapme);
- } else if (command.object.mapme.target == MAPME_TARGET_TIMESCALE) {
- rc = hc_mapme_set_timescale(s, &command.object.mapme);
- } else if (command.object.mapme.target == MAPME_TARGET_RETX) {
- rc = hc_mapme_set_retx(s, &command.object.mapme);
- }
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_LOCAL_PREFIX:
- switch (command.action) {
- case ACTION_CREATE:
- rc = hc_strategy_add_local_prefix(s, &command.object.strategy);
- break;
-
- default:
- break;
- }
- break;
-
- case OBJECT_SUBSCRIPTION:
- // Disable socket recv timeout
- hc_sock_set_recv_timeout_ms(s, 0);
-
- rc = hc_subscription_create(s, &command.object.subscription);
- if (rc < 0) break;
- INFO("Subscription sent");
-
- while (!stop) {
- int rc = hc_sock_callback(s, &data);
- if (rc < 0 && !stop) ERROR("Notification error");
-
- if (!stop) {
- event_type_t event_type = rc;
- INFO("Notification recevied %s [%d]", event_str(event_type),
- event_type);
-
- if (event_type == EVENT_INTERFACE_UPDATE) {
- hc_event_interface_update_t *event =
- (hc_event_interface_update_t *)(data->buffer);
- INFO("Interface update event received: %u", event->interface_type);
- }
- }
- }
-
- INFO("Unsubscribing...");
- rc = hc_subscription_delete(s, &command.object.subscription);
- break;
-
- case OBJECT_STATS:
- switch (command.action) {
- case ACTION_GET:
- rc = hc_stats_get(s, &data);
- if (rc < 0) break;
-
- hc_stats_snprintf(buf, MAX_LEN, (hicn_light_stats_t *)data->buffer);
- INFO("\n%s", buf);
- break;
-
- case ACTION_LIST:
- rc = hc_stats_list(s, &data);
- if (rc < 0) break;
-
- cmd_stats_list_item_t *conn_stats =
- (cmd_stats_list_item_t *)data->buffer;
- cmd_stats_list_item_t *end =
- (cmd_stats_list_item_t *)(data->buffer +
- data->size * data->out_element_size);
- while (conn_stats < end) {
- INFO("Connection #%d:", conn_stats->id);
- INFO("\tinterests received: %d pkts (%d bytes)",
- conn_stats->stats.interests.rx_pkts,
- conn_stats->stats.interests.rx_bytes);
- INFO("\tinterests transmitted: %d pkts (%d bytes)",
- conn_stats->stats.interests.tx_pkts,
- conn_stats->stats.interests.tx_bytes);
- INFO("\tdata received: %d pkts (%d bytes)",
- conn_stats->stats.data.rx_pkts,
- conn_stats->stats.data.rx_bytes);
- INFO("\tdata transmitted: %d pkts (%d bytes)",
- conn_stats->stats.data.tx_pkts,
- conn_stats->stats.data.tx_bytes);
-
- conn_stats++;
- }
- break;
-
- default:
- break;
- }
- break;
+ rc = hc_execute(s, command.action, command.object_type, &command.object,
+ &data);
-#ifdef TEST_FACE_CREATION
- case OBJECT_FACE:
- switch (command.action) {
- case ACTION_CREATE: {
- hc_face_t face = {0};
- face.face.type = FACE_TYPE_UDP;
- face.face.family = AF_INET;
- face.face.local_addr = IPV4_LOOPBACK;
- face.face.remote_addr = IPV4_LOOPBACK;
- face.face.local_port = 9696;
- face.face.remote_port = 9696;
-
- rc = hc_face_create(s, &face);
- break;
- }
- default:
- break;
- }
- break;
-#endif
-
- default:
- break;
+ if (rc < 0) {
+ switch (rc) {
+ case INPUT_ERROR:
+ ERROR("Wrong input parameters");
+ break;
+ case UNSUPPORTED_CMD_ERROR:
+ ERROR("Unsupported command");
+ break;
+ default:
+ ERROR("Error executing command");
+ break;
+ }
+ goto ERR_COMMAND;
}
- hc_data_free(data);
- if (rc < -1) {
- if (rc == INPUT_ERROR) ERROR("Wrong input parameters");
- if (rc == UNSUPPORTED_CMD_ERROR) ERROR("Unsupported command");
- goto ERR_CMD;
+ if (!data) goto ERR_QUERY;
+ if (!hc_data_get_result(data)) goto ERR_DATA;
+
+ if (command.action == ACTION_LIST) {
+ char buf[MAXSZ_HC_OBJECT];
+ hc_data_foreach(data, obj, {
+ rc = hc_object_snprintf(buf, MAXSZ_HC_OBJECT, command.object_type, obj);
+ if (rc < 0)
+ WARN("Display error");
+ else if (rc >= MAXSZ_HC_OBJECT)
+ WARN("Output truncated");
+ else
+ printf("%s\n", buf);
+ });
}
- if (rc < 0) ERROR("Error executing command");
- // Remove the connection created to send the command
- command.object.connection.id = 0;
- rc = strcpy_s(command.object.connection.name,
- sizeof(command.object.connection.name), "SELF");
- if (rc != EOK || hc_connection_delete(s, &command.object.connection) < 0)
- fprintf(stderr, "Error removing local connection to forwarder\n");
-
- exit(EXIT_SUCCESS);
+ hc_data_free(data);
+ hc_sock_free(s);
+ return EXIT_SUCCESS;
-ERR_CMD:
+ERR_DATA:
+ hc_data_free(data);
+ERR_QUERY:
+ERR_COMMAND:
ERR_CONNECT:
hc_sock_free(s);
-ERR_SOCK:
+ERR_SOCKET:
ERR_PARSE:
ERR_PARAM:
- exit(EXIT_FAILURE);
+ ERROR("Error");
+ return EXIT_FAILURE;
}
diff --git a/hicn-light/src/hicn/cli/hicns.c b/hicn-light/src/hicn/cli/hicns.c
index 2f7a360f8..fa668062d 100644
--- a/hicn-light/src/hicn/cli/hicns.c
+++ b/hicn-light/src/hicn/cli/hicns.c
@@ -21,7 +21,7 @@
#endif
#include "logo.h"
-#include "../config/parse.h"
+#include <hicn/ctrl/parse.h>
#include <hicn/util/sstrncpy.h>
#define PORT 9695
@@ -181,9 +181,9 @@ int main(int argc, char *const *argv) {
#define BUFSIZE 255
char url[BUFSIZE];
snprintf(url, BUFSIZE, "tcp://%s:%d/", server_ip, server_port);
- s = hc_sock_create_forwarder_url(HICNLIGHT_NG, url);
+ s = hc_sock_create(FORWARDER_TYPE_HICNLIGHT, url);
} else {
- s = hc_sock_create_forwarder(HICNLIGHT_NG);
+ s = hc_sock_create(FORWARDER_TYPE_HICNLIGHT, NULL);
}
if (!s) {
fprintf(stderr, "Could not create socket.\n");
diff --git a/hicn-light/src/hicn/config/CMakeLists.txt b/hicn-light/src/hicn/config/CMakeLists.txt
index 90d0a2229..b1b04d679 100644
--- a/hicn-light/src/hicn/config/CMakeLists.txt
+++ b/hicn-light/src/hicn/config/CMakeLists.txt
@@ -13,28 +13,32 @@
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/configuration.h
- ${CMAKE_CURRENT_SOURCE_DIR}/command.h
${CMAKE_CURRENT_SOURCE_DIR}/commands.h
- ${CMAKE_CURRENT_SOURCE_DIR}/parse.h
)
list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/module_object.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/connection.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/listener.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/face.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/route.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/strategy.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/subscription.c
${CMAKE_CURRENT_SOURCE_DIR}/configuration.c
${CMAKE_CURRENT_SOURCE_DIR}/configuration_file.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_cache.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_connection.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_face.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_listener.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_mapme.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_policy.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_punting.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_route.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_stats.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_strategy.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command_subscription.c
- ${CMAKE_CURRENT_SOURCE_DIR}/command.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_cache.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_connection.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_face.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_listener.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_mapme.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_policy.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_punting.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_route.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_stats.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_strategy.c
+ #${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_subscription.c
${CMAKE_CURRENT_SOURCE_DIR}/commands.c
- ${CMAKE_CURRENT_SOURCE_DIR}/parse.c
)
set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
diff --git a/hicn-light/src/hicn/config/command.c b/hicn-light/src/hicn/config/command.c
deleted file mode 100644
index bee0d2663..000000000
--- a/hicn-light/src/hicn/config/command.c
+++ /dev/null
@@ -1,119 +0,0 @@
-
-/**
- * @file command.c
- * @brief Implementation of commands.
- */
-
-#include <search.h> /* tfind, tdestroy, twalk */
-#include <stdio.h>
-#include <ctype.h>
-#include "command.h"
-#include "parse.h"
-
-/* Commands are registered in the following tree. */
-static void *commands_root = NULL; /**< Tree ordered by name */
-
-#ifdef __linux__
-static void nothing_to_free() {}
-
-__attribute__((destructor)) static void command_clear() {
- tdestroy(commands_root, nothing_to_free);
-}
-#endif /* __linux__ */
-
-static int _command_compare(const command_parser_t *c1,
- const command_parser_t *c2) {
- if (c1->object != c2->object) return c2->object - c1->object;
- if (c1->action != c2->action) return c2->action - c1->action;
- if (c1->nparams != c2->nparams) return c2->nparams - c1->nparams;
- return 0;
-}
-
-#define command_compare (int (*)(const void *, const void *))(_command_compare)
-
-void command_register(const command_parser_t *command) {
- // Insert the command in the tree if the keys does not exist yet
- tsearch(command, &commands_root, command_compare);
-}
-
-const command_parser_t *command_search(const hc_action_t action,
- hc_object_type_t object,
- unsigned nparams) {
- command_parser_t **command, search;
-
- search.action = action;
- search.object = object;
- search.nparams = nparams;
- command = tfind(&search, &commands_root, command_compare);
-
- return command ? *command : NULL;
-}
-
-static inline void to_lowercase(char *p) {
- for (; *p; ++p) *p = tolower(*p);
-}
-
-typedef struct {
- hc_object_type_t object;
- hc_action_t action;
-} cmd_search_params_t;
-
-static hc_object_type_t prev_obj = OBJECT_UNDEFINED;
-static hc_action_t prev_action = ACTION_UNDEFINED;
-static void traversal_action(const void *nodep, VISIT which,
- void *cmd_params0) {
- cmd_search_params_t *cmd_params = cmd_params0;
-
- // Execute this function during inorder traversal
- if (which != postorder && which != leaf) return;
-
- command_parser_t *datap;
- datap = *(command_parser_t **)nodep;
- char *obj_str = strdup(object_str(datap->object));
- to_lowercase(obj_str);
-
- // List all objects
- if (cmd_params->object == OBJECT_UNDEFINED &&
- cmd_params->action == ACTION_UNDEFINED) {
- if (datap->object == prev_obj) goto FREE_STR;
- prev_obj = datap->object;
-
- printf("\thelp %s\n", obj_str);
- goto FREE_STR;
- }
-
- // List actions for specific object
- if (datap->object != cmd_params->object) goto FREE_STR;
- if (cmd_params->action == ACTION_UNDEFINED) {
- if (datap->action == prev_action) goto FREE_STR;
- prev_action = datap->action;
-
- printf("\thelp %s %s\n", obj_str, action_to_cmd_action(datap->action));
- goto FREE_STR;
- }
-
- // List commands for specific object and action
- if (datap->action != cmd_params->action) goto FREE_STR;
- printf(" %s %s ", action_to_cmd_action(datap->action), obj_str);
- for (int i = 0; i < datap->nparams; i++)
- printf("<%s> ", datap->parameters[i].name);
- printf("\n\n");
- // List options' details
- if (datap->nparams == 0) goto FREE_STR;
- for (int i = 0; i < datap->nparams; i++)
- printf("%16s: %s\n", datap->parameters[i].name, datap->parameters[i].help);
- printf("\n");
-
-FREE_STR:
- free(obj_str);
-}
-
-void command_list(hc_object_type_t object, hc_action_t action) {
-#if defined(__linux__) && !defined(__ANDROID__)
- cmd_search_params_t cmd_params = {.object = object, .action = action};
- twalk_r(commands_root, traversal_action, &cmd_params);
-#else
- fprintf(stderr, "twalk_r() function only available on linux");
- (void)traversal_action;
-#endif
-}
diff --git a/hicn-light/src/hicn/config/command.h b/hicn-light/src/hicn/config/command.h
deleted file mode 100644
index 73d8edb1f..000000000
--- a/hicn-light/src/hicn/config/command.h
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef HICNLIGHT_CONFIG_COMMAND
-#define HICNLIGHT_CONFIG_COMMAND
-
-/**
- * @file command.h
- * @brief Commands.
- */
-
-#include <stddef.h> // offsetof
-#include <hicn/util/ip_address.h>
-
-#include <hicn/ctrl/api.h>
-
-/* Update sscanf accordingly in parse_cmd.c */
-#define MAX_PARAMETERS 10
-#define MAX_SCANF_PARAM_LEN 100
-
-typedef int (*parser_hook_t)(void *arg);
-
-typedef enum {
- TYPENAME_UNDEFINED,
- TYPENAME_INT,
- TYPENAME_UINT,
- TYPENAME_STR,
- TYPENAME_SYMBOLIC_OR_ID,
- TYPENAME_INTERFACE_NAME,
- TYPENAME_IP_ADDRESS,
- TYPENAME_IP_PREFIX,
- TYPENAME_ON_OFF,
- TYPENAME_ENUM,
- TYPENAME_POLICY_STATE,
-} parser_typename_t;
-
-typedef struct {
- parser_typename_t name;
- union {
- struct {
- size_t max_size;
- } str;
- struct {
- int min;
- int max;
- } sint;
- struct {
- int min;
- int max;
- } uint;
- struct {
- int (*from_str)(const char *str);
- } enum_;
- struct {
- policy_tag_t tag;
- } policy_state;
- };
-} parser_type_t;
-
-typedef struct {
- const char *name;
- const char *help;
- parser_type_t type;
- size_t offset;
- /*
- * quick hack to let the functions update two or more parameters, like for
- * IP_ADDRESS or IP_PREFIX types
- */
- size_t offset2;
- size_t offset3;
-} command_parameter_t;
-
-typedef struct {
- hc_action_t action;
- hc_object_type_t object;
- unsigned nparams;
- command_parameter_t parameters[MAX_PARAMETERS];
- parser_hook_t post_hook;
-} command_parser_t;
-
-#define TYPE_STRN(N) \
- (parser_type_t) { \
- .name = TYPENAME_STR, \
- .str = { \
- .max_size = N, \
- }, \
- }
-#define TYPE_FMT_STRN(N) "%s"
-
-#define TYPE_INT(MIN, MAX) \
- (parser_type_t) { \
- .name = TYPENAME_INT, \
- .sint = { \
- .min = (MIN), \
- .max = (MAX), \
- }, \
- }
-#define TYPE_FMT_INT "%d"
-
-#define TYPE_UINT(min, max) \
- (parser_type_t) { \
- .name = TYPENAME_UINT, \
- .uint = { \
- .min = min, \
- .max = max, \
- }, \
- }
-#define TYPE_FMT_UINT "%u"
-
-#define TYPE_SYMBOLIC_OR_ID TYPE_STRN(SYMBOLIC_NAME_LEN)
-#define TYPE_FMT_SYMBOLIC_OR_ID "%s"
-
-#define TYPE_INTERFACE_NAME TYPE_STRN(INTERFACE_LEN)
-#define TYPE_FMT_INTERFACE_NAME "%s"
-
-#define TYPE_IP_ADDRESS \
- (parser_type_t) { .name = TYPENAME_IP_ADDRESS, }
-#define TYPE_FMT_IP_ADDRESS "%s"
-
-#define TYPE_IP_PREFIX \
- (parser_type_t) { .name = TYPENAME_IP_PREFIX, }
-#define TYPE_FMT_IP_PREFIX "%s"
-
-#define TYPE_ON_OFF \
- (parser_type_t) { .name = TYPENAME_ON_OFF, }
-#define TYPE_FMT_ON_OFF "%s"
-
-#define TYPE_ENUM(x) \
- (parser_type_t) { \
- .name = TYPENAME_ENUM, \
- .enum_ = { \
- .from_str = (int (*)(const char *))x##_from_str, \
- }, \
- }
-/* We need to allocate room for the intermediate string */
-#define TYPE_FMT_ENUM "%s"
-
-#define TYPE_POLICY_STATE(TAG) \
- (parser_type_t) { \
- .name = TYPENAME_POLICY_STATE, \
- .policy_state = { \
- .tag = TAG, \
- }, \
- }
-/* We need to allocate room for the intermediate string */
-#define TYPE_FMT_POLICY_STATE "%s"
-
-/**
- * \brief Register a protocol
- * \param protocol Pointer to a protocol_t structure describing the protocol to
- * register \return None
- */
-
-void command_register(const command_parser_t *command);
-
-/**
- * \brief Search a registered protocol in the library according to its name
- * \param[in] action The action of the command.
- * \param[in] object The object of the command.
- * \param[in] nparams The number of parameters expected in the command.
- * \return A pointer to the corresponding command if any, NULL othewise
- */
-const command_parser_t *command_search(hc_action_t action,
- hc_object_type_t object,
- unsigned nparams);
-
-/**
- * @brief List the commands associated with the specified object and/or action.
- * Use OBJECT_UNDEFINED and ACTION_UNDEFINED to list all the available objects.
- * Use ACTION_UNDEFINED to list all the actions associated to the specified
- * object.
- *
- * @param object The action of the command
- * @param action The object of the command
- */
-void command_list(hc_object_type_t object, hc_action_t action);
-
-#define COMMAND_REGISTER(MOD) \
- static void __init_##MOD(void) __attribute__((constructor)); \
- static void __init_##MOD(void) { command_register(&MOD); }
-
-#endif /* HICNLIGHT_CONFIG_COMMAND */
diff --git a/hicn-light/src/hicn/config/command_cache.c b/hicn-light/src/hicn/config/command_cache.c
deleted file mode 100644
index 073221cf0..000000000
--- a/hicn-light/src/hicn/config/command_cache.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <math.h>
-#include "command.h"
-
-/* Parameters */
-
-#define serve \
- { \
- .name = "serve", \
- .help = \
- "Enables/disables replies from local content store. Either the " \
- "string 'on' or 'off'", \
- .type = TYPE_ON_OFF, .offset = offsetof(hc_cache_t, serve), \
- }
-
-#define store \
- { \
- .name = "store", \
- .help = \
- "enables/disables the storage of incoming data packets in the local " \
- "content store. Either the string 'on' or 'off'", \
- .type = TYPE_ON_OFF, .offset = offsetof(hc_cache_t, store), \
- }
-
-/* Commands */
-
-static const command_parser_t command_cache_set_serve = {
- .action = ACTION_SERVE,
- .object = OBJECT_CACHE,
- .nparams = 1,
- .parameters = {serve},
-};
-COMMAND_REGISTER(command_cache_set_serve);
-
-static const command_parser_t command_cache_set_store = {
- .action = ACTION_STORE,
- .object = OBJECT_CACHE,
- .nparams = 1,
- .parameters = {store},
-};
-COMMAND_REGISTER(command_cache_set_store);
-
-static const command_parser_t command_cache_clear = {
- .action = ACTION_CLEAR,
- .object = OBJECT_CACHE,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_cache_clear);
-
-static const command_parser_t command_cache_list = {
- .action = ACTION_LIST,
- .object = OBJECT_CACHE,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_cache_list);
diff --git a/hicn-light/src/hicn/config/command_connection.c b/hicn-light/src/hicn/config/command_connection.c
deleted file mode 100644
index 069bf55a6..000000000
--- a/hicn-light/src/hicn/config/command_connection.c
+++ /dev/null
@@ -1,128 +0,0 @@
-#include <math.h>
-#include "command.h"
-
-/* Parameters */
-
-#define type_hicn \
- { \
- .name = "type", .help = "connection type (hICN)", \
- .type = TYPE_ENUM(face_type), .offset = offsetof(hc_connection_t, type), \
- }
-
-#define type_tcp_udp \
- { \
- .name = "type", .help = "connection type [tcp | udp]", \
- .type = TYPE_ENUM(face_type), .offset = offsetof(hc_connection_t, type), \
- }
-
-#define symbolic \
- { \
- .name = "symbolic", \
- .help = "symbolic name, e.g. 'conn1' (must be unique, start with alpha)", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_connection_t, name), \
- }
-
-#define local_address \
- { \
- .name = "local_addr", .help = "local IP address on which to bind.", \
- .type = TYPE_IP_ADDRESS, .offset = offsetof(hc_connection_t, local_addr), \
- .offset2 = offsetof(hc_connection_t, family), \
- }
-
-#define local_port \
- { \
- .name = "local_port", .help = "Local port.", \
- .type = TYPE_INT(1, UINT16_MAX), \
- .offset = offsetof(hc_connection_t, local_port), \
- }
-
-#define remote_address \
- { \
- .name = "remote_address", \
- .help = "The IPv4 or IPv6 or hostname of the remote system.", \
- .type = TYPE_IP_ADDRESS, .offset = offsetof(hc_connection_t, remote_addr), \
- .offset2 = offsetof(hc_connection_t, family), \
- }
-
-#define remote_port \
- { \
- .name = "remote_port", .help = "Remote port.", \
- .type = TYPE_INT(1, UINT16_MAX), \
- .offset = offsetof(hc_connection_t, remote_port), \
- }
-
-#define interface \
- { \
- .name = "interface", .help = "Interface on which to bind", \
- .type = TYPE_INTERFACE_NAME, \
- .offset = offsetof(hc_connection_t, interface_name), \
- }
-
-#define symbolic_or_id \
- { \
- .name = "symbolic", .help = "The connection symbolic name or id", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_connection_t, name), \
- }
-
-/* Commands */
-
-int on_connection_create(hc_connection_t* connection) {
- connection->admin_state = FACE_STATE_UP;
- return 0;
-}
-
-#if 0
-static command_parser_t command_connection_create4 = {
- .action = ACTION_CREATE,
- .object = OBJECT_CONNECTION,
- .nparams = 4,
- .parameters = {type_hicn, symbolic, local_address, remote_address},
- .post_hook = (parser_hook_t)on_connection_create,
-};
-COMMAND_REGISTER(command_connection_create4);
-
-static const command_parser_t command_connection_create5 = {
- .action = ACTION_CREATE,
- .object = OBJECT_CONNECTION,
- .nparams = 5,
- .parameters = {type_hicn, symbolic, local_address, remote_address,
- interface},
- .post_hook = (parser_hook_t)on_connection_create,
-};
-COMMAND_REGISTER(command_connection_create5);
-#endif
-
-static const command_parser_t command_connection_create6 = {
- .action = ACTION_CREATE,
- .object = OBJECT_CONNECTION,
- .nparams = 6,
- .parameters = {type_tcp_udp, symbolic, remote_address, remote_port,
- local_address, local_port},
- .post_hook = (parser_hook_t)on_connection_create,
-};
-COMMAND_REGISTER(command_connection_create6);
-
-static const command_parser_t command_connection_create7 = {
- .action = ACTION_CREATE,
- .object = OBJECT_CONNECTION,
- .nparams = 7,
- .parameters = {type_tcp_udp, symbolic, remote_address, remote_port,
- local_address, local_port, interface},
- .post_hook = (parser_hook_t)on_connection_create,
-};
-COMMAND_REGISTER(command_connection_create7);
-
-static const command_parser_t command_connection_list = {
- .action = ACTION_LIST,
- .object = OBJECT_CONNECTION,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_connection_list);
-
-static const command_parser_t command_connection_remove = {
- .action = ACTION_DELETE,
- .object = OBJECT_CONNECTION,
- .nparams = 1,
- .parameters = {symbolic_or_id},
-};
-COMMAND_REGISTER(command_connection_remove);
diff --git a/hicn-light/src/hicn/config/command_face.c b/hicn-light/src/hicn/config/command_face.c
deleted file mode 100644
index 95ec404f0..000000000
--- a/hicn-light/src/hicn/config/command_face.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#if 0
-#include "command.h"
-
-/* Parameters */
-
-/* Commands */
-
-// XXX missing add
-
-static const command_parser_t command_face_list = {
- .action = ACTION_LIST,
- .object = OBJECT_FACE,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_face_list);
-#endif \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/command_listener.c b/hicn-light/src/hicn/config/command_listener.c
deleted file mode 100644
index 8ad7c94be..000000000
--- a/hicn-light/src/hicn/config/command_listener.c
+++ /dev/null
@@ -1,111 +0,0 @@
-#include <math.h>
-#include "command.h"
-
-/* Parameters */
-
-#define protocol_hicn \
- { \
- .name = "protocol", .help = "Protocol [hicn].", \
- .type = TYPE_ENUM(face_type), .offset = offsetof(hc_listener_t, type), \
- }
-
-#define protocol_tcp_udp \
- { \
- .name = "protocol", .help = "Protocol [tcp | udp]", \
- .type = TYPE_ENUM(face_type), .offset = offsetof(hc_listener_t, type), \
- }
-
-#define symbolic \
- { \
- .name = "symbolic", \
- .help = \
- "User defined name for listener, must start with alpha and be " \
- "alphanum", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_listener_t, name), \
- }
-
-#define local_address \
- { \
- .name = "local_addr", \
- .help = \
- "IPv4 or IPv6 address (or prefix protocol = hicn) assigend to the " \
- "local interface", \
- .type = TYPE_IP_ADDRESS, .offset = offsetof(hc_listener_t, local_addr), \
- .offset2 = offsetof(hc_listener_t, family), \
- }
-
-#define local_port \
- { \
- .name = "local_port", .help = "Local port.", \
- .type = TYPE_INT(1, UINT16_MAX), \
- .offset = offsetof(hc_listener_t, local_port), \
- }
-
-#define interface \
- { \
- .name = "interface", .help = "Interface on which to bind", \
- .type = TYPE_INTERFACE_NAME, \
- .offset = offsetof(hc_listener_t, interface_name), \
- }
-
-#define symbolic_or_id \
- { \
- .name = "symbolic", .help = "The listener symbolic name or id", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_listener_t, name), \
- }
-
-/* Commands */
-
-/* The parse sets the wrong face_type_t for listener, we fix that here */
-int on_listener_create(hc_listener_t* listener) {
- switch (listener->type) {
- case FACE_TYPE_UDP:
- listener->type = FACE_TYPE_UDP_LISTENER;
- break;
- case FACE_TYPE_TCP:
- listener->type = FACE_TYPE_TCP_LISTENER;
- break;
- case FACE_TYPE_HICN:
- listener->type = FACE_TYPE_HICN_LISTENER;
- break;
- default:
- break;
- }
- return 0;
-}
-
-#if 0
-static const command_parser_t command_listener_create4 = {
- .action = ACTION_CREATE,
- .object = OBJECT_LISTENER,
- .nparams = 4,
- .parameters = {protocol_hicn, symbolic, local_address, interface},
- .post_hook = (parser_hook_t)on_listener_create,
-};
-COMMAND_REGISTER(command_listener_create4);
-#endif
-
-static const command_parser_t command_listener_create6 = {
- .action = ACTION_CREATE,
- .object = OBJECT_LISTENER,
- .nparams = 5,
- .parameters = {protocol_tcp_udp, symbolic, local_address, local_port,
- interface},
- .post_hook = (parser_hook_t)on_listener_create,
-};
-COMMAND_REGISTER(command_listener_create6);
-
-static const command_parser_t command_listener_list = {
- .action = ACTION_LIST,
- .object = OBJECT_LISTENER,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_listener_list);
-
-static const command_parser_t command_listener_remove = {
- .action = ACTION_DELETE,
- .object = OBJECT_LISTENER,
- .nparams = 1,
- .parameters = {symbolic_or_id},
-};
-COMMAND_REGISTER(command_listener_remove);
diff --git a/hicn-light/src/hicn/config/command_mapme.c b/hicn-light/src/hicn/config/command_mapme.c
deleted file mode 100644
index a22e8b340..000000000
--- a/hicn-light/src/hicn/config/command_mapme.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <math.h>
-#include "command.h"
-
-/* Parameters */
-
-#define target \
- { \
- .name = "target", \
- .help = \
- "Target for the set action, e.g. enable, discovery, timescale, retx", \
- .type = TYPE_ENUM(mapme_target), .offset = offsetof(hc_mapme_t, target), \
- }
-
-#define value \
- { \
- .name = "value", \
- .help = "Value to set for the target, e.g. 'on', 'off', milliseconds", \
- .type = TYPE_STRN(4), .offset = offsetof(hc_mapme_t, unparsed_arg), \
- }
-
-#define prefix \
- { \
- .name = "prefix", \
- .help = "The hicn name as IPv4 or IPv6 address (e.g 1234::0/64).", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_mapme_t, address), \
- .offset2 = offsetof(hc_mapme_t, len), \
- .offset3 = offsetof(hc_mapme_t, family), \
- }
-
-/* Commands */
-
-// Parse the raw string argument into 'timescale' or 'enabled',
-// necessary since the command dispatch is based on the number
-// of arguments and not their type
-int parse_args(hc_mapme_t* mapme) {
- mapme->timescale = atoi(mapme->unparsed_arg);
-
- if (strcasecmp(mapme->unparsed_arg, "off") == 0) mapme->enabled = 0;
- if (strcasecmp(mapme->unparsed_arg, "on") == 0) mapme->enabled = 1;
-
- return 0;
-}
-
-static const command_parser_t command_mapme_set = {
- .action = ACTION_SET,
- .object = OBJECT_MAPME,
- .nparams = 2,
- .parameters = {target, value},
- .post_hook = (parser_hook_t)parse_args,
-};
-COMMAND_REGISTER(command_mapme_set);
-
-static const command_parser_t command_mapme_update = {
- .action = ACTION_UPDATE,
- .object = OBJECT_MAPME,
- .nparams = 1,
- .parameters = {prefix},
-};
-COMMAND_REGISTER(command_mapme_update); \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/command_policy.c b/hicn-light/src/hicn/config/command_policy.c
deleted file mode 100644
index 1e802c3f5..000000000
--- a/hicn-light/src/hicn/config/command_policy.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#if 0
-#include <hicn/policy.h>
-
-#include "command.h"
-
-/* Parameters */
-
-#define prefix \
- { \
- .name = "prefix", \
- .help = "The hicn name as IPv4 or IPv6 address (e.g 1234::0/64).", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_policy_t, remote_addr), \
- .offset2 = offsetof(hc_policy_t, len), \
- .offset3 = offsetof(hc_policy_t, family), \
- }
-
-#define app_name \
- { \
- .name = "app_name", \
- .help = "The application name associated to this policy", \
- .type = TYPE_STR, .offset = offsetof(hc_policy_t, policy.app_name), \
- }
-
-/* Commands */
-
-static const command_parser_t command_policy_create = {
- .action = ACTION_CREATE,
- .object = OBJECT_POLICY,
- .nparams = 2 + POLICY_TAG_N,
- .parameters = {prefix, app_name,
-#define _(x, y) \
- { \
- .name = "flag:" #x, \
- .help = \
- "A value among [neutral|require|prefer|avoid|prohibit] with an " \
- "optional '!' character prefix for disabling changes", \
- .type = TYPE_POLICY_STATE(POLICY_TAG_##x), \
- .offset = offsetof(hc_policy_t, policy.tags), \
- },
- foreach_policy_tag
-#undef _
- },
-};
-COMMAND_REGISTER(command_policy_create);
-
-static const command_parser_t command_policy_list = {
- .action = ACTION_LIST,
- .object = OBJECT_POLICY,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_policy_list);
-#endif \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/command_punting.c b/hicn-light/src/hicn/config/command_punting.c
deleted file mode 100644
index 8c7a6dec3..000000000
--- a/hicn-light/src/hicn/config/command_punting.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#if 0
-#include "command.h"
-
-/* Parameters */
-
-#define symbolic_or_id \
- { \
- .name = "symbolic_or_id", \
- .help = \
- "The symbolic name for an egress, or the egress punting id (see " \
- "'help list puntings')", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_punting_t, face_id), \
- }
-
-#define prefix \
- { \
- .name = "prefix", \
- .help = "Prefix to add as a punting rule. (example 1234::0/64)", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_punting_t, prefix), \
- .offset2 = offsetof(hc_punting_t, prefix_len), \
- .offset3 = offsetof(hc_punting_t, family), \
- }
-
-/* Commands */
-
-static const command_parser_t command_punting_create = {
- .action = ACTION_CREATE,
- .object = OBJECT_PUNTING,
- .nparams = 2,
- .parameters = {symbolic_or_id, prefix},
-};
-COMMAND_REGISTER(command_punting_create);
-
-static const command_parser_t command_punting_list = {
- .action = ACTION_LIST,
- .object = OBJECT_PUNTING,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_punting_list);
-#endif \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/command_route.c b/hicn-light/src/hicn/config/command_route.c
deleted file mode 100644
index dfbea101f..000000000
--- a/hicn-light/src/hicn/config/command_route.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <math.h>
-#include "command.h"
-
-/* Parameters */
-
-#define symbolic_or_id \
- { \
- .name = "symbolic_or_id", \
- .help = \
- "The symbolic name for an egress, or the egress route id (see 'help " \
- "list routes')", \
- .type = TYPE_SYMBOLIC_OR_ID, .offset = offsetof(hc_route_t, name), \
- }
-
-#define prefix \
- { \
- .name = "prefix", \
- .help = "The hicn name as IPv4 or IPv6 address (e.g 1234::0/64).", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_route_t, remote_addr), \
- .offset2 = offsetof(hc_route_t, len), \
- .offset3 = offsetof(hc_route_t, family), \
- }
-
-#define cost \
- { \
- .name = "cost", .help = "Positive integer representing cost.", \
- .type = TYPE_INT(1, 255), .offset = offsetof(hc_route_t, cost), \
- }
-
-/* Commands */
-
-static const command_parser_t command_route_create = {
- .action = ACTION_CREATE,
- .object = OBJECT_ROUTE,
- .nparams = 3,
- .parameters = {symbolic_or_id, prefix, cost},
-};
-COMMAND_REGISTER(command_route_create);
-
-static const command_parser_t command_route_list = {
- .action = ACTION_LIST,
- .object = OBJECT_ROUTE,
- .nparams = 0,
-};
-COMMAND_REGISTER(command_route_list);
-
-static const command_parser_t command_route_remove = {
- .action = ACTION_DELETE,
- .object = OBJECT_ROUTE,
- .nparams = 2,
- .parameters = {symbolic_or_id, prefix},
-};
-COMMAND_REGISTER(command_route_remove);
diff --git a/hicn-light/src/hicn/config/command_strategy.c b/hicn-light/src/hicn/config/command_strategy.c
deleted file mode 100644
index 2341ac830..000000000
--- a/hicn-light/src/hicn/config/command_strategy.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "command.h"
-
-/* Parameters */
-#define prefix \
- { \
- .name = "prefix", \
- .help = "The hicn name as IPv4 or IPv6 address (e.g 1234::0/64).", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_strategy_t, address), \
- .offset2 = offsetof(hc_strategy_t, len), \
- .offset3 = offsetof(hc_strategy_t, family), \
- }
-
-#define strategy \
- { \
- .name = "strategy", \
- .help = \
- "Strategy type (e.g. 'random', 'loadbalancer', 'low_latency', " \
- "'replication', 'bestpath').", \
- .type = TYPE_ENUM(strategy_type), .offset = offsetof(hc_strategy_t, type), \
- }
-
-#define local_prefix \
- { \
- .name = "local_prefix", \
- .help = "The hicn name as IPv4 or IPv6 address (e.g 1234::0/64).", \
- .type = TYPE_IP_PREFIX, .offset = offsetof(hc_strategy_t, local_address), \
- .offset2 = offsetof(hc_strategy_t, local_len), \
- .offset3 = offsetof(hc_strategy_t, local_family), \
- }
-
-/* Commands */
-
-static const command_parser_t command_strategy_list = {
- .action = ACTION_SET,
- .object = OBJECT_STRATEGY,
- .nparams = 2,
- .parameters = {prefix, strategy},
-};
-COMMAND_REGISTER(command_strategy_list);
-
-static const command_parser_t local_prefix_add = {
- .action = ACTION_CREATE,
- .object = OBJECT_LOCAL_PREFIX,
- .nparams = 3,
- .parameters = {prefix, strategy, local_prefix},
-};
-COMMAND_REGISTER(local_prefix_add);
diff --git a/hicn-light/src/hicn/config/command_subscription.c b/hicn-light/src/hicn/config/command_subscription.c
deleted file mode 100644
index 89e3dcd98..000000000
--- a/hicn-light/src/hicn/config/command_subscription.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "command.h"
-
-/* Parameters */
-
-#define topics \
- { \
- .name = "topics", \
- .help = \
- "Topics to subscribe to, e.g. 6 (110 in binary) means topic 2 (10 in " \
- "binary, TOPIC_CONNECTION) and topic 4 (100 in binary, " \
- "TOPIC_LISTENER).", \
- .type = TYPE_INT(1, 255), .offset = offsetof(hc_subscription_t, topics), \
- }
-
-/* Commands */
-
-static const command_parser_t command_subscription_create = {
- .action = ACTION_CREATE,
- .object = OBJECT_SUBSCRIPTION,
- .nparams = 1,
- .parameters = {topics},
-};
-COMMAND_REGISTER(command_subscription_create); \ No newline at end of file
diff --git a/hicn-light/src/hicn/config/commands.c b/hicn-light/src/hicn/config/commands.c
index be00575d7..08c43ba24 100644
--- a/hicn-light/src/hicn/config/commands.c
+++ b/hicn-light/src/hicn/config/commands.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:
@@ -42,7 +42,8 @@
#include <hicn/core/listener.h> //the listener list
#include <hicn/core/listener_table.h>
#include <hicn/core/subscription.h>
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/ctrl/hicn-light.h>
+//#include <hicn/utils/utils.h>
#include <hicn/utils/punting.h>
#include <hicn/util/log.h>
#include <hicn/validation.h>
@@ -55,8 +56,17 @@
#define DEFAULT_COST 1
#define DEFAULT_PORT 1234
-#define make_ack(msg) ((msg_header_t *)msg)->header.message_type = ACK_LIGHT
-#define make_nack(msg) ((msg_header_t *)msg)->header.message_type = NACK_LIGHT
+#define make_ack(msg) \
+ do { \
+ ((msg_header_t *)msg)->header.message_type = ACK_LIGHT; \
+ ((msg_header_t *)msg)->header.length = 0; \
+ } while (0)
+
+#define make_nack(msg) \
+ do { \
+ ((msg_header_t *)msg)->header.message_type = NACK_LIGHT; \
+ ((msg_header_t *)msg)->header.length = 0; \
+ } while (0)
#define msg_malloc_list(msg, COMMAND_ID, N, seq_number) \
do { \
@@ -138,6 +148,7 @@ uint8_t *configuration_on_listener_add(forwarder_t *forwarder, uint8_t *packet,
case FACE_TYPE_HICN_LISTENER:
break;
default:
+ ERROR("Wrong listener type");
goto NACK;
}
@@ -266,8 +277,11 @@ uint8_t *configuration_on_listener_remove(forwarder_t *forwarder,
continue;
unsigned conn_id =
- (unsigned int)connection_table_get_connection_id(table, connection);
+ (unsigned)connection_table_get_connection_id(table, connection);
+
/* Remove connection from the FIB */
+ // XXX TODO get entries, raise notifications...
+ // XXX isn't it possible to implement this in the forwarder ?????
forwarder_remove_connection_id_from_routes(forwarder, conn_id);
/* Remove connection */
@@ -288,10 +302,8 @@ NACK:
}
// TODO(eloparco): Unused forwarder param
-static inline void fill_listener_command(forwarder_t *forwarder,
- listener_t *listener,
+static inline void fill_listener_command(const listener_t *listener,
cmd_listener_list_item_t *cmd) {
- assert(forwarder);
assert(listener);
assert(cmd);
@@ -306,15 +318,15 @@ static inline void fill_listener_command(forwarder_t *forwarder,
switch (addr->as_ss.ss_family) {
case AF_INET:
sin = (struct sockaddr_in *)addr;
- cmd->family = AF_INET;
- cmd->address.v4.as_inaddr = sin->sin_addr;
- cmd->port = sin->sin_port;
+ cmd->family = (uint8_t)AF_INET;
+ cmd->local_addr.v4.as_inaddr = sin->sin_addr;
+ cmd->local_port = sin->sin_port;
break;
case AF_INET6:
sin6 = (struct sockaddr_in6 *)addr;
- cmd->family = AF_INET6;
- cmd->address.v6.as_in6addr = sin6->sin6_addr;
- cmd->port = sin6->sin6_port;
+ cmd->family = (uint8_t)AF_INET6;
+ cmd->local_addr.v6.as_in6addr = sin6->sin6_addr;
+ cmd->local_port = sin6->sin6_port;
break;
default:
break;
@@ -344,9 +356,8 @@ uint8_t *configuration_on_listener_list(forwarder_t *forwarder, uint8_t *packet,
if (!msg) goto NACK;
cmd_listener_list_item_t *payload = &msg->payload;
- listener_t *listener;
listener_table_foreach(table, listener, {
- fill_listener_command(forwarder, listener, payload);
+ fill_listener_command(listener, payload);
payload++;
});
@@ -406,41 +417,10 @@ uint8_t *configuration_on_connection_add(forwarder_t *forwarder,
control->remote_port) < 0)
goto NACK;
- connection_t *connection = connection_table_get_by_pair(table, &pair);
-#ifdef WITH_MAPME
- connection_event_t event;
-#endif /* WITH_MAPME */
-
- if (!connection) {
- connection =
- connection_create(control->type, symbolic_name, &pair, forwarder);
- if (!connection) {
- ERROR("Failed to create %s connection", face_type_str(control->type));
- goto NACK;
- }
-
-#ifdef WITH_MAPME
- event = CONNECTION_EVENT_CREATE;
-#endif /* WITH_MAPME */
- } else {
- WARN("Connection already exists");
-
-#ifdef WITH_MAPME
- event = CONNECTION_EVENT_UPDATE;
-#endif /* WITH_MAPME */
- }
-
-#ifdef WITH_POLICY
- connection_set_tags(connection, control->tags);
- connection_set_priority(connection, control->priority);
-#endif /* WITH_POLICY */
-
- connection_set_admin_state(connection, control->admin_state);
-
-#ifdef WITH_MAPME
- /* Hook: new connection created through the control protocol */
- forwarder_on_connection_event(forwarder, connection, event);
-#endif /* WITH_MAPME */
+ if (forwarder_add_connection(forwarder, symbolic_name, control->type, &pair,
+ control->tags, control->priority,
+ control->admin_state) < 0)
+ goto NACK;
make_ack(msg);
return (uint8_t *)msg;
@@ -486,24 +466,20 @@ uint8_t *configuration_on_connection_remove(forwarder_t *forwarder,
goto NACK;
}
- /* Remove connection from the FIB */
- forwarder_remove_connection_id_from_routes(forwarder, conn_id);
-
- /* Remove connection */
- connection_table_t *table = forwarder_get_connection_table(forwarder);
- connection_t *connection = connection_table_get_by_id(table, conn_id);
- connection_table_remove_by_id(table, conn_id);
+ /*
+ *
+ * Don't close the fd for SELF otherwise it won't be possible
+ * to send the reply back. The connection is finalized later in
+ * _forwarder_finalize_connection_if_self
+ */
+ bool finalize = (strcmp(control->symbolic_or_connid, "SELF") != 0);
- // Don't close the fd for SELF otherwise it won't be possible
- // to send the reply back
- if (strcmp(control->symbolic_or_connid, "SELF") != 0)
- connection_finalize(connection);
- WITH_DEBUG(connection_table_print_by_pair(table);)
+ if (forwarder_remove_connection(forwarder, conn_id, finalize) < 0) goto NACK;
-#ifdef WITH_MAPME
- /* Hook: new connection created through the control protocol */
- forwarder_on_connection_event(forwarder, NULL, CONNECTION_EVENT_DELETE);
-#endif /* WITH_MAPME */
+ WITH_DEBUG({
+ connection_table_t *table = forwarder_get_connection_table(forwarder);
+ connection_table_print_by_pair(table);
+ })
make_ack(msg);
return (uint8_t *)msg;
@@ -519,10 +495,8 @@ static inline void tolower_str(char *str) {
}
// TODO(eloparco): Forwarder param not used
-static inline void fill_connections_command(forwarder_t *forwarder,
- connection_t *connection,
+static inline void fill_connections_command(const connection_t *connection,
cmd_connection_list_item_t *cmd) {
- assert(forwarder);
assert(connection);
assert(cmd);
@@ -531,12 +505,12 @@ static inline void fill_connections_command(forwarder_t *forwarder,
const address_pair_t *pair = connection_get_pair(connection);
cmd->id = connection_get_id(connection),
- cmd->state = connection_get_state(connection),
- cmd->admin_state = connection_get_admin_state(connection),
- cmd->type = connection_get_type(connection),
+ cmd->state = (uint8_t)connection_get_state(connection),
+ cmd->admin_state = (uint8_t)connection_get_admin_state(connection),
+ cmd->type = (uint8_t)connection_get_type(connection),
#ifdef WITH_POLICY
cmd->priority = connection_get_priority(connection),
- cmd->tags = connection_get_tags(connection),
+ cmd->tags = (uint8_t)connection_get_tags(connection),
#endif /* WITH_POLICY */
snprintf(cmd->name, SYMBOLIC_NAME_LEN, "%s", connection_get_name(connection));
@@ -547,7 +521,7 @@ static inline void fill_connections_command(forwarder_t *forwarder,
switch (pair->local.as_ss.ss_family) {
case AF_INET:
- cmd->family = AF_INET;
+ cmd->family = (uint8_t)AF_INET;
sin = (struct sockaddr_in *)(&pair->local);
cmd->local_port = sin->sin_port;
@@ -559,7 +533,7 @@ static inline void fill_connections_command(forwarder_t *forwarder,
break;
case AF_INET6:
- cmd->family = AF_INET6;
+ cmd->family = (uint8_t)AF_INET6;
sin6 = (struct sockaddr_in6 *)(&pair->local);
cmd->local_port = sin6->sin6_port;
@@ -594,6 +568,7 @@ uint8_t *configuration_on_connection_list(forwarder_t *forwarder,
// -1 since current connection (i.e. the one used to send
// the command) is not considered
size_t n = connection_table_len(table) - 1;
+
msg_connection_list_t *msg_received = (msg_connection_list_t *)packet;
uint8_t command_id = msg_received->header.command_id;
uint32_t seq_num = msg_received->header.seq_num;
@@ -603,10 +578,9 @@ uint8_t *configuration_on_connection_list(forwarder_t *forwarder,
if (!msg) goto NACK;
cmd_connection_list_item_t *payload = &msg->payload;
- connection_t *connection;
- connection_table_foreach(table, connection, {
+ connection_table_foreach_new(table, connection, {
if (connection->id == ingress_id) continue;
- fill_connections_command(forwarder, connection, payload);
+ fill_connections_command(connection, payload);
payload++;
});
@@ -619,6 +593,7 @@ NACK:
return (uint8_t *)msg;
}
+#if 0
uint8_t *configuration_on_connection_set_admin_state(forwarder_t *forwarder,
uint8_t *packet,
unsigned ingress_id,
@@ -640,13 +615,11 @@ uint8_t *configuration_on_connection_set_admin_state(forwarder_t *forwarder,
connection_set_admin_state(conn, control->admin_state);
-#ifdef WITH_MAPME
/* Hook: connection event */
forwarder_on_connection_event(forwarder, conn,
control->admin_state == FACE_STATE_UP
? CONNECTION_EVENT_SET_UP
: CONNECTION_EVENT_SET_DOWN);
-#endif /* WITH_MAPME */
make_ack(msg);
return (uint8_t *)msg;
@@ -656,6 +629,7 @@ NACK:
return (uint8_t *)msg;
}
+#endif
uint8_t *configuration_on_connection_update(forwarder_t *forwarder,
uint8_t *packet,
unsigned ingress_id,
@@ -684,6 +658,8 @@ NACK:
return (uint8_t *)msg;
}
+#if 0
+
uint8_t *configuration_on_connection_set_priority(forwarder_t *forwarder,
uint8_t *packet,
unsigned ingress_id,
@@ -701,11 +677,9 @@ uint8_t *configuration_on_connection_set_priority(forwarder_t *forwarder,
connection_set_priority(conn, control->priority);
-#ifdef WITH_MAPME
/* Hook: connection event */
forwarder_on_connection_event(forwarder, conn,
CONNECTION_EVENT_PRIORITY_CHANGED);
-#endif /* WITH_MAPME */
make_ack(msg);
return (uint8_t *)msg;
@@ -733,10 +707,8 @@ uint8_t *configuration_on_connection_set_tags(forwarder_t *forwarder,
connection_set_tags(conn, control->tags);
-#ifdef WITH_MAPME
/* Hook: connection event */
forwarder_on_connection_event(forwarder, conn, CONNECTION_EVENT_TAGS_CHANGED);
-#endif /* WITH_MAPME */
make_ack(msg);
return (uint8_t *)msg;
@@ -747,6 +719,8 @@ NACK:
return (uint8_t *)msg;
}
+#endif
+
/* Route */
uint8_t *configuration_on_route_add(forwarder_t *forwarder, uint8_t *packet,
@@ -763,9 +737,9 @@ uint8_t *configuration_on_route_add(forwarder_t *forwarder, uint8_t *packet,
forwarder, control->symbolic_or_connid, ingress_id);
if (!connection_id_is_valid(conn_id)) goto NACK;
- ip_prefix_t prefix = {.family = control->family,
- .address = control->address,
- .len = control->len};
+ hicn_ip_prefix_t prefix = {.family = control->family,
+ .address = control->address,
+ .len = control->len};
if (!forwarder_add_or_update_route(forwarder, &prefix, conn_id)) goto NACK;
@@ -792,9 +766,9 @@ uint8_t *configuration_on_route_remove(forwarder_t *forwarder, uint8_t *packet,
symbolic_to_conn_id(forwarder, control->symbolic_or_connid);
if (!connection_id_is_valid(conn_id)) goto NACK;
- ip_prefix_t prefix = {.family = control->family,
- .address = control->address,
- .len = control->len};
+ hicn_ip_prefix_t prefix = {.family = control->family,
+ .address = control->address,
+ .len = control->len};
if (!forwarder_remove_route(forwarder, &prefix, conn_id)) goto NACK;
@@ -806,6 +780,29 @@ NACK:
return (uint8_t *)msg;
}
+static inline void fill_route_command(const fib_entry_t *entry,
+ cmd_route_list_item_t *cmd) {
+ const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
+ assert(nexthops_get_len(nexthops) == nexthops_get_curlen(nexthops));
+ size_t num_nexthops = nexthops_get_len(nexthops);
+
+ if (num_nexthops == 0) return;
+
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
+ const hicn_ip_address_t *address = hicn_prefix_get_ip_address(prefix);
+ int family = hicn_ip_address_get_family(address);
+
+ nexthops_foreach(nexthops, nexthop, {
+ cmd->family = family;
+ cmd->remote_addr = *address;
+ cmd->face_id = nexthop;
+ cmd->len = hicn_prefix_get_len(prefix);
+ cmd->cost = DEFAULT_COST;
+
+ cmd++;
+ });
+}
+
uint8_t *configuration_on_route_list(forwarder_t *forwarder, uint8_t *packet,
unsigned ingress_id, size_t *reply_size) {
INFO("CMD: route list (ingress=%d)", ingress_id);
@@ -816,7 +813,6 @@ uint8_t *configuration_on_route_list(forwarder_t *forwarder, uint8_t *packet,
uint8_t command_id = msg_received->header.command_id;
uint32_t seq_num = msg_received->header.seq_num;
const fib_t *fib = forwarder_get_fib(forwarder);
- fib_entry_t *entry;
/*
* Two step approach to precompute the number of entries to allocate
@@ -835,38 +831,7 @@ uint8_t *configuration_on_route_list(forwarder_t *forwarder, uint8_t *packet,
if (!msg) goto NACK;
cmd_route_list_item_t *payload = &msg->payload;
- fib_foreach_entry(fib, entry, {
- const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
- assert(nexthops_get_len(nexthops) == nexthops_get_curlen(nexthops));
- size_t num_nexthops = nexthops_get_len(nexthops);
-
- if (num_nexthops == 0) continue;
-
- NameBitvector *prefix = name_GetContentName(fib_entry_get_prefix(entry));
-
- unsigned nexthop;
- nexthops_foreach(nexthops, nexthop, {
- address_t address;
- nameBitvector_ToAddress(prefix, &address);
- switch (address_family(&address)) {
- case AF_INET:
- payload->family = AF_INET;
- payload->address.v4.as_inaddr = address4_ip(&address);
- break;
- case AF_INET6:
- payload->family = AF_INET6;
- payload->address.v6.as_in6addr = address6_ip(&address);
- break;
- default:
- break;
- }
- payload->connection_id = nexthop;
- payload->len = nameBitvector_GetLength(prefix);
- payload->cost = DEFAULT_COST;
-
- payload++;
- });
- });
+ fib_foreach_entry(fib, entry, { fill_route_command(entry, payload); });
*reply_size = sizeof(msg->header) + n * sizeof(msg->payload);
return (uint8_t *)msg;
@@ -983,12 +948,12 @@ uint8_t *configuration_on_strategy_set(forwarder_t *forwarder, uint8_t *packet,
cmd_strategy_set_t *control = &msg->payload;
char prefix_s[MAXSZ_IP_PREFIX];
- ip_prefix_t prefix = {
+ hicn_ip_prefix_t prefix = {
.family = control->family,
.address = control->address,
.len = control->len,
};
- 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) goto NACK;
@@ -998,9 +963,10 @@ uint8_t *configuration_on_strategy_set(forwarder_t *forwarder, uint8_t *packet,
configuration_get_strategy(config, prefix_s);
strategy_options_t *options = NULL;
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, control->family, control->address,
- control->len);
+ // XXX check control->family
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&control->address, control->len,
+ &name_prefix);
// The strategy is not present in the hash table
// or has to be updated or to be restarted
@@ -1012,9 +978,9 @@ uint8_t *configuration_on_strategy_set(forwarder_t *forwarder, uint8_t *packet,
forwarder_set_strategy(forwarder, &name_prefix, strategy, options);
} else {
WITH_WARN({
- char *nameString = name_ToString(&name_prefix);
- WARN("Strategy for prefix %s not updated", nameString);
- free(nameString);
+ char buf[MAXSZ_HICN_PREFIX];
+ hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, &name_prefix);
+ WARN("Strategy for prefix %s not updated", buf);
})
}
@@ -1040,12 +1006,12 @@ uint8_t *configuration_on_strategy_add_local_prefix(forwarder_t *forwarder,
cmd_strategy_add_local_prefix_t *control = &msg->payload;
char prefix_s[MAXSZ_IP_PREFIX];
- ip_prefix_t prefix = {
+ hicn_ip_prefix_t prefix = {
.family = control->family,
.address = control->address,
.len = control->len,
};
- 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) goto NACK;
@@ -1060,17 +1026,17 @@ uint8_t *configuration_on_strategy_add_local_prefix(forwarder_t *forwarder,
strategy != STRATEGY_TYPE_REPLICATION)
goto NACK;
- Name name_prefix = EMPTY_NAME;
- name_CreateFromAddress(&name_prefix, control->family, control->address,
- control->len);
+ hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&control->address, control->len,
+ &name_prefix);
strategy_options_t options;
- Name local_prefix = EMPTY_NAME;
- name_CreateFromAddress(&local_prefix, control->local_family,
- control->local_address, control->local_len);
+ hicn_prefix_t local_prefix = HICN_PREFIX_EMPTY;
+ hicn_prefix_create_from_ip_address_len(&control->address, control->len,
+ &local_prefix);
- // for the moment bestpath and replication are the same but we distinguish the
- // two in case they will diverge in the future
+ // for the moment bestpath and replication are the same but we distinguish
+ // the two in case they will diverge in the future
if (strategy == STRATEGY_TYPE_BESTPATH) {
options.bestpath.local_prefixes = create_local_prefixes();
local_prefixes_add_prefix(options.bestpath.local_prefixes, &local_prefix);
@@ -1212,11 +1178,11 @@ uint8_t *configuration_on_punting_add(forwarder_t *forwarder, uint8_t *packet,
goto NACK;
}
- ip_prefix_t prefix = {.family = control->family,
- .address = control->address,
- .len = control->len};
+ hicn_ip_prefix_t prefix = {.family = control->family,
+ .address = control->address,
+ .len = control->len};
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) goto NACK;
@@ -1359,12 +1325,11 @@ uint8_t *configuration_on_mapme_send_update(forwarder_t *forwarder,
mapme_t *mapme = forwarder_get_mapme(forwarder);
/*
- * The command triggers a mapme update for all prefixes produced on this face
+ * The command triggers a mapme update for all prefixes produced on this
+ * face
* */
- fib_entry_t *entry;
fib_foreach_entry(fib, entry, {
const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
- unsigned nexthop;
nexthops_foreach(nexthops, nexthop, {
if (nexthop != ingress_id) continue;
/* This entry points to the producer face */
@@ -1393,9 +1358,9 @@ uint8_t *configuration_on_policy_add(forwarder_t *forwarder, uint8_t *packet,
msg_policy_add_t *msg = (msg_policy_add_t *)packet;
cmd_policy_add_t *control = &msg->payload;
- ip_prefix_t prefix = {.family = control->family,
- .address = control->address,
- .len = control->len};
+ hicn_ip_prefix_t prefix = {.family = control->family,
+ .address = control->address,
+ .len = control->len};
if (!forwarder_add_or_update_policy(forwarder, &prefix, &control->policy))
goto NACK;
@@ -1419,9 +1384,9 @@ uint8_t *configuration_on_policy_remove(forwarder_t *forwarder, uint8_t *packet,
msg_policy_remove_t *msg = (msg_policy_remove_t *)packet;
cmd_policy_remove_t *control = &msg->payload;
- ip_prefix_t prefix = {.family = control->family,
- .address = control->address,
- .len = control->len};
+ hicn_ip_prefix_t prefix = {.family = control->family,
+ .address = control->address,
+ .len = control->len};
if (!forwarder_remove_policy(forwarder, &prefix)) goto NACK;
@@ -1434,6 +1399,39 @@ NACK:
return (uint8_t *)msg;
}
+static inline void fill_policy_command(const fib_entry_t *entry,
+ cmd_policy_list_item_t *cmd) {
+ const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
+ const hicn_ip_address_t *ip_address = hicn_prefix_get_ip_address(prefix);
+ cmd->remote_addr = *ip_address;
+ cmd->family = hicn_ip_address_get_family(ip_address);
+ cmd->len = hicn_prefix_get_len(prefix);
+
+ hicn_policy_t policy = fib_entry_get_policy(entry);
+ _hicn_policy_t _policy = {
+ .stats = {
+ .wired = {.throughput = htonf(policy.stats.wired.throughput),
+ .latency = htonf(policy.stats.wired.latency),
+ .loss_rate = htonf(policy.stats.wired.loss_rate)},
+ .wifi = {.throughput = htonf(policy.stats.wifi.throughput),
+ .latency = htonf(policy.stats.wifi.latency),
+ .loss_rate = htonf(policy.stats.wifi.loss_rate)},
+ .cellular = {.throughput = htonf(policy.stats.cellular.throughput),
+ .latency = htonf(policy.stats.cellular.latency),
+ .loss_rate = htonf(policy.stats.cellular.loss_rate)},
+ .all = {.throughput = htonf(policy.stats.all.throughput),
+ .latency = htonf(policy.stats.all.latency),
+ .loss_rate = htonf(policy.stats.all.loss_rate)}}};
+ for (unsigned i = 0; i < POLICY_TAG_N; i++) {
+ _policy.tags[i] = (_policy_tag_state_t){
+ .state = policy.tags[i].state,
+ .disabled = policy.tags[i].disabled,
+ };
+ }
+ memcpy(_policy.app_name, policy.app_name, APP_NAME_LEN);
+ memcpy(cmd->policy, &_policy, sizeof(_policy));
+}
+
uint8_t *configuration_on_policy_list(forwarder_t *forwarder, uint8_t *packet,
unsigned ingress_id, size_t *reply_size) {
assert(forwarder);
@@ -1454,30 +1452,8 @@ uint8_t *configuration_on_policy_list(forwarder_t *forwarder, uint8_t *packet,
cmd_policy_list_item_t *payload = &msg->payload;
- fib_entry_t *entry;
-
fib_foreach_entry(fib, entry, {
- NameBitvector *prefix = name_GetContentName(fib_entry_get_prefix(entry));
- address_t address;
- nameBitvector_ToAddress(prefix, &address);
-
- switch (address_family(&address)) {
- case AF_INET:
- payload->family = AF_INET;
- payload->address.v4.as_inaddr = address4_ip(&address);
- break;
-
- case AF_INET6:
- payload->family = AF_INET6;
- payload->address.v6.as_in6addr = address6_ip(&address);
- break;
-
- default:
- break;
- }
- payload->len = nameBitvector_GetLength(prefix);
- payload->policy = fib_entry_get_policy(entry);
-
+ fill_policy_command(entry, payload);
payload++;
});
@@ -1544,9 +1520,17 @@ uint8_t *configuration_on_subscription_remove(forwarder_t *forwarder,
return (uint8_t *)msg;
}
+uint8_t *configuration_on_active_interface_update(forwarder_t *forwarder,
+ uint8_t *packet,
+ unsigned ingress_id,
+ size_t *reply_size) {
+ msg_active_interface_update_t *msg = (msg_active_interface_update_t *)packet;
+ make_nack(msg);
+ return (uint8_t *)msg;
+}
+
uint8_t *command_process(forwarder_t *forwarder, uint8_t *packet,
- command_type_t command_type, unsigned ingress_id,
- size_t *reply_size) {
+ unsigned ingress_id, size_t *reply_size) {
uint8_t *reply = NULL;
/*
@@ -1557,6 +1541,7 @@ uint8_t *command_process(forwarder_t *forwarder, uint8_t *packet,
*
* XXX rework this part.
*/
+ command_type_t command_type = ((msg_header_t *)packet)->header.command_id;
switch (command_type) {
#define _(l, u) \
case COMMAND_TYPE_##u: \
@@ -1586,28 +1571,100 @@ ssize_t command_process_msgbuf(forwarder_t *forwarder, msgbuf_t *msgbuf) {
uint8_t *reply = NULL;
size_t reply_size = 0;
- command_type_t command_type = msgbuf_get_command_type(msgbuf);
-
- reply =
- command_process(forwarder, packet, command_type, ingress_id, &reply_size);
+ reply = command_process(forwarder, packet, ingress_id, &reply_size);
if (connection_id_is_valid(msgbuf->connection_id)) {
connection_table_t *table = forwarder_get_connection_table(forwarder);
const connection_t *connection = connection_table_at(table, ingress_id);
connection_send_packet(connection, reply, reply_size);
}
- switch (msgbuf->command.type) {
- case COMMAND_TYPE_LISTENER_LIST:
- case COMMAND_TYPE_CONNECTION_LIST:
- case COMMAND_TYPE_ROUTE_LIST:
- case COMMAND_TYPE_POLICY_LIST:
- /* Free replies that have been allocated (not NACK's) */
- if (((msg_header_t *)reply)->header.message_type != NACK_LIGHT)
- free(reply);
+ /* Free allocated replies */
+ if (reply != packet) free(reply);
+ return msgbuf_get_len(msgbuf);
+}
+
+void commands_notify(const forwarder_t *forwarder, hc_topic_t topic,
+ uint8_t *msg, size_t size) {
+ // Retrieve subscribed connections
+ subscription_table_t *subscriptions = forwarder_get_subscriptions(forwarder);
+ unsigned *subscribed_conn_ids =
+ subscription_table_get_connections_for_topic(subscriptions, topic);
+
+ // Send notification to subscribed connections
+ const connection_table_t *table = forwarder_get_connection_table(forwarder);
+ for (int i = 0; i < vector_len(subscribed_conn_ids); i++) {
+ const connection_t *conn =
+ connection_table_at(table, subscribed_conn_ids[i]);
+ connection_send_packet(conn, msg, size);
+ }
+}
+
+void commands_notify_connection(const forwarder_t *forwarder,
+ connection_event_t event,
+ const connection_t *connection) {
+#if 0
+ uint8_t command_id;
+ switch (event) {
+ case CONNECTION_EVENT_CREATE:
+ command_id = COMMAND_TYPE_CONNECTION_ADD;
break;
- default:
+ case CONNECTION_EVENT_DELETE:
+ command_id = COMMAND_TYPE_CONNECTION_REMOVE;
+ break;
+ case CONNECTION_EVENT_UPDATE:
+ case CONNECTION_EVENT_SET_UP:
+ case CONNECTION_EVENT_SET_DOWN:
+ case CONNECTION_EVENT_PRIORITY_CHANGED:
+ case CONNECTION_EVENT_TAGS_CHANGED:
+ command_id = COMMAND_TYPE_CONNECTION_UPDATE;
break;
+ case CONNECTION_EVENT_UNDEFINED:
+ case CONNECTION_EVENT_N:
+ default:
+ return;
}
+#endif
- return msgbuf_get_len(msgbuf);
+ msg_connection_notify_t msg = {.header = {
+ .message_type = NOTIFICATION_LIGHT,
+ .command_id = OBJECT_TYPE_CONNECTION,
+ .length = 1,
+ .seq_num = 0,
+ }};
+ fill_connections_command(connection, &msg.payload);
+
+ commands_notify(forwarder, TOPIC_CONNECTION, (uint8_t *)&msg, sizeof(msg));
+}
+
+void commands_notify_route(const forwarder_t *forwarder,
+ const fib_entry_t *entry) {
+ const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
+ size_t n = nexthops_get_len(nexthops);
+ msg_route_notify_t *msg = NULL;
+ msg_malloc_list(msg, OBJECT_TYPE_ROUTE, n, 0);
+ if (!msg) return;
+
+ fill_route_command(entry, &msg->payload);
+
+ commands_notify(forwarder, TOPIC_ROUTE, (uint8_t *)&msg, sizeof(msg));
+}
+
+void commands_notify_active_interface_update(const forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
+ netdevice_flags_t flags) {
+ struct {
+ cmd_header_t header;
+ hc_active_interface_t payload;
+ } msg = {.header =
+ {
+ .message_type = NOTIFICATION_LIGHT,
+ .command_id = OBJECT_TYPE_ACTIVE_INTERFACE,
+ .length = 1,
+ .seq_num = 0,
+ },
+ .payload = {.prefix = *prefix, .interface_types = flags}};
+
+ INFO("Notify active interface");
+ commands_notify(forwarder, TOPIC_ACTIVE_INTERFACE, (uint8_t *)&msg,
+ sizeof(msg));
}
diff --git a/hicn-light/src/hicn/config/commands.h b/hicn-light/src/hicn/config/commands.h
index 3852a76ac..f212c1b0b 100644
--- a/hicn-light/src/hicn/config/commands.h
+++ b/hicn-light/src/hicn/config/commands.h
@@ -29,11 +29,10 @@
#include "../core/msgbuf.h"
#include "../core/strategy.h"
#include <hicn/ctrl/api.h>
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/ctrl/hicn-light.h>
uint8_t *command_process(forwarder_t *forwarder, uint8_t *packet,
- command_type_t command_type, unsigned ingress_id,
- size_t *reply_size);
+ unsigned ingress_id, size_t *reply_size);
ssize_t command_process_msgbuf(forwarder_t *forwarder, msgbuf_t *msgbuf);
@@ -152,4 +151,15 @@ uint8_t *configuration_on_policy_list(forwarder_t *forwarder, uint8_t *packet,
uint8_t *configuration_on_stats_list(forwarder_t *forwarder, uint8_t *packet,
unsigned ingress_id, size_t *reply_size);
+void commands_notify_connection(const forwarder_t *forwarder,
+ connection_event_t event,
+ const connection_t *connection);
+
+void commands_notify_route(const forwarder_t *forwarder,
+ const fib_entry_t *entry);
+
+void commands_notify_active_interface_update(const forwarder_t *forwarder,
+ hicn_ip_prefix_t *prefix,
+ netdevice_flags_t flags);
+
#endif // HICNLIGHT_COMMANDS_H
diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c
index 9123ceebf..f38c4f22f 100644
--- a/hicn-light/src/hicn/config/configuration.c
+++ b/hicn-light/src/hicn/config/configuration.c
@@ -41,7 +41,8 @@
#include <hicn/core/listener.h> //the listener list
#include <hicn/core/listener_table.h>
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/ctrl/hicn-light.h>
+//#include <hicn/utils/utils.h>
#include <hicn/utils/punting.h>
#include <hicn/util/log.h>
#include <hicn/face.h>
@@ -72,6 +73,8 @@ struct configuration_s {
int logfile_fd;
bool daemon;
kh_strategy_map_t *strategy_map;
+ size_t n_suffixes_per_split;
+ int_manifest_split_strategy_t split_strategy;
};
configuration_t *configuration_create() {
@@ -92,6 +95,8 @@ configuration_t *configuration_create() {
#endif
configuration_set_loglevel(config, loglevel_from_str(DEFAULT_LOGLEVEL));
config->strategy_map = kh_init_strategy_map();
+ config->n_suffixes_per_split = DEFAULT_N_SUFFIXES_PER_SPLIT;
+ config->split_strategy = DEFAULT_DISAGGREGATION_STRATEGY;
return config;
}
@@ -127,6 +132,25 @@ void configuration_set_fn_config(configuration_t *config,
config->fn_config = fn_config;
}
+void configuration_set_suffixes_per_split(configuration_t *config,
+ size_t n_suffixes_per_split) {
+ config->n_suffixes_per_split = n_suffixes_per_split;
+}
+
+size_t configuration_get_suffixes_per_split(const configuration_t *config) {
+ return config->n_suffixes_per_split;
+}
+
+void configuration_set_split_strategy(
+ configuration_t *config, int_manifest_split_strategy_t split_strategy) {
+ config->split_strategy = split_strategy;
+}
+
+int_manifest_split_strategy_t configuration_get_split_strategy(
+ const configuration_t *config) {
+ return config->split_strategy;
+}
+
void configuration_set_port(configuration_t *config, uint16_t port) {
config->port = port;
}
diff --git a/hicn-light/src/hicn/config/configuration.h b/hicn-light/src/hicn/config/configuration.h
index 93b4cf7c3..0d1a2b8e7 100644
--- a/hicn-light/src/hicn/config/configuration.h
+++ b/hicn-light/src/hicn/config/configuration.h
@@ -30,7 +30,8 @@
#include "../core/msgbuf.h"
#include "../core/strategy.h"
#include <hicn/ctrl/api.h>
-#include <hicn/ctrl/hicn-light-ng.h>
+#include <hicn/ctrl/hicn-light.h>
+#include <hicn/interest_manifest.h>
KHASH_MAP_INIT_STR(strategy_map, unsigned);
@@ -103,6 +104,18 @@ const char *configuration_get_fn_config(const configuration_t *config);
void configuration_set_fn_config(configuration_t *config,
const char *fn_config);
+void configuration_set_suffixes_per_split(configuration_t *config,
+ size_t n_suffixes_per_split);
+
+size_t configuration_get_suffixes_per_split(const configuration_t *config);
+
+void configuration_set_split_strategy(
+ configuration_t *config,
+ int_manifest_split_strategy_t n_suffixes_per_split);
+
+int_manifest_split_strategy_t configuration_get_split_strategy(
+ const configuration_t *config);
+
void configuration_set_port(configuration_t *config, uint16_t port);
uint16_t configuration_get_port(const configuration_t *config);
diff --git a/hicn-light/src/hicn/config/configuration_file.c b/hicn-light/src/hicn/config/configuration_file.c
index 2e8e7a6ac..8649e0143 100644
--- a/hicn-light/src/hicn/config/configuration_file.c
+++ b/hicn-light/src/hicn/config/configuration_file.c
@@ -20,11 +20,13 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
+
+#include <hicn/ctrl/hicn-light.h>
#include <hicn/config/configuration_file.h>
#include <hicn/util/sstrncpy.h>
#include "commands.h"
-#include "parse.h"
+#include <hicn/ctrl/parse.h>
#define BUFFERLEN 2048
@@ -62,12 +64,17 @@ bool configuration_file_process(forwarder_t *forwarder, const char *filename) {
char buffer[BUFFERLEN];
bool success = true;
+
+#if 0
// TODO(eloparco): We could use a fake socket since we only need the vft
- hc_sock_t *s = hc_sock_create_forwarder(HICNLIGHT_NG);
+ hc_sock_t *s = hc_sock_create(FORWARDER_TYPE_HICNLIGHT, NULL);
if (!s) {
ERROR("Could not create socket");
goto ERR_SOCK;
}
+#else
+ hc_sock_initialize_module(NULL);
+#endif
while (success && fgets(buffer, BUFFERLEN, f) != NULL) {
linesRead++;
@@ -83,42 +90,31 @@ bool configuration_file_process(forwarder_t *forwarder, const char *filename) {
continue;
}
- // TODO(eloparco): Handle all commands
- hc_result_t *result = NULL;
- if (command.action == ACTION_CREATE) {
- if (command.object.type == OBJECT_LISTENER) {
- result = hc_listener_create_conf(s, &command.object.listener);
- } else if (command.object.type == OBJECT_CONNECTION) {
- result = hc_connection_create_conf(s, &command.object.connection);
- } else if (command.object.type == OBJECT_ROUTE) {
- result = hc_route_create_conf(s, &command.object.route);
- } else if (command.object.type == OBJECT_LOCAL_PREFIX) {
- result = hc_strategy_add_local_prefix_conf(s, &command.object.strategy);
- }
- } else if (command.action == ACTION_SET) {
- if (command.object.type == OBJECT_STRATEGY) {
- result = hc_strategy_set_conf(s, &command.object.strategy);
- }
- }
- if (result == NULL) {
- ERROR("Command '%s' not supported", cmd);
- continue;
+ /* Serialize request into message */
+ // hc_msg_t msg;
+ uint8_t msg[1024];
+ ssize_t msg_len = hc_light_command_serialize(
+ command.action, command.object_type, &command.object, msg);
+ switch (msg_len) {
+ case -1:
+ case -2:
+ ERROR("Command '%s' not supported", cmd);
+ continue;
+ case -3:
+ ERROR("Error during command serialization '%s'", cmd);
+ continue;
+ default:
+ break;
}
size_t _unused;
- hc_msg_t *msg = hc_result_get_msg(s, result);
- command_type_t cmd_id = hc_result_get_cmd_id(s, result);
- bool success = hc_result_get_success(s, result);
- if (success == false) {
- ERROR("Error serializing command : '%s'", cmd);
- continue;
- }
-
- command_process(forwarder, (uint8_t *)msg, cmd_id, CONNECTION_ID_UNDEFINED,
+ command_process(forwarder, (uint8_t *)msg, CONNECTION_ID_UNDEFINED,
&_unused);
- hc_result_free(result);
}
+
+#if 0
hc_sock_free(s);
+#endif
if (ferror(f)) {
ERROR("Error on input file %s line %d: (%d) %s", filename, linesRead, errno,
@@ -128,8 +124,10 @@ bool configuration_file_process(forwarder_t *forwarder, const char *filename) {
fclose(f);
return true;
+#if 0
ERR_SOCK:
hc_sock_free(s);
+#endif
ERR_READ:
fclose(f);
ERR_OPEN:
diff --git a/hicn-light/src/hicn/config/configuration_file.h b/hicn-light/src/hicn/config/configuration_file.h
index 4d9535ab7..03599d4f4 100644
--- a/hicn-light/src/hicn/config/configuration_file.h
+++ b/hicn-light/src/hicn/config/configuration_file.h
@@ -28,6 +28,7 @@
#define configuration_file_h
#include <hicn/core/forwarder.h>
+#include <hicn/ctrl/hicn-light.h>
/**
* Configure hicn-light by reading a configuration file line-by-line and
diff --git a/hicn-light/src/hicn/config/parse.c b/hicn-light/src/hicn/config/parse.c
deleted file mode 100644
index ba9c0b348..000000000
--- a/hicn-light/src/hicn/config/parse.c
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-//#include <hicn/ctrl/cli.h>
-#include <hicn/util/log.h>
-#include <hicn/util/sstrncpy.h>
-#include "parse.h"
-
-/*
- * As there is no portable way to generate a va_list to use with sscanf to
- * support a variable number of arguments, and no way to use a variable array
- * initialize in a nested struct, we use a fixed maximum number of parameters
- *
- * NOTE: update sscanf accordingly
- */
-
-#include "command.h"
-
-const char *action_str[] = {
-#define _(x) [ACTION_##x] = #x,
- foreach_action
-#undef _
-};
-
-#define action_str(x) action_str[x]
-
-hc_action_t action_from_str(const char *action_str) {
-#define _(x) \
- if (strcasecmp(action_str, #x) == 0) \
- return ACTION_##x; \
- else
- foreach_action
-#undef _
- if (strcasecmp(action_str, "add") == 0) return ACTION_CREATE;
- else if (strcasecmp(action_str, "remove") == 0) return ACTION_DELETE;
- else return ACTION_UNDEFINED;
-}
-
-const char *object_str[] = {
-#define _(x) [OBJECT_##x] = #x,
- foreach_object
-#undef _
-};
-
-#define object_str(x) object_str[x]
-
-hc_object_type_t object_from_str(const char *object_str) {
-#define _(x) \
- if (strcasecmp(object_str, #x) == 0) \
- return OBJECT_##x; \
- else
- foreach_object
-#undef _
- return OBJECT_UNDEFINED;
-}
-
-const char *action_to_cmd_action(hc_action_t action) {
- switch (action) {
- case ACTION_CREATE:
- return "add";
- case ACTION_UPDATE:
- return "update";
- case ACTION_DELETE:
- return "remove";
- case ACTION_LIST:
- return "list";
- case ACTION_SET:
- return "set";
- case ACTION_SERVE:
- return "serve";
- case ACTION_STORE:
- return "store";
- case ACTION_CLEAR:
- return "clear";
- default:
- return "UNDEFINED";
- }
-}
-
-const char *parser_type_fmt(const parser_type_t *type) {
- switch (type->name) {
- case TYPENAME_INT:
- return TYPE_FMT_INT;
- case TYPENAME_UINT:
- return TYPE_FMT_UINT;
- case TYPENAME_STR:
- return TYPE_FMT_STRN(type->str.max_size);
- case TYPENAME_SYMBOLIC_OR_ID:
- return TYPE_FMT_SYMBOLIC_OR_ID;
- case TYPENAME_INTERFACE_NAME:
- return TYPE_FMT_INTERFACE_NAME;
- case TYPENAME_IP_ADDRESS:
- return TYPE_FMT_IP_ADDRESS;
- case TYPENAME_IP_PREFIX:
- return TYPE_FMT_IP_PREFIX;
- case TYPENAME_ON_OFF:
- return TYPE_FMT_ON_OFF;
- case TYPENAME_ENUM:
- return TYPE_FMT_ENUM;
- case TYPENAME_POLICY_STATE:
- return TYPE_FMT_POLICY_STATE;
- case TYPENAME_UNDEFINED:
- default:
- return NULL;
- }
-}
-
-int parser_type_func(const parser_type_t *type, void *src, void *dst,
- void *dst2, void *dst3) {
- ip_address_t addr;
- char *addr_str;
- char *len_str;
- int len, tmp, rc;
-
- switch (type->name) {
- case TYPENAME_INT:
- tmp = *(int *)src;
- if (tmp < type->sint.min || tmp > type->sint.max) {
- ERROR("Input number (%d) not inside range [%d, %d]", tmp,
- type->sint.min, type->sint.max);
- return -1;
- }
- *(int *)dst = *(int *)src;
- break;
- case TYPENAME_UINT:
- tmp = *(int *)src;
- if (tmp < type->uint.min || tmp > type->uint.max) {
- ERROR("Input number (%d) not inside range [%d, %d]", tmp,
- type->uint.min, type->uint.max);
- return -1;
- }
- *(unsigned *)dst = *(unsigned *)src;
- break;
- case TYPENAME_STR:
- rc = strcpy_s(dst, type->str.max_size, src);
- if (rc != EOK) {
- ERROR("Input string is too long");
- return -1;
- }
- break;
- case TYPENAME_IP_ADDRESS:
- rc = ip_address_pton((char *)src, &addr);
- if (rc < 0) {
- ERROR("Wrong IP address format");
- return -1;
- }
-
- *(ip_address_t *)dst = addr;
- *(int *)dst2 = ip_address_get_family((char *)src);
- break;
- case TYPENAME_ON_OFF:
- if (strcmp((char *)src, "off") == 0) {
- *(unsigned *)dst = 0;
- } else if (strcmp((char *)src, "on") == 0) {
- *(unsigned *)dst = 1;
- } else {
- ERROR("on/off are the only possible values");
- return -1;
- }
- break;
- case TYPENAME_IP_PREFIX:
- addr_str = strtok((char *)src, "/");
- len_str = strtok(NULL, " ");
- rc = ip_address_pton((char *)src, &addr);
- if (rc < 0) {
- ERROR("Wrong IP address format");
- return -1;
- }
- len = atoi(len_str);
-
- *(ip_address_t *)dst = addr;
- *(int *)dst2 = len;
- *(int *)dst3 = ip_address_get_family(addr_str);
- break;
- case TYPENAME_ENUM:
- /* Enum index from string */
- assert(type->enum_.from_str);
- *(int *)dst = type->enum_.from_str((char *)src);
- break;
- case TYPENAME_POLICY_STATE: {
- assert(IS_VALID_POLICY_TAG(type->policy_state.tag));
- policy_tag_t tag = type->policy_state.tag;
- /* Format string is "%ms" */
- const char *str = *(const char **)src;
- policy_tag_state_t *pts = ((policy_tag_state_t *)dst);
- pts[tag].disabled = (str[0] == '!') ? 1 : 0;
- pts[tag].state = policy_state_from_str(str + pts[tag].disabled);
- break;
- }
- case TYPENAME_UNDEFINED:
- default:
- ERROR("Unknown format");
- return -1;
- }
- return 0;
-}
-
-int parse_params(const command_parser_t *parser, const char *params_s,
- hc_command_t *command) {
- char fmt[1024];
- int n;
- size_t size = 0;
- char *pos = fmt;
- /* Update MAX_PARAMETERS accordingly in command.h */
- char sscanf_params[MAX_PARAMETERS][MAX_SCANF_PARAM_LEN];
-
- unsigned count = 0;
- for (unsigned i = 0; i < parser->nparams; i++) {
- const command_parameter_t *p = &parser->parameters[i];
- const char *_fmt = parser_type_fmt(&p->type);
- // printf(" _fmt=%s\n", _fmt);
- if (!_fmt) {
- WARN("Ignored parameter %s with unknown type formatter", p->name);
- continue;
- }
- n = snprintf(pos, 1024 - size, "%s", _fmt);
- pos += n;
-
- *pos = ' ';
- pos++;
-
- size += n + 1;
- count++;
- }
- *pos = '\0';
- DEBUG("parser format: %s", fmt);
-
- int ret = sscanf(params_s, fmt, sscanf_params[0], sscanf_params[1],
- sscanf_params[2], sscanf_params[3], sscanf_params[4],
- sscanf_params[5], sscanf_params[6], sscanf_params[7],
- sscanf_params[8], sscanf_params[9]);
- if (ret != parser->nparams) {
- ERROR("Parsing failed: check for string used where integer was expected");
- goto ERR;
- }
-
- for (unsigned i = 0; i < count; i++) {
- const command_parameter_t *p = &parser->parameters[i];
- if (parser_type_func(&p->type, sscanf_params[i],
- &command->object.as_uint8 + p->offset,
- &command->object.as_uint8 + p->offset2,
- &command->object.as_uint8 + p->offset3) < 0) {
- ERROR("Error during parsing of parameter '%s' value", p->name);
- goto ERR;
- }
- }
- return 0;
-
-ERR:
- return -1;
-}
-
-int parse(const char *cmd, hc_command_t *command) {
- int nparams = 0;
- char action_s[MAX_SCANF_PARAM_LEN];
- char object_s[MAX_SCANF_PARAM_LEN];
- char params_s[MAX_SCANF_PARAM_LEN];
-
- // if n = 2 later, params_s is uninitialized
- memset(params_s, 0, MAX_SCANF_PARAM_LEN * sizeof(char));
-
- errno = 0;
- int n = sscanf(cmd, "%s %s%[^\n]s", action_s, object_s, params_s);
- if ((n < 2) || (n > 3)) {
- if (errno != 0) perror("scanf");
- return -1;
- }
-
- command->action = action_from_str(action_s);
- command->object.type = object_from_str(object_s);
-
- if (strnlen_s(params_s, MAX_SCANF_PARAM_LEN) > 0) {
- for (char *ptr = params_s; (ptr = strchr(ptr, ' ')) != NULL; ptr++)
- nparams++;
- }
-
- /*
- * This checks is important even with 0 parameters as it checks whether the
- * command exists.
- */
- const command_parser_t *parser =
- command_search(command->action, command->object.type, nparams);
- if (!parser) {
- ERROR("Could not find parser for command '%s %s'", action_s, object_s);
- return -1;
- }
-
- if (strnlen_s(params_s, MAX_SCANF_PARAM_LEN) > 0) {
- if (parse_params(parser, params_s, command) < 0) return -1;
- }
-
- if (parser->post_hook) parser->post_hook(&command->object.as_uint8);
- return 0;
-}
-
-int help(const char *cmd) {
- int nparams = 1;
- char action_s[MAX_SCANF_PARAM_LEN];
- char object_s[MAX_SCANF_PARAM_LEN];
- char params_s[MAX_SCANF_PARAM_LEN];
- hc_object_type_t object = OBJECT_UNDEFINED;
- hc_action_t action = ACTION_UNDEFINED;
-
- int n = sscanf(cmd, "help %[^\n]s", params_s);
-
- // No arguments provided to the help command: just list available objects
- if (n != 1) goto CMD_LIST;
-
- // Count number of provided parameters
- for (char *ptr = params_s; (ptr = strchr(ptr, ' ')) != NULL; ptr++) nparams++;
- if (nparams > 2) {
- fprintf(stderr, "Error: too many arguments.\n");
- return -1;
- }
-
- // Object specified: list actions available for that object
- if (nparams == 1) {
- object = object_from_str(params_s);
- if (object == OBJECT_UNDEFINED) {
- fprintf(stderr, "Error: undefined object.\n");
- return -1;
- }
-
- goto CMD_LIST;
- }
-
- // Object and action specified: list detailed commands
- n = sscanf(params_s, "%s %[^\n]s", object_s, action_s);
- assert(n == 2);
- object = object_from_str(object_s);
- action = action_from_str(action_s);
- if (object == OBJECT_UNDEFINED || action == ACTION_UNDEFINED) {
- fprintf(stderr, "Error: undefined object and/or action.\n");
- return -1;
- }
-
-CMD_LIST:
- printf("Available commands:\n");
- command_list(object, action);
- return 0;
-}
-
-#if 0 // tests
-/* For the tests, we will need to test all non-compliant inputs */
-const char * cmds[] = {
- "add connection hicn conn1 8.8.8.8 127.0.0.1 eth0",
- "add connection udp <symbolic> <remote_ip> <port> <local_ip> <port> eth0",
- "add listener udp lst1 127.0.0.1 9695 eth0",
- //"add face",
- "add route 3 b001::/16 1",
- //"add punting",
- //"add strategy",
- "add policy b001::/16 webex require avoid prohibit !prohibit neutral !require prefer",
- "list connection", // need pluralize
- "list listener",
- "list face",
- "list route",
- "list punting",
- "list strategy",
- "list policy",
- "remove connection 1",
- "remove listener 1",
- //"remove face",
- "remove route 1 b001::/16",
- //"remove punting",
- //"remove policy",
- "set debug",
- "unset debug",
- "set strategy b001::/16 random", // related prefixes (10 max) ?
- "set strategy b001::/16 load_balancer",
- "set strategy b001::/16 low_latency",
- "set strategy b001::/16 replication",
- "set strategy b001::/16 bestpath",
- "set wldr <on|off> <connection_id>", // on-off vs unset
- "cache clear",
- "cache store on/off", // set/unset
- "cache serve on/off",
- "mapme enable on/off",
- "mapme discovery on/off",
- "mapme timescale 500ms",
- "mapme retx 500ms",
- "update connection conn1 WT",
-};
-
-#define array_size(x) sizeof(x) / sizeof(typeof(x[0]))
-int main()
-{
- for (unsigned i = 0; i < array_size(cmds); i++) {
- printf("PARSING [%d] %s\n", i, cmds[i]);
- if (parse(cmds[i]) < 0) {
- ERROR("Could not parse command: %s\n", cmds[i]);
- continue;
- }
- }
- exit(EXIT_SUCCESS);
-
-ERR:
- exit(EXIT_FAILURE);
-}
-#endif
diff --git a/hicn-light/src/hicn/config/parse.h b/hicn-light/src/hicn/config/parse.h
deleted file mode 100644
index 06269208a..000000000
--- a/hicn-light/src/hicn/config/parse.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef HICNLIGHT_PARSE_CMD
-#define HICNLIGHT_PARSE_CMD
-
-#include <hicn/ctrl/api.h>
-
-int parse(const char* cmd, hc_command_t* command);
-int help(const char* cmd);
-
-/**
- * @brief Convert the action enum to the action name used in the commands (e.g.
- * from ACTION_CREATE to "add").
- */
-const char* action_to_cmd_action(hc_action_t action);
-
-#endif /* HICNLIGHT_PARSE_CMD */
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
+}
diff --git a/hicn-light/src/hicn/io/base.c b/hicn-light/src/hicn/io/base.c
index cd7362956..38d36efbe 100644
--- a/hicn-light/src/hicn/io/base.c
+++ b/hicn-light/src/hicn/io/base.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:
@@ -42,7 +42,7 @@ ssize_t io_read_single_fd(int fd, msgbuf_t *msgbuf, address_t *address) {
return -1;
}
- msgbuf->length = (unsigned int)n;
+ msgbuf_set_len(msgbuf, (size_t)n);
*address = ADDRESS_ANY(AF_UNSPEC, 0); // XXX placeholder, see hicn.c
}
@@ -50,12 +50,18 @@ ssize_t io_read_single_fd(int fd, msgbuf_t *msgbuf, address_t *address) {
}
ssize_t io_read_single_socket(int fd, msgbuf_t *msgbuf, address_t *address) {
- struct sockaddr_storage *sa = &address->as_ss;
+ struct sockaddr *sa = &(address->as_sa);
socklen_t sa_len = sizeof(sa);
uint8_t *packet = msgbuf_get_packet(msgbuf);
ssize_t n = recvfrom(fd, packet, MTU, 0, (struct sockaddr *)sa, &sa_len);
- msgbuf->length = (unsigned int)n;
+ msgbuf_set_len(msgbuf, (size_t)n);
+
+#ifdef __APPLE__
+ // set __uint8_t sin_len to 0
+ uint8_t *ptr = (uint8_t *)sa;
+ *ptr = 0x0;
+#endif /* __APPLE__ */
return n;
}
@@ -92,6 +98,7 @@ ssize_t io_read_batch_socket(int fd, msgbuf_t **msgbuf, address_t **address,
for (;;) {
n = recvmmsg(fd, msghdr, batch_size, /* flags */ 0,
/* timeout */ NULL);
+ // INFO("Got n=%d messages", n);
if (n == 0) return 0;
if (n < 0) {
if (errno == EINTR) continue; // XXX was break;
@@ -112,7 +119,7 @@ ssize_t io_read_batch_socket(int fd, msgbuf_t **msgbuf, address_t **address,
*/
for (int i = 0; i < n; i++) {
struct mmsghdr *msg = &msghdr[i];
- msgbuf[i]->length = msg->msg_len;
+ msgbuf_set_len(msgbuf[i], msg->msg_len);
memcpy(address[i], msg->msg_hdr.msg_name, msg->msg_hdr.msg_namelen);
}
diff --git a/hicn-light/src/hicn/io/hicn.c b/hicn-light/src/hicn/io/hicn.c
index d019a49c1..c5859fbe3 100644
--- a/hicn-light/src/hicn/io/hicn.c
+++ b/hicn-light/src/hicn/io/hicn.c
@@ -433,8 +433,8 @@ static bool connection_hicn_send(connection_t *connection, msgbuf_t *msgbuf,
// return 0;
//}
//
-static int connection_hicn_send_packet(const connection_t *connection,
- const uint8_t *packet, size_t size) {
+static bool connection_hicn_send_packet(const connection_t *connection,
+ const uint8_t *packet, size_t size) {
assert(connection);
assert(packet);
diff --git a/hicn-light/src/hicn/io/tcp.c b/hicn-light/src/hicn/io/tcp.c
index 50591c3fc..a924b6330 100644
--- a/hicn-light/src/hicn/io/tcp.c
+++ b/hicn-light/src/hicn/io/tcp.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:
@@ -37,7 +37,6 @@
#include "../core/listener_vft.h"
#include "../core/msgbuf.h"
#include "../core/forwarder.h"
-#include "../core/messageHandler.h"
// 128 KB output queue
#define OUTPUT_QUEUE_BYTES (128 * 1024)
@@ -336,8 +335,8 @@ static bool connection_tcp_send(connection_t *connection, msgbuf_t *msgbuf,
return true;
}
-static int connection_tcp_send_packet(const connection_t *connection,
- const uint8_t *packet, size_t size) {
+static bool connection_tcp_send_packet(const connection_t *connection,
+ const uint8_t *packet, size_t size) {
/* Not implemented for local connections */
// XXX shall we set the pointer to NULL and add a check ?
diff --git a/hicn-light/src/hicn/io/udp.c b/hicn-light/src/hicn/io/udp.c
index 149d53aea..b06ee7bce 100644
--- a/hicn-light/src/hicn/io/udp.c
+++ b/hicn-light/src/hicn/io/udp.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:
@@ -58,7 +58,6 @@
#include "../core/forwarder.h"
#include "../core/listener.h"
#include "../core/listener_vft.h"
-#include "../core/messageHandler.h"
#include "../core/msgbuf.h"
//#include "../hicn-light/config.h"
@@ -336,11 +335,12 @@ static int connection_udp_initialize(connection_t *connection) {
static void connection_udp_finalize(connection_t *connection) {
assert(connection);
assert(connection->type == FACE_TYPE_UDP);
-
+#ifdef __linux__
connection_udp_data_t *data = connection->data;
assert(data);
ring_free(data->ring);
+#endif /* __linux__ */
}
static bool connection_udp_flush(connection_t *connection) {
@@ -374,7 +374,7 @@ SEND:
msgbuf_t *msgbuf = msgbuf_pool_at(msgbuf_pool, msgbuf_id);
// update path label
- if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA) {
+ if (msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA) {
msgbuf_update_pathlabel(msgbuf, connection_get_id(connection));
connection->stats.data.tx_pkts++;
@@ -460,7 +460,7 @@ static bool connection_udp_send(connection_t *connection, msgbuf_t *msgbuf,
#endif /* __linux__ */
/* Send one */
// update the path label befor send the packet
- if (msgbuf_get_type(msgbuf) == MSGBUF_TYPE_DATA) {
+ if (msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_DATA) {
msgbuf_update_pathlabel(msgbuf, connection_get_id(connection));
connection->stats.data.tx_pkts++;
@@ -478,8 +478,9 @@ static bool connection_udp_send(connection_t *connection, msgbuf_t *msgbuf,
return false;
} else {
// this print is for debugging
- printf("Incorrect write length %zd, expected %u: (%d) %s\n",
- writeLength, msgbuf_get_len(msgbuf), errno, strerror(errno));
+ printf("Incorrect write length %zd, expected %lu: (%d) %s\n",
+ writeLength, (long unsigned int)msgbuf_get_len(msgbuf), errno,
+ strerror(errno));
return false;
}
}
@@ -532,8 +533,8 @@ connection_udp_sendv(const connection_t * connection, struct iovec * iov,
}
#endif
-static int connection_udp_send_packet(const connection_t *connection,
- const uint8_t *packet, size_t size) {
+static bool connection_udp_send_packet(const connection_t *connection,
+ const uint8_t *packet, size_t size) {
assert(connection);
assert(packet);
@@ -555,16 +556,16 @@ static int connection_udp_send_packet(const connection_t *connection,
ssize_t n = send(connection->fd, packet, size, 0);
if (n < 0) {
perror("sendto");
- return -1;
+ return false;
}
#else
const address_t *remote = connection_get_remote(connection);
ssize_t n = sendto(connection->fd, packet, size, 0, address_sa(remote),
address_socklen(remote));
- if (n < 0) return -1;
+ if (n < 0) return false;
#endif
- return 0;
+ return true;
}
#define connection_udp_read_single \
diff --git a/hicn-light/src/hicn/socket/api.c b/hicn-light/src/hicn/socket/api.c
index e39ebf4b5..db377aecd 100644
--- a/hicn-light/src/hicn/socket/api.c
+++ b/hicn-light/src/hicn/socket/api.c
@@ -43,7 +43,7 @@ static hicn_conf_t hicn_default_conf = {
struct ip_rule_state_ {
char tun_name[IF_NAMESIZE];
- ip_prefix_t prefix;
+ hicn_ip_prefix_t prefix;
uint32_t table_id;
uint8_t priority;
uint8_t address_family;
@@ -193,7 +193,7 @@ int hicn_socket_cmp(hicn_socket_t *a, hicn_socket_t *b) {
return b->fd - a->fd;
}
-ip_prefix_t *hicn_socket_get_src_ip(hicn_socket_t *socket) {
+hicn_ip_prefix_t *hicn_socket_get_src_ip(hicn_socket_t *socket) {
if (socket->type != HS_CONNECTION) {
return NULL;
}
@@ -241,7 +241,8 @@ int hicn_set_local_endpoint(hicn_socket_t *socket, const char *local_ip_address,
*/
/* Copy the local IP address inside the connection */
- rc = ip_prefix_pton(local_ip_address, &socket->connection.tun_ip_address);
+ rc =
+ hicn_ip_prefix_pton(local_ip_address, &socket->connection.tun_ip_address);
if (rc < 0) {
rc = HICN_SOCKET_ERROR_SOCKET_LOCAL_REPR;
goto end;
@@ -251,14 +252,14 @@ end:
return rc;
}
-int hicn_get_local_address(const ip_prefix_t *remote_address,
- ip_prefix_t *local_address) {
+int hicn_get_local_address(const hicn_ip_prefix_t *remote_address,
+ hicn_ip_prefix_t *local_address) {
int rc = 0;
uint32_t interface_id;
char remote_address_str[INET_MAX_ADDRSTRLEN + 4];
- rc = ip_prefix_ntop_short(remote_address, remote_address_str,
- sizeof(remote_address_str));
+ rc = hicn_ip_prefix_ntop_short(remote_address, remote_address_str,
+ sizeof(remote_address_str));
if (rc < 0) {
rc = HICN_SOCKET_ERROR_BIND_REMOTE_REPR;
goto ERR;
@@ -289,7 +290,7 @@ ERR:
int hicn_set_remote_endpoint(hicn_socket_t *socket,
const char *remote_ip_address) {
int af, rc = HICN_SOCKET_ERROR_NONE;
- ip_prefix_t addr;
+ hicn_ip_prefix_t addr;
af = get_addr_family(remote_ip_address);
if ((af != AF_INET6) && (af != AF_INET)) {
@@ -297,7 +298,7 @@ int hicn_set_remote_endpoint(hicn_socket_t *socket,
}
/* Bind local endpoint if not done yet */
- if (ip_prefix_empty(&socket->connection.tun_ip_address)) {
+ if (hicn_ip_prefix_empty(&socket->connection.tun_ip_address)) {
char local_ip_address[INET_MAX_ADDRSTRLEN + 4];
/* Local interface id */
@@ -327,8 +328,8 @@ int hicn_set_remote_endpoint(hicn_socket_t *socket,
/////
/* Convert to representation format */
- rc =
- ip_prefix_ntop_short(&addr, local_ip_address, sizeof(local_ip_address));
+ rc = hicn_ip_prefix_ntop_short(&addr, local_ip_address,
+ sizeof(local_ip_address));
if (rc < 0) {
rc = HICN_SOCKET_ERROR_BIND_REMOTE_REPR;
goto ERR;
@@ -445,8 +446,8 @@ int hicn_listen(hicn_socket_helper_t *hicn, int fd, const char *prefix) {
return rc;
}
- ip_prefix_t ip_prefix;
- rc = ip_prefix_pton(prefix, &ip_prefix);
+ hicn_ip_prefix_t hicn_ip_prefix;
+ rc = hicn_ip_prefix_pton(prefix, &hicn_ip_prefix);
if (rc < 0) {
return rc;
}
@@ -457,7 +458,7 @@ int hicn_listen(hicn_socket_helper_t *hicn, int fd, const char *prefix) {
if (punting_table_id == -1) punting_table_id = socket->connection.table_id;
- rc = ops.add_prio_rule(&ip_prefix, ip_prefix.family, 0,
+ rc = ops.add_prio_rule(&hicn_ip_prefix, hicn_ip_prefix.family, 0,
socket->connection.table_id);
if (rc < 0) {
return rc;
@@ -467,8 +468,8 @@ int hicn_listen(hicn_socket_helper_t *hicn, int fd, const char *prefix) {
sizeof(rules_to_remove[rules_counter].tun_name), "NONE");
if (rc != EOK) return -1;
- rules_to_remove[rules_counter].prefix = ip_prefix;
- rules_to_remove[rules_counter].address_family = ip_prefix.family;
+ rules_to_remove[rules_counter].prefix = hicn_ip_prefix;
+ rules_to_remove[rules_counter].address_family = hicn_ip_prefix.family;
rules_to_remove[rules_counter].table_id = socket->connection.table_id;
rules_to_remove[rules_counter].priority = 0;
++rules_counter;
diff --git a/hicn-light/src/hicn/socket/api.h b/hicn-light/src/hicn/socket/api.h
index a0356e035..3caf9ef1e 100644
--- a/hicn-light/src/hicn/socket/api.h
+++ b/hicn-light/src/hicn/socket/api.h
@@ -83,7 +83,7 @@ typedef struct hicn_socket_s {
union {
struct {
- ip_prefix_t tun_ip_address;
+ hicn_ip_prefix_t tun_ip_address;
uint32_t interface_id;
/* ID of the corresponding table : avoid default values of 0, 32766 and
@@ -162,8 +162,8 @@ void hicn_free(hicn_socket_helper_t *hicn);
*
* @return 0 in case of success, -1 otherwise.
*/
-int hicn_get_local_address(const ip_prefix_t *remote_address,
- ip_prefix_t *local_address);
+int hicn_get_local_address(const hicn_ip_prefix_t *remote_address,
+ hicn_ip_prefix_t *local_address);
/* hICN socket */
diff --git a/hicn-light/src/hicn/socket/ops.h b/hicn-light/src/hicn/socket/ops.h
index 1bee7c6f6..854b0c461 100644
--- a/hicn-light/src/hicn/socket/ops.h
+++ b/hicn-light/src/hicn/socket/ops.h
@@ -17,10 +17,10 @@ typedef struct {
int (*get_output_ifid)(const char *ip_address, uint8_t address_family,
uint32_t *interface_id);
int (*get_ip_addr)(uint32_t interface_id, uint8_t address_family,
- ip_prefix_t *ip_address);
- int (*set_ip_addr)(uint32_t interface_id, ip_prefix_t *ip_address);
+ hicn_ip_prefix_t *ip_address);
+ int (*set_ip_addr)(uint32_t interface_id, hicn_ip_prefix_t *ip_address);
int (*up_if)(uint32_t interface_id);
- int (*add_in_route_table)(const ip_prefix_t *prefix,
+ int (*add_in_route_table)(const hicn_ip_prefix_t *prefix,
const uint32_t interface_id,
const uint8_t table_id);
int (*add_in_route_table_s)(const char *prefix, const uint32_t interface_id,
@@ -30,23 +30,23 @@ typedef struct {
const uint8_t table_id, int default_route);
int (*del_out_route)(const char *gateway, const uint8_t address_family,
const uint8_t table_id);
- int (*del_lo_route)(const ip_prefix_t *ip_address);
+ int (*del_lo_route)(const hicn_ip_prefix_t *ip_address);
int (*add_rule)(const char *interface_name, const uint8_t address_family,
const uint8_t table_id);
int (*del_rule)(const char *interface_name, const uint8_t address_family,
const uint8_t table_id);
- int (*add_neigh_proxy)(const ip_prefix_t *ip_address,
+ int (*add_neigh_proxy)(const hicn_ip_prefix_t *ip_address,
const uint32_t interface_id);
- int (*add_prio_rule)(const ip_prefix_t *ip_address,
+ int (*add_prio_rule)(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority,
const uint8_t table_id);
- int (*add_lo_prio_rule)(const ip_prefix_t *ip_address,
+ int (*add_lo_prio_rule)(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family,
const uint32_t priority);
- int (*del_prio_rule)(const ip_prefix_t *ip_address,
+ int (*del_prio_rule)(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority,
const uint8_t table_id);
- int (*del_lo_prio_rule)(const ip_prefix_t *ip_address,
+ int (*del_lo_prio_rule)(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family,
const uint32_t priority);
} hicn_socket_ops_t;
diff --git a/hicn-light/src/hicn/socket/ops_linux.c b/hicn-light/src/hicn/socket/ops_linux.c
index d741fd2e6..a3675e929 100644
--- a/hicn-light/src/hicn/socket/ops_linux.c
+++ b/hicn-light/src/hicn/socket/ops_linux.c
@@ -62,13 +62,13 @@ int _nl_get_output_ifid(const char *ip_address, uint8_t address_family,
* @see getifaddrs
*/
int _nl_get_ip_addr(uint32_t interface_id, uint8_t address_family,
- ip_prefix_t *ip_address);
+ hicn_ip_prefix_t *ip_address);
-int _nl_set_ip_addr(uint32_t interface_id, ip_prefix_t *ip_address);
+int _nl_set_ip_addr(uint32_t interface_id, hicn_ip_prefix_t *ip_address);
int _nl_up_if(uint32_t interface_id);
-int _nl_add_in_route_table(const ip_prefix_t *prefix,
+int _nl_add_in_route_table(const hicn_ip_prefix_t *prefix,
const uint32_t interface_id, const uint8_t table_id);
int _nl_add_in_route_table_s(const char *prefix, const uint32_t interface_id,
const uint8_t table_id);
@@ -79,25 +79,25 @@ int _nl_add_out_route(const char *gateway, const uint8_t address_family,
int _nl_del_out_route(const char *gateway, const uint8_t address_family,
const uint8_t table_id);
-int _nl_del_lo_route(const ip_prefix_t *ip_address);
+int _nl_del_lo_route(const hicn_ip_prefix_t *ip_address);
int _nl_add_rule(const char *interface_name, const uint8_t address_family,
const uint8_t table_id);
int _nl_del_rule(const char *interface_name, const uint8_t address_family,
const uint8_t table_id);
-int _nl_add_neigh_proxy(const ip_prefix_t *ip_address,
+int _nl_add_neigh_proxy(const hicn_ip_prefix_t *ip_address,
const uint32_t interface_id);
-int _nl_add_prio_rule(const ip_prefix_t *ip_address,
+int _nl_add_prio_rule(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority,
const uint8_t table_id);
-int _nl_add_lo_prio_rule(const ip_prefix_t *ip_address,
+int _nl_add_lo_prio_rule(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority);
-int _nl_del_prio_rule(const ip_prefix_t *ip_address,
+int _nl_del_prio_rule(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority,
const uint8_t table_id);
-int _nl_del_lo_prio_rule(const ip_prefix_t *ip_address,
+int _nl_del_lo_prio_rule(const hicn_ip_prefix_t *ip_address,
const uint8_t address_family, const uint32_t priority);
#endif /* HICN_NETLINK_H */
@@ -533,7 +533,7 @@ ERR:
}
int _nl_get_ip_addr(uint32_t interface_id, uint8_t address_family,
- ip_prefix_t *prefix) {
+ hicn_ip_prefix_t *prefix) {
char buffer[BUFSIZE];
struct nlmsghdr *hdr = (struct nlmsghdr *)buffer;
size_t n;
@@ -602,7 +602,7 @@ ERR_SOCKET:
return HICN_SOCKET_ERROR_UNSPEC;
}
-int _nl_set_ip_addr(uint32_t interface_id, ip_prefix_t *prefix) {
+int _nl_set_ip_addr(uint32_t interface_id, hicn_ip_prefix_t *prefix) {
char buffer[BUFSIZE];
struct nlmsghdr *hdr = (struct nlmsghdr *)buffer;
size_t n;
@@ -622,14 +622,15 @@ int _nl_set_ip_addr(uint32_t interface_id, ip_prefix_t *prefix) {
.payload.ifa_index = interface_id};
/* Set attributes = length/type/value */
- struct rtattr ifa_address = {RTA_LENGTH(ip_address_len(prefix->family)),
+ struct rtattr ifa_address = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
IFA_ADDRESS};
- const void *address = ip_address_get_buffer(&prefix->address, prefix->family);
+ const void *address =
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR_ADDRESS;
const struct iovec iov[] = {
{&msg, sizeof(msg)},
{&ifa_address, sizeof(ifa_address)},
- {(void *)address, ip_address_len(prefix->family)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
};
msg.hdr.nlmsg_len = iov_length(iov, ARRAY_SIZE(iov));
@@ -967,7 +968,7 @@ ERR_SOCKET:
* ip route del 1:2::2 dev lo table local
*
*/
-int _nl_del_lo_route(const ip_prefix_t *prefix) {
+int _nl_del_lo_route(const hicn_ip_prefix_t *prefix) {
char buffer[BUFSIZE];
struct nlmsghdr *hdr = (struct nlmsghdr *)buffer;
size_t n;
@@ -993,17 +994,20 @@ int _nl_del_lo_route(const ip_prefix_t *prefix) {
/* Set attribute = length/type/value */
uint32_t one = 1;
- struct rtattr a_dst = {RTA_LENGTH(ip_address_len(prefix->family)), RTA_DST};
+ struct rtattr a_dst = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
+ RTA_DST};
struct rtattr a_ifid_lo = {RTA_LENGTH(sizeof(uint32_t)), RTA_OIF};
- const void *address = ip_address_get_buffer(&prefix->address, prefix->family);
+ const void *address =
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR;
- const struct iovec iov[] = {{&msg, sizeof(msg)},
- /* Ip address */
- {&a_dst, sizeof(a_dst)},
- {(void *)address, ip_address_len(prefix->family)},
- /* Interface id */
- {&a_ifid_lo, sizeof(a_ifid_lo)},
- {&one, sizeof(one)}};
+ const struct iovec iov[] = {
+ {&msg, sizeof(msg)},
+ /* Ip address */
+ {&a_dst, sizeof(a_dst)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
+ /* Interface id */
+ {&a_ifid_lo, sizeof(a_ifid_lo)},
+ {&one, sizeof(one)}};
msg.hdr.nlmsg_len = iov_length(iov, ARRAY_SIZE(iov));
fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
@@ -1131,7 +1135,7 @@ ERR_SOCKET:
* ip -6 neigh add proxy 1:2::2 dev hicnc-cons-eth0 2>&1 | grep nei
*
*/
-int _nl_add_neigh_proxy(const ip_prefix_t *prefix,
+int _nl_add_neigh_proxy(const hicn_ip_prefix_t *prefix,
const uint32_t interface_id) {
/* Buffer for holding the response, with appropriate casting on the header */
char buffer[BUFSIZE];
@@ -1156,9 +1160,11 @@ int _nl_add_neigh_proxy(const ip_prefix_t *prefix,
};
/* Message attributes = length/type/value */
- struct rtattr a_dst = {RTA_LENGTH(ip_address_len(prefix->family)), NDA_DST};
+ struct rtattr a_dst = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
+ NDA_DST};
- const void *address = ip_address_get_buffer(&prefix->address, prefix->family);
+ const void *address =
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR;
/* Iovec describing the packets */
@@ -1166,7 +1172,7 @@ int _nl_add_neigh_proxy(const ip_prefix_t *prefix,
{&msg, sizeof(msg)},
/* Ip address */
{&a_dst, sizeof(a_dst)},
- {(void *)address, ip_address_len(prefix->family)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
};
msg.hdr.nlmsg_len = iov_length(iov, ARRAY_SIZE(iov));
@@ -1204,7 +1210,7 @@ ERR:
/* ip -6 route add 0:1::/64 dev hicn-if0 table 100 */
/* ip -6 route add 0:2::/64 dev hicn-if1 table 100 */
-int _nl_add_in_route_table(const ip_prefix_t *prefix,
+int _nl_add_in_route_table(const hicn_ip_prefix_t *prefix,
const uint32_t interface_id,
const uint8_t table_id) {
/* Buffer for holding the response, with appropriate casting on the header */
@@ -1236,10 +1242,12 @@ int _nl_add_in_route_table(const ip_prefix_t *prefix,
};
/* Message attributes = length/type/value */
- struct rtattr a_dst = {RTA_LENGTH(ip_address_len(prefix->family)), RTA_DST};
+ struct rtattr a_dst = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
+ RTA_DST};
struct rtattr a_oif = {RTA_LENGTH(sizeof(uint32_t)), RTA_OIF};
- const void *address = ip_address_get_buffer(&prefix->address, prefix->family);
+ const void *address =
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR;
/* Iovec describing the packets */
@@ -1247,7 +1255,7 @@ int _nl_add_in_route_table(const ip_prefix_t *prefix,
{&msg, sizeof(msg)},
/* Destination prefix / ip address */
{&a_dst, sizeof(a_dst)},
- {(void *)address, ip_address_len(prefix->family)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
/* Output interface */
{&a_oif, sizeof(a_oif)},
{(void *)&interface_id, sizeof(uint32_t)},
@@ -1291,9 +1299,9 @@ ERR:
int _nl_add_in_route_table_s(const char *prefix, const uint32_t interface_id,
const uint8_t table_id) {
int rc;
- ip_prefix_t ip_address;
+ hicn_ip_prefix_t ip_address;
- rc = ip_prefix_pton(prefix, &ip_address);
+ rc = hicn_ip_prefix_pton(prefix, &ip_address);
if (rc < 0) {
return rc;
}
@@ -1306,7 +1314,7 @@ int _nl_add_in_route_s(const char *prefix, const uint32_t interface_id) {
}
/* ip -6 rule add from b001::/16 prio 0 table 100 */
-int _nl_add_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
+int _nl_add_prio_rule(const hicn_ip_prefix_t *prefix, uint8_t address_family,
const uint32_t priority, const uint8_t table_id) {
/* Buffer for holding the response, with appropriate casting on the header */
char buffer[BUFSIZE];
@@ -1341,18 +1349,19 @@ int _nl_add_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
if (prefix) {
/* Message attributes = length/type/value */
- struct rtattr a_src = {RTA_LENGTH(ip_address_len(prefix->family)), FRA_SRC};
+ struct rtattr a_src = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
+ FRA_SRC};
struct rtattr a_prio = {RTA_LENGTH(sizeof(uint32_t)), FRA_PRIORITY};
const void *address =
- ip_address_get_buffer(&prefix->address, prefix->family);
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR;
/* Iovec describing the packets */
const struct iovec iov[] = {
{&msg, sizeof(msg)},
/* Source prefix / prefix */
{&a_src, sizeof(a_src)},
- {(void *)address, ip_address_len(prefix->family)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
/* Priority */
{&a_prio, sizeof(a_prio)},
{(void *)&priority, sizeof(uint32_t)},
@@ -1403,13 +1412,13 @@ ERR:
return HICN_SOCKET_ERROR_UNSPEC;
}
-int _nl_add_lo_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
+int _nl_add_lo_prio_rule(const hicn_ip_prefix_t *prefix, uint8_t address_family,
const uint32_t priority) {
return _nl_add_prio_rule(prefix, address_family, priority, RT_TABLE_LOCAL);
}
/* ip -6 rule del from all prio 0 table local */
-int _nl_del_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
+int _nl_del_prio_rule(const hicn_ip_prefix_t *prefix, uint8_t address_family,
const uint32_t priority, const uint8_t table_id) {
/* Buffer for holding the response, with appropriate casting on the header */
char buffer[BUFSIZE];
@@ -1444,11 +1453,12 @@ int _nl_del_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
/* Message attributes = length/type/value */
if (prefix) {
- struct rtattr a_src = {RTA_LENGTH(ip_address_len(prefix->family)), FRA_SRC};
+ struct rtattr a_src = {RTA_LENGTH(hicn_ip_address_len(prefix->family)),
+ FRA_SRC};
struct rtattr a_prio = {RTA_LENGTH(sizeof(uint32_t)), FRA_PRIORITY};
const void *address =
- ip_address_get_buffer(&prefix->address, prefix->family);
+ hicn_ip_address_get_buffer(&prefix->address, prefix->family);
if (!address) goto ERR;
/* Iovec describing the packets */
@@ -1456,7 +1466,7 @@ int _nl_del_prio_rule(const ip_prefix_t *prefix, uint8_t address_family,
{&msg, sizeof(msg)},
/* Source prefix / prefix */
{&a_src, sizeof(a_src)},
- {(void *)address, ip_address_len(prefix->family)},
+ {(void *)address, hicn_ip_address_len(prefix->family)},
/* Priority */
{&a_prio, sizeof(a_prio)},
{(void *)&priority, sizeof(uint32_t)},
@@ -1509,8 +1519,8 @@ ERR:
return HICN_SOCKET_ERROR_UNSPEC;
}
-int _nl_del_lo_prio_rule(const ip_prefix_t *ip_address, uint8_t address_family,
- const uint32_t priority) {
+int _nl_del_lo_prio_rule(const hicn_ip_prefix_t *ip_address,
+ uint8_t address_family, const uint32_t priority) {
return _nl_del_prio_rule(ip_address, address_family, priority,
RT_TABLE_LOCAL);
}
diff --git a/hicn-light/src/hicn/strategies/CMakeLists.txt b/hicn-light/src/hicn/strategies/CMakeLists.txt
index 15ae93fea..434106a44 100644
--- a/hicn-light/src/hicn/strategies/CMakeLists.txt
+++ b/hicn-light/src/hicn/strategies/CMakeLists.txt
@@ -13,7 +13,6 @@
list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/load_balancer.h
- ${CMAKE_CURRENT_SOURCE_DIR}/low_latency.h
${CMAKE_CURRENT_SOURCE_DIR}/random.h
${CMAKE_CURRENT_SOURCE_DIR}/replication.h
${CMAKE_CURRENT_SOURCE_DIR}/best_path.h
@@ -23,7 +22,6 @@ list(APPEND HEADER_FILES
list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/load_balancer.c
- ${CMAKE_CURRENT_SOURCE_DIR}/low_latency.c
${CMAKE_CURRENT_SOURCE_DIR}/random.c
${CMAKE_CURRENT_SOURCE_DIR}/replication.c
${CMAKE_CURRENT_SOURCE_DIR}/best_path.c
diff --git a/hicn-light/src/hicn/strategies/best_path.c b/hicn-light/src/hicn/strategies/best_path.c
index 35a07c43f..9223cc8ac 100644
--- a/hicn-light/src/hicn/strategies/best_path.c
+++ b/hicn-light/src/hicn/strategies/best_path.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:
@@ -88,8 +88,20 @@ static void bestpath_update_remote_node(strategy_entry_t *entry,
strategy_state_t *state = &entry->state.bestpath;
strategy_bestpath_options_t *options = &entry->options.bestpath;
off_t offset = nexthops_find(nexthops, state->best_nexthop);
+
+ /* Backup flags and cur_len: because our code is called from
+ * strategy_on_data / check_stop_probing / stop_probing
+ * which does not expect the nexthop flags to be modified.
+ */
+ uint_fast32_t flags = nexthops->flags;
+ size_t cur_len = nexthops_get_curlen(nexthops);
+
nexthops_select(nexthops, offset);
update_remote_node_paths(nexthops, entry->forwarder, options->local_prefixes);
+
+ /* Restore flags & curlen */
+ nexthops->flags = flags;
+ nexthops->cur_elts = cur_len;
}
// probing functions
@@ -104,9 +116,8 @@ static void start_probing(strategy_entry_t *entry) {
static void stop_probing(strategy_entry_t *entry, nexthops_t *nexthops) {
strategy_state_t *state = &entry->state.bestpath;
- nexthop_t best_nexthop, nexthop;
+ nexthop_t best_nexthop;
best_nexthop = state->best_nexthop;
- unsigned i;
unsigned int min_cost = ~0;
unsigned current_nexthop_cost = ~0;
@@ -164,8 +175,6 @@ static void send_probes(strategy_entry_t *entry, nexthops_t *nexthops,
const msgbuf_t *msgbuf) {
strategy_state_t *state = &entry->state.bestpath;
- unsigned i;
- nexthop_t nexthop;
bool sent_max_probes = false;
nexthops_enumerate(nexthops, i, nexthop, {
if (get_sent_probes(nexthop_state(nexthops, i)) < MAX_PROBES) {
@@ -241,6 +250,7 @@ static nexthops_t *strategy_bestpath_lookup_nexthops(strategy_entry_t *entry,
strategy_state_t *state = &entry->state.bestpath;
off_t best_nexthop_offset = nexthops_find(nexthops, state->best_nexthop);
+ // TODO explain the purpose of this test
if (nexthops_len == 1) {
nexthop_t nh = nexthops_get_one(nexthops);
if (state->best_nexthop != nh) {
@@ -265,7 +275,7 @@ static nexthops_t *strategy_bestpath_lookup_nexthops(strategy_entry_t *entry,
// send a probe for each interest received
send_probes(entry, nexthops, msgbuf);
- uint32_t suffix = name_GetSuffix(msgbuf_get_name(msgbuf));
+ uint32_t suffix = hicn_name_get_suffix(msgbuf_get_name(msgbuf));
if (suffix >= MIN_PROBE_SUFFIX && suffix <= MAX_PROBE_SUFFIX) {
// this packet is a probe from the transport, so register it
Ticks time = get_probe_send_time(state->pg, suffix);
@@ -302,7 +312,7 @@ static int strategy_bestpath_on_data(strategy_entry_t *entry,
strategy_state_t *state = &entry->state.bestpath;
if (state->probing_state == PROBING_OFF) return 0;
- uint32_t seq = name_GetSuffix(msgbuf_get_name(msgbuf));
+ uint32_t seq = hicn_name_get_suffix(msgbuf_get_name(msgbuf));
if (seq >= MIN_PROBE_SUFFIX && seq <= MAX_PROBE_SUFFIX) {
if (pitEntryCreation != 0) {
// this is not a probe sent by the forwader. do not use it in the probing
@@ -311,7 +321,6 @@ static int strategy_bestpath_on_data(strategy_entry_t *entry,
return 0;
}
- unsigned nexthop, i;
Ticks send_time = get_probe_send_time(state->pg, seq);
if (send_time != 0) {
Ticks rtt = ticks_now() - send_time;
diff --git a/hicn-light/src/hicn/strategies/load_balancer.c b/hicn-light/src/hicn/strategies/load_balancer.c
index 709efcf23..0e1a170f7 100644
--- a/hicn-light/src/hicn/strategies/load_balancer.c
+++ b/hicn-light/src/hicn/strategies/load_balancer.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:
@@ -58,8 +58,6 @@ static inline void update_state_dec(nexthop_state_t *state) {
}
static inline void reset_all(nexthops_t *nexthops) {
- unsigned i;
- nexthop_t nexthop;
nexthops_enumerate(nexthops, i, nexthop, {
(void)nexthop;
nexthops->state[i].load_balancer = NEXTHOP_STATE_INIT;
@@ -95,9 +93,9 @@ static int strategy_load_balancer_remove_nexthop(strategy_entry_t *entry,
static nexthops_t *strategy_load_balancer_lookup_nexthops(
strategy_entry_t *entry, nexthops_t *nexthops, const msgbuf_t *msgbuf) {
+ if (nexthops_get_curlen(nexthops) == 0) return nexthops;
/* Compute the sum of weights of potential next hops */
double sum = 0;
- unsigned i, nexthop;
nexthops_enumerate(nexthops, i, nexthop, {
(void)nexthop;
sum += nexthops_state(nexthops, i).load_balancer.weight;
@@ -125,10 +123,7 @@ static int strategy_load_balancer_on_timeout(
* nexthops, we can allow for linear search that will be very efficient
* CPU-wise.
*/
- nexthop_t timeout_nexthop;
nexthops_foreach(timeout_nexthops, timeout_nexthop, {
- nexthop_t nexthop;
- unsigned i;
nexthops_enumerate(nexthops, i, nexthop, {
if (nexthop == timeout_nexthop)
update_state_dec(nexthop_state(nexthops, i));
diff --git a/hicn-light/src/hicn/strategies/local_prefixes.c b/hicn-light/src/hicn/strategies/local_prefixes.c
index 23d72ae80..25927ac69 100644
--- a/hicn-light/src/hicn/strategies/local_prefixes.c
+++ b/hicn-light/src/hicn/strategies/local_prefixes.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,13 +16,12 @@
#include "local_prefixes.h"
#include <hicn/core/forwarder.h>
#include <hicn/core/nexthops.h>
-#include <hicn/core/name.h>
#include <hicn/core/mapme.h>
#define MAX_PREFIXES 10
struct local_prefixes_s {
- Name local_prefixes[MAX_PREFIXES];
+ hicn_prefix_t local_prefixes[MAX_PREFIXES];
unsigned len;
};
@@ -38,9 +37,10 @@ unsigned local_prefixes_get_len(local_prefixes_t *prefixes) {
return prefixes->len;
}
-bool contain_prefix(local_prefixes_t *prefixes, Name *name) {
+bool contain_prefix(const local_prefixes_t *prefixes,
+ const hicn_prefix_t *prefix) {
for (unsigned i = 0; i < prefixes->len; i++) {
- if (name_Equals(&(prefixes->local_prefixes[i]), name)) return true;
+ if (hicn_prefix_equals(&(prefixes->local_prefixes[i]), prefix)) return true;
}
return false;
}
@@ -51,19 +51,19 @@ void local_prefixes_add_prefixes(local_prefixes_t *prefixes,
unsigned i = 0;
while ((i < new_prefixes->len) && (prefixes->len < MAX_PREFIXES)) {
if (!contain_prefix(prefixes, &(new_prefixes->local_prefixes[i]))) {
- name_Copy(&new_prefixes->local_prefixes[i],
- &prefixes->local_prefixes[prefixes->len]);
+ hicn_prefix_copy(&prefixes->local_prefixes[prefixes->len],
+ &new_prefixes->local_prefixes[i]);
prefixes->len++;
}
i++;
}
}
-void local_prefixes_add_prefix(local_prefixes_t *prefixes, const void *prefix) {
+void local_prefixes_add_prefix(local_prefixes_t *prefixes,
+ const hicn_prefix_t *prefix) {
if (prefixes->len >= MAX_PREFIXES) return;
- Name *n = (Name *)prefix;
- if (!contain_prefix(prefixes, n)) {
- name_Copy(n, &(prefixes->local_prefixes[prefixes->len]));
+ if (!contain_prefix(prefixes, prefix)) {
+ hicn_prefix_copy(&(prefixes->local_prefixes[prefixes->len]), prefix);
prefixes->len++;
}
}
@@ -74,8 +74,9 @@ void update_remote_node_paths(const void *nexthops, const void *forwarder,
struct mapme_s *mapme = forwarder_get_mapme((forwarder_t *)forwarder);
fib_t *fib = forwarder_get_fib((forwarder_t *)forwarder);
for (unsigned i = 0; i < prefixes->len; i++) {
- fib_entry_t *entry = fib_match_name(fib, &prefixes->local_prefixes[i]);
+ fib_entry_t *entry = fib_match_prefix(fib, &prefixes->local_prefixes[i]);
if (!entry) continue;
- mapme_set_adjacencies(mapme, entry, (nexthops_t *)nexthops, false);
+ // XXX we don't want to force
+ mapme_set_adjacencies(mapme, entry, (nexthops_t *)nexthops);
}
}
diff --git a/hicn-light/src/hicn/strategies/local_prefixes.h b/hicn-light/src/hicn/strategies/local_prefixes.h
index 833a48057..9d7d8ec78 100644
--- a/hicn-light/src/hicn/strategies/local_prefixes.h
+++ b/hicn-light/src/hicn/strategies/local_prefixes.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,6 +24,8 @@
#ifndef HICNLIGHT_LOCAL_PREFIXES_H
#define HICNLIGHT_LOCAL_PREFIXES_H
+#include <hicn/name.h>
+
typedef struct local_prefixes_s local_prefixes_t;
local_prefixes_t* create_local_prefixes();
@@ -35,7 +37,8 @@ unsigned local_prefixes_get_len(local_prefixes_t* prefixes);
void local_prefixes_add_prefixes(local_prefixes_t* prefixes,
local_prefixes_t* new_prefixes);
-void local_prefixes_add_prefix(local_prefixes_t* prefixes, const void* prefix);
+void local_prefixes_add_prefix(local_prefixes_t* prefixes,
+ const hicn_prefix_t* prefix);
void update_remote_node_paths(const void* nexthops, const void* forwarder,
local_prefixes_t* prefixes);
diff --git a/hicn-light/src/hicn/strategies/low_latency.c b/hicn-light/src/hicn/strategies/low_latency.c
deleted file mode 100644
index 1e5a74c1a..000000000
--- a/hicn-light/src/hicn/strategies/low_latency.c
+++ /dev/null
@@ -1,776 +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.
- */
-
-#if 0
-
-#include <hicn/hicn-light/config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <math.h>
-
-#include <hicn/base/khash.h>
-
-#include <parc/assert/parc_Assert.h>
-#include <parc/algol/parc_HashMap.h>
-#include <parc/algol/parc_Memory.h>
-#include <parc/algol/parc_Object.h>
-#include <parc/algol/parc_Unsigned.h>
-
-#include <hicn/core/messageHandler.h>
-
-#include "low_latency.h"
-
-#define STABILITY_FACTOR 15
-#define MAX_SWITCH_TRY 10
-#define MAX_LATENCY_DIFF 10
-#define MAX_TOLLERATED_LATENCY_DIFF 15
-#define MAX_ROUNDS_MP_WITHOUT_CHECK 2
-#define MAX_ROUNDS_AVOIDING_MULTIPATH 40 /* about 20 sec */
-#define MAX_ROUNDS_WITH_ERROR 4
-#define PROBE_LIFETIME 500 /* ms */
-
-#define MAX_ROUNS_WITHOUT_PROBES 4
-
-/*
- * If we do not receives probes for 4 rounds it means that we had no responce
- * from any producer for 2 sec we can say that this interface is daed
- */
-#define MIN_NON_LOSSY_ROUNDS 10
-
-/*
- * Number of rounds in non lossy mode before switch to no lossy state
- * Defaults to 10 %
- */
-#define MAX_LOSS_RATE 0.10
-
-/* Shorthands */
-#define nexthop_state_t strategy_low_latency_nexthop_state_t
-#define state_t strategy_low_latency_state_t
-
-#define NEXTHOP_STATE_INIT \
- { \
- .in_use = false, .is_allowed = true, .sent_packets = 0, \
- .last_try_to_switch_round = 0, .try_to_switch_counter = 0, \
- .recevied_probes = 0, .rounds_without_probes = 0, .sent_probes = 0, \
- .lost_probes = 0, .non_lossy_rounds = MIN_NON_LOSSY_ROUNDS, \
- .avg_rtt = -1.0, .avg_rtt_in_use = -1.0, .avg_queue = 0.0001, \
- .avg_loss_rate = 0.0, \
- }
-
-// XXX ????
-#define STATE_INIT \
- {}
-
-static
- void
-strategy_low_latency_SendProbesCB(int fd, PARCEventType which_event, void *data)
-{
- parcAssertTrue(which_event & PARCEventType_Timeout,
- "Event incorrect, expecting %X set, got %X",
- PARCEventType_Timeout, which_event);
-
- StrategyLowLatency *ll = (StrategyLowLatency *) data;
-
- //delete old pending probes
- if(parcHashMap_Size(ll->pending_probes_ticks) != 0){
- Ticks now = forwarder_GetTicks(ll->forwarder);
- PARCIterator *iterator = parcHashMap_CreateKeyIterator(ll->pending_probes_ticks);
- NumberSet *to_remove = numberSet_Create();
- while(parcIterator_HasNext(iterator)) {
- PARCUnsigned *parc_seq = (PARCUnsigned *) parcIterator_Next(iterator);
- PARCUnsigned *parc_time = (PARCUnsigned *) parcHashMap_Get(ll->pending_probes_ticks, parc_seq);
- Ticks sent_time = parcUnsigned_GetUnsigned(parc_time);
- if((now - sent_time) > PROBE_LIFETIME){
- //probes to delete
- numberSet_Add(to_remove, parcUnsigned_GetUnsigned(parc_seq));
- }
- }
- parcIterator_Release(&iterator);
-
- for(int i = 0; i < numberSet_Length(to_remove); i++){
- PARCUnsigned *prob_seq = parcUnsigned_Create(numberSet_GetItem(to_remove,i));
- PARCUnsigned *cid = (PARCUnsigned *) parcHashMap_Get(ll->pending_probes_faces, prob_seq);
- StrategyNexthopStateLL *state =
- (StrategyNexthopStateLL *) parcHashMap_Get(ll->strategy_state, cid);
- strategyNexthopStateLL_LostProbe(state);
- parcHashMap_Remove(ll->pending_probes_ticks, prob_seq);
- parcHashMap_Remove(ll->pending_probes_faces, prob_seq);
- parcUnsigned_Release(&prob_seq);
- }
- numberSet_Release(&to_remove);
- }
-
- ConnectionTable * ct = forwarder_GetConnectionTable(ll->forwarder);
-
- PARCIterator *iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- while(parcIterator_HasNext(iterator)){
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- Connection *conn =
- (Connection *)connectionTable_FindById(ct,
- parcUnsigned_GetUnsigned(cid));
- if(!conn)
- continue;
-
- StrategyNexthopStateLL *state =
- (StrategyNexthopStateLL *) parcHashMap_Get(ll->strategy_state, cid);
-
- //probe only usable paths
- if(!strategyNexthopStateLL_IsAllowed(state))
- continue;
-
- uint32_t seq = rand();
- messageHandler_SetProbeName(ll->probe, HF_INET6_TCP,
- ll->name, seq);
- connection_Probe(conn, ll->probe);
-
- PARCUnsigned *parc_seq = parcUnsigned_Create(seq);
- Ticks now = forwarder_GetTicks(ll->forwarder);
- PARCUnsigned *parc_time = parcUnsigned_Create((unsigned int)now);
- parcHashMap_Put(ll->pending_probes_ticks, parc_seq, parc_time);
- parcHashMap_Put(ll->pending_probes_faces, parc_seq, cid);
- strategyNexthopStateLL_SentProbe(state);
- parcUnsigned_Release(&parc_seq);
- parcUnsigned_Release(&parc_time);
- }
- parcIterator_Release(&iterator);
-
- struct timeval timeout = {0,50000};
- parcEventTimer_Start(ll->sendProbes, &timeout);
-}
-
-static
-void
-strategy_low_latency_SendMapmeUpdate(StrategyLowLatency *ll,
- const NumberSet * nexthops){
- MapMe * mapme = forwarder_getMapmeInstance(ll->forwarder);
- FIB * fib = forwarder_getFib((Forwarder*) ll->forwarder);
- for(unsigned i = 0; i < ll->related_prefixes_len; i++){
- FibEntry *fibEntry = fib_MatchName(fib, ll->related_prefixes[i]);
- if (!fibEntry)
- continue;
- mapme_maybe_send_to_nexthops(mapme, fibEntry, nexthops);
- }
-}
-
-static
-void
-strategy_low_latency_SelectBestFaces(StrategyLowLatency *ll, bool new_round)
-{
-
- StrategyNexthopStateLL * old_faces[2];
- old_faces[0] = ll->bestFaces[0];
- old_faces[1] = ll->bestFaces[1];
-
- if(new_round){
- ll->round++;
- }
-
- if(parcHashMap_Size(ll->strategy_state) == 0){
- ll->bestFaces[0] = NULL;
- ll->bestFaces[1] = NULL;
- ll->use2paths = false;
- goto NEW_ROUND;
- }
-
- if(ll->use2paths && ll->bestFaces[0] != NULL && ll->bestFaces[1] != NULL){
- //multipath case
-
- if(!strategyNexthopStateLL_IsLossy(ll->bestFaces[0])
- && !strategyNexthopStateLL_IsLossy(ll->bestFaces[1])
- && strategyNexthopStateLL_IsAllowed(ll->bestFaces[0])
- && strategyNexthopStateLL_IsAllowed(ll->bestFaces[1])){
-
- if(ll->rounds_in_multipath < MAX_ROUNDS_MP_WITHOUT_CHECK){
- //we are at the first rounds of the multipath let's wait a bit
- //(MAX_ROUNDS_MP_WITHOUT_CHECK) to make the queuing converge
- ll->rounds_in_multipath++;
- goto NEW_ROUND;
- }
-
- //we need to decide if we want ot keep using two paths or not
- ll->rounds_in_multipath++;
- double rtt0 = strategyNexthopStateLL_GetRTTLive(ll->bestFaces[0]);
- double rtt1 = strategyNexthopStateLL_GetRTTLive(ll->bestFaces[1]);
- double diff = fabs(rtt0 - rtt1);
-
- if(diff < MAX_LATENCY_DIFF){
- //everything is working, keep using the two paths
- ll->rounds_with_error = 0;
- goto NEW_ROUND;
- }
-
- //check for how many rounds we had problems
- if(ll->rounds_with_error < MAX_ROUNDS_WITH_ERROR &&
- diff < MAX_TOLLERATED_LATENCY_DIFF){
- //we can tollerate few round with errors
- ll->rounds_with_error++;
- goto NEW_ROUND;
- }
-
- //prevent the usage of multiple paths
- ll->rounds_with_error = 0;
- ll->avoid_multipath = true;
- ll->rounds_avoiding_multipath = 0;
- } //else
- //at least one of the two path is lossy
- //or it is not allowed by the policies.
- //search for a better possibility
- }
-
- ll->bestFaces[0] = NULL;
- ll->bestFaces[1] = NULL;
-
- //check if there is at least one non lossy connection
- PARCIterator *iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- bool check_losses = true;
- bool found_good_face = false;
- while(parcIterator_HasNext(iterator) && !found_good_face){
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- const StrategyNexthopStateLL *state = parcHashMap_Get(ll->strategy_state, cid);
- if(!strategyNexthopStateLL_IsLossy(state) &&
- strategyNexthopStateLL_IsAllowed(state)){
- found_good_face = true;
- }
- }
- parcIterator_Release(&iterator);
- if(!found_good_face){
- // all the available faces are lossy, so we take into account only
- // the latency computed with the probes
- check_losses = false;
- }
-
- if(ll->bestFaces[0] == NULL){
- //try to take a random face
- PARCIterator *iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- bool face_found = false;
- while(parcIterator_HasNext(iterator) && !face_found) {
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- StrategyNexthopStateLL *state = (StrategyNexthopStateLL *)
- parcHashMap_Get(ll->strategy_state, cid);
-
- if((check_losses && strategyNexthopStateLL_IsLossy(state)) ||
- !strategyNexthopStateLL_IsAllowed(state)){
- //skip the face
- continue;
- }
-
- ll->bestFaces[0] = state;
- face_found = true;
- }
- parcIterator_Release(&iterator);
- }
-
- if(ll->bestFaces[0] == NULL){
- //no usable face exists
- ll->bestFaces[0] = NULL;
- ll->bestFaces[1] = NULL;
- ll->use2paths = false;
- goto NEW_ROUND;
- }
-
- double bestRtt = strategyNexthopStateLL_GetRTTLive(ll->bestFaces[0]);
-
- if(ll->avoid_multipath)
- ll->rounds_avoiding_multipath++;
-
- if(ll->rounds_avoiding_multipath > MAX_ROUNDS_AVOIDING_MULTIPATH){
- ll->avoid_multipath = false;
- ll->rounds_avoiding_multipath = 0;
- }
-
- iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- while (parcIterator_HasNext(iterator)) {
-
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- StrategyNexthopStateLL *state = (StrategyNexthopStateLL *)
- parcHashMap_Get(ll->strategy_state, cid);
- double rtt = strategyNexthopStateLL_GetRTTLive(state);
-
- if((check_losses && strategyNexthopStateLL_IsLossy(state)) ||
- !strategyNexthopStateLL_IsAllowed(state)){
- //skip the face
- continue;
- }
-
- if(rtt + STABILITY_FACTOR < bestRtt){
- //maybe we found a better face
- double rttInUse = strategyNexthopStateLL_GetRTTInUse(state);
- unsigned try = strategyNexthopStateLL_GetTryToSwitch(state);
-
- //we check the rtt in use to check if the new face that we found
- //gets congested when we use it to send the traffic
- if(rttInUse < bestRtt || try > MAX_SWITCH_TRY){
- //we have a new best face!
- strategyNexthopStateLL_ResetTryToSwitch((StrategyNexthopStateLL*) state);
- bestRtt = rtt;
- if(ll->bestFaces[0] != NULL)
- strategyNexthopStateLL_SetUnusedFace(ll->bestFaces[0]);
- ll->bestFaces[0] = (StrategyNexthopStateLL*) state;
- }else{
- //in this case we should switch but we wait MAX_SWITCH_TRY
- //before switch to avoid ossillations between different paths
- strategyNexthopStateLL_IncreaseTryToSwitch(
- (StrategyNexthopStateLL*) state, ll->round);
- }
- }
- }
-
- parcIterator_Release(&iterator);
-
- if(ll->bestFaces[0] == NULL){
- //we found no face so return
- ll->bestFaces[0] = NULL;
- ll->bestFaces[1] = NULL;
- ll->use2paths = false;
- goto NEW_ROUND;
- }
-
- if(parcHashMap_Size(ll->strategy_state) == 1 || ll->avoid_multipath){
- //in this case (one face available or avoid multipath) we stop the
- //search here. Just reset face 1 if needed
- if(ll->bestFaces[1] != NULL){
- strategyNexthopStateLL_SetUnusedFace(ll->bestFaces[1]);
- ll->bestFaces[1] = NULL;
- }
- ll->use2paths = false;
- goto NEW_ROUND;
- }
-
- //if we are here we have more than 1 interface, so we search for a second one
- //to use in case of multipath
- iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- while (parcIterator_HasNext(iterator)) {
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- if(parcUnsigned_GetUnsigned(cid) !=
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0])){
-
- StrategyNexthopStateLL *state = (StrategyNexthopStateLL *)
- parcHashMap_Get(ll->strategy_state, cid);
-
- if((check_losses && strategyNexthopStateLL_IsLossy(state)) ||
- !strategyNexthopStateLL_IsAllowed(state)){
- //skip the face
- continue;
- }
-
- if(ll->bestFaces[1] == NULL){
- //in case of 2 faces we should pass always here
- ll->bestFaces[1] = state;
- }else{
- //TODO this must be tested with more then 2 faces
- double rtt1 = strategyNexthopStateLL_GetRTTLive(ll->bestFaces[1]);
- double rttNewFace = strategyNexthopStateLL_GetRTTLive(state);
- if(rttNewFace + STABILITY_FACTOR < rtt1){
- strategyNexthopStateLL_SetUnusedFace(ll->bestFaces[1]);
- ll->bestFaces[1] = state;
- }
- }
- }
- }
- parcIterator_Release(&iterator);
-
- if(ll->bestFaces[1] != NULL){
- //we are not using the second face yet so we use the normal rtt for comparison
- double rtt0 = strategyNexthopStateLL_GetRTTProbe(ll->bestFaces[0]);
- double rtt1 = strategyNexthopStateLL_GetRTTProbe(ll->bestFaces[1]);
- double diff = fabs(rtt0 - rtt1);
- if(diff < MAX_LATENCY_DIFF) {
- //let's start to use 2 paths
- ll->rounds_with_error = 0;
- ll->use2paths = true;
- ll->rounds_in_multipath = 0;
- }else{
- //we use only one path
- strategyNexthopStateLL_SetUnusedFace(ll->bestFaces[1]);
- ll->bestFaces[1] = NULL;
- ll->use2paths = false;
- }
- }else{
- ll->use2paths = false;
- }
-
-NEW_ROUND:
- {
- Logger * log = forwarder_GetLogger(ll->forwarder);
- if(log != NULL &&
- logger_IsLoggable(log, LoggerFacility_Strategy, PARCLogLevel_Info)){
- if(ll->use2paths){
- logger_Log(log, LoggerFacility_Strategy, PARCLogLevel_Info,
- __func__, "use 2 paths. rtt face %d = %f queue = %f is_lossy = %d,"
- "rtt face %d = %f queue = %f is_lossy = %d\n",
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]),
- strategyNexthopStateLL_GetRTTLive(ll->bestFaces[0]),
- strategyNexthopStateLL_GetQueuing(ll->bestFaces[0]),
- strategyNexthopStateLL_IsLossy(ll->bestFaces[0]),
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[1]),
- strategyNexthopStateLL_GetRTTLive(ll->bestFaces[1]),
- strategyNexthopStateLL_GetQueuing(ll->bestFaces[1]),
- strategyNexthopStateLL_IsLossy(ll->bestFaces[1]));
- }else{
- if(ll->bestFaces[0] != NULL){
- logger_Log(log, LoggerFacility_Strategy,
- PARCLogLevel_Info, __func__,
- "use 1 path. rtt face %d = %f is_lossy = %d, "
- "(avoid multipath = %d)\n",
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]),
- strategyNexthopStateLL_GetRTTLive(ll->bestFaces[0]),
- strategyNexthopStateLL_IsLossy(ll->bestFaces[0]),
- ll->avoid_multipath);
- }else{
- logger_Log(log, LoggerFacility_Strategy, PARCLogLevel_Info,
- __func__, "no face to use!\n");
- }
- }
- }
- }
-
- //update the round only at the end for all the faces
- if(new_round){
- PARCIterator * iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- while (parcIterator_HasNext(iterator)) {
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- strategyNexthopStateLL_StartNewRound((StrategyNexthopStateLL *)
- parcHashMap_Get(ll->strategy_state, cid));
- }
- parcIterator_Release(&iterator);
- }
-
- //mapme updates
- //if ll->bestFaces[0] == NULL we don't have any output faces
- //so don't need to send any updates since we are disconnected
- if(ll->related_prefixes_len != 0){
- if(ll->bestFaces[0] != NULL){
- NumberSet *out = numberSet_Create();
- if(old_faces[0] == NULL ||
- (strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]) !=
- strategyNexthopStateLL_GetFaceId(old_faces[0]))){
- //there is a new face 0 so we need a map me update
- //if ll->bestFaces[1] != NULL we need to send the update
- //even if it is the same as before
- numberSet_Add(out,
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
- if(ll->bestFaces[1] != NULL){
- numberSet_Add(out,
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[1]));
- }
- strategy_low_latency_SendMapmeUpdate(ll,out);
- }else{
- if(ll->bestFaces[1] != NULL){
- if(old_faces[1] == NULL ||
- (strategyNexthopStateLL_GetFaceId(ll->bestFaces[1]) !=
- strategyNexthopStateLL_GetFaceId(old_faces[1]))){
- //send a mapme both with face 0 and face 1
- numberSet_Add(out,
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
- numberSet_Add(out,
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[1]));
- strategy_low_latency_SendMapmeUpdate(ll,out);
- }
- }else{
- if(old_faces[1] != NULL){
- //in the previuos round we were using two faces, now only one
- //send update with only face 0
- numberSet_Add(out,
- strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
- strategy_low_latency_SendMapmeUpdate(ll,out);
- }
- }
- }
- numberSet_Release(&out);
- }
- }
-}
-
-static
-void
-strategy_low_latency_BestFaceCB(int fd, PARCEventType which_event, void *data)
-{
- parcAssertTrue(which_event & PARCEventType_Timeout,
- "Event incorrect, expecting %X set, got %X",
- PARCEventType_Timeout, which_event);
-
- StrategyLowLatency * ll = (StrategyLowLatency *) data;
- strategy_low_latency_SelectBestFaces(ll, true);
-
- struct timeval timeout = {0, 500000};
- parcEventTimer_Start(ll->computeBestFace, &timeout);
-}
-
-static
-void
-_startTimers(strategy_entry_t * entry)
-{
- struct timeval timeoutProbes = {0, 10000};
- struct timeval timeoutBF = {1, 0};
-
- parcEventTimer_Start(entry->state.sendProbes, &timeoutProbes);
- parcEventTimer_Start(entry->state.computeBestFace, &timeoutBF);
-}
-
-static
-void
-_stopTimers(strategy_entry_t * entry)
-{
- parcEventTimer_Stop(entry->state.sendProbes);
- parcEventTimer_Stop(entry->state.computeBestFace);
-}
-
-static
-void
-strategy_low_latency_initialize(strategy_entry_t * entry)
-{
- srand((unsigned int)time(NULL));
-
- /* XXX TODO Three hashmaps to initialize */
- strategy->strategy_state = parcHashMap_Create();
- strategy->pending_probes_ticks = parcHashMap_Create();
- strategy->pending_probes_faces = parcHashMap_Create();
-
- Dispatcher *dispatcher = forwarder_GetDispatcher((Forwarder *)ll->forwarder);
- ip_prefix_t address;
- nameBitvector_ToIPAddress(name_GetContentName(
- fibEntry_GetPrefix(fibEntry)), &address);
-
- entry->state = {
- .probe = messageHandler_CreateProbePacket(HF_INET6_TCP, PROBE_LIFETIME),
- .name = messageHandler_CreateProbeName(&address);
- .sendProbes = dispatcher_CreateTimer(dispatcher, false,
- strategy_low_latency_SendProbesCB, ll);
- .round = 0;
- .rounds_in_multipath = 0;
- .rounds_with_error = 0;
- .rounds_avoiding_multipath = 0;
- .use2paths = false;
- .avoid_multipath = false;
- .computeBestFace = dispatcher_CreateTimer(dispatcher, false,
- strategy_low_latency_BestFaceCB, ll);
- .related_prefixes_len = related_prefixes_len;
- // XXX TODO
- .related_prefixes = malloc(sizeof(Name *) * related_prefixes_len);
- };
-
- for(unsigned i = 0; i < entry->state.related_prefixes_len; i++){
- entry->state.related_prefixes[i] = name_Copy(related_prefixes[i]);
- }
-}
-
-static
-void
-strategy_low_latency_finalize(strategy_entry_t * entry)
-{
- _stopTimers(entry);
-
- parcEventTimer_Destroy(&(strategy->sendProbes));
- parcEventTimer_Destroy(&(strategy->computeBestFace));
-
- if (parcHashMap_Size(strategy->strategy_state) > 0) {
- PARCIterator *it = parcHashMap_CreateKeyIterator(strategy->strategy_state);
- while (parcIterator_HasNext(it)) {
- PARCUnsigned *cid = parcIterator_Next(it);
- StrategyNexthopStateLL *state =
- (StrategyNexthopStateLL *)parcHashMap_Get(strategy->strategy_state, cid);
- parcObject_Release((void**)&state);
- }
- parcIterator_Release(&it);
- }
-
- parcHashMap_Release(&(strategy->strategy_state));
- parcHashMap_Release(&(strategy->pending_probes_ticks));
- parcHashMap_Release(&(strategy->pending_probes_faces));
-
- parcMemory_Deallocate(&(strategy->probe));
- parcMemory_Deallocate(&(strategy->name));
-
- for(unsigned i = 0; i < strategy->related_prefixes_len; i++){
- name_Release(&(strategy->related_prefixes[i]));
- }
- free(strategy->related_prefixes);
-
- parcMemory_Deallocate((void **)&strategy);
- parcMemory_Deallocate((void **)&impl);
- *strategyPtr = NULL;
-}
-
-static
-void
-strategy_low_latency_add_nexthop(strategy_entry_t * entry, unsigned nexthop, nexthop_state_t * state)
-{
- PARCUnsigned *cid = parcUnsigned_Create(connectionId);
-
- StrategyLowLatency *ll = (StrategyLowLatency *)strategy->context;
-
- if (!parcHashMap_Contains(ll->strategy_state, cid)) {
- StrategyNexthopStateLL *state = strategyNexthopStateLL_Create(connectionId);
- parcHashMap_Put(ll->strategy_state, cid, state);
- if(ll->bestFaces[0] == NULL){
- ll->bestFaces[0] = state;
- }
- }
-
- if(parcHashMap_Size(ll->strategy_state) >= 2){
- _startTimers(strategy);
- }
-
- parcUnsigned_Release(&cid);
-}
-
-static
-void
-strategy_low_latency_remove_nexthop(strategy_entry_t * entry, unsigned nexthop, nexthop_state_t * state)
-{
- bool reset_bestFaces = false;
-
- if((entry->state.bestFaces[0] != NULL &&
- strategyNexthopStateLL_GetFaceId(entry->state.bestFaces[0]) == connectionId) ||
- (entry->state.bestFaces[1] != NULL &&
- strategyNexthopStateLL_GetFaceId(entry->state.bestFaces[1]) == connectionId)){
- reset_bestFaces = true;
- }
-
- PARCUnsigned *cid = parcUnsigned_Create(connectionId);
-
- if (parcHashMap_Contains(entry->state.strategy_state, cid)) {
- parcHashMap_Remove(entry->state.strategy_state, cid);
- }
-
- if(reset_bestFaces){
- entry->state.bestFaces[0] = NULL;
- entry->state.bestFaces[1] = NULL;
- strategy_low_latency_SelectBestFaces(ll, false);
- }
-
- if(parcHashMap_Size(entry->state.strategy_state) < 2){
- _stopTimers(strategy);
- }
-
- parcUnsigned_Release(&cid);
-}
-
-static
-nexthops_t *
-strategy_low_latency_lookup_nexthops(strategy_entry_t * entry,
- const msgbuf_t * msgbuf)
-{
- //unsigned out_connection;
- NumberSet *out = numberSet_Create();
-
- StrategyLowLatency *ll = (StrategyLowLatency *)strategy->context;
-
- //update is_allowed flag of all the next hops
- PARCIterator *iterator = parcHashMap_CreateKeyIterator(ll->strategy_state);
- while(parcIterator_HasNext(iterator)){
- PARCUnsigned *cid = (PARCUnsigned *) parcIterator_Next(iterator);
- StrategyNexthopStateLL *state =
- (StrategyNexthopStateLL *) parcHashMap_Get(ll->strategy_state, cid);
- if(numberSet_Contains(nexthops, parcUnsigned_GetUnsigned(cid))){
- strategyNexthopStateLL_SetIsAllowed(state,true);
- }else{
- strategyNexthopStateLL_SetIsAllowed(state,false);
- }
- }
- parcIterator_Release(&iterator);
-
- if(ll->bestFaces[0] != NULL &&
- !strategyNexthopStateLL_IsAllowed(ll->bestFaces[0])){
- //if ll->bestFaces[0] is not allowed we need to find a new face
- strategy_low_latency_SelectBestFaces(ll, false);
- }
-
- //at this point ll->bestFaces[0] must be allowed
- //single path case
- if(ll->bestFaces[0] != NULL && (ll->bestFaces[1] == NULL || !ll->use2paths)){
- strategyNexthopStateLL_SendPacket(ll->bestFaces[0]);
- numberSet_Add(out, strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
-
- //multipath case
- }else if(ll->bestFaces[0] != NULL && ll->bestFaces[1] != NULL && ll->use2paths){
- //it may happen that ll->bestFaces[1] is not allowed, in that case we send on
- //ll->bestFaces[0] until the next best face selection
- if(!strategyNexthopStateLL_IsAllowed(ll->bestFaces[1])){
- strategyNexthopStateLL_SendPacket(ll->bestFaces[0]);
- numberSet_Add(out, strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
- }else{
- double queue0 = strategyNexthopStateLL_GetQueuing(ll->bestFaces[0]);
- double queue1 = strategyNexthopStateLL_GetQueuing(ll->bestFaces[1]);
- double prob0 = 0.5;
- if(queue0 > 1 || queue1 > 1){
- prob0 = 1.0 - (queue0 / (queue0 + queue1));
- }
- double coin = ((double) rand() / (RAND_MAX));
- if(coin < prob0){
- strategyNexthopStateLL_SendPacket(ll->bestFaces[0]);
- numberSet_Add(out, strategyNexthopStateLL_GetFaceId(ll->bestFaces[0]));
- }else{
- strategyNexthopStateLL_SendPacket(ll->bestFaces[1]);
- numberSet_Add(out, strategyNexthopStateLL_GetFaceId(ll->bestFaces[1]));
- }
- }
- }
- return out;
-}
-
-
-
-static
-void
-strategy_low_latency_on_data(strategy_entry_t * entry,
- const nexthops_t * nexthops, const msgbuf_t * msgbuf,
- Ticks pitEntryCreation, Ticks objReception)
-{
- if (!msgbuf_is_probe(msgbuf))
- return;
-
- uint32_t seq = messageHandler_GetSegment(message_FixedHeader(objectMessage));
- if (!parcHashMap_Contains(ll->pending_probes_ticks, seq))
- return; // unexpected
-
- /* A single nexthop is expected */
- unsigned nexthop;
- nexthops_foreach(nexthops, nexthop, {
- const StrategyNexthopStateLL *state =
- parcHashMap_Get(ll->strategy_state, nexthop);
- if (!state)
- // this may happen if we remove a face/route while downloading a file
- // we should ignore this timeout
- continue;
-
- Ticks time = parcUnsigned_GetUnsigned(
- parcHashMap_Get(ll->pending_probes_ticks, seq));
- Ticks now = forwarder_GetTicks(ll->forwarder);
- Ticks RTT = now - time;
- if(RTT <= 0)
- RTT = 1;
- strategyNexthopStateLL_AddRttSample(
- (StrategyNexthopStateLL *) state, (unsigned int)RTT);
- parcHashMap_Remove(ll->pending_probes_ticks, seq);
- }
- };
-}
-
-static
-void
-strategy_low_latency_on_timeout(strategy_entry_t * entry, const nexthops_t * nexthops)
-{
- /* Nothing to do */
-}
-
-DECLARE_STRATEGY(low_latency);
-
-#undef nexthop_state_t
-#undef state_t
-
-#endif
diff --git a/hicn-light/src/hicn/strategies/low_latency.h b/hicn-light/src/hicn/strategies/low_latency.h
deleted file mode 100644
index 6b3001637..000000000
--- a/hicn-light/src/hicn/strategies/low_latency.h
+++ /dev/null
@@ -1,101 +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.
- */
-
-/**
- * Forward on the path with lowest latency
- */
-
-#ifndef HICNLIGHT_STRATEGY_LOW_LATENCY_H
-#define HICNLIGHT_STRATEGY_LOW_LATENCY_H
-
-struct name_s;
-
-#include <hicn/strategy.h>
-
-typedef struct {
- void *_;
-} strategy_low_latency_nexthop_state_t;
-
-typedef struct {
- void *_;
-} strategy_low_latency_state_t;
-
-typedef struct {
- // Name ** related_prefixes;
- struct name_s *related_prefixes[MAX_FWD_STRATEGY_RELATED_PREFIXES];
- unsigned related_prefixes_len;
-} strategy_low_latency_options_t;
-
-#if 0
-
-/*
- * We have global state in addition to state associated for each next hop :
- */
-typedef struct {
- bool in_use;
- bool is_allowed; // XXX TODO the policy may not allow the use of this face
-// unsigned face_id;
- unsigned sent_packets;
- /* switch metrics */
- unsigned last_try_to_switch_round;
- unsigned try_to_switch_counter;
- /* probes counters */
- unsigned recevied_probes;
- unsigned rounds_without_probes;
- unsigned sent_probes;
- unsigned lost_probes;
- unsigned non_lossy_rounds;
- /* Averages */
- double avg_rtt;
- double avg_rtt_in_use;
- double avg_queue;
- double avg_loss_rate;
-} strategy_low_latency_nexthop_state_t;
-
-typedef struct {
- // hash map from connectionId to StrategyNexthopStateLL
- //PARCHashMap *strategy_state;
- // XXX This is now store in each nexthop state
-
- /*
- * Hhash map from sequence number to ticks (sent time)
- *
- * TODO improvement: the tick and face id could be stored in the probe and
- * repeated in the reply to avoid state to be maintained.
- *
- * Also, in case we have few probes, linear scan might be more effective
- */
- PARCHashMap *pending_probes_ticks;
-
- /* hash map from sequence number to face id */
- PARCHashMap *pending_probes_faces;
-
- const Forwarder * forwarder;
- PARCEventTimer *sendProbes;
- PARCEventTimer *computeBestFace;
- uint8_t * probe;
- hicn_name_t * name;
- StrategyNexthopStateLL * bestFaces[2];
- unsigned round;
- unsigned rounds_in_multipath;
- unsigned rounds_with_error;
- unsigned rounds_avoiding_multipath;
- bool use2paths;
- bool avoid_multipath;
-} strategy_low_latency_state_t;
-
-#endif
-
-#endif /* HICNLIGHT_STRATEGY_LOW_LATENCY_H */
diff --git a/hicn-light/src/hicn/strategies/probe_generator.c b/hicn-light/src/hicn/strategies/probe_generator.c
index bc141e518..fd0bf5471 100644
--- a/hicn-light/src/hicn/strategies/probe_generator.c
+++ b/hicn-light/src/hicn/strategies/probe_generator.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:
@@ -87,8 +87,7 @@ int generate_probe(probe_generator_t *pg, const msgbuf_t *msgbuf,
uint32_t seq = get_seq_number(pg);
if (seq == 0) return -1;
-
- messageHandler_ModifySuffix(msgbuf_get_packet(probe), seq);
+ msgbuf_modify_suffix(probe, seq);
connection_send(conn, probe_offset, true);
connection_flush(conn);
add_to_map(pg, seq, ticks_now());
diff --git a/hicn-light/src/hicn/strategies/probe_generator.h b/hicn-light/src/hicn/strategies/probe_generator.h
index 7a9f3a58a..065d824a1 100644
--- a/hicn-light/src/hicn/strategies/probe_generator.h
+++ b/hicn-light/src/hicn/strategies/probe_generator.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:
@@ -20,6 +20,9 @@
#include <hicn/core/ticks.h>
#include <hicn/core/msgbuf.h>
+#define MIN_PROBE_SUFFIX 0xefffffff
+#define MAX_PROBE_SUFFIX 0xffffffff - 1
+
KHASH_MAP_INIT_INT64(bp_map, Ticks);
struct forwarder_s;
diff --git a/hicn-light/src/hicn/strategies/random.c b/hicn-light/src/hicn/strategies/random.c
index 5b076df7c..aabae73bc 100644
--- a/hicn-light/src/hicn/strategies/random.c
+++ b/hicn-light/src/hicn/strategies/random.c
@@ -53,6 +53,7 @@ static int strategy_random_remove_nexthop(strategy_entry_t *entry,
static nexthops_t *strategy_random_lookup_nexthops(strategy_entry_t *entry,
nexthops_t *nexthops,
const msgbuf_t *msgbuf) {
+ if (nexthops_get_curlen(nexthops) == 0) return nexthops;
nexthops_select(nexthops, rand() % nexthops_get_len(nexthops));
return nexthops;
}
diff --git a/hicn-light/src/hicn/test/CMakeLists.txt b/hicn-light/src/hicn/test/CMakeLists.txt
index 65e216c1e..cbe939297 100644
--- a/hicn-light/src/hicn/test/CMakeLists.txt
+++ b/hicn-light/src/hicn/test/CMakeLists.txt
@@ -1,19 +1,13 @@
-# Copyright (c) 2021 Cisco and/or its affiliates.
+# Copyright (c) 2021-2022 Cisco and/or its affiliates.
include(BuildMacros)
list(APPEND TESTS_SRC
- test-bitmap.cc
test-configuration.cc
- test-hash.cc
- test-khash.cc
+ test-fib.cc
test-loop.cc
- test-pool.cc
test-parser.cc
test-ctrl.cc
- test-ring.cc
- test-vector.cc
- test-interest_manifest.cc
test-msgbuf_pool.cc
test-nexthops.cc
test-connection_table.cc
@@ -26,8 +20,8 @@ list(APPEND TESTS_SRC
test-subscription.cc
test-local_prefixes.cc
test-probe_generator.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/../config/command_listener.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../config/command_route.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_listener.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/commands/command_route.c
main.cc
)
@@ -39,6 +33,7 @@ build_executable(hicn_light_tests
DEPENDS gtest ${LIBHICNCTRL_STATIC} ${LIBHICN_LIGHT_SHARED}
COMPONENT ${HICN_LIGHT}
DEFINITIONS "${COMPILER_DEFINITIONS}"
+ COMPILE_OPTIONS ${COMPILER_OPTIONS}
)
add_test_internal(hicn_light_tests)
diff --git a/hicn-light/src/hicn/test/test-bitmap.cc b/hicn-light/src/hicn/test/test-bitmap.cc
deleted file mode 100644
index 1fd21a1bb..000000000
--- a/hicn-light/src/hicn/test/test-bitmap.cc
+++ /dev/null
@@ -1,144 +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 <gtest/gtest.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <netinet/in.h>
-
-extern "C" {
-#define WITH_TESTS
-#include <hicn/util/bitmap.h>
-}
-
-#define DEFAULT_SIZE 10
-
-class BitmapTest : public ::testing::Test {
- protected:
- BitmapTest() {}
-
- virtual ~BitmapTest() {}
-
- bitmap_t* bitmap;
-};
-
-/*
- * TEST: bitmap allocation
- */
-TEST_F(BitmapTest, BitmapAllocation) {
- int rc;
-
- /*
- * We take a value < 32 on purpose to avoid confusion on the choice of a 32
- * or 64 bit integer for storage
- */
- size_t size_not_pow2 = DEFAULT_SIZE;
- bitmap_init(bitmap, size_not_pow2, 0);
-
- /*
- * Bitmap should have been allocated with a size rounded to the next power
- * of 2
- */
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 1UL);
-
- /* By default, no element should be set */
- EXPECT_FALSE(bitmap_is_set(bitmap, 0));
- EXPECT_TRUE(bitmap_is_unset(bitmap, 0));
-
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 1UL);
-
- EXPECT_FALSE(bitmap_is_set(bitmap, size_not_pow2 - 1));
- EXPECT_TRUE(bitmap_is_unset(bitmap, size_not_pow2 - 1));
-
- /* Bitmap should not have been reallocated */
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 1UL);
-
- /* After setting a bit after the end, bitmap should have been reallocated */
- bitmap_set(bitmap, sizeof(bitmap[0]) * 8 - 1);
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 1UL);
-
- /* After setting a bit after the end, bitmap should have been reallocated */
- rc = bitmap_set(bitmap, sizeof(bitmap[0]) * 8);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 2UL);
-
- rc = bitmap_set(bitmap, sizeof(bitmap[0]) * 8 + 1);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 2UL);
-
- bitmap_free(bitmap);
-
- size_t size_pow2 = 16;
-
- /* Limiting test for allocation size */
- bitmap_init(bitmap, size_pow2, 0);
- EXPECT_EQ(bitmap_get_alloc_size(bitmap), 1UL);
-
- bitmap_free(bitmap);
-}
-
-TEST_F(BitmapTest, BitmapSet) {
- bitmap_init(bitmap, DEFAULT_SIZE, 0);
-
- bitmap_set(bitmap, 20);
- EXPECT_TRUE(bitmap_is_set(bitmap, 20));
- EXPECT_FALSE(bitmap_is_unset(bitmap, 20));
- EXPECT_FALSE(bitmap_is_set(bitmap, 19));
- EXPECT_TRUE(bitmap_is_unset(bitmap, 19));
-
- // Test edge cases (i.e. start and end of block)
- off_t start_position = 0;
- bitmap_set(bitmap, start_position);
- EXPECT_TRUE(bitmap_is_set(bitmap, start_position));
- EXPECT_FALSE(bitmap_is_unset(bitmap, start_position));
-
- off_t end_position = BITMAP_WIDTH(bitmap) - 1;
- bitmap_set(bitmap, end_position);
- EXPECT_TRUE(bitmap_is_set(bitmap, end_position));
- EXPECT_FALSE(bitmap_is_unset(bitmap, end_position));
-
- bitmap_free(bitmap);
-}
-
-TEST_F(BitmapTest, BitmapUnSet) {
- bitmap_init(bitmap, DEFAULT_SIZE, 0);
-
- bitmap_set(bitmap, 20);
- bitmap_set(bitmap, 19);
- bitmap_unset(bitmap, 20);
- EXPECT_FALSE(bitmap_is_set(bitmap, 20));
- EXPECT_TRUE(bitmap_is_unset(bitmap, 20));
- EXPECT_TRUE(bitmap_is_set(bitmap, 19));
- EXPECT_FALSE(bitmap_is_unset(bitmap, 19));
-
- bitmap_free(bitmap);
-}
-
-TEST_F(BitmapTest, BitmapSetTo) {
- bitmap_init(bitmap, DEFAULT_SIZE, 0);
-
- bitmap_set_to(bitmap, 40);
- EXPECT_TRUE(bitmap_is_set(bitmap, 20));
- EXPECT_TRUE(bitmap_is_set(bitmap, 21));
- EXPECT_TRUE(bitmap_is_unset(bitmap, 41));
- EXPECT_TRUE(bitmap_is_unset(bitmap, 42));
-
- bitmap_free(bitmap);
-}
diff --git a/hicn-light/src/hicn/test/test-connection_table.cc b/hicn-light/src/hicn/test/test-connection_table.cc
index d17de7c2c..171921b53 100644
--- a/hicn-light/src/hicn/test/test-connection_table.cc
+++ b/hicn-light/src/hicn/test/test-connection_table.cc
@@ -27,6 +27,7 @@
extern "C" {
#define WITH_TESTS
#include <hicn/core/connection_table.h>
+#include <hicn/util/log.h>
}
#define CONNECTION_NAME "connection_name_test"
@@ -275,7 +276,7 @@ TEST_F(ConnectionTableTest, GenerateConnNameExhaustion) {
bool unable_to_allocate = false;
// Force name exhaustion
- int i, n_connections = 1 + USHRT_MAX;
+ int n_connections = 1 + USHRT_MAX;
for (int i = 0; i <= n_connections; i++) {
int rc = connection_table_get_random_name(conn_table_, conn_name);
if (rc < 0) {
diff --git a/hicn-light/src/hicn/test/test-ctrl.cc b/hicn-light/src/hicn/test/test-ctrl.cc
index e24b47f27..f0d3e7c37 100644
--- a/hicn-light/src/hicn/test/test-ctrl.cc
+++ b/hicn-light/src/hicn/test/test-ctrl.cc
@@ -18,7 +18,7 @@
extern "C" {
#include <hicn/util/log.h>
#include <hicn/ctrl.h>
-#include <hicn/config/parse.h>
+#include <hicn/ctrl/parse.h>
#include <hicn/ctrl/route.h>
#include <hicn/util/sstrncpy.h>
}
@@ -27,7 +27,7 @@ class CtrlTest : public ::testing::Test {
protected:
CtrlTest() {
log_conf.log_level = LOG_INFO;
- s_ = hc_sock_create_forwarder(HICNLIGHT_NG);
+ s_ = hc_sock_create_forwarder(FORWARDER_TYPE_HICNLIGHT);
}
virtual ~CtrlTest() { hc_sock_free(s_); }
@@ -40,7 +40,7 @@ class CtrlTest : public ::testing::Test {
* Here we test the serialization of the commands i.e. from command
* to message sent to the forwarder.
*/
-
+#if 0
TEST_F(CtrlTest, AddValidListener) {
std::string cmd = "add listener udp udp0 10.0.0.1 9695 eth0";
ASSERT_EQ(parse(cmd.c_str(), &command_), 0);
@@ -81,7 +81,7 @@ TEST_F(CtrlTest, AddListenerInvalidLocalAddress) {
hc_result_t *result = hc_listener_create_conf(s_, &command_.object.listener);
bool success = hc_result_get_success(s_, result);
- EXPECT_FALSE(success);
+ EXPECT_EQ(success, false);
}
TEST_F(CtrlTest, AddListenerEmptyLocalAddress) {
@@ -193,4 +193,5 @@ TEST_F(CtrlTest, RouteNameOrID) {
route.face_id = 1;
snprintf(route.name, SYMBOLIC_NAME_LEN, "%s", "1test");
EXPECT_EQ(hc_route_validate(&route), -1);
-} \ No newline at end of file
+}
+#endif
diff --git a/hicn-light/src/hicn/test/test-fib.cc b/hicn-light/src/hicn/test/test-fib.cc
new file mode 100644
index 000000000..5db47415f
--- /dev/null
+++ b/hicn-light/src/hicn/test/test-fib.cc
@@ -0,0 +1,85 @@
+/*
+ * 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:
+ *
+ * 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 <gtest/gtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+extern "C" {
+#define WITH_TESTS
+#include <hicn/util/ip_address.h>
+#include <hicn/config/configuration.h>
+#include <hicn/core/forwarder.h>
+#include <hicn/core/fib.h>
+}
+
+/*
+ * TODO
+ * - test max_size
+ */
+
+#define DEFAULT_SIZE 10
+#define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a))))
+
+class FibTest : public ::testing::Test {
+ protected:
+ FibTest() { fib = fib_create(NULL); }
+ virtual ~FibTest() { fib_free(fib); }
+
+ configuration_t *configuration;
+ forwarder_t *forwarder;
+ fib_t *fib;
+};
+
+void _fib_add_prefix(fib_t *fib, const hicn_prefix_t *prefix) {
+ fib_entry_t *entry =
+ fib_entry_create(prefix, STRATEGY_TYPE_UNDEFINED, NULL, NULL);
+ fib_add(fib, entry);
+}
+
+static const hicn_prefix_t p0010 = (hicn_prefix_t){
+ .name = {.v6 = {.as_u64 = {0x1122334455667788, 0x9900aabbccddeeff}}},
+ .len = 4};
+
+/* TEST: Fib allocation and initialization */
+TEST_F(FibTest, FibAddOne) {
+ /* Empty fib should be valid */
+
+ const hicn_prefix_t *empty_prefix_array[] = {};
+ bool empty_used_array[] = {};
+ EXPECT_TRUE(fib_is_valid(fib));
+ EXPECT_TRUE(fib_check_preorder(fib, empty_prefix_array, empty_used_array));
+
+ const hicn_prefix_t *prefix_array[] = {&p0010};
+ bool used_array[] = {true};
+
+ for (unsigned i = 0; i < ARRAY_SIZE(prefix_array); i++) {
+ if (!used_array[i]) continue;
+ _fib_add_prefix(fib, prefix_array[i]);
+ }
+
+ fib_dump(fib);
+
+ EXPECT_TRUE(fib_is_valid(fib));
+ EXPECT_TRUE(fib_check_preorder(fib, prefix_array, used_array));
+
+ /* Check that free indices and bitmaps are correctly updated */
+}
diff --git a/hicn-light/src/hicn/test/test-interest_manifest.cc b/hicn-light/src/hicn/test/test-interest_manifest.cc
deleted file mode 100644
index 6408a3f2a..000000000
--- a/hicn-light/src/hicn/test/test-interest_manifest.cc
+++ /dev/null
@@ -1,79 +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 <gtest/gtest.h>
-
-extern "C" {
-#include <hicn/core/interest_manifest.h>
-}
-
-static constexpr size_t WORD_SIZE = 32;
-
-class InterestManifestTest : public ::testing::Test {
- protected:
- InterestManifestTest() {}
- virtual ~InterestManifestTest() {}
-};
-
-TEST_F(InterestManifestTest, OneWordBitmapUpdate) {
- u32 initial_bitmap[1];
- u32 curr_bitmap[1] = {0};
- initial_bitmap[0] = 0x00000b07; // 000000000000000000000101100000111
-
- // Consume first 4 'one' bits (i.e. suffixes), reaching position 9
- int pos = 0, max_suffixes = 4;
- pos = interest_manifest_update_bitmap(initial_bitmap, curr_bitmap, pos,
- WORD_SIZE, max_suffixes);
- EXPECT_EQ(pos, 9);
- EXPECT_EQ(curr_bitmap[0], 0x00000107);
-
- // Consume the remaining 2 'one' bits, reaching end of bitmap
- u32 curr_bitmap2[1] = {0};
- pos = interest_manifest_update_bitmap(initial_bitmap, curr_bitmap2, pos,
- WORD_SIZE, max_suffixes);
- EXPECT_EQ(pos, WORD_SIZE);
- EXPECT_EQ(curr_bitmap2[0], 0x00000a00);
-
- // Consume all suffixes at once
- u32 curr_bitmap3[1] = {0};
- max_suffixes = 16;
- pos = interest_manifest_update_bitmap(initial_bitmap, curr_bitmap3, 0,
- WORD_SIZE, max_suffixes);
- EXPECT_EQ(pos, WORD_SIZE);
- EXPECT_EQ(curr_bitmap3[0], initial_bitmap[0]);
-}
-
-TEST_F(InterestManifestTest, TwoWordBitmapUpdate) {
- u32 initial_bitmap[2];
- initial_bitmap[0] = 0x00000b07;
- initial_bitmap[1] = 0x00000b07;
- // -> 100000000000000000000101100000111000000000000000000000101100000111
-
- int expected_pos[] = {34, 64};
- u32 expected_bitmap[][2] = {{0x00000b07, 0x00000003}, {0x0, 0x00000b04}};
-
- // Loop to consume all suffixes
- int pos = 0, max_suffixes = 8, i = 0, len = WORD_SIZE * 2;
- while (pos != len) {
- u32 curr_bitmap[2] = {0};
- pos = interest_manifest_update_bitmap(initial_bitmap, curr_bitmap, pos, len,
- max_suffixes);
-
- EXPECT_EQ(pos, expected_pos[i]);
- EXPECT_EQ(curr_bitmap[0], expected_bitmap[i][0]);
- EXPECT_EQ(curr_bitmap[1], expected_bitmap[i][1]);
- i++;
- }
-} \ No newline at end of file
diff --git a/hicn-light/src/hicn/test/test-khash.cc b/hicn-light/src/hicn/test/test-khash.cc
deleted file mode 100644
index f437f8858..000000000
--- a/hicn-light/src/hicn/test/test-khash.cc
+++ /dev/null
@@ -1,154 +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 <gtest/gtest.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <netinet/in.h>
-
-extern "C" {
-#include <hicn/util/khash.h>
-}
-
-KHASH_MAP_INIT_INT(int, unsigned char)
-
-typedef struct {
- unsigned key;
- unsigned char val;
-} int_unpack_t;
-
-typedef struct {
- unsigned key;
- unsigned char val;
-} __attribute__((__packed__)) int_packed_t;
-
-#define hash_eq(a, b) ((a).key == (b).key)
-#define hash_func(a) ((a).key)
-
-KHASH_INIT(iun, int_unpack_t, char, 0, hash_func, hash_eq)
-KHASH_INIT(ipk, int_packed_t, char, 0, hash_func, hash_eq)
-
-class KHashTest : public ::testing::Test {
- protected:
- KHashTest() {}
-
- virtual ~KHashTest() {
- // You can do clean-up work that doesn't throw exceptions here.
- }
-
- // If the constructor and destructor are not enough for setting up
- // and cleaning up each test, you can define the following methods:
-
- virtual void SetUp() { khash = kh_init(int); }
-
- virtual void TearDown() { kh_destroy(int, khash); }
- khash_t(int) * khash;
-};
-
-TEST_F(KHashTest, KhashIntSize) {
- int ret;
- int k;
- int size = kh_size(khash);
-
- EXPECT_EQ(size, 0);
- k = kh_put(int, khash, 10, &ret);
- if (ret == 1) {
- kh_val(khash, k) = 10;
- }
- size = kh_size(khash);
- EXPECT_EQ(size, 1);
-}
-
-TEST_F(KHashTest, KhashIntPut) {
- int ret;
- int k;
- k = kh_put(int, khash, 10, &ret);
- if (ret == 1) {
- kh_val(khash, k) = 10;
- }
- int size = kh_size(khash);
- EXPECT_EQ(size, 1);
- k = kh_put(int, khash, 20, &ret);
- if (ret == 1) {
- kh_val(khash, k) = 20;
- }
- size = kh_size(khash);
- EXPECT_EQ(size, 2);
-}
-
-TEST_F(KHashTest, KhashCheckValue) {
- int ret;
- int k;
- k = kh_put(int, khash, 10, &ret);
- if (ret == 1) {
- kh_val(khash, k) = 100;
- }
- k = kh_put(int, khash, 20, &ret);
- if (ret == 1) {
- kh_val(khash, k) = 200;
- }
-
- k = kh_put(int, khash, 10, &ret);
- int val = -1;
- if (!ret) val = kh_val(khash, k);
- EXPECT_EQ(val, 100);
-
- k = kh_put(int, khash, 20, &ret);
- val = -1;
- if (!ret) val = kh_val(khash, k);
- EXPECT_EQ(val, 200);
-}
-
-// Check that there are no collisions in case of same key hash
-typedef struct {
- int x;
-} Key;
-#define hash_key(key) 1 // Hash is always 1 to simulate collisions
-#define key_hash_eq(a, b) (a->x == b->x) // Function used in case of collisions
-KHASH_INIT(test_map, const Key *, unsigned, 1, hash_key, key_hash_eq);
-
-TEST_F(KHashTest, Collisions) {
- int ret;
- khiter_t k;
-
- kh_test_map_t *map = kh_init(test_map);
- Key key1 = {.x = 10};
- Key key2 = {.x = 11};
-
- k = kh_put_test_map(map, &key1, &ret);
- EXPECT_EQ(ret, 1);
- kh_val(map, k) = 15;
-
- k = kh_put_test_map(map, &key2, &ret);
- EXPECT_EQ(ret, 1);
- kh_val(map, k) = 27;
-
- k = kh_get_test_map(map, &key1);
- ASSERT_NE(k, kh_end(map));
- unsigned val = kh_val(map, k);
- EXPECT_EQ(val, 15u);
-
- k = kh_get_test_map(map, &key2);
- ASSERT_NE(k, kh_end(map));
- val = kh_val(map, k);
- EXPECT_EQ(val, 27u);
-
- kh_destroy_test_map(map);
-}
diff --git a/hicn-light/src/hicn/test/test-listener_table.cc b/hicn-light/src/hicn/test/test-listener_table.cc
index b2ed0c276..f4af02ee1 100644
--- a/hicn-light/src/hicn/test/test-listener_table.cc
+++ b/hicn-light/src/hicn/test/test-listener_table.cc
@@ -27,6 +27,7 @@
extern "C" {
#define WITH_TESTS
#include <hicn/core/listener_table.h>
+#include <hicn/util/log.h>
}
#define LISTENER_NAME "listener_name_test"
@@ -217,7 +218,6 @@ TEST_F(ListenerTableTest, Iterate) {
listener_2->key = key_2;
// Iterate over the listener table and count the listeners
- listener_t *l;
int count = 0;
listener_table_foreach(listener_table_, l, { count++; });
EXPECT_EQ(count, 2);
diff --git a/hicn-light/src/hicn/test/test-local_prefixes.cc b/hicn-light/src/hicn/test/test-local_prefixes.cc
index 80eb46501..52b1c746e 100644
--- a/hicn-light/src/hicn/test/test-local_prefixes.cc
+++ b/hicn-light/src/hicn/test/test-local_prefixes.cc
@@ -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:
@@ -28,7 +28,6 @@ extern "C" {
#define WITH_TESTS
#include <hicn/strategies/local_prefixes.h>
#include <hicn/core/strategy.h>
-#include <hicn/core/name.h>
}
const char *name_str1 = "b001::0";
@@ -51,53 +50,65 @@ class LocalPrefixesTest : public ::testing::Test {
};
TEST_F(LocalPrefixesTest, LocalPrefixesAddName) {
+ int rc;
local_prefixes_t *lp = create_local_prefixes();
EXPECT_FALSE(lp == nullptr);
- ip_address_t result;
- inet_pton(AF_INET6, name_str1, (struct in6_addr *)&result);
- Name name1;
- name_CreateFromAddress(&name1, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str2, (struct in6_addr *)&result);
- Name name2;
- name_CreateFromAddress(&name2, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str3, (struct in6_addr *)&result);
- Name name3;
- name_CreateFromAddress(&name3, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str4, (struct in6_addr *)&result);
- Name name4;
- name_CreateFromAddress(&name4, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str5, (struct in6_addr *)&result);
- Name name5;
- name_CreateFromAddress(&name5, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str6, (struct in6_addr *)&result);
- Name name6;
- name_CreateFromAddress(&name6, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str7, (struct in6_addr *)&result);
- Name name7;
- name_CreateFromAddress(&name7, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str8, (struct in6_addr *)&result);
- Name name8;
- name_CreateFromAddress(&name8, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str9, (struct in6_addr *)&result);
- Name name9;
- name_CreateFromAddress(&name9, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str10, (struct in6_addr *)&result);
- Name name10;
- name_CreateFromAddress(&name10, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str11, (struct in6_addr *)&result);
- Name name11;
- name_CreateFromAddress(&name11, AF_INET6, result, 128);
+ hicn_ip_address_t result = IP_ADDRESS_EMPTY;
+ hicn_ip_address_pton(name_str1, &result);
+ hicn_prefix_t name1;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name1);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str2, &result);
+ hicn_prefix_t name2;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name2);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str3, &result);
+ hicn_prefix_t name3;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name3);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str4, &result);
+ hicn_prefix_t name4;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name4);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str5, &result);
+ hicn_prefix_t name5;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name5);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str6, &result);
+ hicn_prefix_t name6;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name6);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str7, &result);
+ hicn_prefix_t name7;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name7);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str8, &result);
+ hicn_prefix_t name8;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name8);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str9, &result);
+ hicn_prefix_t name9;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name9);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str10, &result);
+ hicn_prefix_t name10;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name10);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str11, &result);
+ hicn_prefix_t name11;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name11);
+ EXPECT_EQ(rc, 0);
local_prefixes_add_prefix(lp, &name1);
EXPECT_EQ(local_prefixes_get_len(lp), (unsigned)1);
@@ -142,29 +153,34 @@ TEST_F(LocalPrefixesTest, LocalPrefixesAddName) {
}
TEST_F(LocalPrefixesTest, LocalPrefixesAddPrefixes) {
+ int rc;
local_prefixes_t *lp = create_local_prefixes();
EXPECT_FALSE(lp == nullptr);
- ip_address_t result;
+ hicn_ip_address_t result;
local_prefixes_t *lp1 = create_local_prefixes();
EXPECT_FALSE(lp1 == nullptr);
- inet_pton(AF_INET6, name_str1, (struct in6_addr *)&result);
- Name name1;
- name_CreateFromAddress(&name1, AF_INET6, result, 128);
+ hicn_ip_address_pton(name_str1, &result);
+ hicn_prefix_t name1;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name1);
+ EXPECT_EQ(rc, 0);
- inet_pton(AF_INET6, name_str2, (struct in6_addr *)&result);
- Name name2;
- name_CreateFromAddress(&name2, AF_INET6, result, 128);
+ hicn_ip_address_pton(name_str2, &result);
+ hicn_prefix_t name2;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name2);
+ EXPECT_EQ(rc, 0);
- inet_pton(AF_INET6, name_str3, (struct in6_addr *)&result);
- Name name3;
- name_CreateFromAddress(&name3, AF_INET6, result, 128);
+ hicn_ip_address_pton(name_str3, &result);
+ hicn_prefix_t name3;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name3);
+ EXPECT_EQ(rc, 0);
- inet_pton(AF_INET6, name_str4, (struct in6_addr *)&result);
- Name name4;
- name_CreateFromAddress(&name4, AF_INET6, result, 128);
+ hicn_ip_address_pton(name_str4, &result);
+ hicn_prefix_t name4;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name4);
+ EXPECT_EQ(rc, 0);
local_prefixes_add_prefix(lp1, &name1);
local_prefixes_add_prefix(lp1, &name2);
@@ -182,33 +198,40 @@ TEST_F(LocalPrefixesTest, LocalPrefixesAddPrefixes) {
local_prefixes_t *lp2 = create_local_prefixes();
EXPECT_FALSE(lp2 == nullptr);
- inet_pton(AF_INET6, name_str5, (struct in6_addr *)&result);
- Name name5;
- name_CreateFromAddress(&name5, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str6, (struct in6_addr *)&result);
- Name name6;
- name_CreateFromAddress(&name6, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str7, (struct in6_addr *)&result);
- Name name7;
- name_CreateFromAddress(&name7, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str8, (struct in6_addr *)&result);
- Name name8;
- name_CreateFromAddress(&name8, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str9, (struct in6_addr *)&result);
- Name name9;
- name_CreateFromAddress(&name9, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str10, (struct in6_addr *)&result);
- Name name10;
- name_CreateFromAddress(&name10, AF_INET6, result, 128);
-
- inet_pton(AF_INET6, name_str11, (struct in6_addr *)&result);
- Name name11;
- name_CreateFromAddress(&name11, AF_INET6, result, 128);
+ hicn_ip_address_pton(name_str5, &result);
+ hicn_prefix_t name5;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name5);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str6, &result);
+ hicn_prefix_t name6;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name6);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str7, &result);
+ hicn_prefix_t name7;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name7);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str8, &result);
+ hicn_prefix_t name8;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name8);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str9, &result);
+ hicn_prefix_t name9;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name9);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str10, &result);
+ hicn_prefix_t name10;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name10);
+ EXPECT_EQ(rc, 0);
+
+ hicn_ip_address_pton(name_str11, &result);
+ hicn_prefix_t name11;
+ rc = hicn_prefix_create_from_ip_address_len(&result, 128, &name11);
+ EXPECT_EQ(rc, 0);
local_prefixes_add_prefix(lp2, &name5);
local_prefixes_add_prefix(lp2, &name6);
diff --git a/hicn-light/src/hicn/test/test-msgbuf_pool.cc b/hicn-light/src/hicn/test/test-msgbuf_pool.cc
index e9c8e6424..0a78a7a5d 100644
--- a/hicn-light/src/hicn/test/test-msgbuf_pool.cc
+++ b/hicn-light/src/hicn/test/test-msgbuf_pool.cc
@@ -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:
@@ -100,7 +100,7 @@ TEST_F(MsgbufPoolTest, AcquireMsgbuf) {
// Get msgbuf from msgbuf_pool
off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, &msgbuf);
- msgbuf->type = MSGBUF_TYPE_COMMAND;
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
EXPECT_NE(msgbuf, nullptr);
EXPECT_NE(msgbuf_id_is_valid((unsigned long)msgbuf_id), 0);
@@ -119,7 +119,7 @@ TEST_F(MsgbufPoolTest, ReleaseMsgbuf) {
// Get msgbuf from msgbuf_pool
off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, &msgbuf);
- msgbuf->type = MSGBUF_TYPE_COMMAND;
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
EXPECT_NE(msgbuf, nullptr);
EXPECT_NE(msgbuf_id_is_valid((unsigned long)msgbuf_id), 0);
@@ -137,7 +137,7 @@ TEST_F(MsgbufPoolTest, ReleaseNotAcquiredMsgbuf) {
// Get valid msgbuf from msgbuf_pool
off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, &msgbuf);
- msgbuf->type = MSGBUF_TYPE_COMMAND;
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
EXPECT_NE(msgbuf, nullptr);
EXPECT_NE(msgbuf_id_is_valid((unsigned long)msgbuf_id), 0);
@@ -157,7 +157,7 @@ TEST_F(MsgbufPoolTest, MultipleAcquireAndReleaseMsgbuf) {
// Get msgbuf from msgbuf_pool
off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, &msgbuf);
- msgbuf->type = MSGBUF_TYPE_COMMAND;
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
EXPECT_NE(msgbuf, nullptr);
EXPECT_NE(msgbuf_id_is_valid((unsigned long)msgbuf_id), 0);
@@ -177,7 +177,7 @@ TEST_F(MsgbufPoolTest, MultipleAcquireAndReleaseMsgbuf) {
TEST_F(MsgbufPoolTest, CloneMsgbuf) {
msgbuf_t *msgbuf = NULL;
off_t msgbuf_id = msgbuf_pool_get(msgbuf_pool, &msgbuf);
- msgbuf->type = MSGBUF_TYPE_COMMAND;
+ msgbuf_set_type(msgbuf, HICN_PACKET_TYPE_COMMAND);
EXPECT_NE(msgbuf, nullptr);
EXPECT_NE(msgbuf_id_is_valid((unsigned long)msgbuf_id), 0);
diff --git a/hicn-light/src/hicn/test/test-packet_cache.cc b/hicn-light/src/hicn/test/test-packet_cache.cc
index 0b4b214f0..76fdb4516 100644
--- a/hicn-light/src/hicn/test/test-packet_cache.cc
+++ b/hicn-light/src/hicn/test/test-packet_cache.cc
@@ -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:
@@ -31,8 +31,6 @@ static constexpr unsigned MSGBUF_ID = 0;
static constexpr unsigned MSGBUF_ID_2 = 1;
static constexpr unsigned MSGBUF_ID_3 = 2;
static constexpr unsigned FIVE_SECONDS = 5000;
-static constexpr unsigned IPV4_LEN = 32;
-static constexpr unsigned IPV6_LEN = 128;
static constexpr int N_OPS = 50000;
@@ -40,39 +38,50 @@ class PacketCacheTest : public ::testing::Test {
protected:
PacketCacheTest() {
pkt_cache = pkt_cache_create(CS_SIZE);
- name = (Name *)malloc(sizeof(Name));
- name_CreateFromAddress(name, AF_INET, IPV4_ANY, IPV4_LEN);
+ int rc = hicn_name_create_from_ip_address(IPV4_ANY, 0, &name);
+ EXPECT_EQ(rc, 0);
msgbuf_pool = msgbuf_pool_create();
- msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, name);
+ msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, &name);
}
virtual ~PacketCacheTest() {
- free(name);
msgbuf_pool_free(msgbuf_pool);
pkt_cache_free(pkt_cache);
}
msgbuf_t *msgbuf_create(msgbuf_pool_t *msgbuf_pool, unsigned conn_id,
- Name *name,
+ hicn_name_t *name,
std::optional<Ticks> lifetime = FIVE_SECONDS) {
msgbuf_t *msgbuf;
msgbuf_pool_get(msgbuf_pool, &msgbuf);
msgbuf->connection_id = conn_id;
- name_Copy(name, msgbuf_get_name(msgbuf));
- hicn_packet_init_header(HF_INET6_TCP,
- (hicn_header_t *)msgbuf_get_packet(msgbuf));
+ msgbuf_set_name(msgbuf, name);
+
+ hicn_packet_set_format(msgbuf_get_pkbuf(msgbuf),
+ HICN_PACKET_FORMAT_IPV6_TCP);
+ hicn_packet_set_type(msgbuf_get_pkbuf(msgbuf), HICN_PACKET_TYPE_INTEREST);
+
+ hicn_packet_buffer_t *pkbuf = msgbuf_get_pkbuf(msgbuf);
+ hicn_packet_set_buffer(pkbuf, msgbuf->packet, MTU, 0);
+
+ int rc = hicn_packet_init_header(msgbuf_get_pkbuf(msgbuf), 0);
+ EXPECT_EQ(rc, 0);
+
+ // Same as 'msgbuf_set_data_expiry_time',
+ // it would write in the same field
msgbuf_set_interest_lifetime(msgbuf, *lifetime);
return msgbuf;
}
- Name get_name_from_prefix(const char *prefix_str) {
- ip_address_t prefix;
+ hicn_name_t get_name_from_prefix(const char *prefix_str) {
+ hicn_ip_address_t prefix;
inet_pton(AF_INET6, prefix_str, (struct in6_addr *)&prefix);
- Name name;
- name_CreateFromAddress(&name, AF_INET6, prefix, IPV6_LEN);
+ hicn_name_t name;
+ int rc = hicn_name_create_from_ip_address(prefix, 0, &name);
+ EXPECT_EQ(rc, 0);
return name;
}
@@ -80,39 +89,33 @@ class PacketCacheTest : public ::testing::Test {
pkt_cache_t *pkt_cache;
pkt_cache_entry_t *entry = nullptr;
msgbuf_pool_t *msgbuf_pool;
- Name *name;
+ hicn_name_t name;
msgbuf_t *msgbuf;
};
TEST_F(PacketCacheTest, LowLevelOperations) {
- int rc;
kh_pkt_cache_prefix_t *prefix_to_suffixes = kh_init_pkt_cache_prefix();
- NameBitvector *prefix = name_GetContentName(name);
+ const hicn_name_prefix_t *prefix = hicn_name_get_prefix(&name);
_add_suffix(prefix_to_suffixes, prefix, 1, 11);
_add_suffix(prefix_to_suffixes, prefix, 2, 22);
- unsigned id = _get_suffix(prefix_to_suffixes, prefix, 1, &rc);
- EXPECT_EQ(rc, KH_FOUND);
- EXPECT_EQ(id, 11);
+ unsigned id = _get_suffix(prefix_to_suffixes, prefix, 1);
+ EXPECT_EQ(id, 11UL);
- id = _get_suffix(prefix_to_suffixes, prefix, 2, &rc);
- EXPECT_EQ(rc, KH_FOUND);
- EXPECT_EQ(id, 22);
+ id = _get_suffix(prefix_to_suffixes, prefix, 2);
+ EXPECT_EQ(id, 22UL);
- id = _get_suffix(prefix_to_suffixes, prefix, 5, &rc);
- EXPECT_EQ(rc, KH_NOT_FOUND);
- EXPECT_EQ(id, -1);
+ id = _get_suffix(prefix_to_suffixes, prefix, 5);
+ EXPECT_EQ(id, HICN_INVALID_SUFFIX);
_add_suffix(prefix_to_suffixes, prefix, 5, 55);
- id = _get_suffix(prefix_to_suffixes, prefix, 5, &rc);
- EXPECT_EQ(rc, KH_FOUND);
- EXPECT_EQ(id, 55);
+ id = _get_suffix(prefix_to_suffixes, prefix, 5);
+ EXPECT_EQ(id, 55UL);
_remove_suffix(prefix_to_suffixes, prefix, 2);
_add_suffix(prefix_to_suffixes, prefix, 2, 222);
- id = _get_suffix(prefix_to_suffixes, prefix, 2, &rc);
- EXPECT_EQ(rc, KH_FOUND);
- EXPECT_EQ(id, 222);
+ id = _get_suffix(prefix_to_suffixes, prefix, 2);
+ EXPECT_EQ(id, 222UL);
_prefix_map_free(prefix_to_suffixes);
}
@@ -133,15 +136,17 @@ TEST_F(PacketCacheTest, CreatePacketCache) {
TEST_F(PacketCacheTest, AddPacketCacheEntry) {
// Add entry to the packet cache
- entry = pkt_cache_allocate(pkt_cache, name);
+ entry = pkt_cache_allocate(pkt_cache);
EXPECT_NE(entry, nullptr);
+ entry->name = name;
ASSERT_EQ(pkt_cache_get_size(pkt_cache), 1u);
+ pkt_cache_add_to_index(pkt_cache, entry);
// Get entry by name
pkt_cache_lookup_t lookup_result;
off_t entry_id;
- pkt_cache_entry_t *entry = pkt_cache_lookup(pkt_cache, name, msgbuf_pool,
- &lookup_result, &entry_id, true);
+ pkt_cache_lookup(pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id,
+ true);
EXPECT_NE(lookup_result, PKT_CACHE_LU_NONE);
}
@@ -165,7 +170,7 @@ TEST_F(PacketCacheTest, GetPIT) {
TEST_F(PacketCacheTest, LookupEmpty) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
- pkt_cache_entry_t *entry = pkt_cache_lookup(pkt_cache, name, msgbuf_pool,
+ pkt_cache_entry_t *entry = pkt_cache_lookup(pkt_cache, &name, msgbuf_pool,
&lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
@@ -174,15 +179,17 @@ TEST_F(PacketCacheTest, LookupEmpty) {
TEST_F(PacketCacheTest, AddEntryAndLookup) {
// Add entry to the packet cache
- entry = pkt_cache_allocate(pkt_cache, name);
+ entry = pkt_cache_allocate(pkt_cache);
+ entry->name = name;
entry->entry_type = PKT_CACHE_PIT_TYPE;
ASSERT_NE(entry, nullptr);
+ pkt_cache_add_to_index(pkt_cache, entry);
// Perform lookup
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_TRUE(lookup_result == PKT_CACHE_LU_INTEREST_NOT_EXPIRED ||
lookup_result == PKT_CACHE_LU_INTEREST_EXPIRED);
@@ -192,7 +199,7 @@ TEST_F(PacketCacheTest, AddEntryAndLookup) {
TEST_F(PacketCacheTest, AddToPIT) {
// Check if entry properly created
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
ASSERT_NE(entry, nullptr);
EXPECT_EQ(entry->entry_type, PKT_CACHE_PIT_TYPE);
EXPECT_TRUE(pit_entry_ingress_contains(&entry->u.pit_entry, CONN_ID));
@@ -203,7 +210,7 @@ TEST_F(PacketCacheTest, AddToPIT) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
@@ -229,14 +236,14 @@ TEST_F(PacketCacheTest, AddToCS) {
// Check if hashtable correctly updated
pkt_cache_lookup_t lookup_result;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
TEST_F(PacketCacheTest, PitToCS) {
// Prepare PIT entry
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
@@ -261,7 +268,7 @@ TEST_F(PacketCacheTest, PitToCS) {
// Check if hashtable correctly updated
pkt_cache_lookup_t lookup_result;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
@@ -286,18 +293,19 @@ TEST_F(PacketCacheTest, CsToPIT) {
// Check if hashtable correctly updated
pkt_cache_lookup_t lookup_result;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
TEST_F(PacketCacheTest, UpdateInPIT) {
// Prepare PIT entry
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
- Name new_name;
- name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t new_name;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &new_name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *new_msgbuf = msgbuf_create(msgbuf_pool, CONN_ID_2, &new_name);
// Check if entry properly updated
@@ -311,7 +319,7 @@ TEST_F(PacketCacheTest, UpdateInPIT) {
// Check if hashtable correctly updated
pkt_cache_lookup_t lookup_result;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
@@ -322,8 +330,9 @@ TEST_F(PacketCacheTest, UpdateInCS) {
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
off_t entry_id = pkt_cache_get_entry_id(pkt_cache, entry);
- Name new_name;
- name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t new_name;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &new_name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *new_msgbuf = msgbuf_create(msgbuf_pool, CONN_ID_2, &new_name);
// Check if entry properly updated
@@ -338,18 +347,18 @@ TEST_F(PacketCacheTest, UpdateInCS) {
// Check if hashtable correctly updated
pkt_cache_lookup_t lookup_result;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
TEST_F(PacketCacheTest, RemoveFromPIT) {
// Prepare PIT entry
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
- pkt_cache_pit_remove_entry(pkt_cache, entry, name);
+ pkt_cache_pit_remove_entry(pkt_cache, entry);
ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 0u);
ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
@@ -357,7 +366,7 @@ TEST_F(PacketCacheTest, RemoveFromPIT) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
EXPECT_EQ(lu_entry, nullptr);
}
@@ -383,15 +392,16 @@ TEST_F(PacketCacheTest, RemoveFromCS) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_NONE);
EXPECT_EQ(lu_entry, nullptr);
}
TEST_F(PacketCacheTest, AddTwoEntriesToCS) {
// Prepare another msgbuf
- Name new_name;
- name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t new_name;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &new_name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *new_msgbuf = msgbuf_create(msgbuf_pool, CONN_ID_2, &new_name);
pkt_cache_entry_t *entry_1 =
@@ -412,16 +422,17 @@ TEST_F(PacketCacheTest, AddTwoEntriesToCS) {
TEST_F(PacketCacheTest, AggregateInPIT) {
// Prepare another msgbuf
- Name new_name;
- name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t new_name;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &new_name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *new_msgbuf = msgbuf_create(msgbuf_pool, CONN_ID_2, &new_name);
// Check if entry properly created (use sleep to get an updated ts)
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
Ticks old_lifetime = entry->expire_ts;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
bool is_aggregated =
- pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf, name);
+ pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf, &name);
Ticks new_lifetime = entry->expire_ts;
ASSERT_NE(entry, nullptr);
@@ -433,23 +444,24 @@ TEST_F(PacketCacheTest, AggregateInPIT) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
TEST_F(PacketCacheTest, RetransmissionInPIT) {
// Prepare another msgbuf (using same connection ID)
- Name new_name;
- name_CreateFromAddress(&new_name, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t new_name;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &new_name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *new_msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, &new_name);
// Check if entry properly created (use sleep to get an updated ts)
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
Ticks old_lifetime = entry->expire_ts;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
bool is_aggregated =
- pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf, name);
+ pkt_cache_try_aggregate_in_pit(pkt_cache, entry, new_msgbuf, &name);
Ticks new_lifetime = entry->expire_ts;
ASSERT_NE(entry, nullptr);
@@ -461,17 +473,17 @@ TEST_F(PacketCacheTest, RetransmissionInPIT) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
pkt_cache_entry_t *lu_entry = pkt_cache_lookup(
- pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id, true);
+ pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id, true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_NOT_EXPIRED);
EXPECT_EQ(lu_entry, entry);
}
TEST_F(PacketCacheTest, LookupExpiredInterest) {
// Prepare msgbuf with 0 as interest lifetime
- msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, name, 0);
+ msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, &name, 0);
// Add to PIT
- pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, name);
+ pkt_cache_entry_t *entry = pkt_cache_add_to_pit(pkt_cache, msgbuf, &name);
ASSERT_NE(entry, nullptr);
// Wait to make the interest expire
@@ -479,14 +491,14 @@ TEST_F(PacketCacheTest, LookupExpiredInterest) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
- pkt_cache_lookup(pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id,
+ pkt_cache_lookup(pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id,
true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_INTEREST_EXPIRED);
}
TEST_F(PacketCacheTest, LookupExpiredData) {
// Prepare msgbuf with 0 as data expiry time
- msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, name, 0);
+ msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, &name, 0);
// Add to CS
pkt_cache_entry_t *entry =
@@ -498,25 +510,27 @@ TEST_F(PacketCacheTest, LookupExpiredData) {
pkt_cache_lookup_t lookup_result;
off_t entry_id;
- pkt_cache_lookup(pkt_cache, name, msgbuf_pool, &lookup_result, &entry_id,
+ pkt_cache_lookup(pkt_cache, &name, msgbuf_pool, &lookup_result, &entry_id,
true);
EXPECT_EQ(lookup_result, PKT_CACHE_LU_DATA_EXPIRED);
}
TEST_F(PacketCacheTest, GetStaleEntries) {
// Add to CS a msgbuf with immediate expiration (i.e. stale)
- msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, name, 0);
+ msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, CONN_ID, &name, 0);
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, MSGBUF_ID);
// Add to CS another msgbuf with immediate expiration (i.e. stale)
- Name name_2;
- name_CreateFromAddress(&name_2, AF_INET, IPV4_LOOPBACK, IPV4_LEN);
+ hicn_name_t name_2;
+ int rc = hicn_name_create_from_ip_address(IPV4_LOOPBACK, 0, &name_2);
+ EXPECT_EQ(rc, 0);
msgbuf_t *msgbuf_2 = msgbuf_create(msgbuf_pool, CONN_ID, &name_2, 0);
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf_2, MSGBUF_ID_2);
// Add to CS a msgbuf with 5-seconds expiration (i.e. not stale)
- Name name_3;
- name_CreateFromAddress(&name_3, AF_INET6, IPV6_LOOPBACK, IPV6_LEN);
+ hicn_name_t name_3;
+ rc = hicn_name_create_from_ip_address(IPV6_LOOPBACK, 0, &name_3);
+ EXPECT_EQ(rc, 0);
msgbuf_t *msgbuf_3 =
msgbuf_create(msgbuf_pool, CONN_ID, &name_3, FIVE_SECONDS);
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf_3, MSGBUF_ID_3);
@@ -526,17 +540,19 @@ TEST_F(PacketCacheTest, GetStaleEntries) {
}
TEST_F(PacketCacheTest, GetMultipleStaleEntries) {
- ip_address_t addr;
+ hicn_ip_address_t addr;
char name[30];
const int NUM_STALES = 10;
+ int rc;
// Add to CS multiple msgbufs with immediate expiration (i.e. 0 seconds),
// resulting in stale entries
for (int i = 0; i < NUM_STALES; i++) {
snprintf(name, 30, "b001::%d", i);
inet_pton(AF_INET6, name, (struct in6_addr *)&addr);
- Name name;
- name_CreateFromAddress(&name, AF_INET6, addr, IPV6_LEN);
+ hicn_name_t name;
+ rc = hicn_name_create_from_ip_address(addr, 0, &name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, i, &name, 0);
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, i);
@@ -547,8 +563,9 @@ TEST_F(PacketCacheTest, GetMultipleStaleEntries) {
for (int i = NUM_STALES; i < 15; i++) {
snprintf(name, 30, "b001::%d", i);
inet_pton(AF_INET6, name, (struct in6_addr *)&addr);
- Name name;
- name_CreateFromAddress(&name, AF_INET6, addr, IPV6_LEN);
+ hicn_name_t name;
+ rc = hicn_name_create_from_ip_address(addr, 0, &name);
+ EXPECT_EQ(rc, 0);
msgbuf_t *msgbuf = msgbuf_create(msgbuf_pool, i, &name, FIVE_SECONDS);
pkt_cache_add_to_cs(pkt_cache, msgbuf_pool, msgbuf, i);
@@ -559,23 +576,22 @@ TEST_F(PacketCacheTest, GetMultipleStaleEntries) {
}
TEST_F(PacketCacheTest, PerformanceDoubleLookup) {
- Name tmp = get_name_from_prefix("b001::0");
+ hicn_name_t tmp = get_name_from_prefix("b001::0");
auto elapsed_time_double = get_execution_time([&]() {
kh_pkt_cache_prefix_t *prefix_to_suffixes = kh_init_pkt_cache_prefix();
// Add to hash table
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seq);
- _add_suffix(prefix_to_suffixes, name_GetContentName(&tmp),
- name_GetSegment(&tmp), name_GetSegment(&tmp));
+ hicn_name_set_suffix(&tmp, seq);
+ _add_suffix(prefix_to_suffixes, hicn_name_get_prefix(&tmp),
+ hicn_name_get_suffix(&tmp), hicn_name_get_suffix(&tmp));
}
// Read from hash table
- int rc;
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seq);
- _get_suffix(prefix_to_suffixes, name_GetContentName(&tmp), seq, &rc);
+ hicn_name_set_suffix(&tmp, seq);
+ _get_suffix(prefix_to_suffixes, hicn_name_get_prefix(&tmp), seq);
}
_prefix_map_free(prefix_to_suffixes);
@@ -584,24 +600,24 @@ TEST_F(PacketCacheTest, PerformanceDoubleLookup) {
}
TEST_F(PacketCacheTest, PerformanceCachedLookup) {
- Name tmp = get_name_from_prefix("b001::0");
+ hicn_name_t tmp = get_name_from_prefix("b001::0");
auto elapsed_time_single = get_execution_time([&]() {
kh_pkt_cache_prefix_t *prefix_to_suffixes = kh_init_pkt_cache_prefix();
kh_pkt_cache_suffix_t *suffixes =
- _get_suffixes(prefix_to_suffixes, name_GetContentName(&tmp));
+ _get_suffixes(prefix_to_suffixes, hicn_name_get_prefix(&tmp), true);
// Add to hash table
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seq);
- __add_suffix(suffixes, name_GetSegment(&tmp), name_GetSegment(&tmp));
+ hicn_name_set_suffix(&tmp, seq);
+ __add_suffix(suffixes, hicn_name_get_suffix(&tmp),
+ hicn_name_get_suffix(&tmp));
}
// Read from hash table
- int rc;
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seq);
- __get_suffix(suffixes, name_GetSegment(&tmp), &rc);
+ hicn_name_set_suffix(&tmp, seq);
+ __get_suffix(suffixes, hicn_name_get_suffix(&tmp));
}
_prefix_map_free(prefix_to_suffixes);
@@ -610,7 +626,7 @@ TEST_F(PacketCacheTest, PerformanceCachedLookup) {
}
TEST_F(PacketCacheTest, PerformanceCachedLookupRandom) {
- Name tmp = get_name_from_prefix("b001::0");
+ hicn_name_t tmp = get_name_from_prefix("b001::0");
// Prepare random sequence numbers
std::random_device rd;
@@ -622,19 +638,19 @@ TEST_F(PacketCacheTest, PerformanceCachedLookupRandom) {
auto elapsed_time_single_rand = get_execution_time([&]() {
kh_pkt_cache_prefix_t *prefix_to_suffixes = kh_init_pkt_cache_prefix();
kh_pkt_cache_suffix_t *suffixes =
- _get_suffixes(prefix_to_suffixes, name_GetContentName(&tmp));
+ _get_suffixes(prefix_to_suffixes, hicn_name_get_prefix(&tmp), true);
// Add to hash table
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seqs[seq]);
- __add_suffix(suffixes, name_GetSegment(&tmp), name_GetSegment(&tmp));
+ hicn_name_set_suffix(&tmp, seqs[seq]);
+ __add_suffix(suffixes, hicn_name_get_suffix(&tmp),
+ hicn_name_get_suffix(&tmp));
}
// Read from hash table
- int rc;
for (int seq = 0; seq < N_OPS; seq++) {
- name_SetSegment(&tmp, seqs[seq]);
- __get_suffix(suffixes, name_GetSegment(&tmp), &rc);
+ hicn_name_set_suffix(&tmp, seqs[seq]);
+ __get_suffix(suffixes, hicn_name_get_suffix(&tmp));
}
_prefix_map_free(prefix_to_suffixes);
@@ -643,17 +659,17 @@ TEST_F(PacketCacheTest, PerformanceCachedLookupRandom) {
}
TEST_F(PacketCacheTest, Clear) {
- Name tmp_name1, tmp_name2;
+ hicn_name_t tmp_name1, tmp_name2;
cs_t *cs = pkt_cache_get_cs(pkt_cache);
// Create name and add to msgbuf pool
- name_Copy(name, &tmp_name1);
- name_SetSegment(&tmp_name1, 1);
+ hicn_name_copy(&tmp_name1, &name);
+ hicn_name_set_suffix(&tmp_name1, 1);
msgbuf_t *tmp_msgbuf1 = msgbuf_create(msgbuf_pool, CONN_ID_2, &tmp_name1);
// Create (another) name and add to msgbuf pool
- name_Copy(name, &tmp_name2);
- name_SetSegment(&tmp_name2, 2);
+ hicn_name_copy(&tmp_name2, &name);
+ hicn_name_set_suffix(&tmp_name2, 2);
msgbuf_t *tmp_msgbuf2 = msgbuf_create(msgbuf_pool, CONN_ID_2, &tmp_name2);
// Add to packet cache (2 entries in the CS, 1 in the PIT)
@@ -665,7 +681,7 @@ TEST_F(PacketCacheTest, Clear) {
ASSERT_EQ(pkt_cache_get_size(pkt_cache), 3u);
ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 2u);
- ASSERT_EQ(cs->num_entries, 2u);
+ ASSERT_EQ(cs->num_entries, 2);
ASSERT_EQ(cs->stats.lru.countAdds, 2u);
// Clear packet cache (i.e. remove content packets from packet cache):
@@ -677,6 +693,6 @@ TEST_F(PacketCacheTest, Clear) {
ASSERT_EQ(pkt_cache_get_size(pkt_cache), 1u);
ASSERT_EQ(pkt_cache_get_pit_size(pkt_cache), 1u);
ASSERT_EQ(pkt_cache_get_cs_size(pkt_cache), 0u);
- ASSERT_EQ(cs->num_entries, 0u);
+ ASSERT_EQ(cs->num_entries, 0);
ASSERT_EQ(cs->stats.lru.countAdds, 0u);
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/test/test-parser.cc b/hicn-light/src/hicn/test/test-parser.cc
index 3a8d2cdb2..2e396b97d 100644
--- a/hicn-light/src/hicn/test/test-parser.cc
+++ b/hicn-light/src/hicn/test/test-parser.cc
@@ -17,7 +17,7 @@
extern "C" {
#include <hicn/util/log.h>
-#include <hicn/config/parse.h>
+#include <hicn/ctrl/parse.h>
}
class ParserTest : public ::testing::Test {
@@ -68,4 +68,4 @@ TEST_F(ParserTest, AddListenerInvalidPortString) {
TEST_F(ParserTest, UnknownCommnad) {
std::string cmd = "add face";
ASSERT_EQ(parse(cmd.c_str(), &command_), -1);
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/test/test-pool.cc b/hicn-light/src/hicn/test/test-pool.cc
deleted file mode 100644
index 8cd891d6a..000000000
--- a/hicn-light/src/hicn/test/test-pool.cc
+++ /dev/null
@@ -1,196 +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 <gtest/gtest.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <netinet/in.h>
-
-extern "C" {
-#define WITH_TESTS
-#include <hicn/util/pool.h>
-}
-
-/*
- * TODO
- * - test max_size
- */
-
-#define DEFAULT_SIZE 10
-
-class PoolTest : public ::testing::Test {
- protected:
- PoolTest() {}
- virtual ~PoolTest() {}
-
- int *pool;
-};
-
-TEST_F(PoolTest, PoolAllocation) {
- int rc;
-
- pool_init(pool, DEFAULT_SIZE, 0);
-
- size_t pool_size = next_pow2(DEFAULT_SIZE);
-
- EXPECT_EQ(pool_get_alloc_size(pool), pool_size);
-
- /* Check that free indices and bitmaps are correctly initialize */
- off_t *fi = pool_get_free_indices(pool);
- EXPECT_EQ(vector_len(fi), pool_size);
- EXPECT_EQ(fi[0], (long)(pool_size - 1));
- EXPECT_EQ(fi[pool_size - 1], 0);
-
- /* The allocated size of the underlying vector should be the next power of two
- */
- EXPECT_EQ(vector_get_alloc_size(fi), pool_size);
-
- bitmap_t *fb = pool_get_free_bitmap(pool);
- EXPECT_TRUE(bitmap_is_set(fb, 0));
- EXPECT_TRUE(bitmap_is_set(fb, pool_size - 2));
- EXPECT_TRUE(bitmap_is_set(fb, pool_size - 1));
- EXPECT_TRUE(bitmap_is_unset(fb, pool_size));
-
- /* Getting elements from the pool should correctly update the free indices
- * and bitmap */
- int *elt;
-
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(vector_len(fi), pool_size - 1);
- EXPECT_TRUE(bitmap_is_unset(fb, 0));
-
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(vector_len(fi), pool_size - 2);
- EXPECT_TRUE(bitmap_is_unset(fb, 1));
-
- for (unsigned i = 0; i < pool_size - 4; i++) {
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
- }
-
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(vector_len(fi), 1UL);
- EXPECT_TRUE(bitmap_is_unset(fb, pool_size - 2));
-
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
- EXPECT_EQ(vector_len(fi), 0UL);
- EXPECT_TRUE(bitmap_is_unset(fb, pool_size - 1));
-
- /*
- * Getting elements within the allocated range should not have triggered a
- * resize
- */
- EXPECT_EQ(pool_len(pool), pool_size);
-
- /*
- * Getting elements once the allocated range has been exceeded should
- * trigger a resize
- */
- rc = pool_get(pool, elt);
- EXPECT_GE(rc, 0);
-
- EXPECT_EQ(pool_get_alloc_size(pool), pool_size * 2);
-
- EXPECT_EQ(pool_len(pool), pool_size + 1);
-
- /*
- * Doubling the size, we should have again pool_size elements free, minus 1
- */
- EXPECT_EQ(pool_get_free_indices_size(pool), pool_size - 1);
-
- /*
- * NOTE: this is wrong as there has been a realloc and the old fi
- * pointer is now invalid
- */
- // EXPECT_EQ(vector_len(fi), pool_size - 1);
-
- /* And the bitmap should also be correctly modified */
- fb = pool_get_free_bitmap(pool);
- EXPECT_TRUE(bitmap_is_unset(fb, pool_size));
-
- /* Check that surrounding values are also correct */
- EXPECT_TRUE(bitmap_is_unset(fb, pool_size - 1));
- EXPECT_TRUE(bitmap_is_set(fb, pool_size + 1));
-
- /* Setting elements after should through */
-
- /* Check that free indices and bitmaps are correctly updated */
-
- pool_free(pool);
-}
-
-TEST_F(PoolTest, PoolPut) {
- pool_init(pool, DEFAULT_SIZE, 0);
-
- int *elt;
- pool_get(pool, elt);
- *elt = 10;
- pool_put(pool, elt);
-
- pool_free(pool);
-}
-
-TEST_F(PoolTest, PoolGetForceBitmapRealloc) {
- const int N = 64;
- int *elts[N];
- int *elt = NULL;
- pool_init(pool, N, 0);
-
- for (int i = 0; i < N; i++) pool_get(pool, elts[i]);
- pool_get(pool, elt);
-
- pool_free(pool);
-}
-
-TEST_F(PoolTest, PoolGetAfterReleasing) {
- int *elt1 = NULL, *elt2 = NULL, *tmp = NULL;
- pool_init(pool, DEFAULT_SIZE, 0);
-
- // If two elements are requested...
- off_t id1 = pool_get(pool, elt1);
- pool_get(pool, tmp);
-
- // ...and the first one is released...
- pool_put(pool, elt1);
-
- // ...requesting a new one should return
- // the first one (that was freed)
- off_t id2 = pool_get(pool, elt2);
- EXPECT_EQ(id1, id2);
- EXPECT_EQ(elt1, elt2);
-
- pool_free(pool);
-}
-
-TEST_F(PoolTest, PoolGetMultipleElementsAfterReleasing) {
- const int N = 2;
- int *elts[N];
- pool_init(pool, N, 0);
-
- for (int i = 0; i < N; i++) pool_get(pool, elts[i]);
- for (int i = 0; i < N; i++) pool_put(pool, elts[i]);
- for (int i = 0; i < N; i++) pool_get(pool, elts[i]);
-
- pool_free(pool);
-}
diff --git a/hicn-light/src/hicn/test/test-ring.cc b/hicn-light/src/hicn/test/test-ring.cc
deleted file mode 100644
index ab96d76c0..000000000
--- a/hicn-light/src/hicn/test/test-ring.cc
+++ /dev/null
@@ -1,99 +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 <gtest/gtest.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <netinet/in.h>
-
-extern "C" {
-#define WITH_TESTS
-#include <hicn/util/ring.h>
-}
-
-#define DEFAULT_SIZE 10UL
-
-class RingTest : public ::testing::Test {
- protected:
- RingTest() { ring_init(ring, DEFAULT_SIZE); }
- virtual ~RingTest() { ring_free(ring); }
-
- int *ring = NULL;
-};
-
-/* TEST: Ring allocation and initialization */
-TEST_F(RingTest, RingAddOne) {
- int val = -1;
- /* Allocated size should be the next power of two */
- EXPECT_EQ(ring_get_size(ring), 0UL);
- ring_add_value(ring, 1);
- EXPECT_EQ(ring_get_size(ring), 1UL);
- ring_get(ring, 0, &val);
- EXPECT_EQ(val, 1);
- EXPECT_EQ(ring_get_size(ring), 1UL);
- ring_advance(ring, 1);
- EXPECT_EQ(ring_get_size(ring), 0UL);
-}
-
-TEST_F(RingTest, RingAddMany) {
- size_t i = 0;
- int val = -1;
- size_t count = 0;
-
- /* Allocated size should be the next power of two */
- EXPECT_EQ(ring_get_size(ring), 0UL);
- for (unsigned i = 0; i < DEFAULT_SIZE; i++) ring_add_value(ring, i);
- EXPECT_EQ(ring_get_size(ring), DEFAULT_SIZE);
-
- count = 0;
- ring_enumerate_n(ring, i, &val, 1, {
- EXPECT_EQ(val, (int)(i));
- count++;
- });
- EXPECT_EQ(count, 1UL);
-
- count = 0;
- ring_enumerate_n(ring, i, &val, DEFAULT_SIZE, {
- EXPECT_EQ(val, (int)(i));
- count++;
- });
- EXPECT_EQ(count, DEFAULT_SIZE);
-
- count = 0;
- ring_enumerate_n(ring, i, &val, DEFAULT_SIZE + 1, {
- EXPECT_EQ(val, (int)(i));
- count++;
- });
- EXPECT_EQ(count, DEFAULT_SIZE);
-
- // Drop one
- ring_add_value(ring, DEFAULT_SIZE);
- EXPECT_EQ(ring_get_size(ring), DEFAULT_SIZE);
-
- count = 0;
- ring_enumerate_n(ring, i, &val, DEFAULT_SIZE, {
- EXPECT_EQ(val, (int)(i + 1)); // all values shoud be shifted
- count++;
- });
- EXPECT_EQ(count, DEFAULT_SIZE);
-
- ring_advance(ring, DEFAULT_SIZE);
- EXPECT_EQ(ring_get_size(ring), 0UL);
-}
diff --git a/hicn-light/src/hicn/test/test-strategy-replication.cc b/hicn-light/src/hicn/test/test-strategy-replication.cc
index ab7dae1f7..2924173cb 100644
--- a/hicn-light/src/hicn/test/test-strategy-replication.cc
+++ b/hicn-light/src/hicn/test/test-strategy-replication.cc
@@ -152,7 +152,6 @@ TEST_F(StrategyReplicationTest, MultipleNexthops) {
/* Retrieve candidate */
- unsigned nexthop;
unsigned tests = 0;
nexthops_foreach(nexthops, nexthop, {
EXPECT_TRUE(nexthop == NEXTHOP_ID1 || nexthop == NEXTHOP_ID2);
diff --git a/hicn-light/src/hicn/test/test-subscription.cc b/hicn-light/src/hicn/test/test-subscription.cc
index f89254e67..5fd3ab57d 100644
--- a/hicn-light/src/hicn/test/test-subscription.cc
+++ b/hicn-light/src/hicn/test/test-subscription.cc
@@ -40,10 +40,10 @@ TEST_F(SubscriptionTest, SetTopic) {
TEST_F(SubscriptionTest, GetObjectFromTopic) {
hc_object_type_t object_type = object_from_topic(TOPIC_STRATEGY);
- EXPECT_EQ(object_type, OBJECT_STRATEGY);
+ EXPECT_EQ(object_type, OBJECT_TYPE_STRATEGY);
object_type = object_from_topic(TOPIC_FACE);
- EXPECT_EQ(object_type, OBJECT_FACE);
+ EXPECT_EQ(object_type, OBJECT_TYPE_FACE);
}
TEST_F(SubscriptionTest, AddSubscription) {
@@ -201,4 +201,4 @@ TEST_F(SubscriptionTest, GetConnectionsForSubscription) {
subscription_table_get_connections_for_topic(subscriptions, TOPIC_FACE);
EXPECT_EQ(vector_len(conn_ids), 1u);
EXPECT_EQ(conn_ids[0], (unsigned)CONN_ID);
-} \ No newline at end of file
+}
diff --git a/hicn-light/src/hicn/test/test-vector.cc b/hicn-light/src/hicn/test/test-vector.cc
deleted file mode 100644
index dda71fd0c..000000000
--- a/hicn-light/src/hicn/test/test-vector.cc
+++ /dev/null
@@ -1,232 +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 <gtest/gtest.h>
-
-extern "C" {
-#include <hicn/util/vector.h>
-}
-
-static constexpr size_t DEFAULT_SIZE = 10;
-static constexpr size_t N_ELEMENTS = 5;
-
-class VectorTest : public ::testing::Test {
- protected:
- VectorTest() { vector_init(vector, DEFAULT_SIZE, 0); }
- virtual ~VectorTest() { vector_free(vector); }
-
- int *vector = NULL;
-};
-
-TEST_F(VectorTest, VectorAllocateAndResize) {
- // Allocated size should be the next power of two
- EXPECT_EQ(vector_get_alloc_size(vector), 16UL);
-
- // Setting elements within the allocated size should not trigger a resize
- vector_ensure_pos(vector, 15);
- EXPECT_EQ(vector_get_alloc_size(vector), 16UL);
-
- // Setting elements after should through
- vector_ensure_pos(vector, 16);
- EXPECT_EQ(vector_get_alloc_size(vector), 32UL);
-}
-
-TEST_F(VectorTest, VectorSize) {
- EXPECT_EQ(vector_len(vector), 0);
-
- // Check size after pushing one element
- vector_push(vector, 1);
- EXPECT_EQ(vector_len(vector), 1);
-
- // Check size after pushing additional elements
- vector_push(vector, 2);
- vector_push(vector, 3);
- EXPECT_EQ(vector_len(vector), 3);
-
- // Try adding multiple elements
- const int n_elements_to_add = 5;
- size_t expected_new_len = vector_len(vector) + n_elements_to_add;
- for (int i = 0; i < n_elements_to_add; i++) vector_push(vector, i);
- EXPECT_EQ(vector_len(vector), expected_new_len);
-}
-
-TEST_F(VectorTest, VectorCheckValue) {
- // Add elements
- vector_push(vector, 109);
- vector_push(vector, 200);
- EXPECT_EQ(vector_at(vector, 0), 109);
- EXPECT_EQ(vector_at(vector, 1), 200);
-
- // Update element
- vector_set(vector, 1, 400);
- EXPECT_EQ(vector_at(vector, 1), 400);
-
- // Add at last available position
- size_t prev_size = vector_len(vector);
- vector_set(vector, vector_len(vector) - 1, 123);
- EXPECT_EQ(vector_at(vector, vector_len(vector) - 1), 123);
- EXPECT_EQ(prev_size, vector_len(vector)) << "Size should not have changed";
-}
-
-TEST_F(VectorTest, RemoveElement) {
- // Populate vector
- for (size_t i = 0; i < N_ELEMENTS; i++) vector_push(vector, i);
- EXPECT_EQ(vector_len(vector), N_ELEMENTS);
- for (size_t i = 0; i < vector_len(vector); i++)
- EXPECT_EQ(vector_at(vector, i), (int)i);
-
- // Remove element
- int value_to_remove = 3;
- int num_removed = vector_remove_unordered(vector, value_to_remove);
-
- EXPECT_EQ(vector_len(vector), N_ELEMENTS - 1);
- EXPECT_EQ(num_removed, 1);
- for (size_t i = 0; i < vector_len(vector); i++)
- EXPECT_NE(vector_at(vector, i), value_to_remove);
-}
-
-TEST_F(VectorTest, RemoveNonExistingElement) {
- // Push some initial values
- vector_push(vector, 1);
- vector_push(vector, 2);
- vector_push(vector, 3);
- EXPECT_EQ(vector_len(vector), 3);
-
- // Remove non-existing element
- int num_removed = vector_remove_unordered(vector, 5);
- EXPECT_EQ(num_removed, 0);
- size_t prev_size = vector_len(vector);
- EXPECT_EQ(prev_size, vector_len(vector)) << "Size should not have changed";
-}
-
-TEST_F(VectorTest, RemoveDuplicatedElement) {
- // Populate vector
- for (size_t i = 0; i < N_ELEMENTS; i++) vector_push(vector, i);
- EXPECT_EQ(vector_len(vector), N_ELEMENTS);
- for (size_t i = 0; i < vector_len(vector); i++)
- EXPECT_EQ(vector_at(vector, i), (int)i);
- vector_set(vector, 0, 3); // Duplicate element
-
- // Remove (duplicated) elements
- int value_to_remove = 3;
- int num_removed = vector_remove_unordered(vector, value_to_remove);
-
- EXPECT_EQ(vector_len(vector), N_ELEMENTS - 2);
- EXPECT_EQ(num_removed, 2);
- for (size_t i = 0; i < vector_len(vector); i++)
- EXPECT_NE(vector_at(vector, i), value_to_remove);
-}
-
-TEST_F(VectorTest, Iterate) {
- for (size_t i = 0; i < N_ELEMENTS; i++) vector_push(vector, i);
-
- int count = 0;
- int *elem;
- vector_foreach(vector, elem, { EXPECT_EQ(*elem, count++); });
-}
-
-TEST_F(VectorTest, MultipleResize) {
- // Use small vector (size=1) to force multiple realloc operations
- int *small_vector;
- vector_init(small_vector, 1, 0);
-
- for (size_t i = 0; i < N_ELEMENTS; i++) vector_push(small_vector, i);
-
- for (size_t i = 0; i < N_ELEMENTS; i++)
- EXPECT_EQ(vector_at(small_vector, i), (int)i);
-
- EXPECT_EQ(vector_len(small_vector), 5UL);
- EXPECT_EQ(vector_get_alloc_size(small_vector), 8UL);
-
- vector_free(small_vector);
-}
-
-TEST_F(VectorTest, MaxSize) {
- const int max_size = 4;
-
- // Fill the vector until max size is reached
- int *small_vector;
- vector_init(small_vector, 2, max_size);
- for (int i = 0; i < max_size; i++) vector_push(small_vector, i);
-
- // Try expanding or appending elements should fail
- int rc = vector_ensure_pos(small_vector, max_size);
- EXPECT_EQ(rc, -1);
- rc = vector_push(small_vector, 123);
- EXPECT_EQ(rc, -1);
-
- vector_free(small_vector);
-}
-
-TEST_F(VectorTest, Contains) {
- // No elements
- EXPECT_EQ(vector_contains(vector, 1), false);
-
- // Push one element
- vector_push(vector, 1);
- EXPECT_EQ(vector_contains(vector, 1), true);
-
- // Update element
- vector_set(vector, 0, 2);
- EXPECT_EQ(vector_contains(vector, 1), false);
- EXPECT_EQ(vector_contains(vector, 2), true);
-}
-
-TEST_F(VectorTest, Remove) {
- // Remove element at invalid position
- int rc = vector_remove_at(vector, 2);
- EXPECT_EQ(rc, -1); // Failure
-
- // Push two elements and remove the second one
- vector_push(vector, 1);
- vector_push(vector, 2);
- rc = vector_remove_at(vector, 1);
- EXPECT_EQ(rc, 0); // Success
- EXPECT_EQ(vector_len(vector), 1);
-
- // Push another element: it should replace the previous one
- vector_push(vector, 3);
- EXPECT_EQ(vector_len(vector), 2);
- EXPECT_EQ(vector_at(vector, 1), 3);
-}
-
-TEST_F(VectorTest, RemoveInTheMiddle) {
- for (size_t i = 0; i < N_ELEMENTS; i++) vector_push(vector, i);
-
- // Remove element in central position
- int rc = vector_remove_at(vector, 2);
- EXPECT_EQ(rc, 0); // Success
- EXPECT_EQ(vector_contains(vector, 2), false);
- EXPECT_EQ(vector_len(vector), N_ELEMENTS - 1);
-
- // Check if elements have been shifted (preserving the order)
- int expected[] = {0, 1, 3, 4};
- for (int i = 0; i < vector_len(vector); i++)
- EXPECT_EQ(vector_at(vector, i), expected[i]);
-}
-
-TEST_F(VectorTest, Reset) {
- vector_push(vector, 1);
- vector_push(vector, 2);
- EXPECT_EQ(vector_len(vector), 2);
-
- vector_reset(vector);
- EXPECT_EQ(vector_len(vector), 0);
-
- vector_push(vector, 5);
- EXPECT_EQ(vector_len(vector), 1);
- EXPECT_EQ(vector_contains(vector, 5), true);
- EXPECT_EQ(vector_at(vector, 0), 5);
-} \ No newline at end of file
diff --git a/hicn-light/src/hicn/test/test-hash.cc b/hicn-light/src/hicn/test/test_hash.cc
index 3b03a08a6..c742aa248 100644
--- a/hicn-light/src/hicn/test/test-hash.cc
+++ b/hicn-light/src/hicn/test/test_hash.cc
@@ -187,8 +187,7 @@ TEST(HashTest, PerformanceComparisonBigStruct) {
TEST(HashTest, CollisionsComparison) {
small_struct_t small_struct = {0};
std::unordered_set<uint32_t> hashes;
- int n_collisions_fnv = 0, n_collisions_jenkins = 0, n_collisions_murmur = 0,
- n_collisions_xxhash = 0;
+ int n_collisions_fnv = 0, n_collisions_jenkins = 0;
// FNV
for (int i = 0; i < 10 * N_HASHES; i++) {