diff options
48 files changed, 2024 insertions, 597 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5977b7955..9bff3d35e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,15 +29,16 @@ option(BUILD_CTRL "Build the hicn control tools" ON) option(BUILD_HICNPLUGIN "Build the hicn vpp plugin" OFF) option(BUILD_HICNEXTRAPLUGIN "Build the hicn extra plugin" OFF) option(BUILD_SYSREPOPLUGIN "Build the sysrepo plugin" OFF) +option(BUILD_CTRL_HICNPLUGIN "Build the hicn control tools for hicn plugin" OFF) list(APPEND dir_options BUILD_LIBHICN BUILD_HICNLIGHT + BUILD_HICNPLUGIN BUILD_LIBTRANSPORT BUILD_UTILS BUILD_APPS BUILD_CTRL - BUILD_HICNPLUGIN BUILD_HICNEXTRAPLUGIN BUILD_SYSREPOPLUGIN BUILD_LIBMEMIF @@ -92,11 +93,6 @@ if (BUILD_HICNPLUGIN AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") unset(LIBMEMIF_LIBRARIES) endif() - list(APPEND HICN_BINARY_API_INCLUDE_DIRS - ${PROJECT_BINARY_DIR}/hicn-plugin - ${PROJECT_BINARY_DIR}/hicn-plugin/vpp_plugins - ) - set(LIBTRANSPORT ${LIBTRANSPORT}-memif) endif() diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 9f4e753bb..c74be92ba 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -46,7 +46,7 @@ endif() set(SUFFIX "") if (${LIBTRANSPORT_LIBRARIES} MATCHES ".*-memif.*") set(SUFFIX "-memif") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-unresolved-symbols=ignore-in-shared-libs") + set(LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs") endif() set(HICN_APPS "${HICN_APPS}${SUFFIX}") diff --git a/apps/higet/CMakeLists.txt b/apps/higet/CMakeLists.txt index 83a13bcca..76814384d 100644 --- a/apps/higet/CMakeLists.txt +++ b/apps/higet/CMakeLists.txt @@ -37,4 +37,5 @@ build_executable(${HIGET} DEPENDS ${LIBTRANSPORT_LIBRARIES} COMPONENT ${HICN_APPS} DEFINITIONS ${COMPILER_DEFINITIONS} + LINK_FLAGS ${LINK_FLAGS} ) diff --git a/apps/http-proxy/CMakeLists.txt b/apps/http-proxy/CMakeLists.txt index 7e29edcf8..cc47e4b6f 100644 --- a/apps/http-proxy/CMakeLists.txt +++ b/apps/http-proxy/CMakeLists.txt @@ -55,6 +55,7 @@ build_library(${LIBHTTP_PROXY} LINK_LIBRARIES ${LIBRARIES} DEPENDS ${DEPENDENCIES} INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} + LINK_FLAGS ${LINK_FLAGS} ) build_executable(${HTTP_PROXY} @@ -63,4 +64,5 @@ build_executable(${HTTP_PROXY} DEPENDS ${LIBHTTP_PROXY_STATIC} COMPONENT ${HICN_APPS} DEFINITIONS ${COMPILER_DEFINITIONS} + LINK_FLAGS ${LINK_FLAGS} ) diff --git a/cmake/Modules/BuildMacros.cmake b/cmake/Modules/BuildMacros.cmake index 8b591d05b..85789a08a 100644 --- a/cmake/Modules/BuildMacros.cmake +++ b/cmake/Modules/BuildMacros.cmake @@ -21,7 +21,7 @@ macro(build_executable exec) cmake_parse_arguments(ARG "NO_INSTALL" "COMPONENT" - "SOURCES;LINK_LIBRARIES;DEPENDS;INCLUDE_DIRS;DEFINITIONS" + "SOURCES;LINK_LIBRARIES;DEPENDS;INCLUDE_DIRS;DEFINITIONS;LINK_FLAGS" ${ARGN} ) @@ -37,6 +37,7 @@ macro(build_executable exec) ARCHIVE_OUTPUT_DIRECTORY "${BUILD_ROOT}/lib" LIBRARY_OUTPUT_DIRECTORY "${BUILD_ROOT}/lib" RUNTIME_OUTPUT_DIRECTORY "${BUILD_ROOT}/bin" + LINK_FLAGS "${ARG_LINK_FLAGS}" ) if(ARG_LINK_LIBRARIES) diff --git a/cmake/Modules/FindHicnBinaryApi.cmake b/cmake/Modules/FindHicnBinaryApi.cmake deleted file mode 100644 index 86a96ea19..000000000 --- a/cmake/Modules/FindHicnBinaryApi.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(HICN_BINARY_API_SEARCH_PATH_LIST - ${HICN_BINARY_API_HOME} - $ENV{HICN_BINARY_API_HOME} - /usr/local - /opt - /usr -) - -find_path(HICN_BINARY_API_INCLUDE_DIR vpp_plugins/hicn/hicn_api.h - HINTS ${VPP_SEARCH_PATH_LIST} - PATH_SUFFIXES include - DOC "Find the VPP includes" -) - -set(HICN_BINARY_API_INCLUDE_DIRS ${VPP_INCLUDE_DIR}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(HicnBinaryApi DEFAULT_MSG VPP_LIBRARIES VPP_INCLUDE_DIRS)
\ No newline at end of file diff --git a/cmake/Modules/FindHicnPlugin.cmake b/cmake/Modules/FindHicnPlugin.cmake index b9d1b1099..0e67e22d8 100644 --- a/cmake/Modules/FindHicnPlugin.cmake +++ b/cmake/Modules/FindHicnPlugin.cmake @@ -12,6 +12,7 @@ # limitations under the License. set(HICNPLUGIN_SEARCH_PATH_LIST + ${VPP_SEARCH_PATH_LIST} ${HICNPLUGIN_HOME} $ENV{HICNPLUGIN_HOME} /usr/local @@ -26,9 +27,9 @@ find_path(HICNPLUGIN_INCLUDE_DIR vapi/hicn.api.vapi.h ) -set(HICNPLUGIN_INCLUDE_DIRS ${HICNPLUGIN_INCLUDE_DIR}) +set(HICNPLUGIN_INCLUDE_DIRS ${HICNPLUGIN_INCLUDE_DIR} ${HICNPLUGIN_INCLUDE_DIR}/vpp_plugins) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(HicnPlugin DEFAULT_MSG HICNPLUGIN_INCLUDE_DIRS) -mark_as_advanced(HICNPLUGIN_INCLUDE_DIR) +mark_as_advanced(HICNPLUGIN_INCLUDE_DIR)
\ No newline at end of file diff --git a/cmake/Modules/FindVpp.cmake b/cmake/Modules/FindVpp.cmake index d29f37339..4f8dba17a 100644 --- a/cmake/Modules/FindVpp.cmake +++ b/cmake/Modules/FindVpp.cmake @@ -71,10 +71,24 @@ find_library(VPP_LIBRARY_VPPAPICLIENT NAMES vppapiclient HINTS ${VPP_SEARCH_PATH_LIST} PATH_SUFFIXES lib lib64 - DOC "Find the Vpp vlib library" + DOC "Find the Vpp api library" +) + +find_library(VPP_LIBRARY_VAPICLIENT + NAMES vapiclient + HINTS ${VPP_SEARCH_PATH_LIST} + PATH_SUFFIXES lib lib64 + DOC "Find the Vpp vapi library" +) + +find_library(VPP_LIBRARY_VLIBMEMORY + NAMES vlibmemory + HINTS ${VPP_SEARCH_PATH_LIST} + PATH_SUFFIXES lib lib64 + DOC "Find the Vpp vlibmemory library" ) -set(VPP_LIBRARIES ${VPP_LIBRARY_MEMORYCLIENT} ${VPP_LIBRARY_SVM} ${VPP_LIBRARY_INFRA} ${VPP_LIBRARY_VATPLUGIN} ${VPP_LIBRARY_VLIB} ${VPP_LIBRARY_VNET}) +set(VPP_LIBRARIES ${VPP_LIBRARY_MEMORYCLIENT} ${VPP_LIBRARY_SVM} ${VPP_LIBRARY_INFRA} ${VPP_LIBRARY_VATPLUGIN} ${VPP_LIBRARY_VLIB} ${VPP_LIBRARY_VNET} ${VPP_LIBRARY_VAPICLIENT} ${VPP_LIBRARY_VLIBMEMORY}) set(VPP_INCLUDE_DIRS ${VPP_INCLUDE_DIR} ${VPP_INCLUDE_DIR}/vpp_plugins) include(FindPackageHandleStandardArgs) diff --git a/ctrl/CMakeLists.txt b/ctrl/CMakeLists.txt index cdce8bbdb..50357651f 100644 --- a/ctrl/CMakeLists.txt +++ b/ctrl/CMakeLists.txt @@ -16,4 +16,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(ctrl) add_subdirectory(libhicnctrl) -add_subdirectory(facemgr) + +if (NOT (BUILD_HICNPLUGIN AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")) + add_subdirectory(facemgr) +endif ()
\ No newline at end of file diff --git a/ctrl/libhicnctrl/CMakeLists.txt b/ctrl/libhicnctrl/CMakeLists.txt index 960eb6743..43d120473 100644 --- a/ctrl/libhicnctrl/CMakeLists.txt +++ b/ctrl/libhicnctrl/CMakeLists.txt @@ -35,7 +35,11 @@ set(CMAKE_MACOSX_RPATH ON) if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) - find_package_wrapper(Libhicn REQUIRED) + if (BUILD_CTRL_HICNPLUGIN AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + find_package_wrapper(HicnPlugin REQUIRED) + else () + find_package_wrapper(Libhicn REQUIRED) + endif() set(HICNCTRL hicnctrl) set(LIBHICNCTRL hicnctrl) @@ -48,6 +52,16 @@ else() list(APPEND DEPENDENCIES ${LIBHICN_STATIC} ) + elseif (BUILD_CTRL_HICNPLUGIN AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + set(HICN_INCLUDE_DIRS + ${HICN_INCLUDE_DIRS} + ${HICNPLUGIN_INCLUDE_DIRS}) + + set(HICN_LIBRARIES ${HICNPLUGIN_LIBRARIES}) + + list(APPEND DEPENDENCIES + hicn_plugin + ) else () set(HICN_LIBRARIES ${LIBHICN_SHARED}) list(APPEND DEPENDENCIES diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h index e522f33a6..eba80bdb3 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -51,9 +51,9 @@ * NOTES: * * - Different extensions of the forwarder functionalities bring both new API - * calls, and new object attributes. While it is expected that the former will - * only raised NACK answers because of unsupported API calls, the latter will - * certainly trigger incompatibilities. It is expected that the forwarder + * calls, and new object attributes. While it is expected that the former + * will only raised NACK answers because of unsupported API calls, the latter + * will certainly trigger incompatibilities. It is expected that the forwarder * validates the message length and returns a NACK too. In that case, we * provide a set of defines to preserve backwards compatibility. At the * moment, those defines are : @@ -77,25 +77,30 @@ #define HOTFIXMARGIN 0 /* Helper for avoiding warnings about type-punning */ +#ifndef UNION_CAST #define UNION_CAST(x, destType) \ - (((union {__typeof__(x) a; destType b;})x).b) - + (((union { \ + __typeof__(x) a; \ + destType b; \ + })x) \ + .b) +#endif /****************************************************************************** * Message helper types and aliases ******************************************************************************/ #define foreach_command \ - _(UNDEFINED) \ - _(CREATE) \ - _(UPDATE) \ - _(DELETE) \ - _(LIST) \ - _(SET) \ - _(N) + _(UNDEFINED) \ + _(CREATE) \ + _(UPDATE) \ + _(DELETE) \ + _(LIST) \ + _(SET) \ + _(N) typedef enum { -#define _(x) ACTION_ ## x, -foreach_command +#define _(x) ACTION_##x, + foreach_command #undef _ } hc_action_t; @@ -115,33 +120,32 @@ typedef int (*data_callback_t)(struct hc_data_s *, void *); * \brief Holds the results of an hICN control request */ typedef struct hc_data_s { - size_t size; - size_t max_size_log; - size_t in_element_size; - size_t out_element_size; - u8 command_id; /**< Expected message type (should give element size) */ - u8 * buffer; - bool complete; - - /* Callbacks */ - data_callback_t complete_cb; // XXX int (*complete_cb)(struct hc_data_s * data); - void * complete_cb_data; - int ret; + size_t size; + size_t current; + size_t max_size_log; + size_t in_element_size; + size_t out_element_size; + u8 command_id; /**< Expected message type (should give element size) */ + u8 *buffer; + bool complete; + + /* Callbacks */ + data_callback_t complete_cb; // XXX int (*complete_cb)(struct hc_data_s * data); + void *complete_cb_data; + int ret; } hc_data_t; /** * Create a structure holding the results of an hICN control request. * \result The newly create data structure. */ -hc_data_t * -hc_data_create(size_t in_element_size, size_t out_element_size); +hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size); /** * Free a structure holding the results of an hICN control request. * \param [in] data - The data structure to free. */ -void -hc_data_free(hc_data_t * data); +void hc_data_free(hc_data_t *data); /** * \brief Adds many new results at the end of the data structure, eventually @@ -154,8 +158,7 @@ hc_data_free(hc_data_t * data); * NOTE: The size of the element should match the one declared at structure * initialization. */ -int -hc_data_push_many(hc_data_t * data, const void * elements, size_t count); +int hc_data_push_many(hc_data_t *data, const void *elements, size_t count); /** * \brief Adds a new result at the end of the data structure, eventually @@ -167,8 +170,7 @@ hc_data_push_many(hc_data_t * data, const void * elements, size_t count); * NOTE: The size of the element should match the one declared at structure * initialization. */ -int -hc_data_push(hc_data_t * data, const void * element); +int hc_data_push(hc_data_t *data, const void *element); /** * \brief Configure a callback (along with private data) to be called upon @@ -177,8 +179,7 @@ hc_data_push(hc_data_t * data, const void * element); * \param [in] cb - Callback function * \param [in] cb_data - Callback private data */ -int -hc_data_set_callback(hc_data_t * data, data_callback_t cb, void * cb_data); +int hc_data_set_callback(hc_data_t *data, data_callback_t cb, void *cb_data); /** * \brief Mark the data structure as complete. @@ -187,16 +188,14 @@ hc_data_set_callback(hc_data_t * data, data_callback_t cb, void * cb_data); * returned if the callback executed successfully, or if no callback were * defined. */ -int -hc_data_set_complete(hc_data_t * data); +int hc_data_set_complete(hc_data_t *data); /** * \brief Reset the data structure holding control data * \param [in] data - hICN control data * \return Error code */ -int -hc_data_reset(hc_data_t * data); +int hc_data_reset(hc_data_t *data); /** * \brief Find en element in the data structure @@ -242,33 +241,33 @@ typedef struct hc_sock_s hc_sock_t; * \param [in] url - The URL to connect to. * \return an hICN control socket */ -hc_sock_t * hc_sock_create_url(const char * url); +hc_sock_t *hc_sock_create_url(const char *url); /** * \brief Create an hICN control socket using the default connection type. * \return an hICN control socket */ -hc_sock_t * hc_sock_create(void); +hc_sock_t *hc_sock_create(void); /** * \brief Frees an hICN control socket * \param [in] s - hICN control socket */ -void hc_sock_free(hc_sock_t * s); +void hc_sock_free(hc_sock_t *s); /** * \brief Returns the next available sequence number to use for requests to the * API. * \param [in] s - hICN control socket */ -int hc_sock_get_next_seq(hc_sock_t * s); +int hc_sock_get_next_seq(hc_sock_t *s); /** * \brief Sets the socket as non-blocking * \param [in] s - hICN control socket * \return Error code */ -int hc_sock_set_nonblocking(hc_sock_t * s); +int hc_sock_set_nonblocking(hc_sock_t *s); /** * \brief Return the file descriptor associated to the hICN contorl sock @@ -276,14 +275,13 @@ int hc_sock_set_nonblocking(hc_sock_t * s); * \return The file descriptor (positive value), or a negative integer in case * of error */ -int hc_sock_get_fd(hc_sock_t * s); +int hc_sock_get_fd(hc_sock_t *s); /** * \brief Connect the socket * \return Error code */ -int -hc_sock_connect(hc_sock_t * s); +int hc_sock_connect(hc_sock_t *s); /** * \brief Return the offset and size of available buffer space @@ -292,7 +290,7 @@ hc_sock_connect(hc_sock_t * s); * \param [out] size - Remaining size * \return Error code */ -int hc_sock_get_available(hc_sock_t * s, u8 ** buffer, size_t * size); +int hc_sock_get_available(hc_sock_t *s, u8 **buffer, size_t *size); /** * \brief Write/read iexchance on the control socket (internal helper function) @@ -301,14 +299,14 @@ int hc_sock_get_available(hc_sock_t * s, u8 ** buffer, size_t * size); * \param [in] msglen - Length of the message to send * \return Error code */ -int hc_sock_send(hc_sock_t * s, hc_msg_t * msg, size_t msglen, int seq); +int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen, int seq); /** * \brief Helper for reading socket contents * \param [in] s - hICN control socket * \return Error code */ -int hc_sock_recv(hc_sock_t * s); +int hc_sock_recv(hc_sock_t *s); /** * \brief Processing data received by socket @@ -317,21 +315,21 @@ int hc_sock_recv(hc_sock_t * s); * types, or NULL not to perform any translation. * \return Error code */ -int hc_sock_process(hc_sock_t * s, hc_data_t ** data); +int hc_sock_process(hc_sock_t *s, hc_data_t **data); /** * \brief Callback used in async mode when data is available on the socket * \param [in] s - hICN control socket * \return Error code */ -int hc_sock_callback(hc_sock_t * s, hc_data_t ** data); +int hc_sock_callback(hc_sock_t *s, hc_data_t **data); /** * \brief Reset the state of the sock (eg. to handle a reconnecton) * \param [in] s - hICN control socket * \return Error code */ -int hc_sock_reset(hc_sock_t * s); +int hc_sock_reset(hc_sock_t *s); /****************************************************************************** * Command-specific structures and functions @@ -391,54 +389,52 @@ int hc_sock_reset(hc_sock_t * s); #define MAXSZ_HC_ID_ 10 /* Number of digits for MAX_INT */ #define MAXSZ_HC_ID MAXSZ_HC_ID_ + NULLTERM - -#define foreach_type(TYPE, VAR, data) \ - for (TYPE * VAR = (TYPE*)data->buffer; \ - VAR < (TYPE*)(data->buffer + data->size * data->out_element_size); \ - VAR++) +#define foreach_type(TYPE, VAR, data) \ + for (TYPE *VAR = (TYPE *)data->buffer; \ + VAR < (TYPE *)(data->buffer + data->size * data->out_element_size); \ + VAR++) /** * New type is defined to reconciliate different enum for add and list. * Also, values not implemented have been removed for clarity. */ #define foreach_connection_type \ - _(UNDEFINED) \ - _(TCP) \ - _(UDP) \ - _(HICN) \ - _(N) + _(UNDEFINED) \ + _(TCP) \ + _(UDP) \ + _(HICN) \ + _(N) typedef enum { -#define _(x) CONNECTION_TYPE_ ## x, -foreach_connection_type +#define _(x) CONNECTION_TYPE_##x, + foreach_connection_type #undef _ } hc_connection_type_t; #define MAXSZ_HC_CONNECTION_TYPE_ 9 #define MAXSZ_HC_CONNECTION_TYPE MAXSZ_HC_CONNECTION_TYPE_ + NULLTERM + HOTFIXMARGIN -extern const char * connection_type_str[]; +extern const char *connection_type_str[]; -hc_connection_type_t -connection_type_from_str(const char * str); +hc_connection_type_t connection_type_from_str(const char *str); /* Same order as connection_state_t in hicn/core/connectionState.h */ #define foreach_connection_state \ - _(UNDEFINED) \ - _(DOWN) \ - _(UP) \ - _(N) + _(UNDEFINED) \ + _(DOWN) \ + _(UP) \ + _(N) typedef enum { -#define _(x) HC_CONNECTION_STATE_ ## x, -foreach_connection_state +#define _(x) HC_CONNECTION_STATE_##x, + foreach_connection_state #undef _ } hc_connection_state_t; #define MAXSZ_HC_CONNECTION_STATE_ 9 #define MAXSZ_HC_CONNECTION_STATE MAXSZ_HC_CONNECTION_STATE_ + NULLTERM -extern const char * connection_state_str[]; +extern const char *connection_state_str[]; typedef int (*HC_PARSE)(const u8 *, u8 *); @@ -448,34 +444,35 @@ typedef int (*HC_PARSE)(const u8 *, u8 *); // FIXME the listener should not require any port for hICN... typedef struct { - char name[SYMBOLIC_NAME_LEN]; /* K.w */ // XXX clarify what used for - char interface_name[INTERFACE_LEN]; /* Kr. */ - u32 id; - hc_connection_type_t type; /* .rw */ - int family; /* .rw */ - ip_address_t local_addr; /* .rw */ - u16 local_port; /* .rw */ + char name[SYMBOLIC_NAME_LEN]; /* K.w */ // XXX clarify what used for + char interface_name[INTERFACE_LEN]; /* Kr. */ + u32 id; + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ } hc_listener_t; -int hc_listener_create(hc_sock_t * s, hc_listener_t * listener); +int hc_listener_create(hc_sock_t *s, hc_listener_t *listener); /* listener_found might eventually be allocated, and needs to be freed */ -int hc_listener_get(hc_sock_t * s, hc_listener_t * listener, - hc_listener_t ** listener_found); -int hc_listener_delete(hc_sock_t * s, hc_listener_t * listener); -int hc_listener_list(hc_sock_t * s, hc_data_t ** pdata); +int hc_listener_get(hc_sock_t *s, hc_listener_t *listener, + hc_listener_t **listener_found); +int hc_listener_delete(hc_sock_t *s, hc_listener_t *listener); +int hc_listener_list(hc_sock_t *s, hc_data_t **pdata); -int hc_listener_validate(const hc_listener_t * listener); -int hc_listener_cmp(const hc_listener_t * l1, const hc_listener_t * l2); -int hc_listener_parse(void * in, hc_listener_t * listener); +int hc_listener_validate(const hc_listener_t *listener); +int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2); +int hc_listener_parse(void *in, hc_listener_t *listener); #define foreach_listener(VAR, data) foreach_type(hc_listener_t, VAR, data) -#define MAXSZ_HC_LISTENER_ INTERFACE_LEN + SPACE + MAXSZ_URL_ + SPACE + MAXSZ_HC_CONNECTION_TYPE_ +#define MAXSZ_HC_LISTENER_ \ + INTERFACE_LEN + SPACE + MAXSZ_URL_ + SPACE + MAXSZ_HC_CONNECTION_TYPE_ #define MAXSZ_HC_LISTENER MAXSZ_HC_LISTENER_ + NULLTERM GENERATE_FIND_HEADER(listener); -int hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener); +int hc_listener_snprintf(char *s, size_t size, hc_listener_t *listener); /*----------------------------------------------------------------------------* * Connections @@ -487,16 +484,16 @@ int hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener); * not itself used to create connections. */ typedef struct { - u32 id; /* Kr. */ - char name[SYMBOLIC_NAME_LEN]; /* K.w */ - char interface_name[INTERFACE_LEN]; /* Kr. */ - hc_connection_type_t type; /* .rw */ - int family; /* .rw */ - ip_address_t local_addr; /* .rw */ - u16 local_port; /* .rw */ - ip_address_t remote_addr; /* .rw */ - u16 remote_port; /* .rw */ - hc_connection_state_t admin_state; /* .rw */ + u32 id; /* Kr. */ + char name[SYMBOLIC_NAME_LEN]; /* K.w */ + char interface_name[INTERFACE_LEN]; /* Kr. */ + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ + ip_address_t remote_addr; /* .rw */ + u16 remote_port; /* .rw */ + hc_connection_state_t admin_state; /* .rw */ #ifdef WITH_POLICY uint32_t priority; /* .rw */ policy_tags_t tags; /* .rw */ @@ -504,25 +501,24 @@ typedef struct { hc_connection_state_t state; /* .r. */ } hc_connection_t; - -int hc_connection_create(hc_sock_t * s, hc_connection_t * connection); +int hc_connection_create(hc_sock_t *s, hc_connection_t *connection); /* connection_found will be allocated, and must be freed */ -int hc_connection_get(hc_sock_t * s, hc_connection_t * connection, - hc_connection_t ** connection_found); -int hc_connection_update_by_id(hc_sock_t * s, int hc_connection_id, - hc_connection_t * connection); -int hc_connection_update(hc_sock_t * s, hc_connection_t * connection_current, - hc_connection_t * connection_updated); -int hc_connection_delete(hc_sock_t * s, hc_connection_t * connection); +int hc_connection_get(hc_sock_t *s, hc_connection_t *connection, + hc_connection_t **connection_found); +int hc_connection_update_by_id(hc_sock_t *s, int hc_connection_id, + hc_connection_t *connection); +int hc_connection_update(hc_sock_t *s, hc_connection_t *connection_current, + hc_connection_t *connection_updated); +int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection); /* int hc_connection_remove_by_id(hc_sock_t * s, char * name); int hc_connection_remove_by_name(hc_sock_t * s, char * name); */ -int hc_connection_list(hc_sock_t * s, hc_data_t ** pdata); +int hc_connection_list(hc_sock_t *s, hc_data_t **pdata); -int hc_connection_validate(const hc_connection_t * connection); -int hc_connection_cmp(const hc_connection_t * c1, const hc_connection_t * c2); -int hc_connection_parse(void * in, hc_connection_t * connection); +int hc_connection_validate(const hc_connection_t *connection); +int hc_connection_cmp(const hc_connection_t *c1, const hc_connection_t *c2); +int hc_connection_parse(void *in, hc_connection_t *connection); int hc_connection_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state); #ifdef WITH_POLICY @@ -531,14 +527,15 @@ int hc_connection_set_priority(hc_sock_t * s, const char * conn_id_or_name, uint #define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) -#define MAXSZ_HC_CONNECTION_ MAXSZ_HC_CONNECTION_STATE_ + \ - INTERFACE_LEN + SPACE + \ - 2 * MAXSZ_URL_ + MAXSZ_HC_CONNECTION_TYPE_ + SPACES(3) +#define MAXSZ_HC_CONNECTION_ \ + MAXSZ_HC_CONNECTION_STATE_ + INTERFACE_LEN + SPACE + 2 * MAXSZ_URL_ + \ + MAXSZ_HC_CONNECTION_TYPE_ + SPACES(3) #define MAXSZ_HC_CONNECTION MAXSZ_HC_CONNECTION_ + NULLTERM GENERATE_FIND_HEADER(connection); -int hc_connection_snprintf(char * s, size_t size, const hc_connection_t * connection); +int hc_connection_snprintf(char *s, size_t size, + const hc_connection_t *connection); /*----------------------------------------------------------------------------* * Faces @@ -551,10 +548,10 @@ int hc_connection_snprintf(char * s, size_t size, const hc_connection_t * connec *----------------------------------------------------------------------------*/ typedef struct { - u8 id; - char name[SYMBOLIC_NAME_LEN]; - face_t face; // or embed ? - //face_id_t parent; /* Pointer from connection to listener */ + u8 id; + char name[SYMBOLIC_NAME_LEN]; + face_t face; // or embed ? + // face_id_t parent; /* Pointer from connection to listener */ } hc_face_t; /** @@ -565,11 +562,11 @@ typedef struct { * * The face parameters will be updated with the face ID. */ -int hc_face_create(hc_sock_t * s, hc_face_t * face); -int hc_face_get(hc_sock_t * s, hc_face_t * face, hc_face_t ** face_found); -int hc_face_delete(hc_sock_t * s, hc_face_t * face); -int hc_face_list(hc_sock_t * s, hc_data_t ** pdata); -int hc_face_list_async(hc_sock_t * s); //, hc_data_t ** pdata); +int hc_face_create(hc_sock_t *s, hc_face_t *face); +int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_face_t **face_found); +int hc_face_delete(hc_sock_t *s, hc_face_t *face); +int hc_face_list(hc_sock_t *s, hc_data_t **pdata); +int hc_face_list_async(hc_sock_t *s); //, hc_data_t ** pdata); int hc_face_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state); #ifdef WITH_POLICY @@ -587,21 +584,21 @@ int hc_face_set_priority(hc_sock_t * s, const char * conn_id_or_name, uint32_t p #define MAXSZ_HC_FACE_ MAXSZ_FACE_ID_ + MAXSZ_FACE_NAME_ + MAXSZ_FACE_ + 5 + HOTFIXMARGIN #define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM -int hc_face_snprintf(char * s, size_t size, hc_face_t * face); +int hc_face_snprintf(char *s, size_t size, hc_face_t *face); /*----------------------------------------------------------------------------* * Routes *----------------------------------------------------------------------------*/ typedef struct { - u8 face_id; /* Kr. */ - int family; /* Krw */ - ip_address_t remote_addr; /* krw */ - u8 len; /* krw */ - u16 cost; /* .rw */ + u8 face_id; /* Kr. */ + int family; /* Krw */ + ip_address_t remote_addr; /* krw */ + u8 len; /* krw */ + u16 cost; /* .rw */ } hc_route_t; -int hc_route_parse(void * in, hc_route_t * route); +int hc_route_parse(void *in, hc_route_t *route); int hc_route_create(hc_sock_t * s, hc_route_t * route); int hc_route_delete(hc_sock_t * s, hc_route_t * route); @@ -615,31 +612,32 @@ int hc_route_list_async(hc_sock_t * s); #define MAX_LEN 255 #define MAXSZ_LEN 3 -#define MAXSZ_HC_ROUTE_ MAXSZ_FACE_ID + 1 + MAXSZ_COST + 1 + MAXSZ_IP_ADDRESS + 1 + MAXSZ_LEN +#define MAXSZ_HC_ROUTE_ \ + MAXSZ_FACE_ID + 1 + MAXSZ_COST + 1 + MAXSZ_IP_ADDRESS + 1 + MAXSZ_LEN #define MAXSZ_HC_ROUTE MAXSZ_HC_ROUTE_ + NULLTERM -int hc_route_snprintf(char * s, size_t size, hc_route_t * route); - +int hc_route_snprintf(char *s, size_t size, hc_route_t *route); /*----------------------------------------------------------------------------* * Punting *----------------------------------------------------------------------------*/ typedef struct { - u8 face_id; /* Kr. */ // XXX listener id, could be NULL for all ? - int family; /* Krw */ - ip_address_t prefix; /* krw */ - u8 prefix_len; /* krw */ + u8 face_id; /* Kr. */ // XXX listener id, could be NULL for all ? + int family; /* Krw */ + ip_address_t prefix; /* krw */ + u8 prefix_len; /* krw */ } hc_punting_t; -int hc_punting_create(hc_sock_t * s, hc_punting_t * punting); -int hc_punting_get(hc_sock_t * s, hc_punting_t * punting, hc_punting_t ** punting_found); -int hc_punting_delete(hc_sock_t * s, hc_punting_t * punting); -int hc_punting_list(hc_sock_t * s, hc_data_t ** pdata); +int hc_punting_create(hc_sock_t *s, hc_punting_t *punting); +int hc_punting_get(hc_sock_t *s, hc_punting_t *punting, + hc_punting_t **punting_found); +int hc_punting_delete(hc_sock_t *s, hc_punting_t *punting); +int hc_punting_list(hc_sock_t *s, hc_data_t **pdata); -int hc_punting_validate(const hc_punting_t * punting); -int hc_punting_cmp(const hc_punting_t * c1, const hc_punting_t * c2); -int hc_punting_parse(void * in, hc_punting_t * punting); +int hc_punting_validate(const hc_punting_t *punting); +int hc_punting_cmp(const hc_punting_t *c1, const hc_punting_t *c2); +int hc_punting_parse(void *in, hc_punting_t *punting); #define foreach_punting(VAR, data) foreach_type(hc_punting_t, VAR, data) @@ -648,15 +646,14 @@ int hc_punting_parse(void * in, hc_punting_t * punting); GENERATE_FIND_HEADER(punting); -int hc_punting_snprintf(char * s, size_t size, hc_punting_t * punting); - +int hc_punting_snprintf(char *s, size_t size, hc_punting_t *punting); /*----------------------------------------------------------------------------* * Cache *----------------------------------------------------------------------------*/ -int hc_cache_set_store(hc_sock_t * s, int enabled); -int hc_cache_set_serve(hc_sock_t * s, int enabled); +int hc_cache_set_store(hc_sock_t *s, int enabled); +int hc_cache_set_serve(hc_sock_t *s, int enabled); /*----------------------------------------------------------------------------* * Strategy @@ -665,36 +662,36 @@ int hc_cache_set_serve(hc_sock_t * s, int enabled); #define MAXSZ_STRATEGY_NAME 255 typedef struct { - char name[MAXSZ_STRATEGY_NAME]; + char name[MAXSZ_STRATEGY_NAME]; } hc_strategy_t; -int hc_strategy_list(hc_sock_t * s, hc_data_t ** data); +int hc_strategy_list(hc_sock_t *s, hc_data_t **data); #define foreach_strategy(VAR, data) foreach_type(hc_strategy_t, VAR, data) #define MAXSZ_HC_STRATEGY_ MAXSZ_STRATEGY_NAME #define MAXSZ_HC_STRATEGY MAXSZ_HC_STRATEGY_ + NULLTERM -int hc_strategy_snprintf(char * s, size_t size, hc_strategy_t * strategy); +int hc_strategy_snprintf(char *s, size_t size, hc_strategy_t *strategy); // per prefix -int hc_strategy_set(hc_sock_t * s /* XXX */); +int hc_strategy_set(hc_sock_t *s /* XXX */); /*----------------------------------------------------------------------------* * WLDR *----------------------------------------------------------------------------*/ // per connection -int hc_wldr_set(hc_sock_t * s /* XXX */); +int hc_wldr_set(hc_sock_t *s /* XXX */); /*----------------------------------------------------------------------------* * MAP-Me *----------------------------------------------------------------------------*/ -int hc_mapme_set(hc_sock_t * s, int enabled); -int hc_mapme_set_discovery(hc_sock_t * s, int enabled); -int hc_mapme_set_timescale(hc_sock_t * s, double timescale); -int hc_mapme_set_retx(hc_sock_t * s, double timescale); +int hc_mapme_set(hc_sock_t *s, int enabled); +int hc_mapme_set_discovery(hc_sock_t *s, int enabled); +int hc_mapme_set_timescale(hc_sock_t *s, double timescale); +int hc_mapme_set_retx(hc_sock_t *s, double timescale); /*----------------------------------------------------------------------------* * Policies @@ -703,17 +700,17 @@ int hc_mapme_set_retx(hc_sock_t * s, double timescale); #ifdef WITH_POLICY typedef struct { - int family; /* Krw */ - ip_address_t remote_addr; /* krw */ - u8 len; /* krw */ - policy_t policy; /* .rw */ + int family; /* Krw */ + ip_address_t remote_addr; /* krw */ + u8 len; /* krw */ + policy_t policy; /* .rw */ } hc_policy_t; -int hc_policy_parse(void * in, hc_policy_t * policy); +int hc_policy_parse(void *in, hc_policy_t *policy); -int hc_policy_create(hc_sock_t * s, hc_policy_t * policy); -int hc_policy_delete(hc_sock_t * s, hc_policy_t * policy); -int hc_policy_list(hc_sock_t * s, hc_data_t ** pdata); +int hc_policy_create(hc_sock_t *s, hc_policy_t *policy); +int hc_policy_delete(hc_sock_t *s, hc_policy_t *policy); +int hc_policy_list(hc_sock_t *s, hc_data_t **pdata); #define foreach_policy(VAR, data) foreach_type(hc_policy_t, VAR, data) @@ -721,7 +718,7 @@ int hc_policy_list(hc_sock_t * s, hc_data_t ** pdata); #define MAXSZ_HC_POLICY_ 0 #define MAXSZ_HC_POLICY MAXSZ_HC_POLICY_ + NULLTERM -int hc_policy_snprintf(char * s, size_t size, hc_policy_t * policy); +int hc_policy_snprintf(char *s, size_t size, hc_policy_t *policy); #endif /* WITH_POLICY */ diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt index ea63217dd..14c204dda 100644 --- a/ctrl/libhicnctrl/src/CMakeLists.txt +++ b/ctrl/libhicnctrl/src/CMakeLists.txt @@ -26,11 +26,22 @@ set(UTIL_HEADER_FILES ) set(SOURCE_FILES - api.c face.c route.c ) +if(BUILD_CTRL_HICNPLUGIN) + set(SOURCE_FILES + ${SOURCE_FILES} + hicn_plugin_api.c + ) +else () + set(SOURCE_FILES + ${SOURCE_FILES} + api.c + ) +endif() + set(LIBRARIES m ${HICN_LIBRARIES} @@ -42,43 +53,37 @@ set(INCLUDE_DIRS ${HICN_INCLUDE_DIRS} ) +# Android requires static libraries if (${CMAKE_SYSTEM_NAME} STREQUAL "Android") - set(HICN_LIBRARIES ${LIBHICN_STATIC} log) - build_library(${LIBHICNCTRL} - STATIC - SOURCES ${SOURCE_FILES} - INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} - LINK_LIBRARIES ${LIBRARIES} - DEPENDS ${LIBHICN_STATIC} - COMPONENT ${LIBHICNCTRL_COMPONENT} - DEPENDS ${LIBHICN_STATIC} - INCLUDE_DIRS ${INCLUDE_DIRS} - INSTALL_ROOT_DIR hicn - DEFINITIONS ${COMPILER_DEFINITIONS} - ) + set(LIBRARIES ${LIBRARIES} ${LIBHICN_STATIC}) + set(LINK_TYPE STATIC) else () - build_library(${LIBHICNCTRL} - SHARED STATIC - SOURCES ${SOURCE_FILES} - INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} - LINK_LIBRARIES ${LIBRARIES} - DEPENDS ${LIBHICN_SHARED} - COMPONENT ${LIBHICNCTRL_COMPONENT} - DEPENDS ${LIBHICN_SHARED} - INCLUDE_DIRS ${INCLUDE_DIRS} - INSTALL_ROOT_DIR hicn - DEFINITIONS ${COMPILER_DEFINITIONS} - ) + set(LINK_TYPE SHARED STATIC) endif () +build_library(${LIBHICNCTRL} + ${LINK_TYPE} + SOURCES ${SOURCE_FILES} + INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} + LINK_LIBRARIES ${LIBRARIES} + DEPENDS ${DEPENDENCIES} + COMPONENT ${LIBHICNCTRL_COMPONENT} + INCLUDE_DIRS ${INCLUDE_DIRS} + INSTALL_ROOT_DIR hicn + DEFINITIONS ${COMPILER_DEFINITIONS} +) + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Android" AND NOT COMPILE_FOR_IOS) + set(LIBRARIES ${LIBRARIES} ${LIBHICN_SHARED} ${LIBHICNCTRL_SHARED}) + list(APPEND DAEMON_SRC cli.c ) + build_executable(${HICNCTRL} SOURCES ${DAEMON_SRC} - LINK_LIBRARIES ${LIBHICNCTRL_SHARED} ${LIBHICN_SHARED} - DEPENDS ${LIBHICNCTRL_SHARED} ${LIBHICN_SHARED} + LINK_LIBRARIES ${LIBRARIES} + DEPENDS ${LIBHICNCTRL_SHARED} COMPONENT ${LIBHICNCTRL_COMPONENT} INCLUDE_DIRS ${INCLUDE_DIRS} DEFINITIONS ${COMPILER_DEFINITIONS} diff --git a/ctrl/libhicnctrl/src/api.c b/ctrl/libhicnctrl/src/api.c index 84c3390e5..8540addcf 100644 --- a/ctrl/libhicnctrl/src/api.c +++ b/ctrl/libhicnctrl/src/api.c @@ -91,7 +91,6 @@ struct hc_sock_s { hc_sock_request_t * hc_sock_request_create(int seq, hc_data_t * data, HC_PARSE parse) { - assert(seq >= 0); assert(data); hc_sock_request_t * request = malloc(sizeof(hc_sock_request_t)); @@ -859,11 +858,7 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len, } int seq = hc_sock_get_next_seq(s); - if (seq < 0) { - ERROR("[hc_execute_command] Could not get next sequence number"); - goto ERR_SEQ; - } - + /* Create state used to process the request */ hc_sock_request_t * request = NULL; request = hc_sock_request_create(seq, data, params->parse); @@ -921,7 +916,6 @@ ERR_PROCESS: ERR_MAP: hc_sock_request_free(request); ERR_REQUEST: -ERR_SEQ: hc_data_free(data); ERR_DATA: return -99; diff --git a/ctrl/libhicnctrl/src/hicn_plugin_api.c b/ctrl/libhicnctrl/src/hicn_plugin_api.c new file mode 100644 index 000000000..7dbd88771 --- /dev/null +++ b/ctrl/libhicnctrl/src/hicn_plugin_api.c @@ -0,0 +1,1186 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file api.c + * \brief Implementation of hICN control library API + */ + +#include <assert.h> // assert +#include <fcntl.h> // fcntl +#include <math.h> // log2 +#include <stdbool.h> +#include <stdio.h> // snprintf +#include <string.h> // memmove, strcasecmp +#include <sys/socket.h> // socket +#include <unistd.h> // close, fcntl + +#include <hicn/ctrl/api.h> +#include <hicn/ctrl/commands.h> +#include <hicn/util/token.h> +#include <strings.h> +#include <vapi/hicn.api.vapi.h> +#include <hicn/util/log.h> +#include <hicn/util/map.h> + +#define APP_NAME "hicn_plugin" +#define MAX_OUTSTANDING_REQUESTS 4 +#define RESPONSE_QUEUE_SIZE 2 + +DEFINE_VAPI_MSG_IDS_HICN_API_JSON + +/* + * Internal state associated to a pending request + */ +typedef struct { + int seq; + // Reusing the buffer of data to hold both the unparsed response from the + // forwarder and the result of the parsing + hc_data_t *data; + /* Information used to process results */ + int size_in; + HC_PARSE parse; +} hc_sock_request_t; + +/** + * Messages to the forwarder might be multiplexed thanks to the seqNum fields in + * the header_control_message structure. The forwarder simply answers back the + * original sequence number. We maintain a map of such sequence number to + * outgoing queries so that replied can be demultiplexed and treated + * appropriately. + */ +TYPEDEF_MAP_H(hc_sock_map, int, hc_sock_request_t *); +TYPEDEF_MAP(hc_sock_map, int, hc_sock_request_t *, int_cmp, int_snprintf, + generic_snprintf); + +struct hc_sock_s { + vapi_ctx_t g_vapi_ctx_instance; + char *url; + int fd; + + size_t roff; /**< Read offset */ + size_t woff; /**< Write offset */ + u32 buffer[RECV_BUFLEN]; + /* Next sequence number to be used for requests */ + int seq; + + bool async; + hc_sock_map_t *map; +}; + +hc_sock_request_t *hc_sock_request_create(int seq, hc_data_t *data, + HC_PARSE parse) { + assert(data); + + hc_sock_request_t *request = malloc(sizeof(hc_sock_request_t)); + if (!request) return NULL; + request->seq = seq; + request->data = data; + request->parse = parse; + request->size_in = 0; + return request; +} + +void hc_sock_request_free(hc_sock_request_t *request) { free(request); } + +/****************************************************************************** + * Message helper types and aliases + ******************************************************************************/ + +#define foreach_hc_command \ + _(hicn_api_node_params_set) \ + _(hicn_api_node_params_set_reply) \ + _(hicn_api_node_params_get_reply) \ + _(hicn_api_node_stats_get_reply) \ + _(hicn_api_face_ip_add) \ + _(hicn_api_face_ip_add_reply) \ + _(hicn_api_face_ip_del) \ + _(hicn_api_face_ip_del_reply) \ + _(hicn_api_face_ip_params_get) \ + _(hicn_api_face_stats_details) \ + _(hicn_api_face_ip_params_get_reply) \ + _(hicn_api_route_nhops_add) \ + _(hicn_api_route_nhops_add_reply) \ + _(hicn_api_route_del) \ + _(hicn_api_route_del_reply) \ + _(hicn_api_route_nhop_del) \ + _(hicn_api_route_nhop_del_reply) \ + _(hicn_api_route_get) \ + _(hicn_api_route_get_reply) \ + _(hicn_api_routes_details) \ + _(hicn_api_strategies_get_reply) \ + _(hicn_api_strategy_get) \ + _(hicn_api_strategy_get_reply) \ + _(hicn_api_punting_add) \ + _(hicn_api_punting_add_reply) \ + _(hicn_api_punting_del) \ + _(hicn_api_punting_del_reply) + +typedef vapi_type_msg_header2_t hc_msg_header_t; + +typedef union { +#define _(a) vapi_payload_ ## a a; + foreach_hc_command +#undef _ +} hc_msg_payload_t; + +#define IS_DUMP_MSG(a) (a == vapi_msg_id_hicn_api_face_stats_dump || a == vapi_msg_id_hicn_api_routes_dump) + +typedef struct __attribute__ ((__packed__)) { + hc_msg_header_t hdr; + hc_msg_payload_t payload; +} hc_hicnp_t; + +typedef void (* NTOH)(void *msg); + +typedef struct __attribute__((__packed__)) { + hc_sock_t *s; + uint32_t ctx_msg; +} callback_ctx_t; + +typedef struct __attribute__((__packed__)) { + hc_hicnp_t * hicnp_msg; + vapi_cb_t callback; + callback_ctx_t *callback_ctx; + NTOH ntoh; +} hc_msg_s; + +/****************************************************************************** + * Control Data + ******************************************************************************/ + +hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size) { + hc_data_t *data = malloc(sizeof(hc_data_t)); + if (!data) goto ERR_MALLOC; + + /* FIXME Could be NULL thanks to realloc provided size is 0 */ + data->in_element_size = in_element_size; + data->out_element_size = out_element_size; + data->size = 0; + data->current = 0; + data->complete = false; + data->command_id = 0; // TODO this could also be a busy mark in the socket + /* No callback needed in blocking code for instance */ + data->complete_cb = NULL; + + return data; + +ERR_MALLOC: + return NULL; +} + +void hc_data_free(hc_data_t *data) { + if (data != NULL) { + if (data->buffer) free(data->buffer); + free(data); + } +} + +/****************************************************************************** + * Control socket + ******************************************************************************/ + +/** + * \brief Parse a connection URL into a sockaddr + * \param [in] url - URL + * \param [out] sa - Resulting struct sockaddr, expected zero'ed. + * \return 0 if parsing succeeded, a negative error value otherwise. + */ +int hc_sock_parse_url(const char *url, struct sockaddr *sa) { + // NOT IMPLEMENTED + return -1; +} + +hc_sock_t *hc_sock_create_url(const char *url) { + // NOT IMPLEMENTED + return NULL; +} + +hc_sock_t *hc_sock_create(void) { + hc_sock_t *s = malloc(sizeof(hc_sock_t)); + memset(s, 0, sizeof(hc_sock_t)); + + s->map = hc_sock_map_create(); + if (!s->map) goto ERR_MAP; + + //By default the socket is blocking -- not async + s->async = 0; + + return s; + +ERR_MAP: + free(s); + return NULL; +} + +void hc_sock_free(hc_sock_t *s) { + hc_sock_request_t **request_array = NULL; + int n = hc_sock_map_get_value_array(s->map, &request_array); + if (n < 0) { + ERROR("Could not retrieve pending request array for freeing up resources"); + } else { + for (unsigned i = 0; i < n; i++) { + hc_sock_request_t *request = request_array[i]; + hc_sock_request_free(request); + } + free(request_array); + } + + hc_sock_map_free(s->map); + if (s->url) free(s->url); + close(s->fd); + free(s); +} + +int hc_sock_get_next_seq(hc_sock_t *s) { + return vapi_gen_req_context(s->g_vapi_ctx_instance); +} + +int hc_sock_set_nonblocking(hc_sock_t *s) { + s->async = 1; + return 0; +} + +int hc_sock_get_fd(hc_sock_t *s) { return 1; } + +vapi_error_e vapi_cb(vapi_ctx_t ctx, void *callback_ctx, vapi_error_e error, bool is_last, void *payload) { + callback_ctx_t *ctx_call = (callback_ctx_t *)callback_ctx; + hc_sock_t *s = ctx_call->s; + + if ((s->woff != s->roff) && (s->woff % RECV_BUFLEN == 0)) { + ERROR("[hc_sock_process] No more space on the buffer to store responces"); + return -1; + } + + if (is_last) { + s->buffer[s->woff % RECV_BUFLEN] = ctx_call->ctx_msg; + s->woff++; + } + + if(!payload) + return 0; + + hc_sock_request_t *request = NULL; + if (hc_sock_map_get(s->map, ctx_call->ctx_msg, &request) < + 0) { + ERROR("[hc_sock_process] Error searching for matching request"); + return -1; + } + + if (request->data->current == request->data->size) { + if (request->data->size == 0){ + request->data->size = 1; + request->data->buffer = malloc(request->data->in_element_size * request->data->size); + } else { + void *tmp = + malloc(request->data->in_element_size * request->data->size * 2); + memcpy(tmp, request->data->buffer, request->data->current * request->data->in_element_size); + free(request->data->buffer); + request->data->size *= 2; + request->data->buffer = tmp; + } + } + memcpy(request->data->buffer + + request->data->current * request->data->in_element_size, + payload, request->data->in_element_size); + request->data->current++; + + return 0; +} + +int hc_sock_connect(hc_sock_t *s) { + if (s->g_vapi_ctx_instance == NULL) { + vapi_error_e rv = vapi_ctx_alloc(&s->g_vapi_ctx_instance); + rv = vapi_connect(s->g_vapi_ctx_instance, APP_NAME, NULL, + MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, + s->async ? VAPI_MODE_NONBLOCKING : VAPI_MODE_BLOCKING, true); + if (rv != VAPI_OK) { + vapi_ctx_free(s->g_vapi_ctx_instance); + goto ERR_CONNECT; + } + printf("[hc_sock_connect] *connected %s ok", APP_NAME); + } else { + printf("connection %s keeping", APP_NAME); + } + + return 0; + +ERR_CONNECT: + ERROR("[hc_sock_connect] connection %s failes", APP_NAME); + return -1; +} + +int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen, int seq) { + vapi_cb_t callback = ((hc_msg_s *)msg)->callback; + callback_ctx_t *callback_ctx = ((hc_msg_s *)msg)->callback_ctx; + + if (!msg || !callback) { + return VAPI_EINVAL; + } + if (vapi_is_nonblocking(s->g_vapi_ctx_instance) && vapi_requests_full(s->g_vapi_ctx_instance)) { + return VAPI_EAGAIN; + } + vapi_error_e rv; + if (VAPI_OK != (rv = vapi_producer_lock (s->g_vapi_ctx_instance))) { + return rv; + } + ((hc_msg_s *)msg)->hicnp_msg->hdr.context = seq; + callback_ctx->ctx_msg = seq; + vapi_msg_id_t msg_id = vapi_lookup_vapi_msg_id_t(s->g_vapi_ctx_instance, ((hc_msg_s *)msg)->hicnp_msg->hdr._vl_msg_id); + ((hc_msg_s *)msg)->ntoh(((hc_msg_s *)msg)->hicnp_msg); + if (IS_DUMP_MSG(msg_id)) { + if (VAPI_OK == (rv = vapi_send_with_control_ping (s->g_vapi_ctx_instance, ((hc_msg_s *)msg)->hicnp_msg, seq))) { + vapi_store_request(s->g_vapi_ctx_instance, seq, true, (vapi_cb_t)callback, callback_ctx); + } + } else { + if (VAPI_OK == (rv = vapi_send (s->g_vapi_ctx_instance, ((hc_msg_s *)msg)->hicnp_msg))) { + vapi_store_request(s->g_vapi_ctx_instance, seq, false, (vapi_cb_t)callback, callback_ctx); + } + } + + if (rv != VAPI_OK) { + if (VAPI_OK != vapi_producer_unlock (s->g_vapi_ctx_instance)) { + abort (); /* this really shouldn't happen */ + } + } + return rv; +} + +int hc_sock_get_available(hc_sock_t *s, u8 **buffer, size_t *size) { + // NOT IMPLEMENTED + return -1; +} + +int hc_sock_recv(hc_sock_t *s) { + vapi_error_e rv; + if (VAPI_OK != vapi_producer_unlock (s->g_vapi_ctx_instance)) { + abort (); /* this really shouldn't happen */ + } + if (vapi_is_nonblocking(s->g_vapi_ctx_instance)) { + rv = VAPI_OK; + } else { + rv = vapi_dispatch(s->g_vapi_ctx_instance); + } + + return rv; +} + +int hc_sock_process(hc_sock_t *s, hc_data_t **pdata) { + int err = 0; + int seq = s->buffer[s->roff % RECV_BUFLEN]; + + hc_sock_request_t *request = NULL; + if (hc_sock_map_get(s->map, seq, &request) < 0) { + ERROR("[hc_sock_process] Error searching for matching request"); + return -1; + } + if (!request) { + ERROR("[hc_sock_process] No request matching received sequence number"); + return -1; + } + + if (s->roff == s->woff) { + ERROR("[hc_sock_process] No data received for the corresponding request"); + return -1; + } + + err = request->parse((u8 *)request, NULL); + request->data->complete = 1; + s->roff++; + + if (pdata) *pdata = request->data; + + hc_sock_map_remove(s->map, seq, NULL); + hc_sock_request_free(request); + + return err; +} + +int hc_sock_callback(hc_sock_t *s, hc_data_t **pdata) { + hc_data_t *data = NULL; + + for (;;) { + int n = hc_sock_recv(s); + if (n == 0) { + goto ERR_EOF; + } + if (n < 0) { + switch (errno) { + case ECONNRESET: + case ENODEV: + /* Forwarder restarted */ + WARN("Forwarder likely restarted: not (yet) implemented"); + goto ERR; + case EWOULDBLOCK: + // DEBUG("Would block... stop reading from socket"); + goto END; + default: + perror("hc_sock_recv"); + goto ERR; + } + } + if (hc_sock_process(s, &data) < 0) { + goto ERR; + } + } +END: + if (pdata) + *pdata = data; + else + hc_data_free(data); + return 0; + +ERR: + hc_data_free(data); +ERR_EOF: + return -1; +} + +int hc_sock_reset(hc_sock_t *s) { + s->roff = s->woff = 0; + return 0; +} + +/****************************************************************************** + * Command-specific structures and functions + ******************************************************************************/ + +typedef int (*HC_PARSE)(const u8 *, u8 *); + +typedef struct { + hc_action_t cmd; + command_id cmd_id; + size_t size_in; + size_t size_out; + HC_PARSE parse; +} hc_command_params_t; + +int hc_execute_command(hc_sock_t *s, hc_msg_t *msg, size_t msg_len, + hc_command_params_t *params, hc_data_t **pdata, + bool async) { + if (async) assert(!pdata); + + /* Sanity check */ + switch (params->cmd) { + case ACTION_CREATE: + assert(params->size_in != 0); /* payload repeated */ + assert(params->size_out == 0); + //assert(params->parse == NULL); + break; + case ACTION_DELETE: + assert(params->size_in != 0); /* payload repeated */ + assert(params->size_out == 0); + //assert(params->parse == NULL); + break; + case ACTION_LIST: + assert(params->size_in != 0); + assert(params->size_out != 0); + //assert(params->parse != NULL); + break; + case ACTION_SET: + assert(params->size_in != 0); + assert(params->size_out == 0); + //assert(params->parse == NULL); + break; + default: + return -1; + } + + /* XXX data will at least store the result (complete) */ + hc_data_t *data = hc_data_create(params->size_in, params->size_out); + if (!data) { + ERROR("[hc_execute_command] Could not create data storage"); + goto ERR_DATA; + } + + int seq = hc_sock_get_next_seq(s); + + /* Create state used to process the request */ + hc_sock_request_t *request = NULL; + request = hc_sock_request_create(seq, data, params->parse); + if (!request) { + ERROR("[hc_execute_command] Could not create request state"); + goto ERR_REQUEST; + } + + /* Add state to map */ + if (hc_sock_map_add(s->map, seq, request) < 0) { + ERROR("[hc_execute_command] Error adding request state to map"); + goto ERR_MAP; + } + + if (hc_sock_send(s, msg, msg_len, seq) < 0) { + ERROR("[hc_execute_command] Error sending message"); + goto ERR_PROCESS; + } + + if (async) return 0; + + while (!data->complete) { + // CAN WE COLLAPSE THEM INTO A SINGLE COMMAND? Ideally the process would be + // done in the recv + /* + * As the socket is non blocking it might happen that we need to read + * several times before success... shall we alternate between blocking + * and non-blocking mode ? + */ + if (hc_sock_recv(s) < 0) continue; // break; + if (hc_sock_process(s, pdata) < 0) { + ERROR("[hc_execute_command] Error processing socket results"); + goto ERR_PROCESS; + } + } + + if (!pdata) hc_data_free(data); + + return 0; + +ERR_PROCESS: +ERR_MAP: + hc_sock_request_free(request); +ERR_REQUEST: + hc_data_free(data); +ERR_DATA: + return -1; +} + +/*----------------------------------------------------------------------------* + * Listeners + *----------------------------------------------------------------------------*/ + +/* LISTENER CREATE */ + +int _hc_listener_create(hc_sock_t *s, hc_listener_t *listener, bool async) { + // NOT IMPLEMENTED + return -1; +} + +int hc_listener_create(hc_sock_t *s, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +int hc_listener_create_async(hc_sock_t *s, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER GET */ + +int hc_listener_get(hc_sock_t *s, hc_listener_t *listener, + hc_listener_t **listener_found) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER DELETE */ + +int hc_listener_delete(hc_sock_t *s, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +int hc_listener_delete_async(hc_sock_t *s, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER LIST */ +int hc_listener_list(hc_sock_t *s, hc_data_t **pdata) { + // NOT IMPLEMENTED + return -1; +} + +int hc_listener_list_async(hc_sock_t *s, hc_data_t **pdata) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER VALIDATE */ + +int hc_listener_validate(const hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER CMP */ + +int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2) { + // NOT IMPLEMENTED + return -1; +} + +/* LISTENER PARSE */ + +int hc_listener_parse(void *in, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +GENERATE_FIND(listener) + +/* LISTENER SNPRINTF */ + +/* /!\ Please update constants in header file upon changes */ +int hc_listener_snprintf(char *s, size_t size, hc_listener_t *listener) { + // NOT IMPLEMENTED + return -1; +} + +/*----------------------------------------------------------------------------* + * CONNECTION + *----------------------------------------------------------------------------*/ + +/* CONNECTION CREATE */ + +int hc_connection_create(hc_sock_t *s, hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +int hc_connection_create_async(hc_sock_t *s, hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION GET */ + +int hc_connection_get(hc_sock_t *s, hc_connection_t *connection, + hc_connection_t **connection_found) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION DELETE */ + +int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +int hc_connection_delete_async(hc_sock_t *s, hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION LIST */ + +int hc_connection_list(hc_sock_t *s, hc_data_t **pdata) { + // NOT IMPLEMENTED + return -1; +} + +int hc_connection_list_async(hc_sock_t *s, hc_data_t **pdata) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION VALIDATE */ + +int hc_connection_validate(const hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION CMP */ + +/* + * hICN light uses ports even for hICN connections, but their value is ignored. + * As connections are specific to hicn-light, we can safely use IP and ports for + * comparison independently of the face type. + */ +int hc_connection_cmp(const hc_connection_t *c1, const hc_connection_t *c2) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION PARSE */ + +int hc_connection_parse(void *in, hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +GENERATE_FIND(connection) + +/* CONNECTION SNPRINTF */ + +/* /!\ Please update constants in header file upon changes */ +int hc_connection_snprintf(char *s, size_t size, + const hc_connection_t *connection) { + // NOT IMPLEMENTED + return -1; +} + +/* CONNECTION SET ADMIN STATE */ + +int hc_connection_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, + face_state_t state) { + // NOT IMPLEMENTED + return -1; +} + +int hc_connection_set_admin_state_async(hc_sock_t *s, + const char *conn_id_or_name, + face_state_t state) { + // NOT IMPLEMENTED + return -1; +} + +/*----------------------------------------------------------------------------* + * Routes + *----------------------------------------------------------------------------*/ + +/* ROUTE CREATE */ +int parse_route_create(uint8_t *src, uint8_t *dst) { + // No need to write anything on the dst, no data expected + + hc_sock_request_t *request = (hc_sock_request_t *)src; + vapi_payload_hicn_api_route_nhops_add_reply *reply = + (vapi_payload_hicn_api_route_nhops_add_reply *)request->data->buffer; + + int retval = reply->retval; + free(reply); + return retval; +} + +int _hc_route_create(hc_sock_t *s, hc_route_t *route, bool async) { + if (!IS_VALID_FAMILY(route->family)) return -1; + + hc_msg_s *msg = malloc(sizeof(hc_msg_s)); + vapi_msg_hicn_api_route_nhops_add *hicnp_msg; + hicnp_msg = vapi_alloc_hicn_api_route_nhops_add(s->g_vapi_ctx_instance); + msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg; + msg->callback = &vapi_cb; + msg->callback_ctx = malloc(sizeof(callback_ctx_t)); + msg->callback_ctx->s = s; + msg->ntoh = (NTOH)&vapi_msg_hicn_api_route_nhops_add_hton; + + if (route->family == AF_INET) { + memcpy(&hicnp_msg->payload.prefix.address.un.ip4[0], &route->remote_addr.v4, 4); + } + else { + memcpy(&hicnp_msg->payload.prefix.address.un.ip6[0], &route->remote_addr.v6, 16); + } + hicnp_msg->payload.prefix.address.af = + route->family == AF_INET ? ADDRESS_IP4 : ADDRESS_IP6; + hicnp_msg->payload.prefix.len = route->len; + hicnp_msg->payload.face_ids[0] = route->face_id; + hicnp_msg->payload.n_faces = 1; + + hc_command_params_t params = { + .cmd = ACTION_CREATE, + .cmd_id = ADD_ROUTE, + .size_in = + sizeof(vapi_msg_hicn_api_route_nhops_add), + .size_out = 0, + .parse = (HC_PARSE)parse_route_create, + }; + + return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), ¶ms, NULL, + async); +} + +int hc_route_create(hc_sock_t *s, hc_route_t *route) { + return _hc_route_create(s, route, false); +} + +int hc_route_create_async(hc_sock_t *s, hc_route_t *route) { + return _hc_route_create(s, route, true); +} + +/* ROUTE DELETE */ + +int parse_route_delete(uint8_t *src, uint8_t *dst) { + // No need to write anything on the dst, no data expected + + hc_sock_request_t *request = (hc_sock_request_t *)src; + vapi_payload_hicn_api_route_nhop_del_reply *reply = + (vapi_payload_hicn_api_route_nhop_del_reply *)request->data->buffer; + + int retval = reply->retval; + free(reply); + return retval; +} + +int _hc_route_delete(hc_sock_t *s, hc_route_t *route, bool async) { + if (!IS_VALID_FAMILY(route->family)) return -1; + + hc_msg_s *msg = malloc(sizeof(hc_msg_s)); + vapi_msg_hicn_api_route_nhop_del *hicnp_msg; + hicnp_msg = vapi_alloc_hicn_api_route_nhop_del(s->g_vapi_ctx_instance); + msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg; + msg->callback = &vapi_cb; + msg->callback_ctx = malloc(sizeof(callback_ctx_t)); + msg->callback_ctx->s = s; + msg->ntoh = (NTOH)&vapi_msg_hicn_api_route_nhop_del_hton; + + memcpy(&hicnp_msg->payload.prefix.address.un.ip6[0], &route->remote_addr, 16); + hicnp_msg->payload.prefix.address.af = + route->family == AF_INET ? ADDRESS_IP4 : ADDRESS_IP6; + hicnp_msg->payload.prefix.len = route->len; + hicnp_msg->payload.faceid = route->face_id; + + hc_command_params_t params = { + .cmd = ACTION_DELETE, + .cmd_id = REMOVE_ROUTE, + .size_in = + sizeof(vapi_msg_hicn_api_route_nhop_del), + .size_out = 0, + .parse = (HC_PARSE)parse_route_delete, + }; + + return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), ¶ms, NULL, + async); +} + +int hc_route_delete(hc_sock_t *s, hc_route_t *route) { + return _hc_route_delete(s, route, false); +} + +int hc_route_delete_async(hc_sock_t *s, hc_route_t *route) { + return _hc_route_delete(s, route, true); +} + +/* ROUTE LIST */ +int parse_route_list(uint8_t *src, uint8_t *dst) { + // No need to write anything on the dst, no data expected + + hc_sock_request_t *request = (hc_sock_request_t *)src; + + int size = 0; + for (int i = 0; i < request->data->current; i++) { + vapi_payload_hicn_api_routes_details *reply = + (vapi_payload_hicn_api_routes_details + *)(request->data->buffer + i * request->data->in_element_size); + size += reply->nfaces; + } + hc_route_t *output = malloc(sizeof(hc_route_t) * size); + + int cur = 0; + for (int j = 0; j < request->data->current; j++) { + vapi_payload_hicn_api_routes_details *reply = + (vapi_payload_hicn_api_routes_details + *)(request->data->buffer + j * request->data->in_element_size); + for (int i = 0; i < reply->nfaces; i++) { + output[cur].face_id = reply->faceids[i]; + output[cur].cost = 1; + output[cur].len = reply->prefix.len; + if (reply->prefix.address.af == ADDRESS_IP6) + { + memcpy(output[cur].remote_addr.v6.as_u8, reply->prefix.address.un.ip6, 16); + } + else + { + memcpy(output[cur].remote_addr.v4.as_u8, reply->prefix.address.un.ip4, 4); + } + output[cur].family = reply->prefix.address.af == ADDRESS_IP6? AF_INET6 : AF_INET; + cur++; + } + } + + free(request->data->buffer); + request->data->buffer = (void *)output; + request->data->size = size; + request->data->out_element_size = sizeof(hc_route_t); + return 0; +} + +int _hc_route_list(hc_sock_t *s, hc_data_t **pdata, bool async) { + hc_msg_s *msg = malloc(sizeof(hc_msg_s)); + vapi_msg_hicn_api_routes_dump *hicnp_msg; + hicnp_msg = vapi_alloc_hicn_api_routes_dump(s->g_vapi_ctx_instance); + msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg; + msg->callback = &vapi_cb; + msg->callback_ctx = malloc(sizeof(callback_ctx_t)); + msg->callback_ctx->s = s; + msg->ntoh = (NTOH)&vapi_msg_hicn_api_routes_dump_hton; + + hc_command_params_t params = { + .cmd = ACTION_LIST, + .cmd_id = LIST_ROUTES, + .size_in = sizeof(vapi_msg_hicn_api_routes_details), + .size_out = sizeof(hc_route_t), + .parse = (HC_PARSE)parse_route_list, + }; + + return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), ¶ms, pdata, + async); +} + +int hc_route_list(hc_sock_t *s, hc_data_t **pdata) { + return _hc_route_list(s, pdata, false); +} + +int hc_route_list_async(hc_sock_t *s) { + return _hc_route_list(s, NULL, true); +} + +/* ROUTE SNPRINTF */ + +/* /!\ Please update constants in header file upon changes */ +int hc_route_snprintf(char *s, size_t size, hc_route_t *route) { + /* interface cost prefix length */ + + char prefix[MAXSZ_IP_ADDRESS]; + int rc; + + rc = ip_address_snprintf(prefix, MAXSZ_IP_ADDRESS, &route->remote_addr, + route->family); + if (rc < 0) return rc; + + return snprintf(s, size, "%*d %*d %s %*d", MAXSZ_FACE_ID, route->face_id, + MAXSZ_COST, route->cost, prefix, MAXSZ_LEN, route->len); +} + +/*----------------------------------------------------------------------------* + * Face + * + * Face support is not directly available in hicn-light, but we can offer such + * an interface through a combination of listeners and connections. The code + * starts with some conversion functions between faces/listeners/connections. + * + * We also need to make sure that there always exist a (single) listener when a + * connection is created, and in the hICN face case, that there is a single + * connection attached to this listener. + * + *----------------------------------------------------------------------------*/ + +/* FACE -> LISTENER */ + +int hc_face_to_listener(const hc_face_t *face, hc_listener_t *listener) { + const face_t *f = &face->face; + + switch (f->type) { + case FACE_TYPE_HICN_LISTENER: + break; + case FACE_TYPE_TCP_LISTENER: + break; + case FACE_TYPE_UDP_LISTENER: + break; + default: + return -1; + } + return -1; /* XXX Not implemented */ +} + +/* LISTENER -> FACE */ + +int hc_listener_to_face(const hc_listener_t *listener, hc_face_t *face) { + return -1; /* XXX Not implemented */ +} + +/* FACE -> CONNECTION */ + +int hc_face_to_connection(const hc_face_t *face, hc_connection_t *connection, + bool generate_name) { + return 0; +} + +/* CONNECTION -> FACE */ + +int hc_connection_to_face(const hc_connection_t *connection, hc_face_t *face) { + return 0; +} + +/* CONNECTION -> LISTENER */ + +int hc_connection_to_local_listener(const hc_connection_t *connection, + hc_listener_t *listener) { + return 0; +} + +/* FACE CREATE */ + +int hc_face_create(hc_sock_t *s, hc_face_t *face) { return 0; } + +int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_face_t **face_found) { + return 0; +} + +/* FACE DELETE */ + +int hc_face_delete(hc_sock_t *s, hc_face_t *face) { return 0; } + +/* FACE LIST */ + +int hc_face_list(hc_sock_t *s, hc_data_t **pdata) { return 0; } + +int hc_connection_parse_to_face(void *in, hc_face_t *face) { return 0; } + +int hc_face_list_async(hc_sock_t *s) //, hc_data_t ** pdata) +{ + return 0; +} + +/* /!\ Please update constants in header file upon changes */ +int hc_face_snprintf(char *s, size_t size, hc_face_t *face) { return 0; } + +int hc_face_set_admin_state( + hc_sock_t *s, const char *conn_id_or_name, // XXX wrong identifier + face_state_t admin_state) { + return 0; +} + +/*----------------------------------------------------------------------------* + * Punting + *----------------------------------------------------------------------------*/ + +int _hc_punting_create(hc_sock_t *s, hc_punting_t *punting, bool async) { + return 0; +} + +int hc_punting_create(hc_sock_t *s, hc_punting_t *punting) { + return _hc_punting_create(s, punting, false); +} + +int hc_punting_create_async(hc_sock_t *s, hc_punting_t *punting) { + return _hc_punting_create(s, punting, true); +} + +int hc_punting_get(hc_sock_t *s, hc_punting_t *punting, + hc_punting_t **punting_found) { + ERROR("hc_punting_get not (yet) implemented."); + return -1; +} + +int hc_punting_delete(hc_sock_t *s, hc_punting_t *punting) { + ERROR("hc_punting_delete not (yet) implemented."); + return -1; +} + +int hc_punting_list(hc_sock_t *s, hc_data_t **pdata) { + ERROR("hc_punting_list not (yet) implemented."); + return -1; +} + +int hc_punting_validate(const hc_punting_t *punting) { + if (!IS_VALID_FAMILY(punting->family)) return -1; + + /* + * We might use the zero value to add punting on all faces but this is not + * (yet) implemented + */ + if (punting->face_id == 0) { + ERROR("Punting on all faces is not (yet) implemented."); + return -1; + } + + return 0; +} + +int hc_punting_cmp(const hc_punting_t *p1, const hc_punting_t *p2) { + return ((p1->face_id == p2->face_id) && (p1->family == p2->family) && + (ip_address_cmp(&p1->prefix, &p2->prefix, p1->family) == 0) && + (p1->prefix_len == p2->prefix_len)) + ? 0 + : -1; +} + +int hc_punting_parse(void *in, hc_punting_t *punting) { + ERROR("hc_punting_parse not (yet) implemented."); + return -1; +} + +int hc_punting_snprintf(char *s, size_t size, hc_punting_t *punting) { + ERROR("hc_punting_snprintf not (yet) implemented."); + return -1; +} + +/*----------------------------------------------------------------------------* + * Cache + *----------------------------------------------------------------------------*/ + +int _hc_cache_set_store(hc_sock_t *s, int enabled, bool async) { + return 0; +} + +int hc_cache_set_store(hc_sock_t *s, int enabled) { + return _hc_cache_set_store(s, enabled, false); +} + +int hc_cache_set_store_async(hc_sock_t *s, int enabled) { + return _hc_cache_set_store(s, enabled, true); +} + +int _hc_cache_set_serve(hc_sock_t *s, int enabled, bool async) { + return 0; +} + +int hc_cache_set_serve(hc_sock_t *s, int enabled) { + return _hc_cache_set_serve(s, enabled, false); +} + +int hc_cache_set_serve_async(hc_sock_t *s, int enabled) { + return _hc_cache_set_serve(s, enabled, true); +} + +/*----------------------------------------------------------------------------* + * Strategy + *----------------------------------------------------------------------------*/ + +// per prefix +int hc_strategy_set(hc_sock_t *s /* XXX */) { return 0; } + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array)) + +int hc_strategy_list(hc_sock_t *s, hc_data_t **data) { + return 0; +} + +/* /!\ Please update constants in header file upon changes */ +int hc_strategy_snprintf(char *s, size_t size, hc_strategy_t *strategy) { + return snprintf(s, size, "%s", strategy->name); +} + +/*----------------------------------------------------------------------------* + * WLDR + *----------------------------------------------------------------------------*/ + +// per connection +int hc_wldr_set(hc_sock_t *s /* XXX */) { return 0; } + +/*----------------------------------------------------------------------------* + * MAP-Me + *----------------------------------------------------------------------------*/ + +int hc_mapme_set(hc_sock_t *s, int enabled) { return 0; } + +int hc_mapme_set_discovery(hc_sock_t *s, int enabled) { return 0; } + +int hc_mapme_set_timescale(hc_sock_t *s, double timescale) { return 0; } + +int hc_mapme_set_retx(hc_sock_t *s, double timescale) { return 0; } + +/* Useless function defined to prevent undefined reference */ +hc_connection_type_t +connection_type_from_str(const char * str) +{ + if (strcasecmp(str, "TCP") == 0) + return CONNECTION_TYPE_TCP; + else if (strcasecmp(str, "UDP") == 0) + return CONNECTION_TYPE_UDP; + else if (strcasecmp(str, "HICN") == 0) + return CONNECTION_TYPE_HICN; + else + return CONNECTION_TYPE_UNDEFINED; +} + +/*********************** Missing Symbol in vpp libraries *************************/ +u8 * +format_vl_api_address_union (u8 * s, va_list * args) +{ + return NULL; +} diff --git a/hicn-plugin/CMakeLists.txt b/hicn-plugin/CMakeLists.txt index 56c8055ee..e0b06663f 100644 --- a/hicn-plugin/CMakeLists.txt +++ b/hicn-plugin/CMakeLists.txt @@ -192,8 +192,8 @@ set(HICN_API_GENERATED_FILES ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h) set(HICN_VAPI_GENERATED_FILES - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.vapi.h - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.vapi.hpp) + ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h + ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.hpp) set(HICN_VPP_STARTUP_CONF_FILE ${CMAKE_BINARY_DIR}/startup.conf) @@ -216,6 +216,7 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") endif() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hicn) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vapi) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip) # These files are missing from vpp binary distribution @@ -224,43 +225,29 @@ execute_process( bash -c "if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ]; then curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_json_parser.py?h=stable/1908 -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py; - fi;" -) -execute_process( - COMMAND - bash -c - "if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ]; then + fi; + if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ]; then curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_c_gen.py?h=stable/1908 -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py; - fi;" -) -execute_process( - COMMAND - bash -c - "if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ]; then + fi; + if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ]; then curl https://git.fd.io/vpp/plain/src/vpp-api/vapi/vapi_cpp_gen.py?h=stable/1908 -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py; - fi;" -) - -execute_process( - COMMAND - bash -c - "if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_types.api ]; then + fi; + if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_types.api ]; then curl https://git.fd.io/vpp/plain/src/vnet/ip/ip_types.api?h=stable/1908 -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_types.api; - fi;" + fi; + chmod +x ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py" ) add_custom_command( - COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h - COMMAND ${VPP_HOME}/bin/vppapigen --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/src/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/hicn.api - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.json - COMMAND ${VPP_HOME}/bin/vppapigen JSON --input ${CMAKE_CURRENT_SOURCE_DIR}/src/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.json - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.vapi.h - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.json - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.vapi.hpp - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.json - ) + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json + COMMAND ${VPP_HOME}/bin/vppapigen ARGS --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/src/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h + COMMAND ${VPP_HOME}/bin/vppapigen ARGS JSON --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/src/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json +) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.hpp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ARGS ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ARGS ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json +) include_directories(SYSTEM) include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -323,3 +310,9 @@ install(FILES ${HICN_API_GENERATED_FILES} install(FILES ${HICN_VAPI_GENERATED_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vapi COMPONENT ${HICN_PLUGIN}-dev) + +#Set variables for other project depending on hicn-plugin +set(HICNPLUGIN_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins PARENT_SCOPE) +set(HICNPLUGIN_LIBRARIES ${VPP_LIBRARIES} PARENT_SCOPE)
\ No newline at end of file diff --git a/hicn-plugin/src/cache_policies/cs_lru.c b/hicn-plugin/src/cache_policies/cs_lru.c index 1f1d14667..45c4b5b79 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.c +++ b/hicn-plugin/src/cache_policies/cs_lru.c @@ -25,6 +25,7 @@ hicn_cs_policy_vft_t hicn_cs_lru = { .hicn_cs_dequeue = &hicn_cs_lru_dequeue, .hicn_cs_delete_get = &hicn_cs_lru_delete_get, .hicn_cs_trim = &hicn_cs_lru_trim, + .hicn_cs_flush = &hicn_cs_lru_flush, }; /* @@ -151,10 +152,10 @@ hicn_cs_lru_update_head (hicn_pit_cs_t * pit, hicn_hash_node_t * pnode, { /* The element is already dequeue */ if (pcs->u.cs.cs_lru_next == 0) - { - /* Now detached from the list; attach at head */ - hicn_cs_lru_insert (pit, pnode, pcs, lru); - } + { + /* Now detached from the list; attach at head */ + hicn_cs_lru_insert (pit, pnode, pcs, lru); + } ASSERT (lru->head == hicn_hashtb_node_idx_from_node (pit->pcs_table, pnode)); } @@ -212,6 +213,56 @@ hicn_cs_lru_trim (hicn_pit_cs_t * pit, u32 * node_list, int sz, return (i); } +int +hicn_cs_lru_flush (vlib_main_t * vm, struct hicn_pit_cs_s *pitcs, + hicn_cs_policy_t * state) +{ + if (state->head == 0 && state->tail == 0) + return 0; + + hicn_hash_node_t *lrunode; + hicn_pcs_entry_t *lrupcs; + u32 idx; + int i = 0; + + idx = state->tail; + + while (idx != 0) + { + lrunode = hicn_hashtb_node_from_idx (pitcs->pcs_table, idx); + lrupcs = hicn_pit_get_data (lrunode); + + u64 hashval = 0; + hicn_hashtb_fullhash ((u8 *) & (lrunode->hn_key.ks.key), + lrunode->hn_keysize, &hashval); + hicn_hash_bucket_t *bucket = NULL; + if ((hashval & (pitcs->pcs_table->ht_bucket_count - 1)) == + lrunode->bucket_id) + { + //The bucket is in the non overflown + bucket = + pool_elt_at_index (pitcs->pcs_table->ht_buckets, + lrunode->bucket_id); + } + else + { + bucket = + pool_elt_at_index (pitcs->pcs_table->ht_overflow_buckets, + lrunode->bucket_id); + } + hicn_hash_entry_t *hash_entry = + &(bucket->hb_entries[lrunode->entry_idx]); + hash_entry->locks++; + hicn_pcs_cs_delete (vm, pitcs, &lrupcs, &lrunode, hash_entry, NULL, + NULL); + idx = state->tail; + i++; + } + + return (i); + +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/hicn-plugin/src/cache_policies/cs_lru.h b/hicn-plugin/src/cache_policies/cs_lru.h index 94320f7f9..0a58912d6 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.h +++ b/hicn-plugin/src/cache_policies/cs_lru.h @@ -58,6 +58,8 @@ int hicn_cs_lru_trim (hicn_pit_cs_t * pcs, u32 * node_list, int sz, hicn_cs_policy_t * lru); +int hicn_cs_lru_flush (vlib_main_t * vm, struct hicn_pit_cs_s *pitcs, + hicn_cs_policy_t * state); #endif /* // __LRU_H__ */ /* diff --git a/hicn-plugin/src/cache_policies/cs_policy.h b/hicn-plugin/src/cache_policies/cs_policy.h index 08817de18..c1a9a44c9 100644 --- a/hicn-plugin/src/cache_policies/cs_policy.h +++ b/hicn-plugin/src/cache_policies/cs_policy.h @@ -68,6 +68,9 @@ typedef struct hicn_cs_policy_vft_s int (*hicn_cs_trim) (struct hicn_pit_cs_s * p, u32 * node_list, int sz, hicn_cs_policy_t * policy); + + int (*hicn_cs_flush) (vlib_main_t * vm, struct hicn_pit_cs_s * p, + hicn_cs_policy_t * policy_state); } hicn_cs_policy_vft_t; diff --git a/hicn-plugin/src/face_db.h b/hicn-plugin/src/face_db.h index c3308050a..17c28959a 100644 --- a/hicn-plugin/src/face_db.h +++ b/hicn-plugin/src/face_db.h @@ -110,9 +110,6 @@ hicn_face_db_add_face_dpo (dpo_id_t * dpo, hicn_face_db_t * face_db) clib_memcpy (face, dpo, sizeof (dpo_id_t)); - /* This access the dpoi to increase the lock */ - dpo_lock (dpo); - u32 bitmap_index = dpo->dpoi_index % HICN_PIT_N_HOP_BITMAP_SIZE; u32 position_array = bitmap_index / 8; u8 bit_index = (u8) (bitmap_index - position_array * 8); diff --git a/hicn-plugin/src/faces/app/face_app_cli.c b/hicn-plugin/src/faces/app/face_app_cli.c index 200f813cb..1e8eb6a5b 100644 --- a/hicn-plugin/src/faces/app/face_app_cli.c +++ b/hicn-plugin/src/faces/app/face_app_cli.c @@ -35,7 +35,8 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, { vnet_main_t *vnm = vnet_get_main (); fib_prefix_t prefix; - hicn_face_id_t face_id = HICN_FACE_NULL; + hicn_face_id_t face_id1 = HICN_FACE_NULL; + hicn_face_id_t face_id2 = HICN_FACE_NULL; u32 cs_reserved = HICN_PARAM_FACE_DFT_CS_RESERVED; int ret = HICN_ERROR_NONE; int sw_if; @@ -57,7 +58,7 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, face_op = HICN_FACE_DELETE; } else if (face_op == HICN_FACE_DELETE - && unformat (line_input, "id %d", &face_id)) + && unformat (line_input, "id %d", &face_id1)) ; else if (unformat (line_input, "add")) { @@ -95,13 +96,13 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, } } - if (face_id != HICN_FACE_NULL) + if (face_id1 != HICN_FACE_NULL) { - if (!hicn_dpoi_idx_is_valid (face_id)) + if (!hicn_dpoi_idx_is_valid (face_id1)) { - return clib_error_return (0, "%s, face_id %d not valid", - get_error_string (ret), face_id); + return clib_error_return (0, "%s, face_id1 %d not valid", + get_error_string (ret), face_id1); } } @@ -116,15 +117,18 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, if (prod) { - prefix.fp_proto = ip46_address_is_ip4(&prefix.fp_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + prefix.fp_proto = + ip46_address_is_ip4 (&prefix. + fp_addr) ? FIB_PROTOCOL_IP4 : + FIB_PROTOCOL_IP6; rv = - hicn_face_prod_add (&prefix, sw_if, &cs_reserved, - &prod_addr, &face_id); + hicn_face_prod_add (&prefix, sw_if, &cs_reserved, &prod_addr, + &face_id1); if (rv == HICN_ERROR_NONE) { u8 *sbuf = NULL; sbuf = - format (sbuf, "Face id: %d, producer address %U", face_id, + format (sbuf, "Face id: %d, producer address %U", face_id1, format_ip46_address, &prod_addr, 0 /*IP46_ANY_TYPE */ ); vlib_cli_output (vm, "%s", sbuf); @@ -137,13 +141,15 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, else { rv = - hicn_face_cons_add (&cons_addr4, &cons_addr6, sw_if, &face_id); + hicn_face_cons_add (&cons_addr4, &cons_addr6, sw_if, &face_id1, + &face_id2); if (rv == HICN_ERROR_NONE) { u8 *sbuf = NULL; sbuf = - format (sbuf, "Face id: %d, consumer addresses v4 %U v6 %U", - face_id, format_ip4_address, &cons_addr4, + format (sbuf, + "Face id: %d, address v4 %U, face id: %d address v6 %U", + face_id1, format_ip4_address, &cons_addr4, face_id2, format_ip6_address, &cons_addr6); vlib_cli_output (vm, "%s", sbuf); } @@ -156,15 +162,15 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm, } case HICN_FACE_DELETE: { - hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id1); if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS) - rv = hicn_face_cons_del (face_id); + rv = hicn_face_cons_del (face_id1); else - rv = hicn_face_prod_del (face_id); + rv = hicn_face_prod_del (face_id1); if (rv == HICN_ERROR_NONE) { - vlib_cli_output (vm, "Face %d deleted", face_id); + vlib_cli_output (vm, "Face %d deleted", face_id1); } else { diff --git a/hicn-plugin/src/faces/app/face_cons.c b/hicn-plugin/src/faces/app/face_cons.c index 8278b6ab3..f258da787 100644 --- a/hicn-plugin/src/faces/app/face_cons.c +++ b/hicn-plugin/src/faces/app/face_cons.c @@ -23,7 +23,8 @@ int hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, - u32 swif, hicn_face_id_t * faceid) + u32 swif, hicn_face_id_t * faceid1, + hicn_face_id_t * faceid2) { /* Create the corresponding appif if */ /* Retrieve a valid local ip address to assign to the appif */ @@ -56,9 +57,9 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, ip46_address_t nh_addr = to_ip46 (0, (u8 *) nh_addr4); - hicn_iface_ip_add (&if_ip, &nh_addr, swif, faceid); + hicn_iface_ip_add (&if_ip, &nh_addr, swif, faceid1); - hicn_face_t *face = hicn_dpoi_get_from_idx (*faceid); + hicn_face_t *face = hicn_dpoi_get_from_idx (*faceid1); face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS; get_two_ip6_addresses (&(if_ip.ip6), nh_addr6); @@ -67,9 +68,9 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, &(if_ip.ip6), ADDR_MGR_IP6_CONS_LEN, 0 /* is_del */ ); - hicn_iface_ip_add (&if_ip, (ip46_address_t *) nh_addr6, swif, faceid); + hicn_iface_ip_add (&if_ip, (ip46_address_t *) nh_addr6, swif, faceid2); - face = hicn_dpoi_get_from_idx (*faceid); + face = hicn_dpoi_get_from_idx (*faceid2); face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS; return vnet_feature_enable_disable ("ip6-unicast", @@ -81,6 +82,9 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, int hicn_face_cons_del (hicn_face_id_t face_id) { + if (!hicn_dpoi_idx_is_valid (face_id)) + return HICN_ERROR_APPFACE_NOT_FOUND; + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS) diff --git a/hicn-plugin/src/faces/app/face_cons.h b/hicn-plugin/src/faces/app/face_cons.h index 067b45a1f..5f8f5dde8 100644 --- a/hicn-plugin/src/faces/app/face_cons.h +++ b/hicn-plugin/src/faces/app/face_cons.h @@ -47,7 +47,8 @@ */ int hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, - u32 swif, hicn_face_id_t * faceid); + u32 swif, hicn_face_id_t * faceid1, + hicn_face_id_t * faceid2); /** * @brief Delete an existing consumer application face diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c index 6c12e6d33..14e100adc 100644 --- a/hicn-plugin/src/faces/app/face_prod.c +++ b/hicn-plugin/src/faces/app/face_prod.c @@ -16,6 +16,7 @@ #include <vnet/ip/ip6_packet.h> #include <vlib/vlib.h> #include <vnet/vnet.h> +#include <vnet/interface_funcs.h> #include "face_prod.h" #include "address_mgr.h" @@ -53,8 +54,7 @@ hicn_app_state_create (u32 swif, fib_prefix_t * prefix) /* Create the appif and store in the vector */ vec_validate (face_state_vec, swif); - clib_memcpy (&(face_state_vec[swif].prefix), prefix, - sizeof (fib_prefix_t)); + clib_memcpy (&(face_state_vec[swif].prefix), prefix, sizeof (fib_prefix_t)); /* Set as busy the element in the vector */ pool_get (face_state_pool, swif_app); @@ -139,6 +139,12 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, { return HICN_ERROR_FWD_NOT_ENABLED; } + + if (vnet_get_sw_interface_or_null (vnm, sw_if) == NULL) + { + return HICN_ERROR_FACE_HW_INT_NOT_FOUND; + } + int ret = HICN_ERROR_NONE; hicn_face_t *face = NULL; @@ -146,8 +152,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, vnet_sw_interface_set_flags (vnm, sw_if, if_flags); u8 *s0; - s0 = format (0, "Prefix %U", format_fib_prefix, - prefix); + s0 = format (0, "Prefix %U", format_fib_prefix, prefix); vlib_cli_output (vm, "Received request for %s, swif %d\n", s0, sw_if); @@ -218,7 +223,8 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, remote_app_ip = to_ip46 ( /* isv6 */ 0, remote_app_ip4.as_u8); ret = - hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD); + hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, + HICN_FACE_FLAGS_APPFACE_PROD); } else { @@ -238,7 +244,8 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, remote_app_ip = to_ip46 ( /* isv6 */ 1, remote_app_ip6.as_u8); ret = - hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD); + hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, + HICN_FACE_FLAGS_APPFACE_PROD); } face = hicn_dpoi_get_from_idx (*faceid); @@ -257,6 +264,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, prod_face->policy_vft.hicn_cs_delete_get = hicn_cs_lru.hicn_cs_delete_get; prod_face->policy_vft.hicn_cs_trim = hicn_cs_lru.hicn_cs_trim; + prod_face->policy_vft.hicn_cs_flush = hicn_cs_lru.hicn_cs_flush; } @@ -283,13 +291,15 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, int hicn_face_prod_del (hicn_face_id_t face_id) { + if (!hicn_dpoi_idx_is_valid (face_id)) + return HICN_ERROR_APPFACE_NOT_FOUND; + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) { hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data; /* Free the CS reserved for the face */ - hicn_main.pitcs.pcs_app_max += prod_face->policy.max; hicn_main.pitcs.pcs_app_count -= prod_face->policy.max; prod_face->policy.max = 0; @@ -297,6 +307,15 @@ hicn_face_prod_del (hicn_face_id_t face_id) hicn_route_del_nhop (&(face_state_vec[face->shared.sw_if].prefix), face_id); + /* + * Delete the content in the CS before deleting the face. + * Mandatory to prevent hitting the CS and not having the lru list + * due to a early deletion of the face. + */ + vlib_main_t *vm = vlib_get_main (); + prod_face->policy_vft.hicn_cs_flush (vm, &(hicn_main.pitcs), + &(prod_face->policy)); + int ret = hicn_face_ip_del (face_id); return ret == HICN_ERROR_NONE ? hicn_app_state_del (face->shared.sw_if) : ret; diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index 74939b77e..fa9d0d203 100644 --- a/hicn-plugin/src/faces/face.c +++ b/hicn-plugin/src/faces/face.c @@ -132,6 +132,7 @@ hicn_face_del (hicn_face_id_t face_id) if (hicn_dpoi_idx_is_valid (face_id)) { hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + face->shared.locks--; if (face->shared.locks == 0) pool_put_index (hicn_dpoi_face_pool, face_id); else diff --git a/hicn-plugin/src/faces/ip/dpo_ip.h b/hicn-plugin/src/faces/ip/dpo_ip.h index d6b4f5f7e..c893c8be4 100644 --- a/hicn-plugin/src/faces/ip/dpo_ip.h +++ b/hicn-plugin/src/faces/ip/dpo_ip.h @@ -41,11 +41,15 @@ void hicn_dpo_ip_module_init (void); */ always_inline int hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo, - u32 * in_faces_vec_id, + u32 * in_faces_vec_id, u8 * hicnb_flags, const ip4_address_t * local_addr, u32 sw_if) { - hicn_face_ip_input_faces_t * in_faces_vec = + dpo->dpoi_type = DPO_FIRST; + dpo->dpoi_proto = DPO_PROTO_NONE; + dpo->dpoi_index = INDEX_INVALID; + dpo->dpoi_next_node = 0; + hicn_face_ip_input_faces_t *in_faces_vec = hicn_face_ip4_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb); if (PREDICT_FALSE (in_faces_vec == NULL)) @@ -61,7 +65,7 @@ hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo, dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, in_faces_vec->face_id); dpo->dpoi_next_node = ~0; - dpo_lock (dpo); + dpo_unlock (dpo); return HICN_ERROR_NONE; } @@ -80,11 +84,15 @@ hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo, */ always_inline int hicn_dpo_ip6_lock_from_local (dpo_id_t * dpo, - u32 * in_faces_vec_id, + u32 * in_faces_vec_id, u8 * hicnb_flags, const ip6_address_t * local_addr, u32 sw_if) { - hicn_face_ip_input_faces_t * in_faces_vec = + dpo->dpoi_type = DPO_FIRST; + dpo->dpoi_proto = DPO_PROTO_NONE; + dpo->dpoi_index = INDEX_INVALID; + dpo->dpoi_next_node = 0; + hicn_face_ip_input_faces_t *in_faces_vec = hicn_face_ip6_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb); if (PREDICT_FALSE (in_faces_vec == NULL)) @@ -100,7 +108,7 @@ hicn_dpo_ip6_lock_from_local (dpo_id_t * dpo, dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, in_faces_vec->face_id); dpo->dpoi_next_node = ~0; - dpo_lock (dpo); + dpo_unlock (dpo); return HICN_ERROR_NONE; } @@ -144,7 +152,7 @@ hicn_dpo_ip4_add_and_lock_from_remote (dpo_id_t * dpo, dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); return; } @@ -158,7 +166,7 @@ hicn_dpo_ip4_add_and_lock_from_remote (dpo_id_t * dpo, hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); } /** @@ -198,7 +206,7 @@ hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo, dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); return; } @@ -211,7 +219,7 @@ hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo, index_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); } diff --git a/hicn-plugin/src/faces/ip/face_ip.h b/hicn-plugin/src/faces/ip/face_ip.h index 0491af506..74f3a83dc 100644 --- a/hicn-plugin/src/faces/ip/face_ip.h +++ b/hicn-plugin/src/faces/ip/face_ip.h @@ -47,7 +47,7 @@ typedef struct hicn_ip_face_t_ * @bried vector of faces used to collect faces having the same local address * */ -typedef hicn_face_id_t * hicn_face_ip_vec_t; +typedef hicn_face_id_t *hicn_face_ip_vec_t; typedef struct hicn_ip_input_faces_s_ { @@ -77,7 +77,7 @@ extern mhash_t hicn_face_ip_remote_hashtb; /** * Pool containing the vector of possible incoming faces. */ -extern hicn_face_ip_vec_t * hicn_vec_pool; +extern hicn_face_ip_vec_t *hicn_vec_pool; /** * Key definition for the mhash table. An ip face is uniquely identified by ip @@ -161,12 +161,13 @@ hicn_face_ip4_get (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb) * @result Pointer to the face. */ always_inline hicn_face_ip_input_faces_t * -hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb) +hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if, + mhash_t * hashtb) { hicn_face_ip_key_t key; hicn_face_ip4_get_key (addr, sw_if, &key); - return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key); + return (hicn_face_ip_input_faces_t *) mhash_get (hashtb, &key); } /** @@ -179,12 +180,13 @@ hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb) * @result Pointer to the face. */ always_inline hicn_face_ip_input_faces_t * -hicn_face_ip6_get_vec (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb) +hicn_face_ip6_get_vec (const ip6_address_t * addr, u32 sw_if, + mhash_t * hashtb) { hicn_face_ip_key_t key; hicn_face_ip6_get_key (addr, sw_if, &key); - return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key); + return (hicn_face_ip_input_faces_t *) mhash_get (hashtb, &key); } /** @@ -255,7 +257,7 @@ hicn_iface_ip_add (const ip46_address_t * local_addr, face->shared.pl_id = (u16) 0; face->shared.face_type = hicn_face_ip_type; face->shared.flags = HICN_FACE_FLAGS_IFACE; - face->shared.locks = 0; + face->shared.locks = 1; hicn_face_ip_key_t key; hicn_face_ip6_get_key (&(remote_addr->ip6), sw_if, &key); diff --git a/hicn-plugin/src/faces/udp/dpo_udp.h b/hicn-plugin/src/faces/udp/dpo_udp.h index 06c65a9c2..98abf3d29 100644 --- a/hicn-plugin/src/faces/udp/dpo_udp.h +++ b/hicn-plugin/src/faces/udp/dpo_udp.h @@ -92,7 +92,7 @@ hicn_dpo_udp4_lock (dpo_id_t * dpo, index_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = strategy_face_udp4_vlib_edge; - dpo_lock (dpo); + dpo_unlock (dpo); *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; @@ -138,7 +138,7 @@ hicn_dpo_udp4_add_and_lock (dpo_id_t * dpo, *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); return; } @@ -148,7 +148,7 @@ hicn_dpo_udp4_add_and_lock (dpo_id_t * dpo, hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); } /** @@ -212,7 +212,7 @@ hicn_dpo_udp6_lock (dpo_id_t * dpo, hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index); dpo->dpoi_next_node = strategy_face_udp6_vlib_edge; - dpo_lock (dpo); + dpo_unlock (dpo); *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; return HICN_ERROR_NONE; @@ -256,7 +256,7 @@ hicn_dpo_udp6_add_and_lock (dpo_id_t * dpo, *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); return; } @@ -266,7 +266,7 @@ hicn_dpo_udp6_add_and_lock (dpo_id_t * dpo, hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face); dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index); dpo->dpoi_next_node = node_index; - dpo_lock (dpo); + dpo_unlock (dpo); } /** diff --git a/hicn-plugin/src/faces/udp/face_udp.c b/hicn-plugin/src/faces/udp/face_udp.c index ec43d9081..6a8e5c9e0 100644 --- a/hicn-plugin/src/faces/udp/face_udp.c +++ b/hicn-plugin/src/faces/udp/face_udp.c @@ -81,17 +81,15 @@ hicn_face_udp_init (vlib_main_t * vm) /* Default Strategy has index 0 and it always exists */ strategy_face_udp4_vlib_edge = vlib_node_add_next (vm, hicn_dpo_get_strategy_vft - (default_dpo. - hicn_dpo_get_type ())-> - get_strategy_node_index + (default_dpo.hicn_dpo_get_type + ())->get_strategy_node_index (), - hicn_face_udp4_output_node. - index); + hicn_face_udp4_output_node.index); strategy_face_udp6_vlib_edge = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft (default_dpo. - hicn_dpo_get_type ())-> - get_strategy_node_index (), + hicn_dpo_get_strategy_vft + (default_dpo.hicn_dpo_get_type + ())->get_strategy_node_index (), hicn_face_udp6_output_node.index); /* @@ -145,7 +143,7 @@ hicn_face_udp_add (const ip46_address_t * local_addr, fib_prefix_t fib_pfx; fib_node_index_t fib_entry_index; fib_prefix_from_ip46_addr (remote_addr, &fib_pfx); - fib_pfx.fp_len = ip46_address_is_ip4(remote_addr)? 32 : 128; + fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128; u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto, HICN_FIB_TABLE, @@ -155,14 +153,14 @@ hicn_face_udp_add (const ip46_address_t * local_addr, ip_adj = fib_entry_get_adj (fib_entry_index); if (ip_adj == ~0) - return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; + return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; hicn_face_t *face = hicn_face_udp4_get (&local_addr->ip4, &remote_addr->ip4, local_port, remote_port); if (face != NULL) - return HICN_ERROR_FACE_ALREADY_CREATED; + return HICN_ERROR_FACE_ALREADY_CREATED; pool_get (hicn_dpoi_face_pool, face); @@ -211,7 +209,7 @@ hicn_face_udp_add (const ip46_address_t * local_addr, fib_prefix_t fib_pfx; fib_node_index_t fib_entry_index; fib_prefix_from_ip46_addr (remote_addr, &fib_pfx); - fib_pfx.fp_len = ip46_address_is_ip4(remote_addr)? 32 : 128; + fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128; u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto, HICN_FIB_TABLE, @@ -221,14 +219,14 @@ hicn_face_udp_add (const ip46_address_t * local_addr, ip_adj = fib_entry_get_adj (fib_entry_index); if (ip_adj == ~0) - return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; + return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; hicn_face_t *face = hicn_face_udp6_get (&local_addr->ip6, &remote_addr->ip6, local_port, remote_port); if (face != NULL) - return HICN_ERROR_FACE_ALREADY_CREATED; + return HICN_ERROR_FACE_ALREADY_CREATED; pool_get (hicn_dpoi_face_pool, face); @@ -275,8 +273,7 @@ hicn_face_udp_add (const ip46_address_t * local_addr, } retx_t *retx = vlib_process_signal_event_data (vlib_get_main (), - hicn_mapme_eventmgr_process_node. - index, + hicn_mapme_eventmgr_process_node.index, HICN_MAPME_EVENT_FACE_ADD, 1, sizeof (retx_t)); /* *INDENT-OFF* */ @@ -293,6 +290,9 @@ hicn_face_udp_add (const ip46_address_t * local_addr, }; /* *INDENT-ON* */ + //Take a lock on the face which will be removed when the face is deleted + hicn_face_lock (&(retx->dpo)); + return ret; } @@ -304,15 +304,20 @@ hicn_face_udp_del (u32 faceid) hicn_face_udp_key_t key; hicn_face_udp_key_t old_key; - if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS) + if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == + IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS) { - hicn_face_udp4_get_key (&face_udp->hdrs.ip4.ip.src_address, &face_udp->hdrs.ip4.ip.dst_address, face_udp->hdrs.ip4.udp.src_port, + hicn_face_udp4_get_key (&face_udp->hdrs.ip4.ip.src_address, + &face_udp->hdrs.ip4.ip.dst_address, + face_udp->hdrs.ip4.udp.src_port, face_udp->hdrs.ip4.udp.dst_port, &key); mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key); } else { - hicn_face_udp6_get_key (&face_udp->hdrs.ip6.ip.src_address, &face_udp->hdrs.ip6.ip.dst_address, face_udp->hdrs.ip6.udp.src_port, + hicn_face_udp6_get_key (&face_udp->hdrs.ip6.ip.src_address, + &face_udp->hdrs.ip6.ip.dst_address, + face_udp->hdrs.ip6.udp.src_port, face_udp->hdrs.ip6.udp.dst_port, &key); mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key); } diff --git a/hicn-plugin/src/faces/udp/face_udp.h b/hicn-plugin/src/faces/udp/face_udp.h index cea3e7262..5dfc76e22 100644 --- a/hicn-plugin/src/faces/udp/face_udp.h +++ b/hicn-plugin/src/faces/udp/face_udp.h @@ -294,7 +294,7 @@ hicn_iface_udp4_add (const ip4_address_t * local_addr, face->shared.pl_id = (u16) 0; face->shared.face_type = hicn_face_udp_type; face->shared.flags = HICN_FACE_FLAGS_IFACE; - face->shared.locks = 0; + face->shared.locks = 1; face->shared.sw_if = sw_if; hicn_face_udp_key_t key; diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api index 2f33c901b..ba776c5f6 100644 --- a/hicn-plugin/src/hicn.api +++ b/hicn-plugin/src/hicn.api @@ -747,6 +747,18 @@ define hicn_api_register_prod_app_reply u32 faceid; }; +autoreply define hicn_api_face_prod_del +{ + /* Client identifier, set from api_main.my_client_index */ + u32 client_index; + + /* Arbitrary context, so client can match reply to request */ + u32 context; + + /* A Face ID to be deleted */ + u32 faceid; +}; + define hicn_api_register_cons_app { /* Client identifier, set from api_main.my_client_index */ @@ -774,6 +786,21 @@ define hicn_api_register_cons_app_reply vl_api_address_t src_addr6; /* Return value: new Face ID, ~0 means no Face was created */ + u32 faceid1; + + /* Return value: new Face ID, ~0 means no Face was created */ + u32 faceid2; +}; + +autoreply define hicn_api_face_cons_del +{ + /* Client identifier, set from api_main.my_client_index */ + u32 client_index; + + /* Arbitrary context, so client can match reply to request */ + u32 context; + + /* A Face ID to be deleted */ u32 faceid; }; diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c index 1cb14fe1b..4c75d406d 100644 --- a/hicn-plugin/src/hicn_api.c +++ b/hicn-plugin/src/hicn_api.c @@ -86,8 +86,9 @@ _(HICN_API_PUNTING_ADD, hicn_api_punting_add) \ _(HICN_API_PUNTING_DEL, hicn_api_punting_del) \ _(HICN_API_REGISTER_PROD_APP, hicn_api_register_prod_app) \ - _(HICN_API_REGISTER_CONS_APP, hicn_api_register_cons_app) - + _(HICN_API_FACE_PROD_DEL, hicn_api_face_prod_del) \ + _(HICN_API_REGISTER_CONS_APP, hicn_api_register_cons_app) \ + _(HICN_API_FACE_CONS_DEL, hicn_api_face_cons_del) /****** SUPPORTING FUNCTION DECLARATIONS ******/ @@ -392,7 +393,6 @@ vl_api_hicn_api_face_del_t_handler (vl_api_hicn_api_face_del_t * mp) } REPLY_MACRO (VL_API_HICN_API_FACE_DEL_REPLY /* , rmp, mp, rv */ ); - } static void @@ -488,7 +488,7 @@ send_faces_details (vl_api_registration_t * reg, } static void - vl_api_hicn_api_faces_dump_t_handler (vl_api_hicn_api_faces_dump_t * mp) +vl_api_hicn_api_faces_dump_t_handler (vl_api_hicn_api_faces_dump_t * mp) { hicn_face_t *face; vl_api_registration_t *reg; @@ -506,7 +506,7 @@ static void } static void - vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp) +vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp) { vl_api_hicn_api_face_get_reply_t *rmp; int rv = 0; @@ -725,7 +725,7 @@ send_route_details (vl_api_registration_t * reg, mp->_vl_msg_id = htons (VL_API_HICN_API_ROUTES_DETAILS + hm->msg_id_base); mp->context = context; - clib_memcpy (&mp->prefix, &pfx, sizeof (fib_prefix_t)); + ip_prefix_encode(pfx, &mp->prefix); mp->nfaces = 0; const dpo_id_t *hicn_dpo_id; @@ -745,8 +745,8 @@ send_route_details (vl_api_registration_t * reg, { mp->faceids[i] = clib_host_to_net_u32 (((dpo_id_t *) & - hicn_dpo_ctx->next_hops[i])-> - dpoi_index); + hicn_dpo_ctx-> + next_hops[i])->dpoi_index); mp->nfaces++; } } @@ -796,7 +796,7 @@ vl_api_hicn_api_route_dump_walk (fib_node_index_t fei, void *arg) static void vl_api_hicn_api_routes_dump_t_handler - (vl_api_hicn_api_face_stats_dump_t * mp) + (vl_api_hicn_api_routes_dump_t * mp) { vl_api_registration_t *reg; fib_table_t *fib_table; @@ -817,8 +817,7 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP4, vl_api_hicn_api_route_dump_walk, - &ctx); - } + &ctx);} )); pool_foreach (fib_table, im6->fibs, ( @@ -826,8 +825,7 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP6, vl_api_hicn_api_route_dump_walk, - &ctx); - } + &ctx);} )); vec_foreach (lfeip, ctx.feis) @@ -890,17 +888,20 @@ static void vl_api_hicn_api_strategy_get_t_handler /****** PUNTING *******/ -static hicn_error_t add_ip_punting (vl_api_hicn_punting_ip_t * mp) +static hicn_error_t +add_ip_punting (vl_api_hicn_punting_ip_t * mp) { vlib_main_t *vm = vlib_get_main (); fib_prefix_t prefix; ip_prefix_decode (&mp->prefix, &prefix); u32 swif = clib_net_to_host_u32 (mp->swif); - return hicn_punt_interest_data_for_ip (vm, &prefix, swif, HICN_PUNT_IP_TYPE, NO_L2); + return hicn_punt_interest_data_for_ip (vm, &prefix, swif, HICN_PUNT_IP_TYPE, + NO_L2); } -static hicn_error_t add_udp_punting (vl_api_hicn_punting_udp_t * mp) +static hicn_error_t +add_udp_punting (vl_api_hicn_punting_udp_t * mp) { vlib_main_t *vm = vlib_get_main (); fib_prefix_t prefix; @@ -908,9 +909,11 @@ static hicn_error_t add_udp_punting (vl_api_hicn_punting_udp_t * mp) u32 swif = clib_net_to_host_u32 (mp->swif); u16 sport = clib_net_to_host_u16 (mp->sport); u16 dport = clib_net_to_host_u16 (mp->sport); - u8 type = mp->ip_version == ADDRESS_IP6 ? HICN_PUNT_UDP6_TYPE : HICN_PUNT_UDP4_TYPE; + u8 type = + mp->ip_version == ADDRESS_IP6 ? HICN_PUNT_UDP6_TYPE : HICN_PUNT_UDP4_TYPE; - return hicn_punt_interest_data_for_udp (vm, &prefix, swif, type, sport, dport, NO_L2); + return hicn_punt_interest_data_for_udp (vm, &prefix, swif, type, sport, + dport, NO_L2); } static void vl_api_hicn_api_punting_add_t_handler @@ -923,11 +926,11 @@ static void vl_api_hicn_api_punting_add_t_handler if (mp->type == IP_PUNT) { - rv = add_ip_punting(&(mp->rule.ip)); + rv = add_ip_punting (&(mp->rule.ip)); } else if (mp->type == UDP_PUNT) { - rv = add_udp_punting(&(mp->rule.udp)); + rv = add_udp_punting (&(mp->rule.udp)); } else { @@ -981,6 +984,20 @@ static void vl_api_hicn_api_register_prod_app_t_handler /* *INDENT-ON* */ } +static void +vl_api_hicn_api_face_prod_del_t_handler (vl_api_hicn_api_face_prod_del_t * mp) +{ + vl_api_hicn_api_face_prod_del_reply_t *rmp; + int rv = HICN_ERROR_FACE_NOT_FOUND; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); + rv = hicn_face_prod_del (faceid); + + REPLY_MACRO (VL_API_HICN_API_FACE_PROD_DEL_REPLY /* , rmp, mp, rv */ ); +} + static void vl_api_hicn_api_register_cons_app_t_handler (vl_api_hicn_api_register_cons_app_t * mp) { @@ -992,20 +1009,39 @@ static void vl_api_hicn_api_register_cons_app_t_handler ip46_address_t src_addr6 = ip46_address_initializer; u32 swif = clib_net_to_host_u32 (mp->swif); - u32 faceid; + u32 faceid1; + u32 faceid2; - rv = hicn_face_cons_add (&src_addr4.ip4, &src_addr6.ip6, swif, &faceid); + rv = + hicn_face_cons_add (&src_addr4.ip4, &src_addr6.ip6, swif, &faceid1, + &faceid2); /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_HICN_API_REGISTER_CONS_APP_REPLY, ( { ip_address_encode(&src_addr4, IP46_TYPE_ANY, &rmp->src_addr4); ip_address_encode(&src_addr6, IP46_TYPE_ANY, &rmp->src_addr6); - rmp->faceid = clib_net_to_host_u32(faceid); + rmp->faceid1 = clib_net_to_host_u32(faceid1); + rmp->faceid2 = clib_net_to_host_u32(faceid2); })); /* *INDENT-ON* */ } +static void +vl_api_hicn_api_face_cons_del_t_handler (vl_api_hicn_api_face_cons_del_t * mp) +{ + vl_api_hicn_api_face_cons_del_reply_t *rmp; + int rv = HICN_ERROR_FACE_NOT_FOUND; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); + rv = hicn_face_cons_del (faceid); + + REPLY_MACRO (VL_API_HICN_API_FACE_CONS_DEL_REPLY /* , rmp, mp, rv */ ); +} + + /************************************************************************************/ #define vl_msg_name_crc_list diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c index 1dc8158d4..bf58cf245 100644 --- a/hicn-plugin/src/hicn_api_test.c +++ b/hicn-plugin/src/hicn_api_test.c @@ -183,11 +183,11 @@ fib_proto_from_ip46 (ip46_type_t iproto) case IP46_TYPE_IP6: return FIB_PROTOCOL_IP6; case IP46_TYPE_ANY: - ASSERT(0); + ASSERT (0); return FIB_PROTOCOL_IP4; } - ASSERT(0); + ASSERT (0); return FIB_PROTOCOL_IP4; } @@ -203,7 +203,7 @@ fib_proto_to_ip46 (fib_protocol_t fproto) case FIB_PROTOCOL_MPLS: return (IP46_TYPE_ANY); } - ASSERT(0); + ASSERT (0); return (IP46_TYPE_ANY); } @@ -229,7 +229,7 @@ ip_prefix_encode (const fib_prefix_t * in, vl_api_prefix_t * out) { out->len = in->fp_len; ip_address_encode (&in->fp_addr, - fib_proto_to_ip46 (in->fp_proto), &out->address); + fib_proto_to_ip46 (in->fp_proto), &out->address); } ///////////////////////////////////////////////////// @@ -253,7 +253,9 @@ _(hicn_api_face_del_reply) \ _(hicn_api_route_nhops_add_reply) \ _(hicn_api_route_del_reply) \ _(hicn_api_route_nhop_del_reply) \ -_(hicn_api_punting_add_reply) +_(hicn_api_punting_add_reply) \ +_(hicn_api_face_cons_del_reply) \ +_(hicn_api_face_prod_del_reply) #define _(n) \ static void vl_api_##n##_t_handler \ @@ -297,7 +299,9 @@ _(HICN_API_STRATEGIES_GET_REPLY, hicn_api_strategies_get_reply) \ _(HICN_API_STRATEGY_GET_REPLY, hicn_api_strategy_get_reply) \ _(HICN_API_PUNTING_ADD_REPLY, hicn_api_punting_add_reply) \ _(HICN_API_REGISTER_PROD_APP_REPLY, hicn_api_register_prod_app_reply) \ -_(HICN_API_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) +_(HICN_API_FACE_PROD_DEL_REPLY, hicn_api_face_prod_del_reply) \ +_(HICN_API_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) \ +_(HICN_API_FACE_CONS_DEL_REPLY, hicn_api_face_cons_del_reply) static int @@ -777,7 +781,8 @@ static void clib_net_to_host_i32 (rmp->flags)); } -static void format_ip_face (vl_api_hicn_face_ip_t * rmp) +static void +format_ip_face (vl_api_hicn_face_ip_t * rmp) { vat_main_t *vam = hicn_test_main.vat_main; u8 *sbuf = 0; @@ -798,7 +803,8 @@ static void format_ip_face (vl_api_hicn_face_ip_t * rmp) clib_net_to_host_i32 (rmp->flags), rmp->if_name); } -static void format_udp_face (vl_api_hicn_face_udp_t * rmp) +static void +format_udp_face (vl_api_hicn_face_udp_t * rmp) { vat_main_t *vam = hicn_test_main.vat_main; u8 *sbuf = 0; @@ -813,8 +819,7 @@ static void format_udp_face (vl_api_hicn_face_udp_t * rmp) sbuf = format (0, "local_addr %U port %u remote_addr %U port %u", format_ip46_address, &local_addr, 0 /*IP46_ANY_TYPE */ , lport, - format_ip46_address, - &remote_addr, 0 /*IP46_ANY_TYPE */ , rport); + format_ip46_address, &remote_addr, 0 /*IP46_ANY_TYPE */ , rport); fformat (vam->ofp, "%s swif %d flags %d name %s\n", sbuf, @@ -1028,8 +1033,8 @@ api_hicn_api_route_get (vat_main_t * vam) } //Construct the API message M (HICN_API_ROUTE_GET, mp); - if (!ip46_address_is_ip4(&(prefix.fp_addr))) - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); ip_prefix_encode (&prefix, &mp->prefix); //send it... @@ -1185,8 +1190,8 @@ api_hicn_api_route_nhops_add (vat_main_t * vam) M (HICN_API_ROUTE_NHOPS_ADD, mp); ip_prefix_encode (&prefix, &mp->prefix); - if (!ip46_address_is_ip4(&(prefix.fp_addr))) - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); mp->face_ids[0] = clib_host_to_net_u32 (faceid); mp->n_faces = 1; @@ -1232,8 +1237,8 @@ api_hicn_api_route_del (vat_main_t * vam) M (HICN_API_ROUTE_DEL, mp); ip_prefix_encode (&prefix, &mp->prefix); - if (!ip46_address_is_ip4(&(prefix.fp_addr))) - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); /* send it... */ S (mp); @@ -1280,8 +1285,8 @@ api_hicn_api_route_nhop_del (vat_main_t * vam) M (HICN_API_ROUTE_NHOP_DEL, mp); ip_prefix_encode (&prefix, &mp->prefix); - if (!ip46_address_is_ip4(&(prefix.fp_addr))) - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); mp->faceid = clib_host_to_net_u32 (faceid); @@ -1411,8 +1416,9 @@ static void } fformat (vam->ofp, "%s", mp->description); } + static int -api_hicn_api_ip_punting_add(vat_main_t * vam) +api_hicn_api_ip_punting_add (vat_main_t * vam) { unformat_input_t *input = vam->input; vl_api_hicn_api_punting_add_t *mp; @@ -1451,9 +1457,9 @@ api_hicn_api_ip_punting_add(vat_main_t * vam) /* Construct the API message */ M (HICN_API_PUNTING_ADD, mp); mp->type = IP_PUNT; - if (!ip46_address_is_ip4(&(prefix.fp_addr))) + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) { - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); } ip_prefix_encode (&prefix, &mp->rule.ip.prefix); @@ -1469,7 +1475,7 @@ api_hicn_api_ip_punting_add(vat_main_t * vam) } static int -api_hicn_api_udp_punting_add(vat_main_t * vam) +api_hicn_api_udp_punting_add (vat_main_t * vam) { unformat_input_t *input = vam->input; vl_api_hicn_api_punting_add_t *mp; @@ -1489,13 +1495,13 @@ api_hicn_api_udp_punting_add(vat_main_t * vam) else if (unformat (input, "sport %u", &sport)); else if (unformat (input, "dport %u", &dport)); else if (unformat (input, "ip4")) - { - ip_version = ADDRESS_IP4; - } + { + ip_version = ADDRESS_IP4; + } else if (unformat (input, "ip6")) - { - ip_version = ADDRESS_IP6; - } + { + ip_version = ADDRESS_IP6; + } else if (unformat (input, "intfc %d", &swif)) {; } @@ -1526,9 +1532,9 @@ api_hicn_api_udp_punting_add(vat_main_t * vam) /* Construct the API message */ M (HICN_API_PUNTING_ADD, mp); mp->type = UDP_PUNT; - if (!ip46_address_is_ip4(&(prefix.fp_addr))) + if (!ip46_address_is_ip4 (&(prefix.fp_addr))) { - prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); } ip_prefix_encode (&prefix, &mp->rule.ip.prefix); @@ -1579,6 +1585,10 @@ api_hicn_api_register_prod_app (vat_main_t * vam) clib_warning ("Please specify prefix..."); return 1; } + + prefix.fp_proto = + ip46_address_is_ip4 (&(prefix.fp_addr)) ? FIB_PROTOCOL_IP4 : + FIB_PROTOCOL_IP6; /* Construct the API message */ M (HICN_API_REGISTER_PROD_APP, mp); ip_prefix_encode (&prefix, &mp->prefix); @@ -1618,6 +1628,43 @@ static void } static int +api_hicn_api_face_prod_del (vat_main_t * vam) +{ + unformat_input_t *input = vam->input; + vl_api_hicn_api_face_prod_del_t *mp; + u32 faceid = 0, ret; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "face %d", &faceid)) + {; + } + else + { + break; + } + } + + //Check for presence of face ID + if (faceid == ~0) + { + clib_warning ("Please specify face ID"); + return 1; + } + //Construct the API message + M (HICN_API_FACE_PROD_DEL, mp); + mp->faceid = clib_host_to_net_u32 (faceid); + + //send it... + S (mp); + + //Wait for a reply... + W (ret); + + return ret; +} + +static int api_hicn_api_register_cons_app (vat_main_t * vam) { vl_api_hicn_api_register_cons_app_t *mp; @@ -1635,6 +1682,43 @@ api_hicn_api_register_cons_app (vat_main_t * vam) return ret; } +static int +api_hicn_api_face_cons_del (vat_main_t * vam) +{ + unformat_input_t *input = vam->input; + vl_api_hicn_api_face_cons_del_t *mp; + u32 faceid = 0, ret; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "face %d", &faceid)) + {; + } + else + { + break; + } + } + + //Check for presence of face ID + if (faceid == ~0) + { + clib_warning ("Please specify face ID"); + return 1; + } + //Construct the API message + M (HICN_API_FACE_CONS_DEL, mp); + mp->faceid = clib_host_to_net_u32 (faceid); + + //send it... + S (mp); + + //Wait for a reply... + W (ret); + + return ret; +} + static void vl_api_hicn_api_register_cons_app_reply_t_handler (vl_api_hicn_api_register_cons_app_reply_t * mp) @@ -1696,7 +1780,9 @@ _(hicn_api_strategy_get, "strategy <id>") \ _(hicn_api_ip_punting_add, "prefix <IP4/IP6>/<subnet> intfc <swif>") \ _(hicn_api_udp_punting_add, "prefix <IP4/IP6>/<subnet> intfc <swif> sport <port> dport <port> ip4/ip6") \ _(hicn_api_register_prod_app, "prefix <IP4/IP6>/<subnet> id <appif_id>") \ -_(hicn_api_register_cons_app, "") +_(hicn_api_face_prod_del, "face <faceID>") \ +_(hicn_api_register_cons_app, "") \ +_(hicn_api_face_cons_del, "face <faceID>") void hicn_vat_api_hookup (vat_main_t * vam) diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c index 21ba97db3..d5eeb20dd 100644 --- a/hicn-plugin/src/interest_hitpit_node.c +++ b/hicn-plugin/src/interest_hitpit_node.c @@ -173,11 +173,6 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, if (found) { - /* - * Remove lock on the dpo - * stored in the vlib_buffer - */ - dpo_unlock (&hicnb0->face_dpo_id); strategy_vft0->hicn_select_next_hop (dpo_ctx_id0, &nh_idx, &outface); /* Retransmission */ diff --git a/hicn-plugin/src/pcs.c b/hicn-plugin/src/pcs.c index 4226291a1..4355aaeb0 100644 --- a/hicn-plugin/src/pcs.c +++ b/hicn-plugin/src/pcs.c @@ -41,6 +41,7 @@ hicn_pit_create (hicn_pit_cs_t * p, u32 num_elems) p->policy_vft.hicn_cs_dequeue = hicn_cs_lru.hicn_cs_dequeue; p->policy_vft.hicn_cs_delete_get = hicn_cs_lru.hicn_cs_delete_get; p->policy_vft.hicn_cs_trim = hicn_cs_lru.hicn_cs_trim; + p->policy_vft.hicn_cs_flush = hicn_cs_lru.hicn_cs_flush; return (ret); } diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c index 3581fe490..321f11940 100644 --- a/hicn-plugin/src/route.c +++ b/hicn-plugin/src/route.c @@ -86,6 +86,61 @@ hicn_route_get_dpo (const fib_prefix_t * prefix, return ret; } +int +hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len, + const fib_prefix_t * prefix) +{ + const dpo_id_t *hicn_dpo_id; + int ret = HICN_ERROR_NONE; + dpo_id_t faces_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX]; + int n_face_dpo = 0; + const hicn_dpo_vft_t *dpo_vft; + u32 fib_index; + vlib_main_t *vm = vlib_get_main (); + hicn_face_vft_t *face_vft = NULL; + + if (face_id == NULL) + { + return HICN_ERROR_ROUTE_INVAL; + } + /* + * Check is the faces are available, otherwise skip the face + * id_adjacency existance is not checked. It should be checked before + * sending a packet out + */ + for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++) + { + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]); + face_vft = hicn_face_get_vft (face->shared.face_type); + dpo_id_t face_dpo = DPO_INVALID; + face_vft->hicn_face_get_dpo (face, &face_dpo); + + if (!dpo_id_is_valid (&face_dpo)) + { + vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]); + return ret; + } + else + { + faces_dpo_tmp[n_face_dpo++] = face_dpo; + } + } + + ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index); + + if (ret == HICN_ERROR_NONE) + { + for (int i = 0; i < n_face_dpo && (ret == HICN_ERROR_NONE); i++) + { + u32 vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); + dpo_vft = hicn_dpo_get_vft (vft_id); + ret = dpo_vft->hicn_dpo_add_update_nh (&faces_dpo_tmp[i], + hicn_dpo_id->dpoi_index); + } + } + return ret; +} + /* Add a new route for a name prefix */ int hicn_route_add (hicn_face_id_t * face_id, u32 len, @@ -153,8 +208,8 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len, */ dpo_set (&dpo, default_dpo.hicn_dpo_get_type (), - (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 : DPO_PROTO_IP6), - dpo_idx); + (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 : + DPO_PROTO_IP6), dpo_idx); /* Here is where we create the "via" like route */ /* @@ -187,62 +242,7 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len, } else if (ret == HICN_ERROR_NONE) { - ret = HICN_ERROR_ROUTE_ALREADY_EXISTS; - } - return ret; -} - -int -hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len, - const fib_prefix_t * prefix) -{ - const dpo_id_t *hicn_dpo_id; - int ret = HICN_ERROR_NONE; - dpo_id_t faces_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX]; - int n_face_dpo = 0; - const hicn_dpo_vft_t *dpo_vft; - u32 fib_index; - vlib_main_t *vm = vlib_get_main (); - hicn_face_vft_t *face_vft = NULL; - - if (face_id == NULL) - { - return HICN_ERROR_ROUTE_INVAL; - } - /* - * Check is the faces are available, otherwise skip the face - * id_adjacency existance is not checked. It should be checked before - * sending a packet out - */ - for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++) - { - hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]); - face_vft = hicn_face_get_vft (face->shared.face_type); - dpo_id_t face_dpo = DPO_INVALID; - face_vft->hicn_face_get_dpo (face, &face_dpo); - - if (!dpo_id_is_valid (&face_dpo)) - { - vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]); - return ret; - } - else - { - faces_dpo_tmp[n_face_dpo++] = face_dpo; - } - } - - ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index); - - if (ret == HICN_ERROR_NONE) - { - for (int i = 0; i < n_face_dpo && (ret == HICN_ERROR_NONE); i++) - { - u32 vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); - dpo_vft = hicn_dpo_get_vft (vft_id); - ret = dpo_vft->hicn_dpo_add_update_nh (&faces_dpo_tmp[i], - hicn_dpo_id->dpoi_index); - } + ret = hicn_route_add_nhops (face_id, len, prefix); } return ret; } diff --git a/hicn-plugin/src/strategies/dpo_mw.c b/hicn-plugin/src/strategies/dpo_mw.c index 0014c2b7f..981e5b61c 100644 --- a/hicn-plugin/src/strategies/dpo_mw.c +++ b/hicn-plugin/src/strategies/dpo_mw.c @@ -247,7 +247,7 @@ hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, { hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo_idx); - int ret = HICN_ERROR_NONE; + int ret = HICN_ERROR_DPO_CTX_NOT_FOUND; int nh_id = ~0; dpo_id_t invalid = NEXT_HOP_INVALID; @@ -263,6 +263,7 @@ hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, next_hops[i]); hicn_strategy_mw_ctx->default_ctx.next_hops[i] = invalid; hicn_strategy_mw_ctx->default_ctx.entry_count--; + ret = HICN_ERROR_NONE; } } diff --git a/hicn-plugin/src/strategy.c b/hicn-plugin/src/strategy.c index d07045a72..62c2ddc8b 100644 --- a/hicn-plugin/src/strategy.c +++ b/hicn-plugin/src/strategy.c @@ -102,7 +102,7 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0, hicn_face_db_add_face_dpo (&hicnb0->face_dpo_id, &(pitp->u.pit.faces)); /* Remove lock on the dpo stored in the vlib_buffer */ - dpo_unlock (&hicnb0->face_dpo_id); + //dpo_unlock (&hicnb0->face_dpo_id); *next = outface->dpoi_next_node; @@ -209,9 +209,8 @@ hicn_forward_interest_fn (vlib_main_t * vm, */ if (PREDICT_TRUE (ret == HICN_ERROR_NONE && HICN_IS_NAMEHASH_CACHED (b0) - && strategy->hicn_select_next_hop (vnet_buffer (b0)-> - ip.adj_index[VLIB_TX], - &nh_idx, + && strategy->hicn_select_next_hop (vnet_buffer (b0)->ip. + adj_index[VLIB_TX], &nh_idx, &outface) == HICN_ERROR_NONE)) { diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c index 8bbb2bf5d..49818de40 100644 --- a/lib/src/util/ip_address.c +++ b/lib/src/util/ip_address.c @@ -142,12 +142,12 @@ ip_address_snprintf(char * s, size_t size, const ip_address_t * ip_address, int const char * rc; switch(family) { case AF_INET: - if (size <= INET_ADDRSTRLEN) + if (size < INET_ADDRSTRLEN) return -1; rc = inet_ntop (AF_INET, ip_address->v4.buffer, s, INET_ADDRSTRLEN); break; case AF_INET6: - if (size <= INET6_ADDRSTRLEN) + if (size < INET6_ADDRSTRLEN) return -1; rc = inet_ntop (AF_INET6, ip_address->v6.buffer, s, INET6_ADDRSTRLEN); break; diff --git a/libtransport/CMakeLists.txt b/libtransport/CMakeLists.txt index 836a524f5..a76e91208 100644 --- a/libtransport/CMakeLists.txt +++ b/libtransport/CMakeLists.txt @@ -71,7 +71,7 @@ find_package_wrapper(Asio REQUIRED) if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) if (__vpp__) - find_package_wrapper(HicnBinaryApi REQUIRED) + find_package_wrapper(HicnPlugin REQUIRED) find_package(Libmemif REQUIRED) list(APPEND LIBRARIES @@ -147,7 +147,7 @@ list(APPEND LIBRARIES # Include dirs -- Order does matter! list(APPEND LIBTRANSPORT_INTERNAL_INCLUDE_DIRS ${HICN_INCLUDE_DIRS} - ${HICN_BINARY_API_INCLUDE_DIRS} + ${HICNPLUGIN_INCLUDE_DIRS} ${LIBPARC_INCLUDE_DIRS} ${CMAKE_THREADS_INCLUDE_DIRS} ${ASIO_INCLUDE_DIRS} diff --git a/libtransport/src/hicn/transport/core/hicn_binary_api.c b/libtransport/src/hicn/transport/core/hicn_binary_api.c index aea2f09f7..7f63c9826 100644 --- a/libtransport/src/hicn/transport/core/hicn_binary_api.c +++ b/libtransport/src/hicn/transport/core/hicn_binary_api.c @@ -50,6 +50,12 @@ /* Declare message IDs */ #include <hicn/hicn_msg_enum.h> +#define vl_endianfun +#define vl_typedefs +#include <vnet/ip/ip_types.api.h> +#undef vl_typedefs +#undef vl_endianfun + #define vl_endianfun /* define message structures */ #define vl_print(handle, ...) #define vl_printfun @@ -115,7 +121,7 @@ int hicn_binary_api_register_prod_app( memcpy(&prefix.fp_addr, &input_params->prefix->address, sizeof(ip46_address_t)); prefix.fp_len = input_params->prefix->len; prefix.fp_proto = ip46_address_is_ip4(&prefix.fp_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; - ip_prefix_encode(&prefix, &mp->prefix); + ip_prefix_encode(&prefix, &(mp->prefix)); mp->swif = clib_host_to_net_u32(input_params->swif); mp->cs_reserved = clib_host_to_net_u32(input_params->cs_reserved); @@ -169,7 +175,8 @@ static void vl_api_hicn_api_register_cons_app_reply_t_handler( ip_address_decode(&mp->src_addr4, (ip46_address_t *)params->src4); ip_address_decode(&mp->src_addr6, (ip46_address_t *)params->src6); - params->face_id = clib_host_to_net_u32(mp->faceid); + params->face_id1 = clib_host_to_net_u32(mp->faceid1); + params->face_id2 = clib_host_to_net_u32(mp->faceid2); vpp_binary_api_unlock_waiting_thread(binary_api->vpp_api); } diff --git a/libtransport/src/hicn/transport/core/hicn_binary_api.h b/libtransport/src/hicn/transport/core/hicn_binary_api.h index 50590917f..323d22fea 100644 --- a/libtransport/src/hicn/transport/core/hicn_binary_api.h +++ b/libtransport/src/hicn/transport/core/hicn_binary_api.h @@ -47,7 +47,8 @@ typedef struct { typedef struct { ip_address_t* src4; ip_address_t* src6; - uint32_t face_id; + uint32_t face_id1; + uint32_t face_id2; } hicn_consumer_output_params; typedef struct { diff --git a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc index c1a45ebb7..f1057aa57 100644 --- a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc +++ b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc @@ -150,8 +150,9 @@ void RTCProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) { producedBytes_ += (uint32_t)(buffer_size + headerSize_ + TIMESTAMP_LEN); producedPackets_++; + Name n(flowName_); auto content_object = - std::make_shared<ContentObject>(flowName_.setSuffix(currentSeg_.load())); + std::make_shared<ContentObject>(n.setSuffix(currentSeg_.load())); auto payload = utils::MemBuf::create(TIMESTAMP_LEN); memcpy(payload->writableData(), &now, TIMESTAMP_LEN); @@ -340,8 +341,9 @@ void RTCProducerSocket::sendNack(uint32_t sequence) { nack_payload->append(NACK_HEADER_SIZE); ContentObject nack; + Name n(flowName_); nack.appendPayload(std::move(nack_payload)); - nack.setName(flowName_.setSuffix(sequence)); + nack.setName(n.setSuffix(sequence)); uint32_t *payload_ptr = (uint32_t *)nack.getPayload()->data(); *payload_ptr = currentSeg_.load(); diff --git a/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.cc b/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.cc index 05cabc60d..0c3fd76cf 100644 --- a/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.cc +++ b/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.cc @@ -29,7 +29,6 @@ ManifestIndexManager::ManifestIndexManager( interface::ConsumerSocket *icn_socket, TransportProtocol *next_interest) : IncrementalIndexManager(icn_socket), PacketManager<Interest>(1024), - manifests_in_flight_(0), next_reassembly_segment_(suffix_queue_.end()), next_to_retrieve_segment_(suffix_queue_.end()), suffix_manifest_(core::NextSegmentCalculationStrategy::INCREMENTAL, 0), @@ -39,7 +38,6 @@ bool ManifestIndexManager::onManifest( core::ContentObject::Ptr &&content_object) { auto manifest = std::make_unique<ContentObjectManifest>(std::move(*content_object)); - bool manifest_verified = verification_manager_->onPacketToVerify(*manifest); if (manifest_verified) { @@ -54,14 +52,12 @@ bool ManifestIndexManager::onManifest( case core::ManifestType::INLINE_MANIFEST: { auto _it = manifest->getSuffixList().begin(); auto _end = --manifest->getSuffixList().end(); + final_suffix_ = manifest->getFinalBlockNumber(); // final block number if (TRANSPORT_EXPECT_FALSE(manifest->isFinalManifest())) { _end++; } - // Get final block number - final_suffix_ = manifest->getFinalBlockNumber(); - suffix_hash_map_[_it->first] = std::make_pair(std::vector<uint8_t>(_it->second, _it->second + 32), manifest->getHashAlgorithm()); @@ -93,62 +89,13 @@ bool ManifestIndexManager::onManifest( 1); suffix_manifest_.setSuffixStrategy( manifest->getNextSegmentCalculationStrategy()); - } else if (manifests_in_flight_) { - manifests_in_flight_--; } - if (TRANSPORT_EXPECT_FALSE(manifest->isFinalManifest() || - suffix_manifest_.getSuffix() > - final_suffix_)) { - break; + if (TRANSPORT_EXPECT_FALSE(manifest->isFinalManifest()) == 0) { + fillWindow(manifest->getWritableName(), + manifest->getName().getSuffix()); } - // Get current window size - double current_window_size = 0.; - socket_->getSocketOption(GeneralTransportOptions::CURRENT_WINDOW_SIZE, - current_window_size); - - // Get portal - std::shared_ptr<interface::BasePortal> portal; - socket_->getSocketOption(GeneralTransportOptions::PORTAL, portal); - - // Number of segments in manifest - std::size_t segment_count = 0; - - // Manifest namespace - Name &name = manifest->getWritableName(); - - if (manifests_in_flight_ >= MAX_MANIFESTS_IN_FLIGHT) { - break; - } - - // Send as many manifest as required for filling window. - do { - segment_count += suffix_manifest_.getNbSegments(); - suffix_manifest_++; - - Interest::Ptr interest = getPacket(); - name.setSuffix(suffix_manifest_.getSuffix()); - interest->setName(name); - - uint32_t interest_lifetime; - socket_->getSocketOption(GeneralTransportOptions::INTEREST_LIFETIME, - interest_lifetime); - interest->setLifetime(interest_lifetime); - - // Send requests for manifest out of the congestion window (no - // in_flight_interests++) - portal->sendInterest( - std::move(interest), - std::bind(&ManifestIndexManager::onManifestReceived, this, - std::placeholders::_1, std::placeholders::_2), - std::bind(&ManifestIndexManager::onManifestTimeout, this, - std::placeholders::_1)); - manifests_in_flight_++; - } while (segment_count < current_window_size && - suffix_manifest_.getSuffix() < final_suffix_ && - manifests_in_flight_ < MAX_MANIFESTS_IN_FLIGHT); - break; } case core::ManifestType::FLIC_MANIFEST: { @@ -193,6 +140,56 @@ void ManifestIndexManager::onManifestTimeout(Interest::Ptr &&i) { std::placeholders::_1)); } +void ManifestIndexManager::fillWindow(Name &name, uint32_t current_manifest) { + /* Send as many manifest as required for filling window. */ + uint32_t interest_lifetime; + double window_size; + std::shared_ptr<interface::BasePortal> portal; + Interest::Ptr interest; + uint32_t current_segment = *next_to_retrieve_segment_; + // suffix_manifest_ now points to the next manifest to request + uint32_t last_requested_manifest = (suffix_manifest_++).getSuffix(); + + socket_->getSocketOption(GeneralTransportOptions::PORTAL, portal); + socket_->getSocketOption(GeneralTransportOptions::INTEREST_LIFETIME, + interest_lifetime); + socket_->getSocketOption(GeneralTransportOptions::CURRENT_WINDOW_SIZE, + window_size); + + if (TRANSPORT_EXPECT_FALSE(suffix_manifest_.getSuffix() >= final_suffix_)) { + suffix_manifest_.updateSuffix(last_requested_manifest); + return; + } + + if (current_segment + window_size < suffix_manifest_.getSuffix() && + current_manifest != last_requested_manifest) { + suffix_manifest_.updateSuffix(last_requested_manifest); + return; + } + + do { + interest = getPacket(); + name.setSuffix(suffix_manifest_.getSuffix()); + interest->setName(name); + interest->setLifetime(interest_lifetime); + + // Send interests for manifest out of the congestion window (no + // in_flight_interests++) + portal->sendInterest( + std::move(interest), + std::bind(&ManifestIndexManager::onManifestReceived, this, + std::placeholders::_1, std::placeholders::_2), + std::bind(&ManifestIndexManager::onManifestTimeout, this, + std::placeholders::_1)); + + last_requested_manifest = (suffix_manifest_++).getSuffix(); + } while (current_segment + window_size >= suffix_manifest_.getSuffix() && + suffix_manifest_.getSuffix() < final_suffix_); + + // suffix_manifest_ now points to the last requested manifest + suffix_manifest_.updateSuffix(last_requested_manifest); +} + bool ManifestIndexManager::onContentObject( const core::ContentObject &content_object) { bool verify_signature; diff --git a/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.h b/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.h index 74c86eb60..cb88940d5 100644 --- a/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.h +++ b/libtransport/src/hicn/transport/protocols/manifest_indexing_manager.h @@ -21,9 +21,6 @@ #include <list> -/* #define MAX_MANIFESTS_IN_FLIGHT std::numeric_limits<uint32_t>::max() */ -#define MAX_MANIFESTS_IN_FLIGHT 10 - namespace transport { namespace protocol { @@ -58,9 +55,9 @@ class ManifestIndexManager : public IncrementalIndexManager, private: void onManifestReceived(Interest::Ptr &&i, ContentObject::Ptr &&c); void onManifestTimeout(Interest::Ptr &&i); + void fillWindow(Name &name, uint32_t current_manifest); protected: - uint32_t manifests_in_flight_; SuffixQueue suffix_queue_; SuffixQueue::iterator next_reassembly_segment_; SuffixQueue::iterator next_to_retrieve_segment_; diff --git a/libtransport/src/hicn/transport/protocols/rtc.cc b/libtransport/src/hicn/transport/protocols/rtc.cc index 1a3511003..4d8e4c514 100644 --- a/libtransport/src/hicn/transport/protocols/rtc.cc +++ b/libtransport/src/hicn/transport/protocols/rtc.cc @@ -300,6 +300,16 @@ void RTCTransportProtocol::updateStats(uint32_t round_duration) { updateCCState(); updateWindow(); + if(queuingDelay_ > 100.0){ + //this indicates that the client will go soon out of synch, + //switch to synch mode + if (currentState_ == HICN_RTC_NORMAL_STATE) { + currentState_ = HICN_RTC_SYNC_STATE; + } + computeMaxWindow(BW, 0); + increaseWindow(); + } + // in any case we reset all the counters gotNack_ = false; @@ -351,7 +361,7 @@ void RTCTransportProtocol::computeMaxWindow(uint32_t productionRate, void RTCTransportProtocol::updateWindow() { if (currentState_ == HICN_RTC_SYNC_STATE) return; - if (currentCWin_ < maxCWin_ * 0.7) { + if (currentCWin_ < maxCWin_ * 0.9) { currentCWin_ = min(maxCWin_, (uint32_t)(currentCWin_ * HICN_WIN_INCREASE_FACTOR)); } else if (currentCWin_ > maxCWin_) { @@ -378,7 +388,7 @@ void RTCTransportProtocol::increaseWindow() { if (currentState_ == HICN_RTC_NORMAL_STATE) return; // we need to be carefull to do not increase the window to much - if (currentCWin_ < ((double)maxCWin_ * 0.5)) { + if (currentCWin_ < ((double)maxCWin_ * 0.7)) { currentCWin_ = currentCWin_ + 1; // exponential } else { currentCWin_ = min( @@ -505,7 +515,7 @@ void RTCTransportProtocol::scheduleNextInterests() { } void RTCTransportProtocol::sentinelTimer(){ - uint32_t wait = 10; + uint32_t wait = 50; if(pathTable_.find(producerPathLabels_[0]) != pathTable_.end() && pathTable_.find(producerPathLabels_[1]) != pathTable_.end()){ @@ -542,14 +552,15 @@ void RTCTransportProtocol::sentinelTimer(){ } } }else{ - uint64_t max_waiting_time = - round((pathTable_[producerPathLabels_[1]]->getMinRtt() - + uint64_t max_waiting_time = //wait at least 50ms + (pathTable_[producerPathLabels_[1]]->getMinRtt() - pathTable_[producerPathLabels_[0]]->getMinRtt()) + - pathTable_[producerPathLabels_[0]]->getInterArrivalGap()) * 2; + (ceil(pathTable_[producerPathLabels_[0]]->getInterArrivalGap()) * 50); if((currentState_ == HICN_RTC_NORMAL_STATE) && (inflightInterestsCount_ >= currentCWin_) && - ((now - lastEvent_) > max_waiting_time)){ + ((now - lastEvent_) > max_waiting_time) && + (lossRate_ > 10.0)){ uint64_t RTT = pathTable_[producerPathLabels_[1]]->getMinRtt(); @@ -859,8 +870,8 @@ void RTCTransportProtocol::onContentObject( uint32_t pathLabel = content_object->getPathLabel(); if (pathTable_.find(pathLabel) == pathTable_.end()) { - // if this path does not exists we cannot create a new one so drop - return; + std::shared_ptr<RTCDataPath> newPath = std::make_shared<RTCDataPath>(); + pathTable_[pathLabel] = newPath; } // this is the expected probe, update the RTT and drop the packet diff --git a/libtransport/src/hicn/transport/protocols/rtc_data_path.h b/libtransport/src/hicn/transport/protocols/rtc_data_path.h index c8a049368..48a67c525 100644 --- a/libtransport/src/hicn/transport/protocols/rtc_data_path.h +++ b/libtransport/src/hicn/transport/protocols/rtc_data_path.h @@ -20,7 +20,7 @@ #include <climits> #define ALPHA_RTC 0.125 -#define HISTORY_LEN 30 +#define HISTORY_LEN 20 //4 sec namespace transport { diff --git a/libtransport/src/hicn/transport/utils/suffix_strategy.h b/libtransport/src/hicn/transport/utils/suffix_strategy.h index 4358d12f0..3014855f6 100644 --- a/libtransport/src/hicn/transport/utils/suffix_strategy.h +++ b/libtransport/src/hicn/transport/utils/suffix_strategy.h @@ -38,8 +38,6 @@ class SuffixStrategy { std::uint32_t getSuffix() { return suffix_; } - virtual std::uint32_t getNextSuffix() = 0; - void updateSuffix(std::uint32_t new_suffix) { suffix_ = new_suffix; } std::size_t getNbSegments() { return nb_segments_; } @@ -57,6 +55,7 @@ class SuffixStrategy { transport::core::NextSegmentCalculationStrategy suffix_stragegy_; std::uint32_t suffix_; std::size_t nb_segments_; + virtual std::uint32_t getNextSuffix() = 0; }; class SuffixManifest : public SuffixStrategy { @@ -66,27 +65,22 @@ class SuffixManifest : public SuffixStrategy { std::uint32_t start_offset) : SuffixStrategy(suffix_stragegy, start_offset) {} - std::uint32_t getNextSuffix(); - SuffixManifest operator++() { - uint32_t next_suffix = getNextSuffix(); - updateSuffix(next_suffix); - return SuffixManifest(suffix_stragegy_, next_suffix); + updateSuffix(getNextSuffix()); + SuffixManifest temp_suffix(suffix_stragegy_, suffix_); + temp_suffix.setNbSegments(getNbSegments()); + return temp_suffix; } SuffixManifest operator++(int) { SuffixManifest temp_suffix(suffix_stragegy_, suffix_); - uint32_t next_suffix = getNextSuffix(); - updateSuffix(next_suffix); + temp_suffix.setNbSegments(getNbSegments()); + updateSuffix(getNextSuffix()); return temp_suffix; } - SuffixManifest operator+(uint32_t shift) { - for (uint32_t i = 0; i < shift; i++) { - updateSuffix(getNextSuffix()); - } - return SuffixManifest(suffix_stragegy_, getSuffix()); - } + protected: + std::uint32_t getNextSuffix(); }; class SuffixContent : public SuffixStrategy { @@ -101,28 +95,22 @@ class SuffixContent : public SuffixStrategy { std::uint32_t start_offset) : SuffixContent(suffix_stragegy, start_offset, false) {} - std::uint32_t getNextSuffix(); - SuffixContent operator++() { - uint32_t next_suffix = getNextSuffix(); - updateSuffix(next_suffix); - return SuffixContent(suffix_stragegy_, next_suffix, making_manifest_); + updateSuffix(getNextSuffix()); + SuffixContent temp_suffix(suffix_stragegy_, suffix_, making_manifest_); + temp_suffix.setNbSegments(getNbSegments()); + temp_suffix.content_counter_ = content_counter_; + return temp_suffix; } SuffixContent operator++(int) { SuffixContent temp_suffix(suffix_stragegy_, suffix_, making_manifest_); - uint32_t next_suffix = getNextSuffix(); - updateSuffix(next_suffix); + temp_suffix.setNbSegments(getNbSegments()); + temp_suffix.content_counter_ = content_counter_; + updateSuffix(getNextSuffix()); return temp_suffix; } - SuffixContent operator+(uint32_t shift) { - for (uint32_t i = 0; i < shift; i++) { - updateSuffix(getNextSuffix()); - } - return SuffixContent(suffix_stragegy_, getSuffix(), making_manifest_); - } - void setUsingManifest(bool value) { making_manifest_ = value; } void reset(std::uint32_t reset_suffix) { @@ -135,5 +123,6 @@ class SuffixContent : public SuffixStrategy { /* content_counter_ keeps track of the number of segments */ /* between two manifests */ uint32_t content_counter_; + std::uint32_t getNextSuffix(); }; } // namespace utils diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 3ed6f9bf3..0e5430356 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -47,7 +47,7 @@ endif() set(SUFFIX "") if (${LIBTRANSPORT_LIBRARIES} MATCHES ".*-memif.*") set(SUFFIX "-memif") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-unresolved-symbols=ignore-in-shared-libs") + set(LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs") endif() set(HICN_UTILS "${HICN_UTILS}${SUFFIX}") @@ -66,6 +66,7 @@ build_executable(hiperf DEPENDS ${DEPENDENCIES} COMPONENT ${HICN_UTILS} DEFINITIONS ${COMPILER_DEFINITIONS} + LINK_FLAGS ${LINK_FLAGS} ) build_executable(hicn-ping-server @@ -74,6 +75,7 @@ build_executable(hicn-ping-server DEPENDS ${DEPENDENCIES} COMPONENT ${HICN_UTILS} DEFINITIONS ${COMPILER_DEFINITIONS} + LINK_FLAGS ${LINK_FLAGS} ) build_executable(hicn-ping-client @@ -82,4 +84,5 @@ build_executable(hicn-ping-client DEPENDS ${DEPENDENCIES} COMPONENT ${HICN_UTILS} DEFINITIONS ${COMPILER_DEFINITIONS} + LINK_FLAGS ${LINK_FLAGS} ) |