diff options
author | Luca Muscariello <muscariello@ieee.org> | 2022-08-04 16:06:34 +0200 |
---|---|---|
committer | Luca Muscariello <muscariello@ieee.org> | 2022-08-04 16:31:51 +0200 |
commit | 6d22a0db96aa7f8e3102ae44d00c09e36a2e9c57 (patch) | |
tree | 79546bbf09f6fbf74db7bc89117843f06ce937ea /hicn-light | |
parent | 012843b1c0bc0838e69085ed83a79ec8b6f97360 (diff) |
feat: Due to the deep modifications related to names and packet format,
this task cover a large part of the codebase and involves several changes:
- the library provides a name data structure (hicn_name_t ), which is composed
of a name prefix (hicn_name_prefix_t) and a name suffix (hicn_name_suffix_t),
and it has been extended to provide all support functions required for name
manipulation, including common prefix computation, as required for the Longest
Prefix Match (LPM)in the forwarder, in addition to Exact Prefix Match (EPM).
- all code has been rewritten to use this data structure instead of having for
instance the forwarder define its own name class (used to be Name and NameBitVector)
the code has been refactored to minimize name allocations and copies, one remaining
aspect is the difference of name storage between PIT and CS entries (respectively
in the PIT entry, and in the message buffer), which causes the packet cache
index to be updated when a PIT entry is converted into a CS entry. By storing
the name in the PIT/CS entry everytime, we might save on this operation).
- hicn-light FIB has been rewritten : code has been refactored and should now be
shorter and documented; unit tests have been drafted but more would be required
to cover all cases and match the algorithms to add/remove nodes, as specified in the doc.
all protocol details and hICN header formats are now abstracted by the library
for the forwarder (and thus header.h and protocols/*.h have been removed from
public includes, and replaced by packet.h providing protocol agnostic packet
level functions, completely replacing the compat.h header that used to provide
similar functions.
- this works by exposing a opaque buffer to the application (a kind of socket buffer)
which is used by the lib to cache the packet format and offsets of the different
layers in the buffer and provider efficient operations (the packet format is
either defined for packet construction, or guessed at ingress, and this structure
is updated accordingly only once).
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Change-Id: I31e321897f85f0267fe8ba4720363c180564492f
Diffstat (limited to 'hicn-light')
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, ¶ms); + size_t size = hicn_mapme_create_packet(packet, prefix, ¶ms); 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++) { |