diff options
author | Luca Muscariello <lumuscar@cisco.com> | 2022-03-30 22:29:28 +0200 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2022-03-31 19:51:47 +0200 |
commit | c46e5df56b67bb8ea7a068d39324c640084ead2b (patch) | |
tree | eddeb17785938e09bc42eec98ee09b8a28846de6 /ctrl/facemgr/src | |
parent | 18fa668f25d3cc5463417ce7df6637e31578e898 (diff) |
feat: boostrap hicn 22.02
The current patch provides several new features, improvements,
bug fixes and also complete rewrite of entire components.
- lib
The hicn packet parser has been improved with a new packet
format fully based on UDP. The TCP header is still temporarily
supported but the UDP header will replace completely the new hicn
packet format. Improvements have been made to make sure every
packet parsing operation is made via this library. The current
new header can be used as header between the payload and the
UDP header or as trailer in the UDP surplus area to be tested
when UDP options will start to be used.
- hicn-light
The portable packet forwarder has been completely rewritten from
scratch with the twofold objective to improve performance and
code size but also to drop dependencies such as libparc which is
now removed by the current implementation.
- hicn control
the control library is the agent that is used to program the
packet forwarders via their binary API. This component has
benefited from significant improvements in terms of interaction
model which is now event driven and more robust to failures.
- VPP plugin has been updated to support VPP 22.02
- transport
Major improvement have been made to the RTC protocol, to the
support of IO modules and to the security sub system. Signed
manifests are the default data authenticity and integrity framework.
Confidentiality can be enabled by sharing the encryption key to the
prod/cons layer. The library has been tested with group key based
applications such as broadcast/multicast and real-time on-line
meetings with trusted server keys or MLS.
- testing
Unit testing has been introduced using GoogleTest. One third of
the code base is covered by unit testing with priority on
critical features. Functional testing has also been introduce
using Docker, linux bridging and Robot Framework to define
test with Less Code techniques to facilitate the extension
of the coverage.
Co-authored-by: Mauro Sardara <msardara@cisco.com>
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Co-authored-by: Michele Papalini <micpapal@cisco.com>
Co-authored-by: Angelo Mantellini <manangel@cisco.com>
Co-authored-by: Jacques Samain <jsamain@cisco.com>
Co-authored-by: Olivier Roques <oroques+fdio@cisco.com>
Co-authored-by: Enrico Loparco <eloparco@cisco.com>
Co-authored-by: Giulio Grassi <gigrassi@cisco.com>
Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'ctrl/facemgr/src')
44 files changed, 7911 insertions, 8290 deletions
diff --git a/ctrl/facemgr/src/CMakeLists.txt b/ctrl/facemgr/src/CMakeLists.txt index cf5606e04..87938fb57 100644 --- a/ctrl/facemgr/src/CMakeLists.txt +++ b/ctrl/facemgr/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021-2022 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -12,130 +12,157 @@ # limitations under the License. if(UNIX AND NOT APPLE) - set(LINUX TRUE) + set(LINUX TRUE) endif() -set(COMPILER_DEFINITIONS - "-DWITH_POLICY" -) +############################################################## +# Sources +############################################################## set(HEADER_FILES - common.h - error.h - facelet_array.h - interface.h - loop.h + common.h + error.h + facelet_array.h + interface.h + loop.h ) set(SOURCE_FILES - api.c - cfg.c - cfg_file.c - error.c - facelet.c - facelet_array.c - interface.c + api.c + cfg.c + cfg_file.c + error.c + facelet.c + facelet_array.c + interface.c ) if(APPLE) -set(SOURCE_FILES + set(SOURCE_FILES ${SOURCE_FILES} loop_dispatcher.c -) + ) endif() if (LINUX) -set(SOURCE_FILES + set(SOURCE_FILES ${SOURCE_FILES} loop_libevent.c -) + ) endif() +add_subdirectory(interfaces) + + +############################################################## +# Include directories +############################################################## set(INCLUDE_DIRS - ./ - ../includes/ - ${HICN_INCLUDE_DIRS} - ${LIBHICNCTRL_INCLUDE_DIRS} - ${CONFIG_INCLUDE_DIR} - ${LIBEVENT_INCLUDE_DIR} + PRIVATE ./ + PRIVATE ${CONFIG_INCLUDE_DIR} + PRIVATE ${LIBEVENT_INCLUDE_DIR} + PUBLIC + $<BUILD_INTERFACE:${LIBFACEMGR_INCLUDE_DIRS}> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) + +############################################################## +# Libraries to link +############################################################## set(LIBRARIES - m - ${HICN_LIBRARIES} - ${LIBHICNCTRL_LIBRARIES} - ${LIBCONFIG_LIBRARIES} - ${LIBEVENT_LIBRARY} + PUBLIC ${HICN_LIBRARIES} + PUBLIC ${LIBHICNCTRL_LIBRARIES} + PRIVATE m + PRIVATE ${LIBCONFIG_LIBRARIES} + PRIVATE ${LIBEVENT_LIBRARY} ) -set(FACEMGR_LIBRARY_LIST "${LIBCONFIG_LIBRARIES};${LIBEVENT_LIBRARY}" CACHE INTERNAL "FACEMGR_LIBRARY_LIST") +if(WITH_THREAD) + set(LIBRARIES + ${LIBRARIES} + "pthread" + "event_pthreads" + ) + set(COMPILER_DEFINITIONS + ${COMPILER_DEFINITIONS} + "-DWITH_THREAD" + ) +endif() -add_subdirectory(interfaces) +############################################################## +# Compiler definitions +############################################################## if(WITH_THREAD) - set(LIBRARIES - ${LIBRARIES} - "pthread" - "event_pthreads" - ) - set(COMPILER_DEFINITIONS - ${COMPILER_DEFINITIONS} - "-DWITH_THREAD" - ) + list(APPEND COMPILER_DEFINITIONS + "-DWITH_THREAD" + ) endif() if(WITH_EXAMPLE_DUMMY) - set(COMPILER_DEFINITIONS - ${COMPILER_DEFINITIONS} - "-DWITH_EXAMPLE_DUMMY" - ) + list(APPEND COMPILER_DEFINITIONS + "-DWITH_EXAMPLE_DUMMY" + ) endif() if(WITH_EXAMPLE_UPDOWN) - set(COMPILER_DEFINITIONS - ${COMPILER_DEFINITIONS} - "-DWITH_EXAMPLE_UPDOWN" - ) + list(APPEND COMPILER_DEFINITIONS + "-DWITH_EXAMPLE_UPDOWN" + ) endif() + +############################################################## +# Compiler options +############################################################## +set(COMPILER_OPTIONS + ${DEFAULT_COMPILER_OPTIONS} +) + + +############################################################## +# Build type +############################################################## if (DISABLE_SHARED_LIBRARIES) - build_library(${LIBFACEMGR} - STATIC - SOURCES ${SOURCE_FILES} - INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} - DEPENDS ${DEPENDENCIES} - LINK_LIBRARIES ${LIBRARIES} - COMPONENT ${FACEMGR} - INCLUDE_DIRS ${INCLUDE_DIRS} - HEADER_ROOT_DIR hicn - DEFINITIONS ${COMPILER_DEFINITIONS} - ) + set(LINK_TYPE STATIC) else () - build_library(${LIBFACEMGR} - SHARED STATIC NO_DEV - SOURCES ${SOURCE_FILES} - INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} - DEPENDS ${DEPENDENCIES} - LINK_LIBRARIES ${LIBRARIES} - COMPONENT ${FACEMGR} - INCLUDE_DIRS ${INCLUDE_DIRS} - HEADER_ROOT_DIR hicn - DEFINITIONS ${COMPILER_DEFINITIONS} - ) + set(LINK_TYPE SHARED STATIC) endif () + +############################################################## +# Build libfacemgr +############################################################## +build_library(${LIBFACEMGR} + ${LINK_TYPE} + SOURCES ${SOURCE_FILES} + INSTALL_HEADERS ${TO_INSTALL_HEADER_FILES} + DEPENDS ${DEPENDENCIES} + LINK_LIBRARIES ${LIBRARIES} + COMPONENT ${FACEMGR} + INCLUDE_DIRS PRIVATE ${INCLUDE_DIRS} + DEFINITIONS PRIVATE ${COMPILER_DEFINITIONS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} +) + + +############################################################## +# Build executable +############################################################## if(NOT DISABLE_EXECUTABLES) - list(APPEND DAEMON_SRC - main.c - ) - - build_executable(${FACEMGR} - SOURCES ${DAEMON_SRC} - LINK_LIBRARIES ${LIBFACEMGR}.static ${LIBRARIES} - DEPENDS ${LIBFACEMGR}.static - COMPONENT ${FACEMGR} - INCLUDE_DIRS ${INCLUDE_DIRS} - DEFINITIONS ${COMPILER_DEFINITIONS} - ) + list(APPEND DAEMON_SRC + main.c + ) + + build_executable(${FACEMGR} + SOURCES ${DAEMON_SRC} + LINK_LIBRARIES PRIVATE ${LIBFACEMGR}.static + DEPENDS ${LIBFACEMGR}.static + COMPONENT ${FACEMGR} + INCLUDE_DIRS ${INCLUDE_DIRS} + DEFINITIONS ${COMPILER_DEFINITIONS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} + ) endif () diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c index dfbd24bcb..d030abd1f 100644 --- a/ctrl/facemgr/src/api.c +++ b/ctrl/facemgr/src/api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -21,17 +21,9 @@ #ifdef __ANDROID__ /* - * Use FacemgrUtility to determine interface types - * - * NOTE: this is currently disabled as SDK APIs do not allow to determine the - * type of interfaces that are DOWN - */ -//#define WITH_FACEMGR_UTILITY - -/* * Use priority controller interface */ -#define WITH_PRIORITY_CONTROLLER +//#define WITH_PRIORITY_CONTROLLER /* * Dump facelets (debug) @@ -62,15 +54,14 @@ #ifdef __linux__ #include "interfaces/bonjour/bonjour.h" +#ifdef __ANDROID__ +#include "interfaces/android/android.h" +#endif /* __ANDROID__ */ #endif /* __linux__ */ -#ifdef WITH_FACEMGR_UTILITY -#include "interfaces/android_utility/android_utility.h" -#endif /* WITH_FACEMGR_UTILITY */ - #include "interfaces/priority_controller/priority_controller.h" -#include <hicn/ctrl/face.h> +#include <hicn/face.h> #include <hicn/facemgr/facelet.h> #include "common.h" #include "facelet_array.h" @@ -84,19 +75,21 @@ #define MAX_FDS 10 typedef struct { - interface_t * interface; - int fds[MAX_FDS]; - size_t num_fds; + interface_t *interface; + int fds[MAX_FDS]; + size_t num_fds; } interface_map_data_t; TYPEDEF_SET_H(facelet_set, facelet_t *); TYPEDEF_SET(facelet_set, facelet_t *, facelet_cmp, facelet_snprintf); TYPEDEF_MAP_H(interface_map, const char *, interface_map_data_t *); -TYPEDEF_MAP(interface_map, const char *, interface_map_data_t *, strcmp, string_snprintf, generic_snprintf); +TYPEDEF_MAP(interface_map, const char *, interface_map_data_t *, strcmp, + string_snprintf, generic_snprintf); TYPEDEF_MAP_H(bonjour_map, netdevice_t *, interface_t *); -TYPEDEF_MAP(bonjour_map, netdevice_t *, interface_t *, netdevice_cmp, generic_snprintf, generic_snprintf); +TYPEDEF_MAP(bonjour_map, netdevice_t *, interface_t *, netdevice_cmp, + generic_snprintf, generic_snprintf); /* TODO automatically register interfaces */ @@ -104,12 +97,13 @@ TYPEDEF_MAP(bonjour_map, netdevice_t *, interface_t *, netdevice_cmp, generic_sn extern interface_ops_t network_framework_ops; #endif #ifdef __linux__ +#ifdef __ANDROID__ +extern interface_ops_t android_ops; +#else extern interface_ops_t netlink_ops; +#endif /* __ANDROID__ */ extern interface_ops_t bonjour_ops; #endif -#ifdef WITH_FACEMGR_UTILITY -extern interface_ops_t android_utility_ops; -#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER extern interface_ops_t priority_controller_ops; #endif @@ -121,458 +115,421 @@ extern interface_ops_t updown_ops; #endif extern interface_ops_t hicn_light_ops; -int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet); +int facemgr_on_event(facemgr_t *facemgr, facelet_t *facelet); -int -facemgr_overlay_snprintf(char * s, size_t size, const facemgr_overlay_t * overlay) -{ - return -1; +int facemgr_overlay_snprintf(char *s, size_t size, + const facemgr_overlay_t *overlay) { + return -1; } struct facemgr_s { - /**************************************************/ - /* Configuration parameters (exposed through API) */ + /**************************************************/ + /* Configuration parameters (exposed through API) */ - facemgr_cfg_t * cfg; + facemgr_cfg_t *cfg; #ifdef __ANDROID__ - /* - * Those two pointers are needed to call java functions from the face - * manager. - */ - JavaVM *jvm; + /* + * Those two pointers are needed to call java functions from the face + * manager. + */ + JavaVM *jvm; #endif /* __ANDROID__ */ - /* Callback */ - facemgr_cb_t callback; - void * callback_owner; + /* Callback */ + facemgr_cb_t callback; + void *callback_owner; - /****************************/ - /* Internal data structures */ + /****************************/ + /* Internal data structures */ - /* Map of interfaces index by name */ - interface_map_t * interface_map; + /* Map of interfaces index by name */ + interface_map_t *interface_map; - /* Faces under construction */ - facelet_set_t * facelet_cache; + /* Faces under construction */ + facelet_set_t *facelet_cache; - /* Static facelets */ - facelet_array_t * static_facelets; + /* Static facelets */ + facelet_array_t *static_facelets; #ifdef WITH_DEFAULT_PRIORITIES - /* Default priorities */ - u32 default_priority[NETDEVICE_TYPE_N+1]; + /* Default priorities */ + u32 default_priority[NETDEVICE_TYPE_N + 1]; #endif /* WITH_DEFAULT_PRIORITIES */ - /********************************************************/ - /* Interfaces - Those should be fully replaced by a map */ - - interface_t * hl; + /********************************************************/ + /* Interfaces - Those should be fully replaced by a map */ -#ifdef WITH_FACEMGR_UTILITY - interface_t * au; /* android_utility */ -#endif /* WITH_FACEMGR_UTILITY */ + interface_t *hl; #ifdef WITH_PRIORITY_CONTROLLER - interface_t * pc; + interface_t *pc; #endif #ifdef __APPLE__ - interface_t * nf; /* network_framework */ -#endif /* __APPLE__ */ + interface_t *nf; /* network_framework */ +#endif /* __APPLE__ */ #ifdef __linux__ - interface_t * nl; /* netlink */ - /* - * We maintain a map of dynamically created bonjour interfaces, one for each - * found netdevice - */ - bonjour_map_t * bonjour_map; +#ifdef __ANDROID__ + interface_t *android; +#else + interface_t *nl; /* netlink */ +#endif /* __ANDROID__ */ + /* + * We maintain a map of dynamically created bonjour interfaces, one for each + * found netdevice + */ + bonjour_map_t *bonjour_map; #endif /* __linux__ */ #ifdef WITH_EXAMPLE_DUMMY - interface_t * dummy; + interface_t *dummy; #endif #ifdef WITH_EXAMPLE_UPDOWN - interface_t * updown; + interface_t *updown; #endif - int timer_fd; /* Timer used for reattempts */ + int timer_fd; /* Timer used for reattempts */ - int cur_static_id; /* Used to distinguish static faces (pre-incremented) */ + int cur_static_id; /* Used to distinguish static faces (pre-incremented) */ }; -int -facemgr_initialize(facemgr_t * facemgr) -{ - facemgr->interface_map = interface_map_create(); - if (!facemgr->interface_map) { - ERROR("[facemgr_initialize] Error creating interface map"); - goto ERR_INTERFACE_MAP; - } - - facemgr->facelet_cache = facelet_set_create(); - if (!facemgr->facelet_cache) { - ERROR("[facemgr_initialize] Error creating interface map"); - goto ERR_FACE_CACHE_PENDING; - } - - facemgr->static_facelets = facelet_array_create(); - if (!facemgr->static_facelets) { - ERROR("[facemgr_initialize] Error creating interface map"); - goto ERR_STATIC; - } +int facemgr_initialize(facemgr_t *facemgr) { + facemgr->interface_map = interface_map_create(); + if (!facemgr->interface_map) { + ERROR("[facemgr_initialize] Error creating interface map"); + goto ERR_INTERFACE_MAP; + } + + facemgr->facelet_cache = facelet_set_create(); + if (!facemgr->facelet_cache) { + ERROR("[facemgr_initialize] Error creating interface map"); + goto ERR_FACE_CACHE_PENDING; + } + + facemgr->static_facelets = facelet_array_create(); + if (!facemgr->static_facelets) { + ERROR("[facemgr_initialize] Error creating interface map"); + goto ERR_STATIC; + } #ifdef __linux__ - facemgr->bonjour_map = bonjour_map_create(); - if (!facemgr->bonjour_map) { - ERROR("[facemgr_initialize] Error creating bonjour map"); - goto ERR_BJ; - } + facemgr->bonjour_map = bonjour_map_create(); + if (!facemgr->bonjour_map) { + ERROR("[facemgr_initialize] Error creating bonjour map"); + goto ERR_BJ; + } #endif /* __linux */ - facemgr->cfg = facemgr_cfg_create(); - if (!facemgr->cfg) { - ERROR("[facemgr_initialize] Error creating face manager configuration"); - goto ERR_CFG; - } + facemgr->cfg = facemgr_cfg_create(); + if (!facemgr->cfg) { + ERROR("[facemgr_initialize] Error creating face manager configuration"); + goto ERR_CFG; + } - facemgr->timer_fd = 0; - facemgr->cur_static_id = 0; + facemgr->timer_fd = 0; + facemgr->cur_static_id = 0; #ifdef WITH_DEFAULT_PRIORITIES -#define _(x) facemgr->default_priority[NETDEVICE_TYPE_ ## x] = 0; -foreach_netdevice_type +#define _(x) facemgr->default_priority[NETDEVICE_TYPE_##x] = 0; + foreach_netdevice_type #undef _ #endif /* WITH_DEFAULT_PRIORITIES */ - return 0; + return 0; ERR_CFG: #ifdef __linux__ - bonjour_map_free(facemgr->bonjour_map); + bonjour_map_free(facemgr->bonjour_map); ERR_BJ: #endif /* __linux__ */ - facelet_array_free(facemgr->static_facelets); + facelet_array_free(facemgr->static_facelets); ERR_STATIC: - facelet_set_free(facemgr->facelet_cache); + facelet_set_free(facemgr->facelet_cache); ERR_FACE_CACHE_PENDING: - interface_map_free(facemgr->interface_map); + interface_map_free(facemgr->interface_map); ERR_INTERFACE_MAP: - return -1; + return -1; } -int -facemgr_finalize(facemgr_t * facemgr) -{ - int ret = 0; - int rc; +int facemgr_finalize(facemgr_t *facemgr) { + int ret = 0; + int rc; - if (facemgr->timer_fd) { - rc = facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_UNREGISTER_TIMER, &facemgr->timer_fd); - if (rc < 0) { - ERROR("[facemgr_finalize] Error unregistering timer"); - ret = -1; - } - facemgr->timer_fd = 0; + if (facemgr->timer_fd) { + rc = + facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_UNREGISTER_TIMER, &facemgr->timer_fd); + if (rc < 0) { + ERROR("[facemgr_finalize] Error unregistering timer"); + ret = -1; } + facemgr->timer_fd = 0; + } - interface_map_free(facemgr->interface_map); + interface_map_free(facemgr->interface_map); - /* Free all facelets from cache */ - facelet_t ** facelet_array; - int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); - if (n < 0) { - ERROR("[facemgr_finalize] Could not retrieve facelets in cache"); - } else { - for (unsigned i = 0; i < n; i++) { - facelet_t * facelet = facelet_array[i]; - if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL)) { - ERROR("[facemgr_finalize] Could not purge facelet from cache"); - } - facelet_free(facelet); - } - free(facelet_array); + /* Free all facelets from cache */ + facelet_t **facelet_array; + int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); + if (n < 0) { + ERROR("[facemgr_finalize] Could not retrieve facelets in cache"); + } else { + for (unsigned i = 0; i < n; i++) { + facelet_t *facelet = facelet_array[i]; + if (!facelet) continue; /* Should not occur */ + if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL)) { + ERROR("[facemgr_finalize] Could not purge facelet from cache"); + } + facelet_free(facelet); } + free(facelet_array); + } - facelet_set_free(facemgr->facelet_cache); + facelet_set_free(facemgr->facelet_cache); - /* Free all facelets from static array */ - for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) { - facelet_t * facelet; - if (facelet_array_get_index(facemgr->static_facelets, i, &facelet) < 0) { - ERROR("[facemgr_cfg_finalize] Error getting facelet in array"); - continue; - } - if (facelet_array_remove_index(facemgr->static_facelets, i, NULL) < 0) { - ERROR("[facemgr_finalize] Could not purge facelet from static array"); - } - facelet_free(facelet); + /* Free all facelets from static array */ + for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) { + facelet_t *facelet; + if (facelet_array_get_index(facemgr->static_facelets, i, &facelet) < 0) { + ERROR("[facemgr_cfg_finalize] Error getting facelet in array"); + continue; + } + if (facelet_array_remove_index(facemgr->static_facelets, i, NULL) < 0) { + ERROR("[facemgr_finalize] Could not purge facelet from static array"); } + facelet_free(facelet); + } - facelet_array_free(facemgr->static_facelets); + facelet_array_free(facemgr->static_facelets); #ifdef __linux__ - bonjour_map_free(facemgr->bonjour_map); + bonjour_map_free(facemgr->bonjour_map); #endif /* __linux__ */ - interface_unregister_all(); + interface_unregister_all(); - return ret; + return ret; } AUTOGENERATE_CREATE_FREE(facemgr); -int -facemgr_set_config(facemgr_t * facemgr, facemgr_cfg_t * cfg) -{ - if (facemgr->cfg) { - facemgr_cfg_free(facemgr->cfg); - } - facemgr->cfg = cfg; - - /* Populate the initial list of static facelets */ - facelet_t ** facelet_array; - int n = facemgr_cfg_get_static_facelet_array(cfg, &facelet_array); - if (n < 0) { - ERROR("[facemgr_finalize] Could not retrieve static facelets from cfg"); - } else { - for (unsigned i = 0; i < n; i++) { - facelet_t * facelet = facelet_dup(facelet_array[i]); - facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); - facelet_set_attr_clean(facelet); - if (facelet_array_add(facemgr->static_facelets, facelet)) { - ERROR("[facemgr_finalize] Could not add static facelet to face manager"); - } - } +int facemgr_set_config(facemgr_t *facemgr, facemgr_cfg_t *cfg) { + if (facemgr->cfg) { + facemgr_cfg_free(facemgr->cfg); + } + facemgr->cfg = cfg; + + /* Populate the initial list of static facelets */ + facelet_t **facelet_array; + int n = facemgr_cfg_get_static_facelet_array(cfg, &facelet_array); + if (n < 0) { + ERROR("[facemgr_finalize] Could not retrieve static facelets from cfg"); + } else { + for (unsigned i = 0; i < n; i++) { + facelet_t *facelet = facelet_dup(facelet_array[i]); + facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); + facelet_set_attr_clean(facelet); + if (facelet_array_add(facemgr->static_facelets, facelet)) { + ERROR( + "[facemgr_finalize] Could not add static facelet to face manager"); + } } + } - return 0; + return 0; } -int facemgr_reset_config(facemgr_t * facemgr) -{ - assert(facemgr->cfg); - facemgr_cfg_free(facemgr->cfg); - facemgr->cfg = facemgr_cfg_create(); - if (!facemgr->cfg) - return -1; - return 0; +int facemgr_reset_config(facemgr_t *facemgr) { + assert(facemgr->cfg); + facemgr_cfg_free(facemgr->cfg); + facemgr->cfg = facemgr_cfg_create(); + if (!facemgr->cfg) return -1; + return 0; } -facemgr_t * -facemgr_create_with_config(facemgr_cfg_t * cfg) -{ - facemgr_t * facemgr = facemgr_create(); - if (!facemgr) - return NULL; - int rc = facemgr_set_config(facemgr, cfg); - if (rc < 0) { - free(facemgr); - return NULL; - } - return facemgr; +facemgr_t *facemgr_create_with_config(facemgr_cfg_t *cfg) { + facemgr_t *facemgr = facemgr_create(); + if (!facemgr) return NULL; + int rc = facemgr_set_config(facemgr, cfg); + if (rc < 0) { + free(facemgr); + return NULL; + } + return facemgr; } /* * \brief Heuristics to determine face type based on name, until a better * solution is found */ -netdevice_type_t -facemgr_get_netdevice_type(const facemgr_t * facemgr, const char * interface_name) -{ - if (strncmp(interface_name, "lo", 2) == 0) { - return NETDEVICE_TYPE_LOOPBACK; - } - if ((strncmp(interface_name, "eth", 3) == 0) || - (strncmp(interface_name, "en", 2) == 0)) { - /* eth* en* enx* */ - return NETDEVICE_TYPE_WIRED; - } - if (strncmp(interface_name, "wl", 2) == 0) { - /* wlan* wlp* wlx* */ - return NETDEVICE_TYPE_WIFI; - } - if (strncmp(interface_name, "rmnet_ipa", 9) == 0) { - /* Qualcomm IPA driver */ - return NETDEVICE_TYPE_UNDEFINED; - } - if ((strncmp(interface_name, "rmnet", 5) == 0) || - (strncmp(interface_name, "rev_rmnet", 9) == 0) || - (strncmp(interface_name, "ccmni", 5) == 0)) { - /* - * rmnet* (Qualcomm) ccmni* (MediaTek) - */ - return NETDEVICE_TYPE_CELLULAR; - } - /* usb0 might be cellular (eg Zenfone2) */ - /* what about tethering */ - /* tun* dummy* ... */ - /* bnet* pan* hci* for bluetooth */ +netdevice_type_t facemgr_get_netdevice_type(const facemgr_t *facemgr, + const char *interface_name) { + if (strncmp(interface_name, "lo", 2) == 0) { + return NETDEVICE_TYPE_LOOPBACK; + } + if ((strncmp(interface_name, "eth", 3) == 0) || + (strncmp(interface_name, "en", 2) == 0)) { + /* eth* en* enx* */ + return NETDEVICE_TYPE_WIRED; + } + if (strncmp(interface_name, "wl", 2) == 0) { + /* wlan* wlp* wlx* */ + return NETDEVICE_TYPE_WIFI; + } + if (strncmp(interface_name, "rmnet_ipa", 9) == 0) { + /* Qualcomm IPA driver */ return NETDEVICE_TYPE_UNDEFINED; + } + if ((strncmp(interface_name, "rmnet", 5) == 0) || + (strncmp(interface_name, "rev_rmnet", 9) == 0) || + (strncmp(interface_name, "ccmni", 5) == 0)) { + /* + * rmnet* (Qualcomm) ccmni* (MediaTek) + */ + return NETDEVICE_TYPE_CELLULAR; + } + /* usb0 might be cellular (eg Zenfone2) */ + /* what about tethering */ + /* tun* dummy* ... */ + /* bnet* pan* hci* for bluetooth */ + return NETDEVICE_TYPE_UNDEFINED; } -int facemgr_callback(facemgr_t * facemgr, interface_cb_type_t type, void * data); - -int -facemgr_create_interface(facemgr_t * facemgr, const char * name, const char * type, void * cfg, interface_t ** pinterface) -{ - char rand_name[RAND_NAME_LEN+1]; - interface_t * interface; - - if (!name) { - /* - * We can manipulate the name on the stack as it will be strdup'ed by - * interface_create - */ - rand_str(rand_name, RAND_NAME_LEN); - name = rand_name; - } - - INFO("Creating interface %s [%s]...", name, type); - interface = interface_create(name, type); - if (!interface) { - ERROR("Error creating interface %s [%s]", name, type); - goto ERR_CREATE; - } - interface_set_callback(interface, facemgr, facemgr_callback); +int facemgr_callback(facemgr_t *facemgr, interface_cb_type_t type, void *data); - interface_map_data_t * interface_map_data = malloc(sizeof(interface_map_data_t)); - if (!interface_map_data) - goto ERR_MAP_DATA; - - *interface_map_data = (interface_map_data_t) { - .interface = interface, - .fds = {0}, - .num_fds = 0, - }; - - if (interface_map_add(facemgr->interface_map, interface->name, interface_map_data) < 0) - goto ERR_MAP_ADD; +int facemgr_create_interface(facemgr_t *facemgr, const char *name, + const char *type, void *cfg, + interface_t **pinterface) { + char rand_name[RAND_NAME_LEN + 1]; + interface_t *interface; + if (!name) { /* - * This should be called _after_ the interface_map is initialized otherwise - * it will be impossible to register fds from *_initialize + * We can manipulate the name on the stack as it will be strdup'ed by + * interface_create */ - if (interface_initialize(interface, cfg) < 0) { - ERROR("[facemgr_create_interface] Error initializing interface"); - goto ERR_INIT; - } - - DEBUG("Interface %s created successfully.", name); - if (pinterface) - *pinterface = interface; - return 0; - - - //interface_finalize(interface); + rand_str(rand_name, RAND_NAME_LEN); + name = rand_name; + } + + INFO("Creating interface %s [%s]...", name, type); + interface = interface_create(name, type); + if (!interface) { + ERROR("Error creating interface %s [%s]", name, type); + goto ERR_CREATE; + } + interface_set_callback(interface, facemgr, facemgr_callback); + + interface_map_data_t *interface_map_data = + malloc(sizeof(interface_map_data_t)); + if (!interface_map_data) goto ERR_MAP_DATA; + + *interface_map_data = (interface_map_data_t){ + .interface = interface, + .fds = {0}, + .num_fds = 0, + }; + + if (interface_map_add(facemgr->interface_map, interface->name, + interface_map_data) < 0) + goto ERR_MAP_ADD; + + /* + * This should be called _after_ the interface_map is initialized otherwise + * it will be impossible to register fds from *_initialize + */ + if (interface_initialize(interface, cfg) < 0) { + ERROR("[facemgr_create_interface] Error initializing interface"); + goto ERR_INIT; + } + + DEBUG("Interface %s created successfully.", name); + if (pinterface) *pinterface = interface; + return 0; + + // interface_finalize(interface); ERR_INIT: - interface_map_remove(facemgr->interface_map, interface->name, NULL); + interface_map_remove(facemgr->interface_map, interface->name, NULL); ERR_MAP_ADD: - free(interface_map_data); + free(interface_map_data); ERR_MAP_DATA: - interface_free(interface); + interface_free(interface); ERR_CREATE: - if (pinterface) - *pinterface = NULL; - return -1; + if (pinterface) *pinterface = NULL; + return -1; } -int -facemgr_delete_interface(facemgr_t * facemgr, interface_t * interface) -{ - int rc; - - interface_map_data_t * interface_map_data = NULL; +int facemgr_delete_interface(facemgr_t *facemgr, interface_t *interface) { + int rc; - DEBUG("Removing interface %s", interface->name); - rc = interface_map_remove(facemgr->interface_map, interface->name, &interface_map_data); - if (rc < 0) - return -1; + /* + * It is possible that one interface was never initialized, and thus the + * facemgr never started, and we still call stop(). This is for instance the + * case on Android (sdk 30) when netlink is blocked. + */ + if (!interface) return 0; - if (!interface_map_data) - return -1; - - for (unsigned i = 0; i < interface_map_data->num_fds; i++) { - int fd = interface_map_data->fds[i]; - fd_callback_data_t fd_callback_data = { - .fd = fd, - .owner = facemgr, - .callback = NULL, - .data = NULL, - }; - facemgr->callback(facemgr->callback_owner, FACEMGR_CB_TYPE_UNREGISTER_FD, &fd_callback_data); - if (rc < 0) - WARN("[facemgr_delete_interface] Error unregistering fd %d for interface", fd); - } + interface_map_data_t *interface_map_data = NULL; - free(interface_map_data); + DEBUG("Removing interface %s", interface->name); + rc = interface_map_remove(facemgr->interface_map, interface->name, + &interface_map_data); + if (rc < 0) return -1; - interface_finalize(interface); - interface_free(interface); + if (!interface_map_data) return -1; - return 0; -} - -#ifdef __linux__ -int facemgr_query_bonjour(facemgr_t * facemgr, netdevice_t * netdevice) -{ - interface_t * bj = NULL; - - int rc = bonjour_map_get(facemgr->bonjour_map, netdevice, &bj); + for (unsigned i = 0; i < interface_map_data->num_fds; i++) { + int fd = interface_map_data->fds[i]; + fd_callback_data_t fd_callback_data = { + .fd = fd, + .owner = facemgr, + .callback = NULL, + .data = NULL, + }; + facemgr->callback(facemgr->callback_owner, FACEMGR_CB_TYPE_UNREGISTER_FD, + &fd_callback_data); if (rc < 0) - return rc; - - if (!bj) { - /* Create a new bonjour interface */ - bonjour_cfg_t bj_cfg = { - .netdevice = *netdevice, - }; - rc = facemgr_create_interface(facemgr, NULL, "bonjour", &bj_cfg, &bj); - if (rc < 0) { - ERROR("Error creating 'Bonjour' interface for '%s'\n", netdevice->name); - return -1; - } - } + WARN("[facemgr_delete_interface] Error unregistering fd %d for interface", + fd); + } - DEBUG("sending event to bonjour interface"); + free(interface_map_data); - /* Send an event to the interface (GET ?) */ - // XXX error handling - return interface_on_event(bj, NULL); + interface_finalize(interface); + interface_free(interface); + + return 0; } -#endif /* __linux__ */ -#ifdef WITH_FACEMGR_UTILITY -int facemgr_query_android_utility(facemgr_t * facemgr, netdevice_t netdevice) -{ - /* Send an event to the interface */ - facelet_t * facelet = facelet_create(); - if (!facelet) - goto ERR_MALLOC; +#ifdef __linux__ +int facemgr_query_bonjour(facemgr_t *facemgr, netdevice_t *netdevice) { + interface_t *bj = NULL; - int rc = facelet_set_netdevice(facelet, netdevice); - if (rc < 0) - goto ERR_ND; + int rc = bonjour_map_get(facemgr->bonjour_map, netdevice, &bj); + if (rc < 0) return rc; - rc = interface_on_event(facemgr->au, facelet); + if (!bj) { + /* Create a new bonjour interface */ + bonjour_cfg_t bj_cfg = { + .netdevice = *netdevice, + }; + rc = facemgr_create_interface(facemgr, NULL, "bonjour", &bj_cfg, &bj); if (rc < 0) { - // XXX error handling - goto ERR_EVENT; + ERROR("Error creating 'Bonjour' interface for '%s'\n", netdevice->name); + return -1; } + } - return 0; + DEBUG("sending event to bonjour interface"); -ERR_EVENT: -ERR_ND: - facelet_free(facelet); -ERR_MALLOC: - return -1; + /* Send an event to the interface (GET ?) */ + // XXX error handling + return interface_on_event(bj, NULL); } -#endif /* WITH_FACEMGR_UTILITY */ - +#endif /* __linux__ */ /** * \brief Performs a cache lookup to find matching facelets @@ -583,43 +540,38 @@ ERR_MALLOC: * \return The number of entries in the array in case of success (positive * value), or -1 in case of error. */ -int -facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet, - facelet_t ***cached_facelets) -{ - assert(facelet); - - /* ...otherwise, we iterate over the facelet - * cache to find matching elements. - */ - facelet_t ** facelet_array; - int n = facelet_set_get_array(facelet_cache, &facelet_array); - if (n < 0) { - ERROR("[facelet_cache_lookup] Error during cache match"); - return -1; - } - if (cached_facelets) - *cached_facelets = malloc(n * sizeof(facelet_t*)); +int facelet_cache_lookup(const facelet_set_t *facelet_cache, facelet_t *facelet, + facelet_t ***cached_facelets) { + assert(facelet); + + /* ...otherwise, we iterate over the facelet + * cache to find matching elements. + */ + facelet_t **facelet_array; + int n = facelet_set_get_array(facelet_cache, &facelet_array); + if (n < 0) { + ERROR("[facelet_cache_lookup] Error during cache match"); + return -1; + } + if (cached_facelets) *cached_facelets = malloc(n * sizeof(facelet_t *)); - int num_match = 0; - for (unsigned i = 0; i < n; i++) { + int num_match = 0; + for (unsigned i = 0; i < n; i++) { #if 0 - char facelet_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_array[i]); - DEBUG("cache entry #%d/%di = %s", i+1, n, facelet_s); + char facelet_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_array[i]); + DEBUG("cache entry #%d/%di = %s", i + 1, n, facelet_s); #endif - if (!facelet_match(facelet_array[i], facelet)) { - continue; - } - if (cached_facelets) - (*cached_facelets)[num_match] = facelet_array[i]; - num_match++; - } - free(facelet_array); - return num_match; + facelet_t *f = facelet_array[i]; + if (!f) continue; /* Should not occur */ + if (!facelet_match(f, facelet)) continue; + if (cached_facelets) (*cached_facelets)[num_match] = f; + num_match++; + } + free(facelet_array); + return num_match; } - /** * \brief Checks whether the facelet satisfies face creation rules * \param [in] facemgr - Pointer to the face manager instance @@ -627,129 +579,92 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet, * \return 0 in case of success, -2 if we don't have enough information to * decide, -3 if the face does not satisfy rules, and -1 in case of error */ -int -facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet) -{ - /* As key, netdevice and family should always be present */ - netdevice_t netdevice = NETDEVICE_EMPTY; - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) { - ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice from facelet"); +int facemgr_facelet_satisfy_rules(facemgr_t *facemgr, facelet_t *facelet) { + /* As key, netdevice and family should always be present */ + netdevice_t netdevice = NETDEVICE_EMPTY; + int rc = facelet_get_netdevice(facelet, &netdevice); + if (rc < 0) { + ERROR( + "[facemgr_facelet_satisfy_rules] Error retrieving netdevice from " + "facelet"); + return -1; + } + + int family = AF_UNSPEC; + if (facelet_has_family(facelet)) { + if (facelet_get_family(facelet, &family) < 0) { + ERROR( + "[facemgr_facelet_satisfy_rules] Error retrieving family from " + "facelet"); + return -1; + } + } + + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + /* + * In addition to netdevice, netdevice_type should be present to correctly + * apply rules + */ + rc = facelet_get_netdevice_type(facelet, &netdevice_type); + if (rc < 0) { + ERROR( + "[facemgr_facelet_satisfy_rules] Error retrieving netdevice_type from " + "facelet"); + return -2; + } + + /* Default ignore list */ + if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || + (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) { + DEBUG("Ignored interface '%s/%s'...", netdevice.name, + netdevice_type_str(netdevice_type)); + return -3; + } + + /* Ignore */ + bool ignore; + if (facemgr_cfg_get_ignore(facemgr->cfg, &netdevice, netdevice_type, + &ignore) < 0) + return -1; + if (ignore) { + DEBUG("Ignored interface '%s/%s'...", netdevice.name, + netdevice_type_str(netdevice_type)); + return -3; + } + + switch (family) { + case AF_INET: { + bool ipv4; + if (facemgr_cfg_get_ipv4(facemgr->cfg, &netdevice, netdevice_type, + &ipv4) < 0) return -1; - } - - int family = AF_UNSPEC; - if (facelet_has_family(facelet)) { - if (facelet_get_family(facelet, &family) < 0) { - ERROR("[facemgr_facelet_satisfy_rules] Error retrieving family from facelet"); - return -1; - } - } - - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_FACEMGR_UTILITY - /* - * In addition to netdevice, netdevice_type should be present to correctly - * apply rules - */ - rc = facelet_get_netdevice_type(facelet, &netdevice_type); - if (rc < 0) { - ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice_type from facelet"); - return -2; - } -#endif /* WITH_FACEMGR_UTILITY */ - - /* Default ignore list */ - if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) { - DEBUG("Ignored interface '%s/%s'...", netdevice.name, - netdevice_type_str[netdevice_type]); + if (!ipv4) { + DEBUG("Ignored IPv4 facelet..."); return -3; + } + break; } - /* Ignore */ - bool ignore; - if (facemgr_cfg_get_ignore(facemgr->cfg, &netdevice, netdevice_type, - &ignore) < 0) + case AF_INET6: { + bool ipv6; + if (facemgr_cfg_get_ipv6(facemgr->cfg, &netdevice, netdevice_type, + &ipv6) < 0) return -1; - if (ignore) { - DEBUG("Ignored interface '%s/%s'...", netdevice.name, - netdevice_type_str[netdevice_type]); + if (!ipv6) { + DEBUG("Ignored IPv6 facelet..."); return -3; + } + break; } - switch(family) { - case AF_INET: - { - bool ipv4; - if (facemgr_cfg_get_ipv4(facemgr->cfg, &netdevice, netdevice_type, - &ipv4) < 0) - return -1; - if (!ipv4) { - DEBUG("Ignored IPv4 facelet..."); - return -3; - } - break; - } - - case AF_INET6: - { - bool ipv6; - if (facemgr_cfg_get_ipv6(facemgr->cfg, &netdevice, netdevice_type, - &ipv6) < 0) - return -1; - if (!ipv6) { - DEBUG("Ignored IPv6 facelet..."); - return -3; - } - break; - } - - default: - DEBUG("Ignored facelet with unknown family"); - return -2; - } + default: + DEBUG("Ignored facelet with unknown family"); + return -2; + } - return 0; + return 0; } -#ifdef WITH_FACEMGR_UTILITY -/** - * \brief Complements facelet information through Android Utility interface - * \return 0 if request was successful, -1 in case of error, and -2 if the - * interface is not applicable - * - * This function returnds _after_ completion. - */ -int -facemgr_complement_facelet_au(facemgr_t * facemgr, facelet_t * facelet) -{ - - if (facelet_has_netdevice_type(facelet)) - return -2; - - if (facelet_is_au_done(facelet)) - return -2; - - netdevice_t netdevice = NETDEVICE_EMPTY; - - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice from facelet"); - return -1; - } - - DEBUG("Querying android utility..."); - - /* /!\ Synchronous code here /!\ */ - if (facemgr_query_android_utility(facemgr, netdevice) < 0) { - return -1; - } - - facelet_set_au_done(facelet); - return 0; -} -#endif /* WITH_FACEMGR_UTILITY */ - #ifdef __linux__ /** * \brief Complements facelet information through Bonjour interface. @@ -759,66 +674,68 @@ facemgr_complement_facelet_au(facemgr_t * facemgr, facelet_t * facelet) * This function returnds _before_ completion as bonjour querying is * asynchronous. */ -int -facemgr_complement_facelet_bj(facemgr_t * facemgr, facelet_t * facelet) -{ - netdevice_t netdevice = NETDEVICE_EMPTY; - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice from facelet"); - return -1; - } - - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_FACEMGR_UTILITY - /* - * In addition to netdevice, netdevice_type should be present to correctly - * apply rules - */ - rc = facelet_get_netdevice_type(facelet, &netdevice_type); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice_type from facelet"); - return -2; - } -#endif /* WITH_FACEMGR_UTILITY */ - - bool discovery; - if (facemgr_cfg_get_discovery(facemgr->cfg, &netdevice, netdevice_type, - &discovery) < 0) - return -2; - - DEBUG("Discovery: %s", discovery ? "ON" : "OFF"); - - if (!discovery) - return -2; - - facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; - if (facelet_get_face_type(facelet, &face_type) < 0) { - ERROR("[facemgr_complement_facelet_bj] Error retrieving face type from facelet"); - return -1; - } +int facemgr_complement_facelet_bj(facemgr_t *facemgr, facelet_t *facelet) { + netdevice_t netdevice = NETDEVICE_EMPTY; + int rc = facelet_get_netdevice(facelet, &netdevice); + if (rc < 0) { + ERROR( + "[facemgr_complement_facelet_bj] Error retrieving netdevice from " + "facelet"); + return -1; + } + + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + /* + * In addition to netdevice, netdevice_type should be present to correctly + * apply rules + */ + rc = facelet_get_netdevice_type(facelet, &netdevice_type); + if (rc < 0) { + ERROR( + "[facemgr_complement_facelet_bj] Error retrieving netdevice_type from " + "facelet"); + return -2; + } + + bool discovery; + if (facemgr_cfg_get_discovery(facemgr->cfg, &netdevice, netdevice_type, + &discovery) < 0) + return -2; + + DEBUG("Discovery: %s", discovery ? "ON" : "OFF"); + + if (!discovery) return -2; + + facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; + if (facelet_get_face_type(facelet, &face_type) < 0) { + ERROR( + "[facemgr_complement_facelet_bj] Error retrieving face type from " + "facelet"); + return -1; + } - bool discovery_needed = (face_type.layer == FACE_TYPE_LAYER_4) && - ((!facelet_has_remote_addr(facelet)) || (!facelet_has_remote_port(facelet))); + bool discovery_needed = (face_type.layer == FACE_TYPE_LAYER_4) && + ((!facelet_has_remote_addr(facelet)) || + (!facelet_has_remote_port(facelet))); - DEBUG("Discovery needed: %s", discovery ? "ON" : "OFF"); + DEBUG("Discovery needed: %s", discovery ? "ON" : "OFF"); - if (!discovery_needed) { - return -2; - } + if (!discovery_needed) { + return -2; + } - if (!facelet_has_local_addr(facelet)) { - DEBUG("No discovery possible without local address"); - return -2; - } + if (!facelet_has_local_addr(facelet)) { + DEBUG("No discovery possible without local address"); + return -2; + } - if (facelet_is_bj_done(facelet)) { - DEBUG("Bonjour already queried"); - return -2; - } + if (facelet_is_bj_done(facelet)) { + DEBUG("Bonjour already queried"); + return -2; + } - facelet_set_bj_done(facelet); - return facemgr_query_bonjour(facemgr, &netdevice); + facelet_set_bj_done(facelet); + return facemgr_query_bonjour(facemgr, &netdevice); } #endif /* __linux__ */ @@ -830,49 +747,52 @@ facemgr_complement_facelet_bj(facemgr_t * facemgr, facelet_t * facelet) * This function returnds _before_ completion as bonjour querying is * asynchronous. */ -int -facemgr_complement_facelet_manual(facemgr_t * facemgr, facelet_t * facelet) -{ - - netdevice_t netdevice = NETDEVICE_EMPTY; - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_manual] Error retrieving netdevice from facelet"); - return -1; - } - - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_FACEMGR_UTILITY - /* - * In addition to netdevice, netdevice_type should be present to correctly - * apply rules - */ - rc = facelet_get_netdevice_type(facelet, &netdevice_type); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_manual] Error retrieving netdevice_type from facelet"); - return -2; - } -#endif /* WITH_FACEMGR_UTILITY */ - - int family = AF_UNSPEC; - if (facelet_has_family(facelet)) { - if (facelet_get_family(facelet, &family) < 0) { - ERROR("[facemgr_complement_facelet_manual] Error retrieving family from facelet"); - return -1; - } - } - - /* Do not query manual is there is a change to go through bonjour */ - bool discovery; - if (facemgr_cfg_get_discovery(facemgr->cfg, &netdevice, netdevice_type, - &discovery) < 0) - return -2; - - facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; - if (facelet_get_face_type(facelet, &face_type) < 0) { - ERROR("[facemgr_complement_facelet_manual] Error retrieving face type from facelet"); - return -1; - } +int facemgr_complement_facelet_manual(facemgr_t *facemgr, facelet_t *facelet) { + netdevice_t netdevice = NETDEVICE_EMPTY; + int rc = facelet_get_netdevice(facelet, &netdevice); + if (rc < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error retrieving netdevice from " + "facelet"); + return -1; + } + + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + /* + * In addition to netdevice, netdevice_type should be present to correctly + * apply rules + */ + rc = facelet_get_netdevice_type(facelet, &netdevice_type); + if (rc < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error retrieving netdevice_type " + "from facelet"); + return -2; + } + + int family = AF_UNSPEC; + if (facelet_has_family(facelet)) { + if (facelet_get_family(facelet, &family) < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error retrieving family from " + "facelet"); + return -1; + } + } + + /* Do not query manual is there is a change to go through bonjour */ + bool discovery; + if (facemgr_cfg_get_discovery(facemgr->cfg, &netdevice, netdevice_type, + &discovery) < 0) + return -2; + + facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; + if (facelet_get_face_type(facelet, &face_type) < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error retrieving face type from " + "facelet"); + return -1; + } #if 0 /* Wrong if we need to complement local addr / port */ bool discovery_needed = (face_type.layer == FACE_TYPE_LAYER_4) && @@ -884,91 +804,97 @@ facemgr_complement_facelet_manual(facemgr_t * facemgr, facelet_t * facelet) } #endif - if (discovery && !facelet_is_bj_done(facelet)) { - DEBUG("manual settings not considered as discovery is enabled and Bonjour has not yet been done"); - return -2; - } - - DEBUG("Applying manual settings..."); - /* - * Manual overlay specification (remote addr/port) - * We never override a result we have obtained through bonjour - */ - if (!facelet_has_remote_addr(facelet)) { - ip_address_t remote_addr; - if (facemgr_cfg_get_overlay_remote_addr(facemgr->cfg, - &netdevice, netdevice_type, family, &remote_addr) < 0) { - ERROR("[facemgr_complement_facelet_manual] Error getting remote addr information from cfg"); - return -1; - } - if (ip_address_empty(&remote_addr)) { - ERROR("[facemgr_complement_facelet_manual] Got empty remote addr information from cfg"); - } else { - DEBUG(" - remote address"); - facelet_set_remote_addr(facelet, remote_addr); - } - } - - if (!facelet_has_remote_port(facelet)) { - uint16_t remote_port; - int rc = facemgr_cfg_get_overlay_remote_port(facemgr->cfg, - &netdevice, netdevice_type, family, &remote_port); - if (rc < 0) { - ERROR("[facemgr_complement_facelet_manual] Error getting remote port information from cfg"); - return -1; - } - DEBUG(" - remote port"); - facelet_set_remote_port(facelet, remote_port); - } - - /* - * Complementing local addr/port XXX this should be done somewhere - * else : manual settings have the lowest priority - * - * Local IP address is specific as it allows to override the source - * address just before creating the face... we would need to check - * whether this is an address that belong to us... it might be used - * to arbitrate amongst several IP addresses instead... - */ - ip_address_t local_addr; - if (facemgr_cfg_get_overlay_local_addr(facemgr->cfg, &netdevice, - netdevice_type, family, &local_addr) < 0) { - ERROR("[facemgr_complement_facelet_manual] Error getting local addr information from cfg"); - return -1; - } - if (ip_address_empty(&local_addr)) { - ERROR("[facemgr_complement_facelet_manual] Got empty local addr information from cfg"); + if (discovery && !facelet_is_bj_done(facelet)) { + DEBUG( + "manual settings not considered as discovery is enabled and Bonjour " + "has not yet been done"); + return -2; + } + + DEBUG("Applying manual settings..."); + /* + * Manual overlay specification (remote addr/port) + * We never override a result we have obtained through bonjour + */ + if (!facelet_has_remote_addr(facelet)) { + ip_address_t remote_addr; + if (facemgr_cfg_get_overlay_remote_addr(facemgr->cfg, &netdevice, + netdevice_type, family, + &remote_addr) < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error getting remote addr " + "information from cfg"); + return -1; + } + if (ip_address_empty(&remote_addr)) { + ERROR( + "[facemgr_complement_facelet_manual] Got empty remote addr " + "information from cfg"); } else { - DEBUG(" - local addres"); - facelet_set_local_addr(facelet, local_addr); + DEBUG(" - remote address"); + facelet_set_remote_addr(facelet, remote_addr); } + } - /* Sets a default local port, so far nobody sets it */ - uint16_t local_port; - if (facemgr_cfg_get_overlay_local_port(facemgr->cfg, - &netdevice, netdevice_type, family, &local_port) < 0) { - ERROR("[facemgr_complement_facelet_manual] Error getting local port information from cfg"); - return -1; - } - DEBUG(" - local port"); - facelet_set_local_port(facelet, local_port); - return 0; + if (!facelet_has_remote_port(facelet)) { + uint16_t remote_port; + int rc = facemgr_cfg_get_overlay_remote_port( + facemgr->cfg, &netdevice, netdevice_type, family, &remote_port); + if (rc < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error getting remote port " + "information from cfg"); + return -1; + } + DEBUG(" - remote port"); + facelet_set_remote_port(facelet, remote_port); + } + + /* + * Complementing local addr/port XXX this should be done somewhere + * else : manual settings have the lowest priority + * + * Local IP address is specific as it allows to override the source + * address just before creating the face... we would need to check + * whether this is an address that belong to us... it might be used + * to arbitrate amongst several IP addresses instead... + */ + ip_address_t local_addr; + if (facemgr_cfg_get_overlay_local_addr( + facemgr->cfg, &netdevice, netdevice_type, family, &local_addr) < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error getting local addr " + "information from cfg"); + return -1; + } + if (ip_address_empty(&local_addr)) { + ERROR( + "[facemgr_complement_facelet_manual] Got empty local addr information " + "from cfg"); + } else { + DEBUG(" - local addres"); + facelet_set_local_addr(facelet, local_addr); + } + + /* Sets a default local port, so far nobody sets it */ + uint16_t local_port; + if (facemgr_cfg_get_overlay_local_port( + facemgr->cfg, &netdevice, netdevice_type, family, &local_port) < 0) { + ERROR( + "[facemgr_complement_facelet_manual] Error getting local port " + "information from cfg"); + return -1; + } + DEBUG(" - local port"); + facelet_set_local_port(facelet, local_port); + return 0; } -int -facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet) -{ - int rc; +int facemgr_complement_facelet(facemgr_t *facemgr, facelet_t *facelet) { + int rc; - DEBUG("[facemgr_complement_facelet]"); - if (!facelet_has_key(facelet)) - return -2; - -#ifdef WITH_FACEMGR_UTILITY - rc = facemgr_complement_facelet_au(facemgr, facelet); - if (rc != -2) - return rc; -#endif /* WITH_FACEMGR_UTILITY */ + DEBUG("[facemgr_complement_facelet]"); + if (!facelet_has_key(facelet)) return -2; #if 0 if (!facelet_has_netdevice_type(facelet)) { @@ -988,51 +914,51 @@ facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet) */ #ifdef __linux__ - rc = facemgr_complement_facelet_bj(facemgr, facelet); - if (rc != -2) - return rc; + rc = facemgr_complement_facelet_bj(facemgr, facelet); + if (rc != -2) return rc; #endif /* __linux__ */ - DEBUG("[facemgr_complement_facelet] Complement manual"); + DEBUG("[facemgr_complement_facelet] Complement manual"); - rc = facemgr_complement_facelet_manual(facemgr, facelet); - if (rc != -2) - return rc; + rc = facemgr_complement_facelet_manual(facemgr, facelet); + if (rc != -2) return rc; - INFO("[facemgr_complement_facelet] No more interfaces to query... incomplete face"); - return 0; + INFO( + "[facemgr_complement_facelet] No more interfaces to query... incomplete " + "face"); + return 0; } -int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet) -{ - DEBUG("[facemgr_assign_face_type]"); - /* As key, netdevice and family should always be present */ - netdevice_t netdevice = NETDEVICE_EMPTY; - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) { - ERROR("[facemgr_assign_face_type] Error retrieving netdevice from facelet"); - return -1; - } - - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_FACEMGR_UTILITY - /* - * In addition to netdevice, netdevice_type should be present to correctly - * apply rules - */ - rc = facelet_get_netdevice_type(facelet, &netdevice_type); - if (rc < 0) { - ERROR("[facemgr_assign_face_type] Error retrieving netdevice_type from facelet"); - return -2; - } -#endif /* WITH_FACEMGR_UTILITY */ - - facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; - if (facemgr_cfg_get_face_type(facemgr->cfg, &netdevice, netdevice_type, &face_type) < 0) - return rc; - facelet_set_face_type(facelet, face_type); - DEBUG("[facemgr_assign_face_type] %s", FACEMGR_FACE_TYPE_STR(face_type)); - return 0; +int facemgr_assign_face_type(facemgr_t *facemgr, facelet_t *facelet) { + DEBUG("[facemgr_assign_face_type]"); + /* As key, netdevice and family should always be present */ + netdevice_t netdevice = NETDEVICE_EMPTY; + int rc = facelet_get_netdevice(facelet, &netdevice); + if (rc < 0) { + ERROR("[facemgr_assign_face_type] Error retrieving netdevice from facelet"); + return -1; + } + + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + /* + * In addition to netdevice, netdevice_type should be present to correctly + * apply rules + */ + rc = facelet_get_netdevice_type(facelet, &netdevice_type); + if (rc < 0) { + ERROR( + "[facemgr_assign_face_type] Error retrieving netdevice_type from " + "facelet"); + return -2; + } + + facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; + if (facemgr_cfg_get_face_type(facemgr->cfg, &netdevice, netdevice_type, + &face_type) < 0) + return rc; + facelet_set_face_type(facelet, face_type); + DEBUG("[facemgr_assign_face_type] %s", FACEMGR_FACE_TYPE_STR(face_type)); + return 0; } /* @@ -1041,102 +967,102 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet) * * We assume the facelet is already present in the cache */ -int -facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet) -{ - int rc; - facelet_error_reason_t reason = FACELET_ERROR_REASON_INTERNAL_ERROR; - - switch(facelet_get_status(facelet)) { - case FACELET_STATUS_UNCERTAIN: - /* - * All new faces are marked UNCERTAIN. We need to check whether we - * have sufficient information to check rules, if not proceed, - * otherwise possibly mark the face as IGNORED. Otherwise, we verify - * the completeness of the information we have, and continue towards - * being able to mark the face as CREATE. - */ - rc = facemgr_facelet_satisfy_rules(facemgr, facelet); - switch(rc) { - case -3: - /* Does not satisfy rules */ - DEBUG("[facemgr_process_facelet] Does not satisfy rules"); - facelet_set_status(facelet, FACELET_STATUS_IGNORED); - return 0; - - case -2: - DEBUG("[facemgr_process_facelet] Complementing facelet is required"); - if (facemgr_complement_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet] Error while attempting to complement face for fields required by face creation"); - goto ERR; - } - return 0; - - case 0: - /* Ok pass rules */ - break; - - default: - /* -1 - Error */ - goto ERR; - } - - if (facemgr_assign_face_type(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet] Could not assign face type"); - goto ERR; - } - facelet_set_status(facelet, FACELET_STATUS_INCOMPLETE); - /* Continue in case facelet satisfies rules */ - - case FACELET_STATUS_INCOMPLETE: - if (!facelet_validate_face(facelet)) { - /* We need additional information */ - if (facemgr_complement_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet] Error while attempting to complement face for fields required by face creation"); - goto ERR; - } - } - if (!facelet_validate_face(facelet)) - return 0; - - facelet_set_status(facelet, FACELET_STATUS_CREATE); - /* Continue in case we need to proceed to creation */ - - case FACELET_STATUS_CREATE: - facelet_set_event(facelet, FACELET_EVENT_CREATE); - rc = interface_on_event(facemgr->hl, facelet); - if (rc < 0) { - ERROR("[facemgr_process_facelet] Failed to create face"); - reason = -rc; - goto ERR; - } - - /* This works assuming the call to hicn-light is blocking */ - facelet_set_status(facelet, FACELET_STATUS_CLEAN); - break; +int facemgr_process_facelet(facemgr_t *facemgr, facelet_t *facelet) { + int rc; + facelet_error_reason_t reason = FACELET_ERROR_REASON_INTERNAL_ERROR; + + switch (facelet_get_status(facelet)) { + case FACELET_STATUS_UNCERTAIN: + /* + * All new faces are marked UNCERTAIN. We need to check whether we + * have sufficient information to check rules, if not proceed, + * otherwise possibly mark the face as IGNORED. Otherwise, we verify + * the completeness of the information we have, and continue towards + * being able to mark the face as CREATE. + */ + rc = facemgr_facelet_satisfy_rules(facemgr, facelet); + switch (rc) { + case -3: + /* Does not satisfy rules */ + DEBUG("[facemgr_process_facelet] Does not satisfy rules"); + facelet_set_status(facelet, FACELET_STATUS_IGNORED); + return 0; + + case -2: + DEBUG("[facemgr_process_facelet] Complementing facelet is required"); + if (facemgr_complement_facelet(facemgr, facelet) < 0) { + ERROR( + "[facemgr_process_facelet] Error while attempting to " + "complement face for fields required by face creation"); + goto ERR; + } + return 0; + case 0: + /* Ok pass rules */ + break; - case FACELET_STATUS_UPDATE: - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - rc = interface_on_event(facemgr->hl, facelet); - if (rc < 0) { - ERROR("[facemgr_process_facelet] Failed to update face"); - reason = -rc; - goto ERR; - } + default: + /* -1 - Error */ + goto ERR; + } - /* This works assuming the call to hicn-light is blocking */ - facelet_set_status(facelet, FACELET_STATUS_CLEAN); - break; - - case FACELET_STATUS_DELETE: - facelet_set_event(facelet, FACELET_EVENT_DELETE); - rc = interface_on_event(facemgr->hl, facelet); - if (rc < 0) { - ERROR("[facemgr_process_facelet] Failed to delete face"); - reason = -rc; - goto ERR; - } + if (facemgr_assign_face_type(facemgr, facelet) < 0) { + ERROR("[facemgr_process_facelet] Could not assign face type"); + goto ERR; + } + facelet_set_status(facelet, FACELET_STATUS_INCOMPLETE); + /* Continue in case facelet satisfies rules */ + + case FACELET_STATUS_INCOMPLETE: + if (!facelet_validate_face(facelet)) { + /* We need additional information */ + if (facemgr_complement_facelet(facemgr, facelet) < 0) { + ERROR( + "[facemgr_process_facelet] Error while attempting to complement " + "face for fields required by face creation"); + goto ERR; + } + } + if (!facelet_validate_face(facelet)) return 0; + + facelet_set_status(facelet, FACELET_STATUS_CREATE); + /* Continue in case we need to proceed to creation */ + + case FACELET_STATUS_CREATE: + facelet_set_event(facelet, FACELET_EVENT_CREATE); + rc = interface_on_event(facemgr->hl, facelet); + if (rc < 0) { + ERROR("[facemgr_process_facelet] Failed to create face"); + reason = -rc; + goto ERR; + } + + /* This works assuming the call to hicn-light is blocking */ + facelet_set_status(facelet, FACELET_STATUS_CLEAN); + break; + + case FACELET_STATUS_UPDATE: + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + rc = interface_on_event(facemgr->hl, facelet); + if (rc < 0) { + ERROR("[facemgr_process_facelet] Failed to update face"); + reason = -rc; + goto ERR; + } + + /* This works assuming the call to hicn-light is blocking */ + facelet_set_status(facelet, FACELET_STATUS_CLEAN); + break; + + case FACELET_STATUS_DELETE: + facelet_set_event(facelet, FACELET_EVENT_DELETE); + rc = interface_on_event(facemgr->hl, facelet); + if (rc < 0) { + ERROR("[facemgr_process_facelet] Failed to delete face"); + reason = -rc; + goto ERR; + } #if 0 if (facelet_get_id(facelet) > 0) { @@ -1147,111 +1073,102 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet) facelet_free(facelet); } else { #endif - /* This works assuming the call to hicn-light is blocking */ - DEBUG("[facemgr_process_facelet] Cleaning cached data"); - facelet_unset_local_addr(facelet); - facelet_unset_local_port(facelet); - if (facelet_get_id(facelet) == 0) { - facelet_unset_remote_addr(facelet); - facelet_unset_remote_port(facelet); - facelet_clear_routes(facelet); - } - - facelet_unset_admin_state(facelet); - facelet_unset_state(facelet); - facelet_unset_bj_done(facelet); -#ifdef WITH_FACEMGR_UTILITY - facelet_unset_au_done(facelet); -#endif /* WITH_FACEMGR_UTILITY */ - - facelet_set_status(facelet, FACELET_STATUS_DELETED); + /* This works assuming the call to hicn-light is blocking */ + DEBUG("[facemgr_process_facelet] Cleaning cached data"); + facelet_unset_local_addr(facelet); + facelet_unset_local_port(facelet); + if (facelet_get_id(facelet) == 0) { + facelet_unset_remote_addr(facelet); + facelet_unset_remote_port(facelet); + facelet_clear_routes(facelet); + } + + facelet_unset_admin_state(facelet); + facelet_unset_state(facelet); + facelet_unset_bj_done(facelet); + + facelet_set_status(facelet, FACELET_STATUS_DELETED); #if 0 } #endif - break; - - case FACELET_STATUS_CLEAN: - case FACELET_STATUS_IGNORED: - case FACELET_STATUS_DOWN: - case FACELET_STATUS_DELETED: - /* Nothing to do */ - break; - - case FACELET_STATUS_UNDEFINED: - case FACELET_STATUS_N: - ERROR("[facemgr_process_facelet] Unexpected facelet status"); - goto ERR; - } + break; - facelet_unset_error(facelet); - return 0; + case FACELET_STATUS_CLEAN: + case FACELET_STATUS_IGNORED: + case FACELET_STATUS_DOWN: + case FACELET_STATUS_DELETED: + /* Nothing to do */ + break; + + case FACELET_STATUS_UNDEFINED: + case FACELET_STATUS_N: + ERROR("[facemgr_process_facelet] Unexpected facelet status"); + goto ERR; + } + + facelet_unset_error(facelet); + return 0; ERR: - facelet_set_error(facelet, reason); - return -1; + facelet_set_error(facelet, reason); + return -1; } -int -facemgr_reattempt_timeout(facemgr_t * facemgr, int fd, void * data) -{ - bool has_error = false; +int facemgr_reattempt_timeout(facemgr_t *facemgr, int fd, void *data) { + bool has_error = false; - assert(data == NULL); + assert(data == NULL); - /* Free all facelets from cache */ - facelet_t ** facelet_array; - int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); - if (n < 0) { - ERROR("[facemgr_reattempt_timeout] Could not retrieve facelets in cache"); + /* Free all facelets from cache */ + facelet_t **facelet_array; + int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); + if (n < 0) { + ERROR("[facemgr_reattempt_timeout] Could not retrieve facelets in cache"); + has_error = true; + } else { + for (unsigned i = 0; i < n; i++) { + facelet_t *facelet = facelet_array[i]; + if (!facelet) continue; /* Should not occur */ + if (!facelet_get_error(facelet)) continue; + + char buf[MAXSZ_FACELET]; + facelet_snprintf(buf, MAXSZ_FACELET, facelet); + DEBUG("Reattempt to process failed facelet %s", buf); + if (facemgr_process_facelet(facemgr, facelet) < 0) { + ERROR("[facemgr_reattempt_timeout] Error processing facelet"); has_error = true; - } else { - for (unsigned i = 0; i < n; i++) { - facelet_t * facelet = facelet_array[i]; - - if (!facelet_get_error(facelet)) - continue; - - char buf[MAXSZ_FACELET]; - facelet_snprintf(buf, MAXSZ_FACELET, facelet); - DEBUG("Reattempt to process failed facelet %s", buf); - if (facemgr_process_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_reattempt_timeout] Error processing facelet"); - has_error = true; - continue; - } - facelet_unset_error(facelet); - } - free(facelet_array); + continue; + } + facelet_unset_error(facelet); } + free(facelet_array); + } - if (has_error) - return 0; + if (has_error) return 0; - DEBUG("Cancelling timer"); - if (facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_UNREGISTER_TIMER, &facemgr->timer_fd) < 0) { - ERROR("[facemgr_reattempt_timeout] Error unregistering reattempt timer"); - return -1; - } - facemgr->timer_fd = 0; - return 0; + DEBUG("Cancelling timer"); + if (facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_UNREGISTER_TIMER, + &facemgr->timer_fd) < 0) { + ERROR("[facemgr_reattempt_timeout] Error unregistering reattempt timer"); + return -1; + } + facemgr->timer_fd = 0; + return 0; } -int -facemgr_start_reattempts(facemgr_t * facemgr) -{ - if (facemgr->timer_fd > 0) - return 0; - - timer_callback_data_t timer_callback = { - .delay_ms = DEFAULT_REATTEMPT_DELAY_MS, - .owner = facemgr, - .callback = (fd_callback_t)facemgr_reattempt_timeout, - .data = NULL, - }; - facemgr->timer_fd = facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_REGISTER_TIMER, &timer_callback); - return (facemgr->timer_fd > 0); +int facemgr_start_reattempts(facemgr_t *facemgr) { + if (facemgr->timer_fd > 0) return 0; + + timer_callback_data_t timer_callback = { + .delay_ms = DEFAULT_REATTEMPT_DELAY_MS, + .owner = facemgr, + .callback = (fd_callback_t)facemgr_reattempt_timeout, + .data = NULL, + }; + facemgr->timer_fd = facemgr->callback( + facemgr->callback_owner, FACEMGR_CB_TYPE_REGISTER_TIMER, &timer_callback); + return (facemgr->timer_fd > 0); } /** @@ -1261,218 +1178,226 @@ facemgr_start_reattempts(facemgr_t * facemgr) * \return 0 if everything went correctly, or -1 in case of error. * -2 means we ignored the face purposedly */ -int -facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet) -{ - char facelet_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); - DEBUG("[facemgr_process_facelet_create] %s", facelet_s); - switch(facelet_get_status(facelet)) { - case FACELET_STATUS_UNCERTAIN: - case FACELET_STATUS_INCOMPLETE: - case FACELET_STATUS_CREATE: - /* No change */ - DEBUG("[facemgr_process_facelet_create] UNCHANGED STATUS"); - break; - case FACELET_STATUS_UPDATE: - case FACELET_STATUS_DELETE: - /* - * Unlikely. The face had been created and is planned to - * be deleted. Schedule for creation (we should have all - * needed information), but make sure to handle errors - * correctly if the face is still present. - * TODO What if some fields have been updated ? - */ - DEBUG("[facemgr_process_facelet_create] SET STATUS TO CREATE"); - facelet_set_status(facelet, FACELET_STATUS_CREATE); - break; - case FACELET_STATUS_CLEAN: - case FACELET_STATUS_IGNORED: - /* - * We should have nothing to do unless some fields have - * been updated. - */ - DEBUG("[facemgr_process_facelet_create] NOTHING TO DO"); - break; - - case FACELET_STATUS_DOWN: - case FACELET_STATUS_DELETED: - /* - * Unless rules have changed, we only need to recover - * missing information, and proceed to face creation. - * Rule changes should be handled separately. - */ - DEBUG("[facemgr_process_facelet_create] SET STATUS TO INCOMPLETE"); - facelet_set_status(facelet, FACELET_STATUS_INCOMPLETE); - break; - case FACELET_STATUS_UNDEFINED: - case FACELET_STATUS_N: - ERROR("[facemgr_process_facelet_create] Unexpected facelet status"); - return -1; - } - - - DEBUG("[facemgr_process_facelet_create] Processing facelet"); - if (facemgr_process_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet_create] Error processing facelet"); - return -1; - } +int facemgr_process_facelet_create(facemgr_t *facemgr, facelet_t *facelet) { + char facelet_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); + DEBUG("[facemgr_process_facelet_create] %s", facelet_s); + switch (facelet_get_status(facelet)) { + case FACELET_STATUS_UNCERTAIN: + case FACELET_STATUS_INCOMPLETE: + case FACELET_STATUS_CREATE: + /* No change */ + DEBUG("[facemgr_process_facelet_create] UNCHANGED STATUS"); + break; + case FACELET_STATUS_UPDATE: + case FACELET_STATUS_DELETE: + /* + * Unlikely. The face had been created and is planned to + * be deleted. Schedule for creation (we should have all + * needed information), but make sure to handle errors + * correctly if the face is still present. + * TODO What if some fields have been updated ? + */ + DEBUG("[facemgr_process_facelet_create] SET STATUS TO CREATE"); + facelet_set_status(facelet, FACELET_STATUS_CREATE); + break; + case FACELET_STATUS_CLEAN: + case FACELET_STATUS_IGNORED: + /* + * We should have nothing to do unless some fields have + * been updated. + */ + DEBUG("[facemgr_process_facelet_create] NOTHING TO DO"); + break; + + case FACELET_STATUS_DOWN: + case FACELET_STATUS_DELETED: + /* + * Unless rules have changed, we only need to recover + * missing information, and proceed to face creation. + * Rule changes should be handled separately. + */ + DEBUG("[facemgr_process_facelet_create] SET STATUS TO INCOMPLETE"); + facelet_set_status(facelet, FACELET_STATUS_INCOMPLETE); + break; + case FACELET_STATUS_UNDEFINED: + case FACELET_STATUS_N: + ERROR("[facemgr_process_facelet_create] Unexpected facelet status"); + return -1; + } + + DEBUG("[facemgr_process_facelet_create] Processing facelet"); + if (facemgr_process_facelet(facemgr, facelet) < 0) { + ERROR("[facemgr_process_facelet_create] Error processing facelet"); + return -1; + } - return 0; + return 0; } /* * \return 0 in case of success and no static facelet was added, 1 if a static * facelet was added, and -1 in case of error. */ -int -facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet) -{ - /* - * We need to analyze the facelet and eventually: - * - add it in our static list - * - replicate it on multipath interfaces - */ - netdevice_type_t netdevice_type; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) - return -1; - - if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || - (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) - return 0; - - if ((facelet_get_route_array(facelet, NULL) == 0)) - return 0; - - /* - * How to differenciate facelet created by face manager from user - * created ones ? This cannot be a flag in the facelet as it needs - * to work across restarts of the face manager... - * Also we might have two default routes. - * - * TODO: - * - The static one should not be a duplicate of the one we would - * create by default.... - * - This should anyways be detected... - * - * One solution would be to install the default ones as static but - * this requires to implement a priority scheme between some of the - * static routes so that the override mechanism continues to work as - * usual. - * - * Current, we recognize the routes created by default by the face - * maanger thanks to the routing prefixes (a single default route). - */ - - facelet_t * static_facelet = facelet_dup(facelet); - facelet_set_event(static_facelet, FACELET_EVENT_CREATE); - facelet_unset_netdevice(static_facelet); - facelet_unset_netdevice_type(static_facelet); - facelet_unset_local_addr(static_facelet); - facelet_unset_local_port(static_facelet); - - facelet_t * facelet_found = NULL; - if (facelet_array_get(facemgr->static_facelets, static_facelet, &facelet_found) < 0) { - ERROR("[facemgr_consider_static_facelet] Error checking whether static facelet already exists or not"); - return -1; - } +int facemgr_consider_static_facelet(facemgr_t *facemgr, facelet_t *facelet) { + /* + * We need to analyze the facelet and eventually: + * - add it in our static list + * - replicate it on multipath interfaces + */ + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) return -1; + + if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || + (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) + return 0; - /* Skip addition if facelet exists */ - if (facelet_found) - return 0; + if ((facelet_get_route_array(facelet, NULL) == 0)) return 0; + + /* + * How to differenciate facelet created by face manager from user + * created ones ? This cannot be a flag in the facelet as it needs + * to work across restarts of the face manager... + * Also we might have two default routes. + * + * TODO: + * - The static one should not be a duplicate of the one we would + * create by default.... + * - This should anyways be detected... + * + * One solution would be to install the default ones as static but + * this requires to implement a priority scheme between some of the + * static routes so that the override mechanism continues to work as + * usual. + * + * Current, we recognize the routes created by default by the face + * maanger thanks to the routing prefixes (a single default route). + */ + + facelet_t *static_facelet = facelet_dup(facelet); + facelet_set_event(static_facelet, FACELET_EVENT_CREATE); + facelet_unset_netdevice(static_facelet); + facelet_unset_netdevice_type(static_facelet); + facelet_unset_local_addr(static_facelet); + facelet_unset_local_port(static_facelet); + + facelet_t *facelet_found = NULL; + if (facelet_array_get(facemgr->static_facelets, static_facelet, + &facelet_found) < 0) { + ERROR( + "[facemgr_consider_static_facelet] Error checking whether static " + "facelet already exists or not"); + return -1; + } - facemgr->cur_static_id++; + /* Skip addition if facelet exists */ + if (facelet_found) return 0; - facelet_set_id(static_facelet, facemgr->cur_static_id); - facelet_set_id(facelet, facemgr->cur_static_id); + facemgr->cur_static_id++; - if (facelet_array_add(facemgr->static_facelets, static_facelet) < 0) { - ERROR("[facemgr_consider_static_facelet] Could not add facelet to static array"); - facelet_free(static_facelet); - return -1; - } + facelet_set_id(static_facelet, facemgr->cur_static_id); + facelet_set_id(facelet, facemgr->cur_static_id); - char facelet_s[MAXSZ_FACELET]; - int rc = facelet_snprintf(facelet_s, MAXSZ_FACELET, static_facelet); - if (rc >= MAXSZ_FACELET) - ERROR("[facemgr_consider_static_facelet] Unexpected truncation of facelet string"); - if (rc < 0) - ERROR("[facemgr_consider_static_facelet] Error during facelet string output"); - DEBUG("[facemgr_consider_static_facelet] Successfully added facelet to static array %s", facelet_s); + if (facelet_array_add(facemgr->static_facelets, static_facelet) < 0) { + ERROR( + "[facemgr_consider_static_facelet] Could not add facelet to static " + "array"); + facelet_free(static_facelet); + return -1; + } + + char facelet_s[MAXSZ_FACELET]; + int rc = facelet_snprintf(facelet_s, MAXSZ_FACELET, static_facelet); + if (rc >= MAXSZ_FACELET) + ERROR( + "[facemgr_consider_static_facelet] Unexpected truncation of facelet " + "string"); + if (rc < 0) + ERROR( + "[facemgr_consider_static_facelet] Error during facelet string output"); + DEBUG( + "[facemgr_consider_static_facelet] Successfully added facelet to static " + "array %s", + facelet_s); #if 1 - /* Force application of the static face on all existing interfaces */ - facelet_t ** facelet_array; - int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); - if (n >= 0) { - for (unsigned i = 0; i < n; i++) { - facelet_t * cached_facelet = facelet_array[i]; - - netdevice_type_t netdevice_type; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - ERROR("[facemgr_consider_static_facelet] Error retrieving netdevice type from cached facelet"); - continue; - } - if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) - continue; - - facelet_t * new_facelet = facelet_dup(cached_facelet); - facelet_unset_remote_addr(new_facelet); - facelet_unset_remote_port(new_facelet); - facelet_unset_admin_state(new_facelet); - facelet_unset_state(new_facelet); - facelet_unset_bj_done(new_facelet); - facelet_clear_routes(new_facelet); -#ifdef WITH_FACEMGR_UTILITY - facelet_unset_au_done(new_facelet); -#endif /* WITH_FACEMGR_UTILITY */ - - /* We try to apply static_facelet over facelet */ - if (!facelet_match(new_facelet, static_facelet)) { - facelet_free(new_facelet); - continue; - } - - if (facelet_merge(new_facelet, static_facelet) < 0) { - ERROR("[facemgr_consider_static_facelet] Error merging facelets"); - facelet_free(new_facelet); - continue; - } - - /* - * We need to set the id before checking for existence as tuple used - * is (id, netdevice, family) - */ - facelet_set_id(new_facelet, facemgr->cur_static_id); - - facelet_found = NULL; - if (facelet_set_get(facemgr->facelet_cache, new_facelet, &facelet_found) < 0) { - ERROR("[facemgr_consider_static_facelet] Error checking whether new static facelet already exists or not"); - continue; - } - - - /* Skip addition if facelet exists */ - if (facelet_found) { - facelet_free(new_facelet); - continue; - } - - facelet_set_attr_clean(new_facelet); - facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); - - if (facemgr_on_event(facemgr, new_facelet) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error creating static facelet for existing face"); - continue; - } - - INFO("Successfully created static facelet for existing face"); - } - free(facelet_array); + /* Force application of the static face on all existing interfaces */ + facelet_t **facelet_array; + int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); + if (n >= 0) { + for (unsigned i = 0; i < n; i++) { + facelet_t *cached_facelet = facelet_array[i]; + if (!cached_facelet) continue; /* Should not occur */ + + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR( + "[facemgr_consider_static_facelet] Error retrieving netdevice type " + "from cached facelet"); + continue; + } + if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || + (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) + continue; + + facelet_t *new_facelet = facelet_dup(cached_facelet); + facelet_unset_remote_addr(new_facelet); + facelet_unset_remote_port(new_facelet); + facelet_unset_admin_state(new_facelet); + facelet_unset_state(new_facelet); + facelet_unset_bj_done(new_facelet); + facelet_clear_routes(new_facelet); + + /* We try to apply static_facelet over facelet */ + if (!facelet_match(new_facelet, static_facelet)) { + facelet_free(new_facelet); + continue; + } + + if (facelet_merge(new_facelet, static_facelet) < 0) { + ERROR("[facemgr_consider_static_facelet] Error merging facelets"); + facelet_free(new_facelet); + continue; + } + + /* + * We need to set the id before checking for existence as tuple used + * is (id, netdevice, family) + */ + facelet_set_id(new_facelet, facemgr->cur_static_id); + + facelet_found = NULL; + if (facelet_set_get(facemgr->facelet_cache, new_facelet, &facelet_found) < + 0) { + ERROR( + "[facemgr_consider_static_facelet] Error checking whether new " + "static facelet already exists or not"); + continue; + } + + /* Skip addition if facelet exists */ + if (facelet_found) { + facelet_free(new_facelet); + continue; + } + + facelet_set_attr_clean(new_facelet); + facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); + + if (facemgr_on_event(facemgr, new_facelet) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error creating static " + "facelet for existing face"); + continue; + } + + INFO("Successfully created static facelet for existing face"); } + free(facelet_array); + } #endif - return 1; + return 1; } /** @@ -1482,93 +1407,96 @@ facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet) * \return 0 if everything went correctly, or -1 in case of error. * -2 means we ignored the face purposedly */ -int -facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet) -{ - assert(facelet); +int facemgr_process_facelet_get(facemgr_t *facemgr, facelet_t *facelet) { + assert(facelet); - if (!facelet_has_netdevice(facelet)) - return -2; + if (!facelet_has_netdevice(facelet)) return -2; - netdevice_t netdevice; - if (facelet_get_netdevice(facelet, &netdevice) < 0) - return -1; - if (!IS_VALID_NETDEVICE(netdevice)) - return -2; + netdevice_t netdevice; + if (facelet_get_netdevice(facelet, &netdevice) < 0) return -1; + if (!IS_VALID_NETDEVICE(netdevice)) return -2; - facelet_set_status(facelet, FACELET_STATUS_CLEAN); + facelet_set_status(facelet, FACELET_STATUS_CLEAN); - /* Skip if face exists */ - int n = facelet_cache_lookup(facemgr->facelet_cache, facelet, NULL); - if (n < 0) { - ERROR("[facemgr_process_facelet_get] Error during cache lookup"); - return -1; - } - assert (n <= 1); - if (n > 0) - return 0; - - /* Process untagged faces */ - netdevice_type_t netdevice_type; + /* Skip if face exists */ + int n = facelet_cache_lookup(facemgr->facelet_cache, facelet, NULL); + if (n < 0) { + ERROR("[facemgr_process_facelet_get] Error during cache lookup"); + return -1; + } + assert(n <= 1); + if (n > 0) return 0; + + /* Process untagged faces */ + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + facelet_set_netdevice_type( + facelet, facemgr_get_netdevice_type(facemgr, netdevice.name)); if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - facelet_set_netdevice_type(facelet, facemgr_get_netdevice_type(facemgr, netdevice.name)); - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - /* Inspect local address */ - int family; - ip_address_t local; - if (facelet_get_family(facelet, &family) < 0) { - ERROR("[facemgr_process_facelet_get] Error getting facelet family"); - return -1; - } - if (facelet_get_local_addr(facelet, &local) < 0) { - ERROR("[facemgr_process_facelet_get] Error getting facelet local address"); - return -1; - } - switch(family) { - case AF_INET: - if (ip_address_cmp(&local, &IPV4_LOOPBACK, family) == 0) { - facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK); - } else { - return -2; - } - break; - case AF_INET6: - if (ip_address_cmp(&local, &IPV6_LOOPBACK, family) == 0) { - facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK); - } else { - return -2; - } - break; - default: - return -2; - } - } - - if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) - return 0; - - if (facemgr_process_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet_get] Error processing facelet"); - return -1; - } - } - - if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) - return 0; - - if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) { - ERROR("[facemgr_process_facelet_get] Error adding received facelet to cache"); + /* Inspect local address */ + int family; + ip_address_t local; + if (facelet_get_family(facelet, &family) < 0) { + ERROR("[facemgr_process_facelet_get] Error getting facelet family"); return -1; + } + if (facelet_get_local_addr(facelet, &local) < 0) { + ERROR( + "[facemgr_process_facelet_get] Error getting facelet local " + "address"); + return -1; + } + switch (family) { + case AF_INET: + if (ip_address_cmp(&local, &IPV4_LOOPBACK, family) == 0) { + facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK); + } else { + return -2; + } + break; + case AF_INET6: + if (ip_address_cmp(&local, &IPV6_LOOPBACK, family) == 0) { + facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK); + } else { + return -2; + } + break; + default: + return -2; + } } - n = facemgr_consider_static_facelet(facemgr, facelet); - if (n < 0) { - ERROR("[facemgr_process_facelet_get] Could not add facelet to static array"); - return -1; + if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || + (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) + return -2; + + if (facemgr_process_facelet(facemgr, facelet) < 0) { + ERROR("[facemgr_process_facelet_get] Error processing facelet"); + return -1; } + } + if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || + (netdevice_type == NETDEVICE_TYPE_LOOPBACK)) + return -2; - return 0; + if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) { + ERROR( + "[facemgr_process_facelet_get] Error adding received facelet to cache"); + return -1; + } + + /* + * From there, don't raise errors otherwise the facelet just added to cache + * will be freed + */ + n = facemgr_consider_static_facelet(facemgr, facelet); + if (n < 0) { + ERROR( + "[facemgr_process_facelet_get] Could not add facelet to static array"); + } + + return 0; } /** @@ -1578,45 +1506,43 @@ facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet) * \return 0 if everything went correctly, or -1 in case of error. * -2 means we ignored the face purposedly */ -int -facemgr_process_facelet_update(facemgr_t * facemgr, facelet_t * facelet) -{ - char facelet_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); - DEBUG("[facemgr_process_facelet_update] %s", facelet_s); - switch(facelet_get_status(facelet)) { - case FACELET_STATUS_UNCERTAIN: - case FACELET_STATUS_INCOMPLETE: - case FACELET_STATUS_CREATE: - case FACELET_STATUS_UPDATE: - /* No change */ - DEBUG("[facemgr_process_facelet_update] UNCHANGED STATUS"); - break; - case FACELET_STATUS_CLEAN: - DEBUG("[facemgr_process_facelet_update] SET STATUS TO UPDATE"); - facelet_set_status(facelet, FACELET_STATUS_UPDATE); - break; - case FACELET_STATUS_DOWN: - case FACELET_STATUS_DELETE: - case FACELET_STATUS_DELETED: - case FACELET_STATUS_IGNORED: - /* Reconsider face creation in light of new information */ - DEBUG("[facemgr_process_facelet_update] SET STATUS TO UNCERTAIN"); - facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN); - break; - case FACELET_STATUS_UNDEFINED: - case FACELET_STATUS_N: - ERROR("[facemgr_process_facelet_update] Unexpected facelet status"); - return -1; - } - - DEBUG("[facemgr_process_facelet_update] Processing facelet"); - if (facemgr_process_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet_update] Error processing facelet"); - return -1; - } +int facemgr_process_facelet_update(facemgr_t *facemgr, facelet_t *facelet) { + char facelet_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); + DEBUG("[facemgr_process_facelet_update] %s", facelet_s); + switch (facelet_get_status(facelet)) { + case FACELET_STATUS_UNCERTAIN: + case FACELET_STATUS_INCOMPLETE: + case FACELET_STATUS_CREATE: + case FACELET_STATUS_UPDATE: + /* No change */ + DEBUG("[facemgr_process_facelet_update] UNCHANGED STATUS"); + break; + case FACELET_STATUS_CLEAN: + DEBUG("[facemgr_process_facelet_update] SET STATUS TO UPDATE"); + facelet_set_status(facelet, FACELET_STATUS_UPDATE); + break; + case FACELET_STATUS_DOWN: + case FACELET_STATUS_DELETE: + case FACELET_STATUS_DELETED: + case FACELET_STATUS_IGNORED: + /* Reconsider face creation in light of new information */ + DEBUG("[facemgr_process_facelet_update] SET STATUS TO UNCERTAIN"); + facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN); + break; + case FACELET_STATUS_UNDEFINED: + case FACELET_STATUS_N: + ERROR("[facemgr_process_facelet_update] Unexpected facelet status"); + return -1; + } + + DEBUG("[facemgr_process_facelet_update] Processing facelet"); + if (facemgr_process_facelet(facemgr, facelet) < 0) { + ERROR("[facemgr_process_facelet_update] Error processing facelet"); + return -1; + } - return 0; + return 0; } /** @@ -1626,15 +1552,13 @@ facemgr_process_facelet_update(facemgr_t * facemgr, facelet_t * facelet) * \return 0 if everything went correctly, or -1 in case of error. * -2 means we ignored the face purposedly */ -int -facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet) -{ - switch(facelet_get_status(facelet)) { - case FACELET_STATUS_UNCERTAIN: - case FACELET_STATUS_INCOMPLETE: - case FACELET_STATUS_IGNORED: - case FACELET_STATUS_DOWN: - case FACELET_STATUS_CREATE: +int facemgr_process_facelet_delete(facemgr_t *facemgr, facelet_t *facelet) { + switch (facelet_get_status(facelet)) { + case FACELET_STATUS_UNCERTAIN: + case FACELET_STATUS_INCOMPLETE: + case FACELET_STATUS_IGNORED: + case FACELET_STATUS_DOWN: + case FACELET_STATUS_CREATE: #if 0 /* Facelets created from static get deleted */ if (facelet_get_id(facelet) > 0) { @@ -1645,142 +1569,159 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet) facelet_free(facelet); } else { #endif - /* Face has not been created */ - DEBUG("[facemgr_process_facelet] Cleaning cached data"); - facelet_unset_local_addr(facelet); - facelet_unset_local_port(facelet); - if (facelet_get_id(facelet) == 0) { - facelet_unset_remote_addr(facelet); - facelet_unset_remote_port(facelet); - facelet_clear_routes(facelet); - } - facelet_unset_admin_state(facelet); - facelet_unset_state(facelet); - facelet_unset_bj_done(facelet); -#ifdef WITH_FACEMGR_UTILITY - facelet_unset_au_done(facelet); -#endif /* WITH_FACEMGR_UTILITY */ - facelet_unset_error(facelet); - facelet_set_status(facelet, FACELET_STATUS_DELETED); + /* Face has not been created */ + DEBUG("[facemgr_process_facelet] Cleaning cached data"); + facelet_unset_local_addr(facelet); + facelet_unset_local_port(facelet); + if (facelet_get_id(facelet) == 0) { + facelet_unset_remote_addr(facelet); + facelet_unset_remote_port(facelet); + facelet_clear_routes(facelet); + } + facelet_unset_admin_state(facelet); + facelet_unset_state(facelet); + facelet_unset_bj_done(facelet); + facelet_unset_error(facelet); + facelet_set_status(facelet, FACELET_STATUS_DELETED); #if 0 } #endif - break; - - case FACELET_STATUS_UPDATE: - case FACELET_STATUS_CLEAN: - facelet_set_status(facelet, FACELET_STATUS_DELETE); - if (facemgr_process_facelet(facemgr, facelet) < 0) { - ERROR("[facemgr_process_facelet_delete] Error processing facelet"); - return -1; - } - break; + break; - case FACELET_STATUS_DELETE: - case FACELET_STATUS_DELETED: - /* Nothing to do */ - break; + case FACELET_STATUS_UPDATE: + case FACELET_STATUS_CLEAN: + facelet_set_status(facelet, FACELET_STATUS_DELETE); + if (facemgr_process_facelet(facemgr, facelet) < 0) { + ERROR("[facemgr_process_facelet_delete] Error processing facelet"); + return -1; + } + break; - case FACELET_STATUS_UNDEFINED: - case FACELET_STATUS_N: - ERROR("[facemgr_process_facelet_delete] Unexpected facelet status"); - return -1; - } + case FACELET_STATUS_DELETE: + case FACELET_STATUS_DELETED: + /* Nothing to do */ + break; - return 0; -} + case FACELET_STATUS_UNDEFINED: + case FACELET_STATUS_N: + ERROR("[facemgr_process_facelet_delete] Unexpected facelet status"); + return -1; + } -int -facemgr_process_facelet_create_no_family(facemgr_t * facemgr, facelet_t * facelet) -{ + return 0; +} +int facemgr_process_facelet_create_no_family(facemgr_t *facemgr, + facelet_t *facelet) { #ifdef WITH_DEFAULT_PRIORITIES - /* Assign default priority based on face type */ - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error getting netdevice_type: no default priority set."); - goto ERR_PRIORITY; - } - if (facelet_set_priority(facelet, facemgr->default_priority[netdevice_type]) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error setting default priority"); - } + /* Assign default priority based on face type */ + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error getting " + "netdevice_type: no default priority set."); + goto ERR_PRIORITY; + } + if (facelet_set_priority(facelet, facemgr->default_priority[netdevice_type]) < + 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error setting default " + "priority"); + } ERR_PRIORITY: #endif /* WITH_DEFAULT_PRIORITIES */ - DEBUG("[facemgr_process_facelet_create_no_family] Default v4"); - /* Create default v4 and v6 facelets */ - facelet_t * facelet_v4 = facelet_dup(facelet); - if (!facelet_v4) { - ERROR("[facemgr_process_facelet_create_no_family] Error allocating default IPv4 face"); - } else { - facelet_set_family(facelet_v4, AF_INET); - facelet_set_attr_clean(facelet_v4); - if (facemgr_on_event(facemgr, facelet_v4) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv4 face"); - //facelet_free(facelet_v4); - } - } - - DEBUG("[facemgr_process_facelet_create_no_family] Default v6"); - facelet_t * facelet_v6 = facelet_dup(facelet); - if (!facelet_v6) { - ERROR("[facemgr_process_facelet_create_no_family] Error allocating default IPv6 face"); - } else { - facelet_set_family(facelet_v6, AF_INET6); - facelet_set_attr_clean(facelet_v6); - if (facemgr_on_event(facemgr, facelet_v6) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv6 face"); - //facelet_free(facelet_v6); - } + DEBUG("[facemgr_process_facelet_create_no_family] Default v4"); + /* Create default v4 and v6 facelets */ + facelet_t *facelet_v4 = facelet_dup(facelet); + if (!facelet_v4) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error allocating default " + "IPv4 face"); + } else { + facelet_set_family(facelet_v4, AF_INET); + facelet_set_attr_clean(facelet_v4); + if (facemgr_on_event(facemgr, facelet_v4) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error creating default " + "IPv4 face"); + // facelet_free(facelet_v4); + } + } + + DEBUG("[facemgr_process_facelet_create_no_family] Default v6"); + facelet_t *facelet_v6 = facelet_dup(facelet); + if (!facelet_v6) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error allocating default " + "IPv6 face"); + } else { + facelet_set_family(facelet_v6, AF_INET6); + facelet_set_attr_clean(facelet_v6); + if (facemgr_on_event(facemgr, facelet_v6) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error creating default " + "IPv6 face"); + // facelet_free(facelet_v6); + } + } + + /* Create additional connections + * + * This is where we spawn multiple facelets based on the + * configured "static routes" in addition to the default + * routes managed by the face manager. + */ + DEBUG("[facemgr_process_facelet_create_no_family] Loop static"); + for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) { + facelet_t *static_facelet; + if (facelet_array_get_index(facemgr->static_facelets, i, &static_facelet) < + 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error getting static " + "facelet"); + continue; } - /* Create additional connections - * - * This is where we spawn multiple facelets based on the - * configured "static routes" in addition to the default - * routes managed by the face manager. + /* + * We don't enforce any present or absent fields. A match + * operation will be performed deciding whether to create + * the facelet (if it bring additional information to the + * ingress one) or not. */ - DEBUG("[facemgr_process_facelet_create_no_family] Loop static"); - for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) { - facelet_t * static_facelet; - if (facelet_array_get_index(facemgr->static_facelets, i, &static_facelet) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error getting static facelet"); - continue; - } - - /* - * We don't enforce any present or absent fields. A match - * operation will be performed deciding whether to create - * the facelet (if it bring additional information to the - * ingress one) or not. - */ - /* We try to apply static_facelet over facelet */ - if (!facelet_match(facelet, static_facelet)) { - continue; - } - - facelet_t * facelet_new = facelet_dup(facelet); - if (!facelet_new) { - ERROR("[facemgr_process_facelet_create_no_family] Error allocating static facelet"); - continue; - } else { - if (facelet_merge(facelet_new, static_facelet) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error merging facelets"); - facelet_free(facelet_new); - continue; - } - facelet_set_id(facelet_new, facelet_get_id(static_facelet)); - facelet_set_attr_clean(facelet_new); - facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); - - if (facemgr_on_event(facemgr, facelet_new) < 0) { - ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv6 face"); - //facelet_free(facelet_new); - } - } + /* We try to apply static_facelet over facelet */ + if (!facelet_match(facelet, static_facelet)) { + continue; } - return 0; + facelet_t *facelet_new = facelet_dup(facelet); + if (!facelet_new) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error allocating static " + "facelet"); + continue; + } else { + if (facelet_merge(facelet_new, static_facelet) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error merging " + "facelets"); + facelet_free(facelet_new); + continue; + } + facelet_set_id(facelet_new, facelet_get_id(static_facelet)); + facelet_set_attr_clean(facelet_new); + facelet_set_status(facelet, FACELET_STATUS_UNDEFINED); + + if (facemgr_on_event(facemgr, facelet_new) < 0) { + ERROR( + "[facemgr_process_facelet_create_no_family] Error creating default " + "IPv6 face"); + // facelet_free(facelet_new); + } + } + } + + return 0; } /** @@ -1790,30 +1731,29 @@ ERR_PRIORITY: * - Any event or timeout due to an interface triggers either a local cache * update, as well a face operations needed to resync the state. */ -int -facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in) -{ - bool remove_facelet = true; +int facemgr_on_event(facemgr_t *facemgr, facelet_t *facelet_in) { + bool remove_facelet = true; #if WITH_DUMP - bool dump = true; + bool dump = true; #endif /* WITH_DUMP */ - int ret = 0; - int rc; - assert(facelet_in); - - /* Update Netdevice type */ - if ((facelet_get_event(facelet_in) != FACELET_EVENT_GET) && - facelet_has_netdevice(facelet_in) && - (!facelet_has_netdevice_type(facelet_in))) { - netdevice_t netdevice = NETDEVICE_EMPTY; + int ret = 0; + int rc; + assert(facelet_in); + + /* Update Netdevice type */ + if ((facelet_get_event(facelet_in) != FACELET_EVENT_GET) && + facelet_has_netdevice(facelet_in) && + (!facelet_has_netdevice_type(facelet_in))) { + netdevice_t netdevice = NETDEVICE_EMPTY; - rc = facelet_get_netdevice(facelet_in, &netdevice); - if (rc < 0) { - ERROR("[facemgr_on_event] Error retrieving netdevice from facelet"); - return -1; - } - facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name)); + rc = facelet_get_netdevice(facelet_in, &netdevice); + if (rc < 0) { + ERROR("[facemgr_on_event] Error retrieving netdevice from facelet"); + return -1; } + facelet_set_netdevice_type( + facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name)); + } #if 0 netdevice_type_t netdevice_type; @@ -1826,656 +1766,660 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in) return 0; #endif - char facelet_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in); + char facelet_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in); - facelet_t ** cached_facelets = NULL; - assert(facelet_in); + facelet_t **cached_facelets = NULL; + assert(facelet_in); - if (facelet_get_status(facelet_in) == FACELET_STATUS_UNDEFINED) { - facelet_set_status(facelet_in, FACELET_STATUS_UNCERTAIN); - } + if (facelet_get_status(facelet_in) == FACELET_STATUS_UNDEFINED) { + facelet_set_status(facelet_in, FACELET_STATUS_UNCERTAIN); + } - int n = facelet_cache_lookup(facemgr->facelet_cache, facelet_in, &cached_facelets); - if (n < 0) { - ERROR("[facemgr_on_event] Error during cache lookup"); - free(facelet_in); - return -1; - } - if (n == 0) { - /* This is a new facelet... we expect a CREATE event. */ - switch(facelet_get_event(facelet_in)) { - case FACELET_EVENT_CREATE: - { - /* - * This is the first time we hear about a facelet, it will - * likely not have an address family - * - * Assumption: we should always see the link before the address - * assignment - */ - DEBUG("[facemgr_on_event] CREATE NEW %s", facelet_s); - - if (!facelet_has_family(facelet_in)) { - facemgr_assign_face_type(facemgr, facelet_in); - if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error processing new interface event"); - goto ERR; - } - goto DUMP_CACHE; - } + int n = facelet_cache_lookup(facemgr->facelet_cache, facelet_in, + &cached_facelets); + if (n < 0) { + ERROR("[facemgr_on_event] Error during cache lookup"); + free(facelet_in); + return -1; + } + if (n == 0) { + /* This is a new facelet... we expect a CREATE event. */ + switch (facelet_get_event(facelet_in)) { + case FACELET_EVENT_CREATE: { + /* + * This is the first time we hear about a facelet, it will + * likely not have an address family + * + * Assumption: we should always see the link before the address + * assignment + */ + DEBUG("[facemgr_on_event] CREATE NEW %s", facelet_s); - if (facelet_set_add(facemgr->facelet_cache, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error adding facelet to cache"); - goto ERR; - } + if (!facelet_has_family(facelet_in)) { + facemgr_assign_face_type(facemgr, facelet_in); + if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < + 0) { + ERROR("[facemgr_on_event] Error processing new interface event"); + goto ERR; + } + goto DUMP_CACHE; + } - if (facemgr_process_facelet_create(facemgr, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error processing facelet CREATE event"); - ret = -1; - } + if (facelet_set_add(facemgr->facelet_cache, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error adding facelet to cache"); + goto ERR; + } - remove_facelet = false; + if (facemgr_process_facelet_create(facemgr, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error processing facelet CREATE event"); + ret = -1; + } - break; - } + remove_facelet = false; - case FACELET_EVENT_GET: - /* Insert new facelet in cached */ - //DEBUG("[facemgr_on_event] GET NEW %s", facelet_s); - rc = facemgr_process_facelet_get(facemgr, facelet_in); - if (rc == 0) - remove_facelet = false; + break; + } + + case FACELET_EVENT_GET: + /* Insert new facelet in cached */ + // DEBUG("[facemgr_on_event] GET NEW %s", facelet_s); + rc = facemgr_process_facelet_get(facemgr, facelet_in); + if (rc == 0) remove_facelet = false; #if WITH_DUMP - dump = false; + dump = false; #endif - if (rc == -1) { - ERROR("[facemgr_on_event] Error processing GET event"); - goto ERR; - } - break; + if (rc == -1) { + ERROR("[facemgr_on_event] Error processing GET event"); + goto ERR; + } + break; - case FACELET_EVENT_UPDATE: - /* Might be because we previously ignored the facelet... */ - //ERROR("[facemgr_on_event] Unexpected UPDATE... face does not exist"); - //goto ERR; + case FACELET_EVENT_UPDATE: + /* Might be because we previously ignored the facelet... */ + // ERROR("[facemgr_on_event] Unexpected UPDATE... face does not exist"); + // goto ERR; #ifdef WITH_DEFAULT_PRIORITIES - if (facelet_has_netdevice_type(facelet_in) && !facelet_has_netdevice(facelet_in) && facelet_has_priority(facelet_in)) { - /* Remember last priority choice for newly created facelets */ - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; - u32 priority = 0; - if (facelet_get_netdevice_type(facelet_in, &netdevice_type) < 0) { - ERROR("[facelet_on_event] Error getting netdevice_type"); - goto ERR; - } - if (facelet_get_priority(facelet_in, &priority) < 0) { - ERROR("[facelet_on_event] Error getting priority"); - goto ERR; - } - facemgr->default_priority[netdevice_type] = priority; - } + if (facelet_has_netdevice_type(facelet_in) && + !facelet_has_netdevice(facelet_in) && + facelet_has_priority(facelet_in)) { + /* Remember last priority choice for newly created facelets */ + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + u32 priority = 0; + if (facelet_get_netdevice_type(facelet_in, &netdevice_type) < 0) { + ERROR("[facelet_on_event] Error getting netdevice_type"); + goto ERR; + } + if (facelet_get_priority(facelet_in, &priority) < 0) { + ERROR("[facelet_on_event] Error getting priority"); + goto ERR; + } + facemgr->default_priority[netdevice_type] = priority; + } #endif /* WITH_DEFAULT_PRIORITIES */ - DEBUG("[facemgr_on_event] UPDATE NEW %s", facelet_s); - INFO("Ignored UPDATE for non-existing face"); - break; + DEBUG("[facemgr_on_event] UPDATE NEW %s", facelet_s); + INFO("Ignored UPDATE for non-existing face"); + break; - case FACELET_EVENT_DELETE: - DEBUG("[facemgr_on_event] DELETE NEW %s", facelet_s); - ERROR("[facemgr_on_event] Unexpected DELETE... face does not exist"); - goto ERR; - - case FACELET_EVENT_SET_UP: - case FACELET_EVENT_SET_DOWN: - ERROR("[facemgr_on_event] Unexpected event on a face that does not exist"); - goto ERR; + case FACELET_EVENT_DELETE: + DEBUG("[facemgr_on_event] DELETE NEW %s", facelet_s); + ERROR("[facemgr_on_event] Unexpected DELETE... face does not exist"); + goto ERR; - case FACELET_EVENT_UNDEFINED: - case FACELET_EVENT_N: - ERROR("[facemgr_on_event] Unexpected UNDEFINED event."); - ret = -1; - goto ERR; + case FACELET_EVENT_SET_UP: + case FACELET_EVENT_SET_DOWN: + ERROR( + "[facemgr_on_event] Unexpected event on a face that does not " + "exist"); + goto ERR; - } - goto DUMP_CACHE; + case FACELET_EVENT_UNDEFINED: + case FACELET_EVENT_N: + ERROR("[facemgr_on_event] Unexpected UNDEFINED event."); + ret = -1; + goto ERR; } + goto DUMP_CACHE; + } + /* + * From now on, it should not make any difference whether we have one or + * more facelet. + */ + for (unsigned i = 0; i < n; i++) { /* - * From now on, it should not make any difference whether we have one or - * more facelet. + * We merge each cached facelet with incoming one, and perform state + * reconciliation by sending appropriate updates to the forwarder */ - for (unsigned i = 0; i < n; i ++) { + facelet_t *facelet = cached_facelets[i]; + + char facelet_old_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_old_s, MAXSZ_FACELET, facelet); + // DEBUG("Facelet from cache #%d %s", i, facelet_s); + + switch (facelet_get_event(facelet_in)) { + case FACELET_EVENT_CREATE: /* - * We merge each cached facelet with incoming one, and perform state - * reconciliation by sending appropriate updates to the forwarder + * This can occur for a facelet already in cache but that has + * been previously deleted... we need to be able to consider + * static facelets in this situation too... */ - facelet_t * facelet = cached_facelets[i]; - - char facelet_old_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_old_s, MAXSZ_FACELET, facelet); - //DEBUG("Facelet from cache #%d %s", i, facelet_s); - - switch(facelet_get_event(facelet_in)) { - case FACELET_EVENT_CREATE: - /* - * This can occur for a facelet already in cache but that has - * been previously deleted... we need to be able to consider - * static facelets in this situation too... - */ - DEBUG("[facemgr_on_event] CREATE EXISTING %s", facelet_s); - - if (!facelet_has_family(facelet_in)) { - if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error processing new interface event"); - goto ERR; - } - goto DUMP_CACHE; - } + DEBUG("[facemgr_on_event] CREATE EXISTING %s", facelet_s); - // This case will occur when we try to re-create existing faces, - // eg. in the situation of a forwarder restarting. - // likely this occurs when the interface receives a (potentially new) address - if (facelet_merge(facelet, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error merging facelets"); - continue; - } + if (!facelet_has_family(facelet_in)) { + if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < + 0) { + ERROR("[facemgr_on_event] Error processing new interface event"); + goto ERR; + } + goto DUMP_CACHE; + } - if (facemgr_process_facelet_create(facemgr, facelet) < 0) { - ERROR("[facemgr_on_event] Error processing facelet CREATE event"); - ret = -1; - } + // This case will occur when we try to re-create existing faces, + // eg. in the situation of a forwarder restarting. + // likely this occurs when the interface receives a (potentially new) + // address + if (facelet_merge(facelet, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error merging facelets"); + continue; + } - continue; + if (facemgr_process_facelet_create(facemgr, facelet) < 0) { + ERROR("[facemgr_on_event] Error processing facelet CREATE event"); + ret = -1; + } - case FACELET_EVENT_GET: /* should be an INFORM message */ - /* - * This happens due to polling of the forwarder (or when it - * restarts) - */ - //DEBUG("[facemgr_on_event] GET EXISTING %s", facelet_old_s); - //DEBUG(" WITH %s", facelet_s); - //ERROR("[facemgr_on_event] GET event for a face that already exists..."); + continue; + + case FACELET_EVENT_GET: /* should be an INFORM message */ + /* + * This happens due to polling of the forwarder (or when it + * restarts) + */ + // DEBUG("[facemgr_on_event] GET EXISTING %s", facelet_old_s); + // DEBUG(" WITH %s", facelet_s); + // ERROR("[facemgr_on_event] GET event for a face that already + // exists..."); #ifdef WITH_DUMP - dump = false; + dump = false; #endif /* WITH_DUMP */ - continue; + continue; - case FACELET_EVENT_UPDATE: - DEBUG("[facemgr_on_event] UPDATE EXISTING %s", facelet_old_s); - DEBUG(" WITH %s", facelet_s); + case FACELET_EVENT_UPDATE: + DEBUG("[facemgr_on_event] UPDATE EXISTING %s", facelet_old_s); + DEBUG(" WITH %s", facelet_s); #ifdef WITH_DEFAULT_PRIORITIES - if (facelet_has_netdevice_type(facelet_in) && !facelet_has_netdevice(facelet_in) && facelet_has_priority(facelet_in)) { - /* Remember last priority choice for newly created facelets */ - netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; - u32 priority = 0; - if (facelet_get_netdevice_type(facelet_in, &netdevice_type) < 0) { - ERROR("[facelet_on_event] Error getting netdevice_type"); - goto ERR; - } - if (facelet_get_priority(facelet_in, &priority) < 0) { - ERROR("[facelet_on_event] Error getting priority"); - goto ERR; - } - facemgr->default_priority[netdevice_type] = priority; - } + if (facelet_has_netdevice_type(facelet_in) && + !facelet_has_netdevice(facelet_in) && + facelet_has_priority(facelet_in)) { + /* Remember last priority choice for newly created facelets */ + netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; + u32 priority = 0; + if (facelet_get_netdevice_type(facelet_in, &netdevice_type) < 0) { + ERROR("[facelet_on_event] Error getting netdevice_type"); + goto ERR; + } + if (facelet_get_priority(facelet_in, &priority) < 0) { + ERROR("[facelet_on_event] Error getting priority"); + goto ERR; + } + facemgr->default_priority[netdevice_type] = priority; + } #endif /* WITH_DEFAULT_PRIORITIES */ - if (facelet_merge(facelet, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error merging facelets"); - continue; - } - if (facemgr_process_facelet_update(facemgr, facelet) < 0) { - ERROR("[facemgr_on_event] Error processing facelet UPDATE event"); - ret = -1; - } - continue; - - case FACELET_EVENT_DELETE: - DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_old_s); - DEBUG(" WITH %s", facelet_s); - if (facelet_merge(facelet, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error merging facelets"); - continue; - } - if (facemgr_process_facelet_delete(facemgr, facelet) < 0) { - ERROR("[facemgr_on_event] Error processing facelet DELETE event"); - ret = -1; - } - continue; - - case FACELET_EVENT_SET_UP: - ERROR("[facemgr_on_event] Not implemented\n"); - ret = -1; - continue; - - case FACELET_EVENT_SET_DOWN: - DEBUG("[facemgr_on_event] SET DOWN EXISTING %s", facelet_old_s); - DEBUG(" WITH %s", facelet_s); - /* We don't even need to merge */ - if (facelet_merge(facelet, facelet_in) < 0) { - ERROR("[facemgr_on_event] Error merging facelets"); - continue; - } - if (facemgr_process_facelet_delete(facemgr, facelet) < 0) { - ERROR("[facemgr_on_event] Error processing facelet DELETE event"); - continue; - } - continue; - - case FACELET_EVENT_UNDEFINED: - case FACELET_EVENT_N: - ERROR("[facemgr_on_event] Unexpected UNDEFINED event."); - ret = -1; - goto ERR; - + if (facelet_merge(facelet, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error merging facelets"); + continue; } + if (facemgr_process_facelet_update(facemgr, facelet) < 0) { + ERROR("[facemgr_on_event] Error processing facelet UPDATE event"); + ret = -1; + } + continue; + + case FACELET_EVENT_DELETE: + DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_old_s); + DEBUG(" WITH %s", facelet_s); + if (facelet_merge(facelet, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error merging facelets"); + continue; + } + if (facemgr_process_facelet_delete(facemgr, facelet) < 0) { + ERROR("[facemgr_on_event] Error processing facelet DELETE event"); + ret = -1; + } + continue; + + case FACELET_EVENT_SET_UP: + ERROR("[facemgr_on_event] Not implemented\n"); + ret = -1; + continue; + + case FACELET_EVENT_SET_DOWN: + DEBUG("[facemgr_on_event] SET DOWN EXISTING %s", facelet_old_s); + DEBUG(" WITH %s", facelet_s); + /* We don't even need to merge */ + if (facelet_merge(facelet, facelet_in) < 0) { + ERROR("[facemgr_on_event] Error merging facelets"); + continue; + } + if (facemgr_process_facelet_delete(facemgr, facelet) < 0) { + ERROR("[facemgr_on_event] Error processing facelet DELETE event"); + continue; + } + continue; + case FACELET_EVENT_UNDEFINED: + case FACELET_EVENT_N: + ERROR("[facemgr_on_event] Unexpected UNDEFINED event."); + ret = -1; + goto ERR; } - goto DUMP_CACHE; + } + goto DUMP_CACHE; ERR: - ret = -1; + ret = -1; DUMP_CACHE: #if WITH_DUMP - if (dump) { - DEBUG(" <CACHE>"); - facelet_set_dump(facemgr->facelet_cache); - DEBUG(" </CACHE>"); - DEBUG("</EVENT ret=%d>", ret); - DEBUG("----------------------------------"); - } + if (dump) { + DEBUG(" <CACHE>"); + facelet_set_dump(facemgr->facelet_cache); + DEBUG(" </CACHE>"); + DEBUG("</EVENT ret=%d>", ret); + DEBUG("----------------------------------"); + } #endif /* WITH_DUMP */ - free(cached_facelets); + free(cached_facelets); - if (remove_facelet) - facelet_free(facelet_in); + if (remove_facelet) facelet_free(facelet_in); - if (ret == -1) { - INFO("Error... starting reattempts"); - facemgr_start_reattempts(facemgr); - } + if (ret == -1) { + INFO("Error... starting reattempts"); + facemgr_start_reattempts(facemgr); + } - return ret; + return ret; } -int facemgr_callback(facemgr_t * facemgr, interface_cb_type_t type, void * data) -{ - switch(type) { - case INTERFACE_CB_TYPE_RAISE_EVENT: - return facemgr_on_event(facemgr, data); - - case INTERFACE_CB_TYPE_REGISTER_FD: - { - /* Remember fd for further release */ - fd_callback_data_t * fd_callback_data = data; - interface_t * interface = (interface_t*)(fd_callback_data->owner); - - interface_map_data_t * interface_map_data = NULL; - if (interface_map_get(facemgr->interface_map, interface->name, &interface_map_data) < 0) { - ERROR("[facemgr_callback] Error getting interface map data"); - return -1; - } - if (!interface_map_data) { - ERROR("[facemgr_callback] No entry in interface map data"); - return -1; - } - interface_map_data->fds[interface_map_data->num_fds++] = fd_callback_data->fd; +int facemgr_callback(facemgr_t *facemgr, interface_cb_type_t type, void *data) { + switch (type) { + case INTERFACE_CB_TYPE_RAISE_EVENT: + return facemgr_on_event(facemgr, data); - return facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_REGISTER_FD, data); - } + case INTERFACE_CB_TYPE_REGISTER_FD: { + /* Remember fd for further release */ + fd_callback_data_t *fd_callback_data = data; + interface_t *interface = (interface_t *)(fd_callback_data->owner); - case INTERFACE_CB_TYPE_UNREGISTER_FD: - { - fd_callback_data_t * fd_callback_data = data; - interface_t * interface = (interface_t*)(fd_callback_data->owner); + interface_map_data_t *interface_map_data = NULL; + if (interface_map_get(facemgr->interface_map, interface->name, + &interface_map_data) < 0) { + ERROR("[facemgr_callback] Error getting interface map data"); + return -1; + } + if (!interface_map_data) { + ERROR("[facemgr_callback] No entry in interface map data"); + return -1; + } + interface_map_data->fds[interface_map_data->num_fds++] = + fd_callback_data->fd; - interface_map_data_t * interface_map_data = NULL; - if (interface_map_get(facemgr->interface_map, interface->name, &interface_map_data) < 0) { - ERROR("[facemgr_callback] Error getting interface map data"); - return -1; - } - if (!interface_map_data) { - ERROR("[facemgr_callback] No entry in interface map data"); - return -1; - } + return facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_REGISTER_FD, data); + } - for (unsigned i = 0; i < interface_map_data->num_fds; i++) { - if (interface_map_data->fds[i] == fd_callback_data->fd) { - interface_map_data->fds[i] = interface_map_data->fds[--interface_map_data->num_fds]; - break; - } - } + case INTERFACE_CB_TYPE_UNREGISTER_FD: { + fd_callback_data_t *fd_callback_data = data; + interface_t *interface = (interface_t *)(fd_callback_data->owner); - return facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_UNREGISTER_FD, data); + interface_map_data_t *interface_map_data = NULL; + if (interface_map_get(facemgr->interface_map, interface->name, + &interface_map_data) < 0) { + ERROR("[facemgr_callback] Error getting interface map data"); + return -1; + } + if (!interface_map_data) { + ERROR("[facemgr_callback] No entry in interface map data"); + return -1; + } + + for (unsigned i = 0; i < interface_map_data->num_fds; i++) { + if (interface_map_data->fds[i] == fd_callback_data->fd) { + interface_map_data->fds[i] = + interface_map_data->fds[--interface_map_data->num_fds]; + break; } + } - case INTERFACE_CB_TYPE_REGISTER_TIMER: - return facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_REGISTER_TIMER, data); + return facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_UNREGISTER_FD, data); + } - case INTERFACE_CB_TYPE_UNREGISTER_TIMER: - return facemgr->callback(facemgr->callback_owner, - FACEMGR_CB_TYPE_UNREGISTER_TIMER, data); + case INTERFACE_CB_TYPE_REGISTER_TIMER: + return facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_REGISTER_TIMER, data); - } - return -1; + case INTERFACE_CB_TYPE_UNREGISTER_TIMER: + return facemgr->callback(facemgr->callback_owner, + FACEMGR_CB_TYPE_UNREGISTER_TIMER, data); + } + return -1; } -int -facemgr_bootstrap(facemgr_t * facemgr) -{ - int rc; +int facemgr_bootstrap(facemgr_t *facemgr) { + int rc; - DEBUG("Registering interfaces..."); - rc = interface_register(&hicn_light_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering hicn_light interface"); - goto ERR_REGISTER; - } + DEBUG("Registering interfaces..."); + rc = interface_register(&hicn_light_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering hicn_light interface"); + goto ERR_REGISTER; + } #ifdef __APPLE__ - rc = interface_register(&network_framework_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering network_framework interface"); - goto ERR_REGISTER; - } + rc = interface_register(&network_framework_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering network_framework interface"); + goto ERR_REGISTER; + } #endif /* __APPLE__ */ #ifdef __linux__ - rc = interface_register(&netlink_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering netlink interface"); - goto ERR_REGISTER; - } +#ifdef __ANDROID__ + rc = interface_register(&android_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering android interface"); + goto ERR_REGISTER; + } +#else + rc = interface_register(&netlink_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering netlink interface"); + goto ERR_REGISTER; + } +#endif /* __ANDROID__ */ - rc = interface_register(&bonjour_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering bonjour interface"); - goto ERR_REGISTER; - } + rc = interface_register(&bonjour_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering bonjour interface"); + goto ERR_REGISTER; + } #endif /* __linux__ */ -#ifdef WITH_FACEMGR_UTILITY - rc = interface_register(&android_utility_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering android_utility interface"); - goto ERR_REGISTER; - } -#endif /* WITH_FACEMGR_UTILITY */ - #ifdef WITH_PRIORITY_CONTROLLER - INFO("[facemgr_bootstrap] registering priority_controller interface"); - rc = interface_register(&priority_controller_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering priority_controller interface"); - goto ERR_REGISTER; - } + INFO("[facemgr_bootstrap] registering priority_controller interface"); + rc = interface_register(&priority_controller_ops); + if (rc < 0) { + ERROR( + "[facemgr_bootstrap] Error registering priority_controller interface"); + goto ERR_REGISTER; + } #endif #ifdef WITH_EXAMPLE_DUMMY - rc = interface_register(&dummy_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering dummy interface"); - goto ERR_REGISTER; - } + rc = interface_register(&dummy_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering dummy interface"); + goto ERR_REGISTER; + } #endif #ifdef WITH_EXAMPLE_UPDOWN - rc = interface_register(&updown_ops); - if (rc < 0) { - ERROR("[facemgr_bootstrap] Error registering updown interface"); - goto ERR_REGISTER; - } + rc = interface_register(&updown_ops); + if (rc < 0) { + ERROR("[facemgr_bootstrap] Error registering updown interface"); + goto ERR_REGISTER; + } #endif - rc = facemgr_create_interface(facemgr, "hl", "hicn_light", NULL, &facemgr->hl); - if (rc < 0) { - ERROR("Error creating 'hICN forwarder (hicn-light)' interface\n"); - goto ERR_HL_CREATE; - } - #ifdef __APPLE__ - network_framework_cfg_t nf_cfg = { - }; - rc = facemgr_create_interface(facemgr, "nf", "network_framework", &nf_cfg, &facemgr->nf); - if (rc < 0) { - ERROR("Error creating 'Apple Network Framework' interface\n"); - goto ERR_NF_CREATE; - } + network_framework_cfg_t nf_cfg = {}; + rc = facemgr_create_interface(facemgr, "nf", "network_framework", &nf_cfg, + &facemgr->nf); + if (rc < 0) { + ERROR("Error creating 'Apple Network Framework' interface\n"); + goto ERR_NF_CREATE; + } #endif /* __APPLE__ */ #ifdef __linux__ - rc = facemgr_create_interface(facemgr, "nl", "netlink", NULL, &facemgr->nl); - if (rc < 0) { - ERROR("Error creating 'Netlink' interface\n"); - goto ERR_NL_CREATE; - } +#ifdef __ANDROID__ + android_cfg_t android_cfg = { + .jvm = facemgr->jvm, + }; + rc = facemgr_create_interface(facemgr, "android", "android", &android_cfg, + &facemgr->android); + if (rc < 0) { + ERROR("Error creating 'Android' interface\n"); + goto ERR_ANDROID_CREATE; + } +#else + rc = facemgr_create_interface(facemgr, "nl", "netlink", NULL, &facemgr->nl); + if (rc < 0) { + ERROR("Error creating 'Netlink' interface\n"); + goto ERR_NL_CREATE; + } +#endif /* __ANDROID__ */ #endif /* __linux__ */ -#ifdef WITH_FACEMGR_UTILITY - android_utility_cfg_t au_cfg = { - .jvm = facemgr->jvm, - }; - rc = facemgr_create_interface(facemgr, "au", "android_utility", &au_cfg, &facemgr->au); - if (rc < 0) { - ERROR("Error creating 'Android Utility' interface\n"); - goto ERR_AU_CREATE; - } -#endif /* WITH_FACEMGR_UTILITY */ - #ifdef WITH_PRIORITY_CONTROLLER - INFO("[facemgr_bootstrap] creating priority_controller interface"); - priority_controller_cfg_t pc_cfg = { + INFO("[facemgr_bootstrap] creating priority_controller interface"); + priority_controller_cfg_t pc_cfg = { #ifdef PRIORITY_CONTROLLER_INTERNAL - .jvm = facemgr->jvm, + .jvm = facemgr->jvm, #endif /* PRIORITY_CONTROLLER_INTERNAL */ - }; - rc = facemgr_create_interface(facemgr, "pc", "priority_controller", &pc_cfg, &facemgr->pc); - if (rc < 0) { - ERROR("Error creating 'Priority Controller' interface\n"); - goto ERR_PC_CREATE; - } + }; + rc = facemgr_create_interface(facemgr, "pc", "priority_controller", &pc_cfg, + &facemgr->pc); + if (rc < 0) { + ERROR("Error creating 'Priority Controller' interface\n"); + goto ERR_PC_CREATE; + } #endif #ifdef WITH_EXAMPLE_DUMMY - rc = facemgr_create_interface(facemgr, "dummy0", "dummy", NULL, &facemgr->dummy); - if (rc < 0) { - ERROR("Error creating 'dummy' interface\n"); - goto ERR_DUMMY_CREATE; - } + rc = facemgr_create_interface(facemgr, "dummy0", "dummy", NULL, + &facemgr->dummy); + if (rc < 0) { + ERROR("Error creating 'dummy' interface\n"); + goto ERR_DUMMY_CREATE; + } #endif #ifdef WITH_EXAMPLE_UPDOWN - rc = facemgr_create_interface(facemgr, "updown0", "updown", NULL, &facemgr->updown); - if (rc < 0) { - ERROR("Error creating 'updown' interface\n"); - goto ERR_UPDOWN_CREATE; - } + rc = facemgr_create_interface(facemgr, "updown0", "updown", NULL, + &facemgr->updown); + if (rc < 0) { + ERROR("Error creating 'updown' interface\n"); + goto ERR_UPDOWN_CREATE; + } #endif - DEBUG("Facemgr successfully initialized..."); + rc = + facemgr_create_interface(facemgr, "hl", "hicn_light", NULL, &facemgr->hl); + if (rc < 0) { + ERROR("Error creating 'hICN forwarder (hicn-light)' interface\n"); + goto ERR_HL_CREATE; + } - return 0; + DEBUG("Facemgr successfully initialized..."); + + return 0; +ERR_HL_CREATE: #ifdef WITH_EXAMPLE_UPDOWN - facemgr_delete_interface(facemgr, facemgr->updown); + facemgr_delete_interface(facemgr, facemgr->updown); ERR_UPDOWN_CREATE: #endif + #ifdef WITH_EXAMPLE_DUMMY - facemgr_delete_interface(facemgr, facemgr->dummy); + facemgr_delete_interface(facemgr, facemgr->dummy); ERR_DUMMY_CREATE: #endif -#ifdef WITH_FACEMGR_UTILITY - facemgr_delete_interface(facemgr, facemgr->au); -ERR_AU_CREATE: -#endif /* WITH_FACEMGR_UTILITY */ + #ifdef WITH_PRIORITY_CONTROLLER - facemgr_delete_interface(facemgr, facemgr->pc); + facemgr_delete_interface(facemgr, facemgr->pc); ERR_PC_CREATE: #endif + #ifdef __linux__ - facemgr_delete_interface(facemgr, facemgr->nl); +#ifdef __ANDROID__ + facemgr_delete_interface(facemgr, facemgr->android); +ERR_ANDROID_CREATE: +#else + facemgr_delete_interface(facemgr, facemgr->nl); ERR_NL_CREATE: +#endif /* __ANDROID__ */ #endif /* __linux__ */ + #ifdef __APPLE__ - facemgr_delete_interface(facemgr, facemgr->nf); + facemgr_delete_interface(facemgr, facemgr->nf); ERR_NF_CREATE: #endif /* __APPLE__ */ - facemgr_delete_interface(facemgr, facemgr->hl); -ERR_HL_CREATE: ERR_REGISTER: - return -1; + return -1; } -void facemgr_stop(facemgr_t * facemgr) -{ - // FIXME we should iterate on interface map +void facemgr_stop(facemgr_t *facemgr) { + // FIXME we should iterate on interface map #ifdef __APPLE__ - facemgr_delete_interface(facemgr, facemgr->nf); + facemgr_delete_interface(facemgr, facemgr->nf); #endif /* __APPLE__ */ - #ifdef __linux__ - facemgr_delete_interface(facemgr, facemgr->nl); - - /* Delete all bonjour interfaces */ - interface_t ** bonjour_array = NULL; - int n = bonjour_map_get_value_array(facemgr->bonjour_map, &bonjour_array); - if (n >= 0) { - netdevice_t ** netdevice_array = NULL; - int m = bonjour_map_get_key_array(facemgr->bonjour_map, &netdevice_array); - if (m >= 0) { - assert(m == n); - for (int i = 0; i < n; i++) { /* Fail silently */ - DEBUG("Deleting bonjour interface associated to %s (%p)", - netdevice_array[i]->name, bonjour_array[i]); - facemgr_delete_interface(facemgr, bonjour_array[i]); - } - free(netdevice_array); - } - free(bonjour_array); - } -#endif /* __linux__ */ +#ifdef __ANDROID__ + facemgr_delete_interface(facemgr, facemgr->android); +#else + facemgr_delete_interface(facemgr, facemgr->nl); +#endif /* __ANDROID__ */ -#ifdef WITH_FACEMGR_UTILITY - facemgr_delete_interface(facemgr, facemgr->au); -#endif /* WITH_FACEMGR_UTILITY */ + /* Delete all bonjour interfaces */ + interface_t **bonjour_array = NULL; + int n = bonjour_map_get_value_array(facemgr->bonjour_map, &bonjour_array); + if (n >= 0) { + netdevice_t **netdevice_array = NULL; + int m = bonjour_map_get_key_array(facemgr->bonjour_map, &netdevice_array); + if (m >= 0) { + assert(m == n); + for (int i = 0; i < n; i++) { /* Fail silently */ + DEBUG("Deleting bonjour interface associated to %s (%p)", + netdevice_array[i]->name, bonjour_array[i]); + facemgr_delete_interface(facemgr, bonjour_array[i]); + } + free(netdevice_array); + } + free(bonjour_array); + } +#endif /* __linux__ */ #ifdef WITH_PRIORITY_CONTROLLER - facemgr_delete_interface(facemgr, facemgr->pc); + facemgr_delete_interface(facemgr, facemgr->pc); #endif - facemgr_delete_interface(facemgr, facemgr->hl); + facemgr_delete_interface(facemgr, facemgr->hl); #ifdef WITH_EXAMPLE_DUMMY - facemgr_delete_interface(facemgr, facemgr->dummy); + facemgr_delete_interface(facemgr, facemgr->dummy); #endif #ifdef WITH_EXAMPLE_UPDOWN - facemgr_delete_interface(facemgr, facemgr->updown); + facemgr_delete_interface(facemgr, facemgr->updown); #endif } #ifdef __ANDROID__ -void facemgr_set_jvm(facemgr_t * facemgr, JavaVM *jvm) -{ - facemgr->jvm = jvm; +void facemgr_set_jvm(facemgr_t *facemgr, JavaVM *jvm) { facemgr->jvm = jvm; } + +void facemgr_on_android_callback(facemgr_t *facemgr, const char *interface_name, + netdevice_type_t netdevice_type, bool up, + int family, const char *ip_address) { + android_on_network_event(facemgr->android, interface_name, netdevice_type, up, + family, ip_address); } #endif /* __ANDROID__ */ -void -facemgr_set_callback(facemgr_t * facemgr, void * callback_owner, facemgr_cb_t callback) -{ - facemgr->callback = callback; - facemgr->callback_owner = callback_owner; +void facemgr_set_callback(facemgr_t *facemgr, void *callback_owner, + facemgr_cb_t callback) { + facemgr->callback = callback; + facemgr->callback_owner = callback_owner; } -void facemgr_list_facelets(const facemgr_t * facemgr, facemgr_list_facelets_cb_t cb, void * user_data) -{ - facelet_t ** facelet_array; - if (!cb) - return; - int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); - if (n < 0) { - ERROR("[facemgr_list_facelets] Could not retrieve facelets in cache"); - return; - } - for (unsigned i = 0; i < n; i++) { - facelet_t * facelet = facelet_array[i]; - cb(facemgr, facelet, user_data); - } - free(facelet_array); +void facemgr_list_facelets(const facemgr_t *facemgr, + facemgr_list_facelets_cb_t cb, void *user_data) { + facelet_t **facelet_array; + if (!cb) return; + int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); + if (n < 0) { + ERROR("[facemgr_list_facelets] Could not retrieve facelets in cache"); + return; + } + for (unsigned i = 0; i < n; i++) { + facelet_t *facelet = facelet_array[i]; + if (!facelet) continue; /* Should not occur */ + cb(facemgr, facelet, user_data); + } + free(facelet_array); } -int -facemgr_list_facelets_json(const facemgr_t * facemgr, char ** buffer) -{ - char * cur; - char * s; - int rc; - - facelet_t ** facelet_array; - int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); - if (n < 0) { - ERROR("[facemgr_list_facelets_json] Could not retrieve facelets in cache"); - return -1; - } - /* This should be enough for JSON overhead, refine later */ - size_t size = 2 * n * MAXSZ_FACELET; - *buffer = malloc(size); - if (!buffer) { - ERROR("[facemgr_list_facelets_json] Could not allocate JSON s"); - free(facelet_array); - return -1; - } - s = *buffer; - cur = s; +int facemgr_list_facelets_json(const facemgr_t *facemgr, char **buffer) { + char *cur; + char *s; + int rc; - rc = snprintf(cur, s + size - cur, "{\"facelets\": [\n"); - if (rc < 0) - goto ERR; - cur += rc; - if (size != 0 && cur >= s + size) - goto END; + facelet_t **facelet_array; + int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array); + if (n < 0) { + ERROR("[facemgr_list_facelets_json] Could not retrieve facelets in cache"); + return -1; + } + /* This should be enough for JSON overhead, refine later */ + size_t size = 2 * n * MAXSZ_FACELET; + *buffer = malloc(size); + if (!buffer) { + ERROR("[facemgr_list_facelets_json] Could not allocate JSON s"); + free(facelet_array); + return -1; + } + s = *buffer; + cur = s; - for (unsigned i = 0; i < n; i++) { - facelet_t * facelet = facelet_array[i]; + rc = snprintf(cur, s + size - cur, "{\"facelets\": [\n"); + if (rc < 0) goto ERR; + cur += rc; + if (size != 0 && cur >= s + size) goto END; - rc = facelet_snprintf_json(cur, s + size - cur, facelet, /* indent */ 1); - if (rc < 0) - goto ERR; - cur += rc; - if (size != 0 && cur >= s + size) - goto END; + for (unsigned i = 0; i < n; i++) { + facelet_t *facelet = facelet_array[i]; + if (!facelet) continue; /* Should not occur */ - rc = snprintf(cur, s + size - cur, (i == n-1) ? "\n" : ",\n"); - if (rc < 0) - goto ERR; - cur += rc; - if (size != 0 && cur >= s + size) - goto END; - } + rc = facelet_snprintf_json(cur, s + size - cur, facelet, /* indent */ 1); + if (rc < 0) goto ERR; + cur += rc; + if (size != 0 && cur >= s + size) goto END; - rc = snprintf(cur, s + size - cur, "]}\n"); - if (rc < 0) - goto ERR; + rc = snprintf(cur, s + size - cur, (i == n - 1) ? "\n" : ",\n"); + if (rc < 0) goto ERR; cur += rc; - if (size != 0 && cur >= s + size) - goto END; + if (size != 0 && cur >= s + size) goto END; + } + + rc = snprintf(cur, s + size - cur, "]}\n"); + if (rc < 0) goto ERR; + cur += rc; + if (size != 0 && cur >= s + size) goto END; END: - free(facelet_array); - return (int)(cur - s); + free(facelet_array); + return (int)(cur - s); ERR: - free(facelet_array); - return rc; + free(facelet_array); + return rc; } - diff --git a/ctrl/facemgr/src/cache.c b/ctrl/facemgr/src/cache.c index f994d7d37..98c68e9b0 100644 --- a/ctrl/facemgr/src/cache.c +++ b/ctrl/facemgr/src/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -22,106 +22,86 @@ * search.h). */ -#include <math.h> // log2 -#include <string.h> // memmove +#include <math.h> // log2 +#include <string.h> // memmove #include "cache.h" #define FACE_CACHE_MAX_SIZE_LOG_INIT 0 -face_cache_t * -face_cache_create() -{ - face_cache_t * face_cache = malloc(sizeof(face_cache_t)); - if (!face_cache) - goto ERR_MALLOC; +face_cache_t* face_cache_create() { + face_cache_t* face_cache = malloc(sizeof(face_cache_t)); + if (!face_cache) goto ERR_MALLOC; - face_cache->max_size_log = FACE_CACHE_MAX_SIZE_LOG_INIT; -#if(FACE_CACHE_MAX_SIZE_LOG_INIT == 0) - face_cache->faces = NULL; + face_cache->max_size_log = FACE_CACHE_MAX_SIZE_LOG_INIT; +#if (FACE_CACHE_MAX_SIZE_LOG_INIT == 0) + face_cache->faces = NULL; #else - face_cache->faces = malloc((1 << face_cache->max_size_log) * sizeof(face_t*)); - if (!face_cache->faces) - goto ERR_ARRAY: + face_cache->faces = malloc((1 << face_cache->max_size_log) * sizeof(face_t*)); + if (!face_cache->faces) + goto ERR_ARRAY : #endif - face_cache->size = 0; + face_cache->size = 0; - return face_cache; + return face_cache; -#if(FACE_CACHE_MAX_SIZE_LOG_INIT != 0) +#if (FACE_CACHE_MAX_SIZE_LOG_INIT != 0) ERR_ARRAY: - free(face_cache); + free(face_cache); #endif ERR_MALLOC: - return NULL; + return NULL; } -void -face_cache_free(face_cache_t * face_cache) -{ - free(face_cache->faces); +void face_cache_free(face_cache_t* face_cache) { + free(face_cache->faces); - free(face_cache); + free(face_cache); } -face_t * -face_cache_add(face_cache_t * face_cache, face_t * face) -{ - /* Ensure sufficient space for next addition */ - size_t new_size_log = (face_cache->size > 0) ? log2(face_cache->size) + 1 : 0; - if (new_size_log > face_cache->max_size_log) { - face_cache->max_size_log = new_size_log; - face_cache->faces = realloc(face_cache->faces, (1 << new_size_log) * sizeof(face_t*)); - } +face_t* face_cache_add(face_cache_t* face_cache, face_t* face) { + /* Ensure sufficient space for next addition */ + size_t new_size_log = (face_cache->size > 0) ? log2(face_cache->size) + 1 : 0; + if (new_size_log > face_cache->max_size_log) { + face_cache->max_size_log = new_size_log; + face_cache->faces = + realloc(face_cache->faces, (1 << new_size_log) * sizeof(face_t*)); + } - if (!face_cache->faces) - goto ERR_REALLOC; + if (!face_cache->faces) goto ERR_REALLOC; - face_cache->faces[face_cache->size++] = face; + face_cache->faces[face_cache->size++] = face; - return face; + return face; ERR_REALLOC: - return NULL; + return NULL; } -int face_cache_search(face_cache_t * face_cache, face_t * face, face_cmp_t face_cmp) -{ - for (int i = 0; i < face_cache->size; i++) - if (face_cmp(face, face_cache->faces[i])) - return i; - return -1; +int face_cache_search(face_cache_t* face_cache, face_t* face, + face_cmp_t face_cmp) { + for (int i = 0; i < face_cache->size; i++) + if (face_cmp(face, face_cache->faces[i])) return i; + return -1; } /* Remove a single occurrence */ -face_t * -face_cache_remove(face_cache_t * face_cache, face_t * face) -{ - int pos = face_cache_search(face_cache, face, face_cmp); - if (pos < 0) - return NULL; +face_t* face_cache_remove(face_cache_t* face_cache, face_t* face) { + int pos = face_cache_search(face_cache, face, face_cmp); + if (pos < 0) return NULL; - /* No need to move memory if last item is removed */ - if (pos < face_cache->size) - memmove(face_cache->faces+pos, face_cache->faces+pos+1, face_cache->size - pos); + /* No need to move memory if last item is removed */ + if (pos < face_cache->size) + memmove(face_cache->faces + pos, face_cache->faces + pos + 1, + face_cache->size - pos); - face_cache->size--; + face_cache->size--; - return face; + return face; } /* TODO : remove by ... */ -face_t * -face_cache_get_by_id(face_cache_t * face_cache, int id) -{ - return NULL; -} - - +face_t* face_cache_get_by_id(face_cache_t* face_cache, int id) { return NULL; } -void -face_cache_dump(face_cache_t * face_cache) -{ - -} +void face_cache_dump(face_cache_t* face_cache) {} diff --git a/ctrl/facemgr/src/cache.h b/ctrl/facemgr/src/cache.h index 1389ed6ec..ac14fabb8 100644 --- a/ctrl/facemgr/src/cache.h +++ b/ctrl/facemgr/src/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,22 +32,22 @@ * \brief Face cache */ typedef struct { - face_t ** faces; /**< array of _pointers_ to faces */ - size_t max_size_log; /**< log2 of allocated size */ - size_t size; /**< effective array size */ + face_t** faces; /**< array of _pointers_ to faces */ + size_t max_size_log; /**< log2 of allocated size */ + size_t size; /**< effective array size */ } face_cache_t; -face_cache_t * face_cache_create(); -void face_cache_free(face_cache_t * face_cache); +face_cache_t* face_cache_create(); +void face_cache_free(face_cache_t* face_cache); /* a la VPP vector, we never create a face outside of the vector */ /* problem is that face ptr can get invalid if we manipulate the vector */ -face_t * face_cache_get(face_cache_t * cache_cache); +face_t* face_cache_get(face_cache_t* cache_cache); -face_t * face_cache_add(face_cache_t * face_cache, face_t * face); -face_t * face_cache_remove(face_cache_t * face_cache, face_t * face); -face_t * face_cache_get_by_id(face_cache_t * face_cache, int id); +face_t* face_cache_add(face_cache_t* face_cache, face_t* face); +face_t* face_cache_remove(face_cache_t* face_cache, face_t* face); +face_t* face_cache_get_by_id(face_cache_t* face_cache, int id); -void face_cache_dump(face_cache_t * face_cache); +void face_cache_dump(face_cache_t* face_cache); #endif /* FACEMGR_CACHE_H */ diff --git a/ctrl/facemgr/src/cfg.c b/ctrl/facemgr/src/cfg.c index df73acd1b..9c374388a 100644 --- a/ctrl/facemgr/src/cfg.c +++ b/ctrl/facemgr/src/cfg.c @@ -4,7 +4,7 @@ */ #include <assert.h> -#include <hicn/ctrl.h> // HICN_DEFAULT_PORT +#include <hicn/ctrl.h> // HICN_DEFAULT_PORT #include <hicn/facemgr/cfg.h> #include <hicn/policy.h> #include <hicn/util/ip_address.h> @@ -14,691 +14,643 @@ /* Overlay */ typedef struct { - bool is_local_port; - uint16_t local_port; - bool is_local_addr; - ip_address_t local_addr; - bool is_remote_port; - uint16_t remote_port; - bool is_remote_addr; - ip_address_t remote_addr; + bool is_local_port; + uint16_t local_port; + bool is_local_addr; + ip_address_t local_addr; + bool is_remote_port; + uint16_t remote_port; + bool is_remote_addr; + ip_address_t remote_addr; } facemgr_cfg_overlay_t; -int facemgr_cfg_overlay_initialize(facemgr_cfg_overlay_t * overlay) -{ - overlay->is_local_port = false; - overlay->local_port = 0; - overlay->is_local_addr = false; - overlay->local_addr = IP_ADDRESS_EMPTY; +int facemgr_cfg_overlay_initialize(facemgr_cfg_overlay_t *overlay) { + overlay->is_local_port = false; + overlay->local_port = 0; + overlay->is_local_addr = false; + overlay->local_addr = IP_ADDRESS_EMPTY; - overlay->is_remote_port = false; - overlay->remote_port = 0; - overlay->is_remote_addr = false; - overlay->remote_addr = IP_ADDRESS_EMPTY; + overlay->is_remote_port = false; + overlay->remote_port = 0; + overlay->is_remote_addr = false; + overlay->remote_addr = IP_ADDRESS_EMPTY; - return 0; + return 0; } -int facemgr_cfg_overlay_finalize(facemgr_cfg_overlay_t * overlay) -{ - return 0; -} +int facemgr_cfg_overlay_finalize(facemgr_cfg_overlay_t *overlay) { return 0; } -facemgr_cfg_overlay_t * facemgr_cfg_overlay_create() -{ - facemgr_cfg_overlay_t * overlay = malloc(sizeof(facemgr_cfg_overlay_t)); - if (!overlay) - return NULL; +facemgr_cfg_overlay_t *facemgr_cfg_overlay_create() { + facemgr_cfg_overlay_t *overlay = malloc(sizeof(facemgr_cfg_overlay_t)); + if (!overlay) return NULL; - int rc = facemgr_cfg_overlay_initialize(overlay); - if (rc < 0) { - free(overlay); - return NULL; - } + int rc = facemgr_cfg_overlay_initialize(overlay); + if (rc < 0) { + free(overlay); + return NULL; + } - return overlay; + return overlay; } -void facemgr_cfg_overlay_free(facemgr_cfg_overlay_t * overlay) -{ - facemgr_cfg_overlay_finalize(overlay); - free(overlay); +void facemgr_cfg_overlay_free(facemgr_cfg_overlay_t *overlay) { + facemgr_cfg_overlay_finalize(overlay); + free(overlay); } typedef struct { - facemgr_cfg_overlay_t * v4; - facemgr_cfg_overlay_t * v6; + facemgr_cfg_overlay_t *v4; + facemgr_cfg_overlay_t *v6; } facemgr_cfg_overlays_t; typedef struct { - const char * interface_name; - netdevice_type_t interface_type; + const char *interface_name; + netdevice_type_t interface_type; } facemgr_cfg_match_t; - typedef struct { - /* Interface specific */ - bool is_face_type; // default is auto - facemgr_face_type_t face_type; - - /* This should be defaut for the global settings */ - bool is_ignore; - bool ignore; - bool is_discovery; - bool discovery; - bool is_ipv4; - bool ipv4; - bool is_ipv6; - bool ipv6; - - facemgr_cfg_overlays_t overlays; // fallback unless discovery is disabled + /* Interface specific */ + bool is_face_type; // default is auto + facemgr_face_type_t face_type; + + /* This should be defaut for the global settings */ + bool is_ignore; + bool ignore; + bool is_discovery; + bool discovery; + bool is_ipv4; + bool ipv4; + bool is_ipv6; + bool ipv6; + + facemgr_cfg_overlays_t overlays; // fallback unless discovery is disabled } facemgr_cfg_override_t; struct facemgr_cfg_rule_s { - facemgr_cfg_match_t match; - facemgr_cfg_override_t override; + facemgr_cfg_match_t match; + facemgr_cfg_override_t override; }; -int facemgr_cfg_override_initialize(facemgr_cfg_override_t * override) -{ - override->is_face_type = false; - override->face_type = FACEMGR_FACE_TYPE_UNDEFINED; +int facemgr_cfg_override_initialize(facemgr_cfg_override_t *override) { + override->is_face_type = false; + override->face_type = FACEMGR_FACE_TYPE_UNDEFINED; - override->is_ignore = false; - override->ignore = false; + override->is_ignore = false; + override->ignore = false; - override->is_discovery = false; - override->discovery = false; + override->is_discovery = false; + override->discovery = false; - override->is_ipv4 = false; - override->ipv6 = false; - override->is_ipv6 = false; - override->ipv6 = false; + override->is_ipv4 = false; + override->ipv6 = false; + override->is_ipv6 = false; + override->ipv6 = false; - override->overlays.v4 = NULL; - override->overlays.v6 = NULL; + override->overlays.v4 = NULL; + override->overlays.v6 = NULL; - return 0; + return 0; } -int facemgr_cfg_override_finalize(facemgr_cfg_override_t * override) -{ - if (override->overlays.v4) { - facemgr_cfg_overlay_free(override->overlays.v4); - override->overlays.v4 = NULL; - } - if (override->overlays.v6) { - facemgr_cfg_overlay_free(override->overlays.v6); - override->overlays.v6 = NULL; - } +int facemgr_cfg_override_finalize(facemgr_cfg_override_t *override) { + if (override->overlays.v4) { + facemgr_cfg_overlay_free(override->overlays.v4); + override->overlays.v4 = NULL; + } + if (override->overlays.v6) { + facemgr_cfg_overlay_free(override->overlays.v6); + override->overlays.v6 = NULL; + } - return 0; + return 0; } - /* Rule */ -facemgr_cfg_rule_t * facemgr_cfg_rule_create() -{ - facemgr_cfg_rule_t * rule = malloc(sizeof(facemgr_cfg_rule_t)); - if (!rule) - return NULL; +facemgr_cfg_rule_t *facemgr_cfg_rule_create() { + facemgr_cfg_rule_t *rule = malloc(sizeof(facemgr_cfg_rule_t)); + if (!rule) return NULL; - int rc = facemgr_cfg_rule_initialize(rule); - if (rc < 0) - return NULL; + int rc = facemgr_cfg_rule_initialize(rule); + if (rc < 0) return NULL; - return rule; + return rule; } -void facemgr_cfg_rule_free(facemgr_cfg_rule_t * rule) -{ - facemgr_cfg_rule_finalize(rule); - free(rule); +void facemgr_cfg_rule_free(facemgr_cfg_rule_t *rule) { + facemgr_cfg_rule_finalize(rule); + free(rule); } -int facemgr_cfg_rule_initialize(facemgr_cfg_rule_t * rule) -{ - rule->match.interface_name = NULL; - rule->match.interface_type = NETDEVICE_TYPE_UNDEFINED; +int facemgr_cfg_rule_initialize(facemgr_cfg_rule_t *rule) { + rule->match.interface_name = NULL; + rule->match.interface_type = NETDEVICE_TYPE_UNDEFINED; - int rc = facemgr_cfg_override_initialize(&rule->override); - if (rc < 0) - return -1; + int rc = facemgr_cfg_override_initialize(&rule->override); + if (rc < 0) return -1; - return 0; + return 0; } -int facemgr_cfg_rule_finalize(facemgr_cfg_rule_t * rule) -{ - if (rule->match.interface_name) { - free((void*)rule->match.interface_name); - rule->match.interface_name = NULL; +int facemgr_cfg_rule_finalize(facemgr_cfg_rule_t *rule) { + if (rule->match.interface_name) { + free((void *)rule->match.interface_name); + rule->match.interface_name = NULL; + } + return facemgr_cfg_override_finalize(&rule->override); +} + +void facemgr_cfg_rule_dump(facemgr_cfg_rule_t *rule) { + DEBUG(" <rule>"); + DEBUG(" <match interface_name=%s interface_type=%s>", + rule->match.interface_name, + netdevice_type_str(rule->match.interface_type)); + DEBUG(" <override>"); + if (rule->override.is_face_type) { + DEBUG(" <face_type>%d</face_type>", rule->override.face_type); + } + if (rule->override.is_ignore) { + DEBUG(" <ignore>%d</ignore>", rule->override.ignore); + } + if (rule->override.is_discovery) { + DEBUG(" <discovery>%d</discovery>", rule->override.discovery); + } + if (rule->override.is_ipv4) { + DEBUG(" <ipv4>%d</ipv4>", rule->override.ipv4); + } + if (rule->override.is_ipv6) { + DEBUG(" <ipv6>%d</ipv6>", rule->override.ipv6); + } + DEBUG(" <overlays>"); + if (rule->override.overlays.v4) { + DEBUG(" <ipv4>"); + if (rule->override.overlays.v4->is_local_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, + &rule->override.overlays.v4->local_addr, AF_INET); + DEBUG(" <local_addr>%s</local_addr>", buf); } - return facemgr_cfg_override_finalize(&rule->override); -} - -void facemgr_cfg_rule_dump(facemgr_cfg_rule_t * rule) -{ - DEBUG(" <rule>"); - DEBUG(" <match interface_name=%s interface_type=%s>", - rule->match.interface_name, - netdevice_type_str[rule->match.interface_type]); - DEBUG(" <override>"); - if (rule->override.is_face_type) { - DEBUG(" <face_type>%d</face_type>", rule->override.face_type); + if (rule->override.overlays.v4->is_local_port) { + DEBUG(" <local_port>%d</local_port>", + rule->override.overlays.v4->local_port); } - if (rule->override.is_ignore) { - DEBUG(" <ignore>%d</ignore>", rule->override.ignore); + if (rule->override.overlays.v4->is_remote_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, + &rule->override.overlays.v4->remote_addr, AF_INET); + DEBUG(" <remote_addr>%s</remote_addr>", buf); } - if (rule->override.is_discovery) { - DEBUG(" <discovery>%d</discovery>", rule->override.discovery); + if (rule->override.overlays.v4->is_remote_port) { + DEBUG(" <remote_port>%d</remote_port>", + rule->override.overlays.v4->remote_port); } - if (rule->override.is_ipv4) { - DEBUG(" <ipv4>%d</ipv4>", rule->override.ipv4); + DEBUG(" </ipv4>"); + } + if (rule->override.overlays.v6) { + DEBUG(" <ipv6>"); + if (rule->override.overlays.v6->is_local_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, + &rule->override.overlays.v6->local_addr, AF_INET6); + DEBUG(" <local_addr>%s</local_addr>", buf); } - if (rule->override.is_ipv6) { - DEBUG(" <ipv6>%d</ipv6>", rule->override.ipv6); + if (rule->override.overlays.v6->is_local_port) { + DEBUG(" <local_port>%d</local_port>", + rule->override.overlays.v6->local_port); } - DEBUG(" <overlays>"); - if (rule->override.overlays.v4) { - DEBUG(" <ipv4>"); - if (rule->override.overlays.v4->is_local_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &rule->override.overlays.v4->local_addr, AF_INET); - DEBUG(" <local_addr>%s</local_addr>", buf); - } - if (rule->override.overlays.v4->is_local_port) { - DEBUG(" <local_port>%d</local_port>", - rule->override.overlays.v4->local_port); - } - if (rule->override.overlays.v4->is_remote_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &rule->override.overlays.v4->remote_addr, AF_INET); - DEBUG(" <remote_addr>%s</remote_addr>", buf); - } - if (rule->override.overlays.v4->is_remote_port) { - DEBUG(" <remote_port>%d</remote_port>", - rule->override.overlays.v4->remote_port); - } - DEBUG(" </ipv4>"); + if (rule->override.overlays.v6->is_remote_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, + &rule->override.overlays.v6->remote_addr, AF_INET6); + DEBUG(" <remote_addr>%s</remote_addr>", buf); } - if (rule->override.overlays.v6) { - DEBUG(" <ipv6>"); - if (rule->override.overlays.v6->is_local_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &rule->override.overlays.v6->local_addr, AF_INET6); - DEBUG(" <local_addr>%s</local_addr>", buf); - } - if (rule->override.overlays.v6->is_local_port) { - DEBUG(" <local_port>%d</local_port>", - rule->override.overlays.v6->local_port); - } - if (rule->override.overlays.v6->is_remote_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &rule->override.overlays.v6->remote_addr, AF_INET6); - DEBUG(" <remote_addr>%s</remote_addr>", buf); - } - if (rule->override.overlays.v6->is_remote_port) { - DEBUG(" <remote_port>%d</remote_port>", - rule->override.overlays.v6->remote_port); - } - DEBUG(" </ipv6>"); + if (rule->override.overlays.v6->is_remote_port) { + DEBUG(" <remote_port>%d</remote_port>", + rule->override.overlays.v6->remote_port); } - DEBUG(" </overlays>"); - DEBUG(" </override>"); - DEBUG(" </rule>"); + DEBUG(" </ipv6>"); + } + DEBUG(" </overlays>"); + DEBUG(" </override>"); + DEBUG(" </rule>"); } -int facemgr_cfg_rule_set_match(facemgr_cfg_rule_t * rule, const char * interface_name, - netdevice_type_t interface_type) -{ - rule->match.interface_name = interface_name ? strdup(interface_name) : NULL; - rule->match.interface_type = interface_type; - return 0; +int facemgr_cfg_rule_set_match(facemgr_cfg_rule_t *rule, + const char *interface_name, + netdevice_type_t interface_type) { + rule->match.interface_name = interface_name ? strdup(interface_name) : NULL; + rule->match.interface_type = interface_type; + return 0; } -int facemgr_cfg_rule_set_face_type(facemgr_cfg_rule_t * rule, facemgr_face_type_t * face_type) -{ - rule->override.is_face_type = true; - rule->override.face_type = *face_type; - return 0; +int facemgr_cfg_rule_set_face_type(facemgr_cfg_rule_t *rule, + facemgr_face_type_t *face_type) { + rule->override.is_face_type = true; + rule->override.face_type = *face_type; + return 0; } -int facemgr_cfg_rule_unset_face_type(facemgr_cfg_rule_t * rule) -{ - rule->override.is_face_type = false; - rule->override.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */ - return 0; +int facemgr_cfg_rule_unset_face_type(facemgr_cfg_rule_t *rule) { + rule->override.is_face_type = false; + rule->override.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */ + return 0; } -int facemgr_cfg_rule_set_discovery(facemgr_cfg_rule_t * rule, bool status) -{ - rule->override.is_discovery = true; - rule->override.discovery = status; - return 0; +int facemgr_cfg_rule_set_discovery(facemgr_cfg_rule_t *rule, bool status) { + rule->override.is_discovery = true; + rule->override.discovery = status; + return 0; } -int facemgr_cfg_rule_unset_discovery(facemgr_cfg_rule_t * rule) -{ - rule->override.is_discovery = false; - return 0; +int facemgr_cfg_rule_unset_discovery(facemgr_cfg_rule_t *rule) { + rule->override.is_discovery = false; + return 0; } -int facemgr_cfg_rule_set_ignore(facemgr_cfg_rule_t * rule, bool status) -{ - rule->override.is_ignore = true; - rule->override.ignore = status; - return 0; +int facemgr_cfg_rule_set_ignore(facemgr_cfg_rule_t *rule, bool status) { + rule->override.is_ignore = true; + rule->override.ignore = status; + return 0; } -int facemgr_cfg_rule_unset_ignore(facemgr_cfg_rule_t * rule) -{ - rule->override.is_ignore = false; - return 0; +int facemgr_cfg_rule_unset_ignore(facemgr_cfg_rule_t *rule) { + rule->override.is_ignore = false; + return 0; } -int facemgr_cfg_rule_set_ipv4(facemgr_cfg_rule_t * rule, bool status) -{ - rule->override.is_ipv4 = true; - rule->override.ipv4 = status; - return 0; +int facemgr_cfg_rule_set_ipv4(facemgr_cfg_rule_t *rule, bool status) { + rule->override.is_ipv4 = true; + rule->override.ipv4 = status; + return 0; } -int facemgr_cfg_rule_unset_ipv4(facemgr_cfg_rule_t * rule) -{ - rule->override.is_ipv4 = false; - return 0; +int facemgr_cfg_rule_unset_ipv4(facemgr_cfg_rule_t *rule) { + rule->override.is_ipv4 = false; + return 0; } -int facemgr_cfg_rule_set_ipv6(facemgr_cfg_rule_t * rule, bool status) -{ - rule->override.is_ipv6 = true; - rule->override.ipv6 = status; - return 0; +int facemgr_cfg_rule_set_ipv6(facemgr_cfg_rule_t *rule, bool status) { + rule->override.is_ipv6 = true; + rule->override.ipv6 = status; + return 0; } -int facemgr_cfg_rule_unset_ipv6(facemgr_cfg_rule_t * rule) -{ - rule->override.is_ipv6 = false; - return 0; +int facemgr_cfg_rule_unset_ipv6(facemgr_cfg_rule_t *rule) { + rule->override.is_ipv6 = false; + return 0; } -int facemgr_cfg_rule_set_overlay(facemgr_cfg_rule_t * rule, int family, - ip_address_t * local_addr, uint16_t local_port, - ip_address_t * remote_addr, uint16_t remote_port) { - if ((family != AF_INET) && (family != AF_INET6)) - return -1; +int facemgr_cfg_rule_set_overlay(facemgr_cfg_rule_t *rule, int family, + ip_address_t *local_addr, uint16_t local_port, + ip_address_t *remote_addr, + uint16_t remote_port) { + if ((family != AF_INET) && (family != AF_INET6)) return -1; - facemgr_cfg_overlay_t * overlay = facemgr_cfg_overlay_create(); - if (local_addr) { - overlay->is_local_addr = true; - overlay->local_addr = *local_addr; - } - if (IS_VALID_PORT(local_port)) { - overlay->is_local_port = true; - overlay->local_port = local_port; - } - if (remote_addr) { - overlay->is_remote_addr = true; - overlay->remote_addr = *remote_addr; - } - if (IS_VALID_PORT(remote_port)) { - overlay->is_remote_port = true; - overlay->remote_port = remote_port; - } + facemgr_cfg_overlay_t *overlay = facemgr_cfg_overlay_create(); + if (local_addr) { + overlay->is_local_addr = true; + overlay->local_addr = *local_addr; + } + if (IS_VALID_PORT(local_port)) { + overlay->is_local_port = true; + overlay->local_port = local_port; + } + if (remote_addr) { + overlay->is_remote_addr = true; + overlay->remote_addr = *remote_addr; + } + if (IS_VALID_PORT(remote_port)) { + overlay->is_remote_port = true; + overlay->remote_port = remote_port; + } - switch(family) { - case AF_INET: - rule->override.overlays.v4 = overlay; - break; + switch (family) { + case AF_INET: + rule->override.overlays.v4 = overlay; + break; - case AF_INET6: - rule->override.overlays.v6 = overlay; - break; + case AF_INET6: + rule->override.overlays.v6 = overlay; + break; - default: - return -1; - } + default: + return -1; + } - return 0; + return 0; } -int facemgr_rule_unset_overlay(facemgr_cfg_rule_t * rule, int family) -{ - if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC)) - return -1; +int facemgr_rule_unset_overlay(facemgr_cfg_rule_t *rule, int family) { + if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC)) + return -1; - if ((family == AF_UNSPEC) || (family == AF_INET)) { - if (rule->override.overlays.v4) { - facemgr_cfg_overlay_free(rule->override.overlays.v4); - rule->override.overlays.v4 = NULL; - } - } - if ((family == AF_UNSPEC) || (family == AF_INET6)) { - if (rule->override.overlays.v6) { - facemgr_cfg_overlay_free(rule->override.overlays.v6); - rule->override.overlays.v6 = NULL; - } + if ((family == AF_UNSPEC) || (family == AF_INET)) { + if (rule->override.overlays.v4) { + facemgr_cfg_overlay_free(rule->override.overlays.v4); + rule->override.overlays.v4 = NULL; } - return 0; -} - -int facemgr_cfg_rule_cmp(const facemgr_cfg_rule_t * r1, const facemgr_cfg_rule_t * r2) -{ - /* - * We implement a lexicographic order on the tuple (interface_name, - * interface_type) - */ - - /* We need to handle NULL cases out of strcmp */ - if (!r1->match.interface_name) { - if (r2->match.interface_name) - return 1; - else - goto BOTH_NULL; - } else { - if (!r2->match.interface_name) - return -1; + } + if ((family == AF_UNSPEC) || (family == AF_INET6)) { + if (rule->override.overlays.v6) { + facemgr_cfg_overlay_free(rule->override.overlays.v6); + rule->override.overlays.v6 = NULL; } - - - /* Only if both are non-NULL, we proceed to strcmp */ - int rc = strcmp(r1->match.interface_name, r2->match.interface_name); - if (rc != 0) - return rc; + } + return 0; +} + +int facemgr_cfg_rule_cmp(const facemgr_cfg_rule_t *r1, + const facemgr_cfg_rule_t *r2) { + /* + * We implement a lexicographic order on the tuple (interface_name, + * interface_type) + */ + + /* We need to handle NULL cases out of strcmp */ + if (!r1->match.interface_name) { + if (r2->match.interface_name) + return 1; + else + goto BOTH_NULL; + } else { + if (!r2->match.interface_name) return -1; + } + + /* Only if both are non-NULL, we proceed to strcmp */ + int rc = strcmp(r1->match.interface_name, r2->match.interface_name); + if (rc != 0) return rc; BOTH_NULL: - return r1->match.interface_type - r2->match.interface_type; + return r1->match.interface_type - r2->match.interface_type; } /* General */ TYPEDEF_SET_H(facemgr_cfg_rule_set, facemgr_cfg_rule_t *); -TYPEDEF_SET(facemgr_cfg_rule_set, facemgr_cfg_rule_t *, facemgr_cfg_rule_cmp, generic_snprintf); +TYPEDEF_SET(facemgr_cfg_rule_set, facemgr_cfg_rule_t *, facemgr_cfg_rule_cmp, + generic_snprintf); struct facemgr_cfg_s { - facemgr_cfg_override_t global; - facemgr_cfg_rule_set_t * rule_set; - facelet_array_t * static_facelets; - //log_cfg_t log; + facemgr_cfg_override_t global; + facemgr_cfg_rule_set_t *rule_set; + facelet_array_t *static_facelets; + // log_cfg_t log; }; -facemgr_cfg_t * facemgr_cfg_create() -{ - facemgr_cfg_t * cfg = malloc(sizeof(facemgr_cfg_t)); - if (!cfg) { - ERROR("[facemgr_cfg_create] Error allocating face manager configuration"); - goto ERR_MALLOC; - } +facemgr_cfg_t *facemgr_cfg_create() { + facemgr_cfg_t *cfg = malloc(sizeof(facemgr_cfg_t)); + if (!cfg) { + ERROR("[facemgr_cfg_create] Error allocating face manager configuration"); + goto ERR_MALLOC; + } - int rc = facemgr_cfg_initialize(cfg); - if (rc < 0) { - ERROR("[facemgr_cfg_create] Error initializing face manager configuration"); - goto ERR_INIT; - } + int rc = facemgr_cfg_initialize(cfg); + if (rc < 0) { + ERROR("[facemgr_cfg_create] Error initializing face manager configuration"); + goto ERR_INIT; + } - return cfg; + return cfg; ERR_INIT: - free(cfg); + free(cfg); ERR_MALLOC: - return NULL; + return NULL; } -void facemgr_cfg_free(facemgr_cfg_t * cfg) -{ - facemgr_cfg_finalize(cfg); - free(cfg); +void facemgr_cfg_free(facemgr_cfg_t *cfg) { + facemgr_cfg_finalize(cfg); + free(cfg); } -int facemgr_cfg_initialize(facemgr_cfg_t * cfg) -{ - int rc = facemgr_cfg_override_initialize(&cfg->global); - if (rc < 0) { - ERROR("[facemgr_cfg_initialize] Error initializing global values"); - goto ERR_OVERRIDE; - } +int facemgr_cfg_initialize(facemgr_cfg_t *cfg) { + int rc = facemgr_cfg_override_initialize(&cfg->global); + if (rc < 0) { + ERROR("[facemgr_cfg_initialize] Error initializing global values"); + goto ERR_OVERRIDE; + } - cfg->rule_set = facemgr_cfg_rule_set_create(); - if (!cfg->rule_set) { - ERROR("[facemgr_cfg_initialize] Error creating rule set"); - goto ERR_RULE_SET; - } + cfg->rule_set = facemgr_cfg_rule_set_create(); + if (!cfg->rule_set) { + ERROR("[facemgr_cfg_initialize] Error creating rule set"); + goto ERR_RULE_SET; + } - cfg->static_facelets = facelet_array_create(cfg->static_facelets); - if (!cfg->static_facelets) { - ERROR("[facemgr_cfg_initialize] Error creating static facelet set"); - goto ERR_STATIC; - } + cfg->static_facelets = facelet_array_create(); + if (!cfg->static_facelets) { + ERROR("[facemgr_cfg_initialize] Error creating static facelet set"); + goto ERR_STATIC; + } - return 0; + return 0; ERR_STATIC: - facemgr_cfg_rule_set_free(cfg->rule_set); + facemgr_cfg_rule_set_free(cfg->rule_set); ERR_RULE_SET: - facemgr_cfg_override_finalize(&cfg->global); + facemgr_cfg_override_finalize(&cfg->global); ERR_OVERRIDE: - return -1; -} - -int facemgr_cfg_finalize(facemgr_cfg_t * cfg) -{ - /* TODO Free all rules */ - facemgr_cfg_rule_t ** rule_array; - int n = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); - if (n < 0) { - ERROR("[facemgr_cfg_finalize] Could not retrieve rule set array from configuration"); - } else { - for (unsigned i = 0; i < n; i++) { - facemgr_cfg_rule_t * rule = rule_array[i]; - if (facemgr_cfg_rule_set_remove(cfg->rule_set, rule, NULL) < 0) { - ERROR("[facemgr_cfg_finalize] Could not remove rule from set"); - } - facemgr_cfg_rule_free(rule); - } - free(rule_array); + return -1; +} + +int facemgr_cfg_finalize(facemgr_cfg_t *cfg) { + /* TODO Free all rules */ + facemgr_cfg_rule_t **rule_array; + int n = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); + if (n < 0) { + ERROR( + "[facemgr_cfg_finalize] Could not retrieve rule set array from " + "configuration"); + } else { + for (unsigned i = 0; i < n; i++) { + facemgr_cfg_rule_t *rule = rule_array[i]; + if (!rule) continue; /* Should not occur */ + if (facemgr_cfg_rule_set_remove(cfg->rule_set, rule, NULL) < 0) { + ERROR("[facemgr_cfg_finalize] Could not remove rule from set"); + } + facemgr_cfg_rule_free(rule); } - facemgr_cfg_rule_set_free(cfg->rule_set); - - /* Free all facelets from static array */ - for (unsigned i = 0; i < facelet_array_len(cfg->static_facelets); i++) { - facelet_t * facelet; - if (facelet_array_get_index(cfg->static_facelets, i, &facelet) < 0) { - ERROR("[facemgr_cfg_finalize] Error getting facelet in array"); - continue; - } - if (facelet_array_remove_index(cfg->static_facelets, i, NULL)) { - ERROR("[facemgr_cfg_finalize] Could not purge facelet from static set"); - } - facelet_free(facelet); + free(rule_array); + } + facemgr_cfg_rule_set_free(cfg->rule_set); + + /* Free all facelets from static array */ + for (unsigned i = 0; i < facelet_array_len(cfg->static_facelets); i++) { + facelet_t *facelet; + if (facelet_array_get_index(cfg->static_facelets, i, &facelet) < 0) { + ERROR("[facemgr_cfg_finalize] Error getting facelet in array"); + continue; } + if (facelet_array_remove_index(cfg->static_facelets, i, NULL)) { + ERROR("[facemgr_cfg_finalize] Could not purge facelet from static set"); + } + facelet_free(facelet); + } - facelet_array_free(cfg->static_facelets); + facelet_array_free(cfg->static_facelets); - return facemgr_cfg_override_finalize(&cfg->global); + return facemgr_cfg_override_finalize(&cfg->global); } -void facemgr_cfg_dump(facemgr_cfg_t * cfg) -{ - return; /* NOT IMPLEMENTED */ -} +void facemgr_cfg_dump(facemgr_cfg_t *cfg) { return; /* NOT IMPLEMENTED */ } /* General */ -int facemgr_cfg_set_face_type(facemgr_cfg_t * cfg, facemgr_face_type_t * face_type) -{ - cfg->global.is_face_type = true; - cfg->global.face_type = *face_type; - return 0; -} - -int facemgr_cfg_unset_face_type(facemgr_cfg_t * cfg) -{ - cfg->global.is_face_type = false; - cfg->global.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */ - return 0; -} - -int facemgr_cfg_set_discovery(facemgr_cfg_t * cfg, bool status) -{ - cfg->global.is_discovery = true; - cfg->global.discovery = status; - return 0; -} - -int facemgr_cfg_unset_discovery(facemgr_cfg_t * cfg) -{ - cfg->global.is_discovery = false; - return 0; -} - -int facemgr_cfg_set_ipv4(facemgr_cfg_t * cfg, bool status) -{ - cfg->global.is_ipv4 = true; - cfg->global.ipv4 = status; - DEBUG("<global>"); - DEBUG(" <ipv4>%d</ipv4>", cfg->global.ipv4); - DEBUG("</global>"); - return 0; -} - -int facemgr_cfg_unset_ipv4(facemgr_cfg_t * cfg) -{ - cfg->global.is_ipv4 = false; - return 0; -} - -int facemgr_cfg_set_ipv6(facemgr_cfg_t * cfg, bool status) -{ - cfg->global.is_ipv6 = true; - cfg->global.ipv6 = status; - DEBUG("<global>"); - DEBUG(" <ipv6>%d</ipv6>", cfg->global.ipv6); - DEBUG("</global>"); - return 0; -} - -int facemgr_cfg_unset_ipv6(facemgr_cfg_t * cfg) -{ - cfg->global.is_ipv6 = false; - return 0; -} - -int facemgr_cfg_set_overlay(facemgr_cfg_t * cfg, int family, - ip_address_t * local_addr, uint16_t local_port, - ip_address_t * remote_addr, uint16_t remote_port) -{ - if ((family != AF_INET) && (family != AF_INET6)) - return -1; - - facemgr_cfg_overlay_t * overlay = facemgr_cfg_overlay_create(); - if (local_addr) { - overlay->is_local_addr = true; - overlay->local_addr = *local_addr; +int facemgr_cfg_set_face_type(facemgr_cfg_t *cfg, + facemgr_face_type_t *face_type) { + cfg->global.is_face_type = true; + cfg->global.face_type = *face_type; + return 0; +} + +int facemgr_cfg_unset_face_type(facemgr_cfg_t *cfg) { + cfg->global.is_face_type = false; + cfg->global.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */ + return 0; +} + +int facemgr_cfg_set_discovery(facemgr_cfg_t *cfg, bool status) { + cfg->global.is_discovery = true; + cfg->global.discovery = status; + return 0; +} + +int facemgr_cfg_unset_discovery(facemgr_cfg_t *cfg) { + cfg->global.is_discovery = false; + return 0; +} + +int facemgr_cfg_set_ipv4(facemgr_cfg_t *cfg, bool status) { + cfg->global.is_ipv4 = true; + cfg->global.ipv4 = status; + DEBUG("<global>"); + DEBUG(" <ipv4>%d</ipv4>", cfg->global.ipv4); + DEBUG("</global>"); + return 0; +} + +int facemgr_cfg_unset_ipv4(facemgr_cfg_t *cfg) { + cfg->global.is_ipv4 = false; + return 0; +} + +int facemgr_cfg_set_ipv6(facemgr_cfg_t *cfg, bool status) { + cfg->global.is_ipv6 = true; + cfg->global.ipv6 = status; + DEBUG("<global>"); + DEBUG(" <ipv6>%d</ipv6>", cfg->global.ipv6); + DEBUG("</global>"); + return 0; +} + +int facemgr_cfg_unset_ipv6(facemgr_cfg_t *cfg) { + cfg->global.is_ipv6 = false; + return 0; +} + +int facemgr_cfg_set_overlay(facemgr_cfg_t *cfg, int family, + ip_address_t *local_addr, uint16_t local_port, + ip_address_t *remote_addr, uint16_t remote_port) { + if ((family != AF_INET) && (family != AF_INET6)) return -1; + + facemgr_cfg_overlay_t *overlay = facemgr_cfg_overlay_create(); + if (local_addr) { + overlay->is_local_addr = true; + overlay->local_addr = *local_addr; + } + if (IS_VALID_PORT(local_port)) { + overlay->is_local_port = true; + overlay->local_port = local_port; + } + if (remote_addr) { + overlay->is_remote_addr = true; + overlay->remote_addr = *remote_addr; + } + if (IS_VALID_PORT(remote_port)) { + overlay->is_remote_port = true; + overlay->remote_port = remote_port; + } + + DEBUG("facemgr_cfg_set_overlay"); + + switch (family) { + case AF_INET: + cfg->global.overlays.v4 = overlay; + break; + + case AF_INET6: + cfg->global.overlays.v6 = overlay; + break; + + default: + return -1; + } + + DEBUG("<global>"); + DEBUG(" <overlay>"); + if (overlay) { + DEBUG(" <ipv4>"); + if (overlay->is_local_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, &overlay->local_addr, AF_INET); + DEBUG(" <local_addr>%s</local_addr>", buf); } - if (IS_VALID_PORT(local_port)) { - overlay->is_local_port = true; - overlay->local_port = local_port; + if (overlay->is_local_port) { + DEBUG(" <local_port>%d</local_port>", overlay->local_port); } - if (remote_addr) { - overlay->is_remote_addr = true; - overlay->remote_addr = *remote_addr; - } - if (IS_VALID_PORT(remote_port)) { - overlay->is_remote_port = true; - overlay->remote_port = remote_port; - } - - DEBUG("facemgr_cfg_set_overlay"); - - switch(family) { - case AF_INET: - cfg->global.overlays.v4 = overlay; - break; - - case AF_INET6: - cfg->global.overlays.v6 = overlay; - break; - - default: - return -1; + if (overlay->is_remote_addr) { + char buf[MAXSZ_IP_ADDRESS]; + ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, &overlay->remote_addr, + AF_INET); + DEBUG(" <remote_addr>%s</remote_addr>", buf); } - - DEBUG("<global>"); - DEBUG(" <overlay>"); - if (overlay) { - DEBUG(" <ipv4>"); - if (overlay->is_local_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &overlay->local_addr, AF_INET); - DEBUG(" <local_addr>%s</local_addr>", buf); - } - if (overlay->is_local_port) { - DEBUG(" <local_port>%d</local_port>", - overlay->local_port); - } - if (overlay->is_remote_addr) { - char buf[MAXSZ_IP_ADDRESS]; - ip_address_snprintf(buf, MAXSZ_IP_ADDRESS, - &overlay->remote_addr, AF_INET); - DEBUG(" <remote_addr>%s</remote_addr>", buf); - } - if (overlay->is_remote_port) { - DEBUG(" <remote_port>%d</remote_port>", - overlay->remote_port); - } - DEBUG(" </ipv4>"); + if (overlay->is_remote_port) { + DEBUG(" <remote_port>%d</remote_port>", overlay->remote_port); } - DEBUG(" </overlay>"); - DEBUG("</global>"); + DEBUG(" </ipv4>"); + } + DEBUG(" </overlay>"); + DEBUG("</global>"); - return 0; + return 0; } -int facemgr_cfg_unset_overlay(facemgr_cfg_t * cfg, int family) -{ - if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC)) - return -1; +int facemgr_cfg_unset_overlay(facemgr_cfg_t *cfg, int family) { + if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC)) + return -1; - if ((family == AF_UNSPEC) || (family == AF_INET)) { - if (cfg->global.overlays.v4) { - facemgr_cfg_overlay_free(cfg->global.overlays.v4); - cfg->global.overlays.v4 = NULL; - } + if ((family == AF_UNSPEC) || (family == AF_INET)) { + if (cfg->global.overlays.v4) { + facemgr_cfg_overlay_free(cfg->global.overlays.v4); + cfg->global.overlays.v4 = NULL; } - if ((family == AF_UNSPEC) || (family == AF_INET6)) { - if (cfg->global.overlays.v6) { - facemgr_cfg_overlay_free(cfg->global.overlays.v6); - cfg->global.overlays.v6 = NULL; - } + } + if ((family == AF_UNSPEC) || (family == AF_INET6)) { + if (cfg->global.overlays.v6) { + facemgr_cfg_overlay_free(cfg->global.overlays.v6); + cfg->global.overlays.v6 = NULL; } - return 0; + } + return 0; } -int facemgr_cfg_add_rule(facemgr_cfg_t * cfg, facemgr_cfg_rule_t * rule) -{ - facemgr_cfg_rule_dump(rule); - return facemgr_cfg_rule_set_add(cfg->rule_set, rule); +int facemgr_cfg_add_rule(facemgr_cfg_t *cfg, facemgr_cfg_rule_t *rule) { + facemgr_cfg_rule_dump(rule); + return facemgr_cfg_rule_set_add(cfg->rule_set, rule); } -int facemgr_cfg_del_rule(facemgr_cfg_t * cfg, facemgr_cfg_rule_t * rule) -{ - return facemgr_cfg_rule_set_remove(cfg->rule_set, rule, NULL); +int facemgr_cfg_del_rule(facemgr_cfg_t *cfg, facemgr_cfg_rule_t *rule) { + return facemgr_cfg_rule_set_remove(cfg->rule_set, rule, NULL); } -int facemgr_cfg_get_rule(const facemgr_cfg_t * cfg, const char * interface_name, - netdevice_type_t interface_type, facemgr_cfg_rule_t ** rule) { - facemgr_cfg_rule_t rule_search = { - .match = { - .interface_name = interface_name, - .interface_type = interface_type, - }, - }; - return facemgr_cfg_rule_set_get(cfg->rule_set, &rule_search, rule); +int facemgr_cfg_get_rule(const facemgr_cfg_t *cfg, const char *interface_name, + netdevice_type_t interface_type, + facemgr_cfg_rule_t **rule) { + facemgr_cfg_rule_t rule_search = { + .match = + { + .interface_name = interface_name, + .interface_type = interface_type, + }, + }; + return facemgr_cfg_rule_set_get(cfg->rule_set, &rule_search, rule); } /* Query API */ @@ -709,506 +661,476 @@ int facemgr_cfg_get_rule(const facemgr_cfg_t * cfg, const char * interface_name, * TODO: * - until we have proper indexes we loop through the whole structure */ -int facemgr_cfg_get_override(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - facemgr_cfg_override_t ** override) -{ - if (!netdevice) { - *override = NULL; - return 0; - } - - facemgr_cfg_rule_t **rule_array; - int rc = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); - if (rc < 0) { - ERROR("facemgr_cfg_rule_set_get_array failed"); - return rc; - } - for (unsigned i = 0; i < rc; i++) { - const char * interface_name = rule_array[i]->match.interface_name; - /* Check match for interface name */ - if (interface_name && (strcmp(interface_name, netdevice->name) != 0)) - continue; - /* Check match for interface type */ - if (rule_array[i]->match.interface_type != NETDEVICE_TYPE_UNDEFINED) { -//#ifdef __ANDROID__ - if (netdevice_type != rule_array[i]->match.interface_type) - continue; -//#else -// ERROR("Match on interface type is currently not implemented"); -// goto ERR_ARRAY; -//#endif /* __ANDROID__ */ - } - /* Found match... do we have an override for face_type */ - *override = &rule_array[i]->override; - goto FOUND; - } - +int facemgr_cfg_get_override(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + facemgr_cfg_override_t **override) { + if (!netdevice) { *override = NULL; - -FOUND: - free(rule_array); return 0; - -//#ifndef __ANDROID__ -//ERR_ARRAY: -// free(rule_array); -// return -1; -//#endif /* __ANDROID__ */ -} - -int facemgr_cfg_get_face_type(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - facemgr_face_type_t * face_type) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) { - ERROR("get override failed"); - return rc; + } + + facemgr_cfg_rule_t **rule_array; + int rc = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); + if (rc < 0) { + ERROR("facemgr_cfg_rule_set_get_array failed"); + return rc; + } + for (unsigned i = 0; i < rc; i++) { + facemgr_cfg_rule_t *rule = rule_array[i]; + if (!rule) continue; /* Should not occur */ + const char *interface_name = rule->match.interface_name; + /* Check match for interface name */ + if (interface_name && (strcmp(interface_name, netdevice->name) != 0)) + continue; + /* Check match for interface type */ + if (rule->match.interface_type != NETDEVICE_TYPE_UNDEFINED) { + //#ifdef __ANDROID__ + if (netdevice_type != rule->match.interface_type) continue; + //#else + // ERROR("Match on interface type is currently not + // implemented"); goto ERR_ARRAY; + //#endif /* __ANDROID__ */ } + /* Found match... do we have an override for face_type */ + *override = &rule->override; + goto FOUND; + } - if ((override) && (override->is_face_type)) { - *face_type = override->face_type; - return 0; - } - - *face_type = cfg->global.is_face_type - ? cfg->global.face_type - : FACEMGR_FACE_TYPE_DEFAULT; - - return 0; -} - -int facemgr_cfg_get_discovery(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - bool * discovery) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - if ((override) && (override->is_discovery)) { - *discovery = override->discovery; - return 0; - } - - *discovery = cfg->global.is_discovery - ? cfg->global.discovery - : FACEMGR_CFG_DEFAULT_DISCOVERY; - return 0; -} - -int facemgr_cfg_get_ipv4(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - bool * ipv4) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; + *override = NULL; - if ((override) && (override->is_ipv4)) { - *ipv4 = override->ipv4; - return 0; - } - - *ipv4 = cfg->global.is_ipv4 - ? cfg->global.ipv4 - : FACEMGR_CFG_DEFAULT_IPV4; - return 0; -} - -int facemgr_cfg_get_ipv6(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - bool * ipv6) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - if ((override) && (override->is_ipv6)) { - *ipv6 = override->ipv6; - return 0; - } - - *ipv6 = cfg->global.is_ipv6 - ? cfg->global.ipv6 - : FACEMGR_CFG_DEFAULT_IPV6; +FOUND: + free(rule_array); + return 0; + + //#ifndef __ANDROID__ + // ERR_ARRAY: + // free(rule_array); + // return -1; + //#endif /* __ANDROID__ */ +} + +int facemgr_cfg_get_face_type(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + facemgr_face_type_t *face_type) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) { + ERROR("get override failed"); + return rc; + } + + if ((override) && (override->is_face_type)) { + *face_type = override->face_type; return 0; -} + } -int facemgr_cfg_get_ignore(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - bool * ignore) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; + *face_type = cfg->global.is_face_type ? cfg->global.face_type + : FACEMGR_FACE_TYPE_DEFAULT; - if ((override) && (override->is_ignore)) { - *ignore = override->ignore; - return 0; - } - - assert (!cfg->global.is_ignore); - - *ignore = (netdevice && (netdevice->name[0] != '\0') && strcmp(netdevice->name, "lo") == 0); - - return 0; + return 0; } -int facemgr_cfg_get_overlay_local_addr(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - int family, ip_address_t * addr) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - switch (family) { - case AF_INET: - if ((override) && (override->overlays.v4) && (override->overlays.v4->is_local_addr)) { - *addr = override->overlays.v4->local_addr; - return 0; - } - if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_local_addr)) { - *addr = cfg->global.overlays.v4->local_addr; - return 0; - } - break; - case AF_INET6: - if ((override) && (override->overlays.v6) && (override->overlays.v6->is_local_addr)) { - *addr = override->overlays.v6->local_addr; - return 0; - } - if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_local_addr)) { - *addr = cfg->global.overlays.v6->local_addr; - return 0; - } - break; - case AF_UNSPEC: - break; - default: - return -1; - } +int facemgr_cfg_get_discovery(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + bool *discovery) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; - *addr = IP_ADDRESS_EMPTY; + if ((override) && (override->is_discovery)) { + *discovery = override->discovery; return 0; -} - -int facemgr_cfg_get_overlay_local_port(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - int family, u16 * port) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - switch (family) { - case AF_INET: - if ((override) && (override->overlays.v4) && (override->overlays.v4->is_local_port)) { - *port = override->overlays.v4->local_port; - return 0; - } - if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_local_port)) { - *port = cfg->global.overlays.v4->local_port; - return 0; - } - break; - case AF_INET6: - if ((override) && (override->overlays.v6) && (override->overlays.v6->is_local_port)) { - *port = override->overlays.v6->local_port; - return 0; - } - if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_local_port)) { - *port = cfg->global.overlays.v6->local_port; - return 0; - } - break; - case AF_UNSPEC: - break; - default: - return -1; - } + } - *port = HICN_DEFAULT_PORT; - return 0; + *discovery = cfg->global.is_discovery ? cfg->global.discovery + : FACEMGR_CFG_DEFAULT_DISCOVERY; + return 0; } -int facemgr_cfg_get_overlay_remote_addr(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - int family, ip_address_t * addr) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - switch (family) { - case AF_INET: - if ((override) && (override->overlays.v4) && (override->overlays.v4->is_remote_addr)) { - DEBUG("remote addr v4 from override"); - *addr = override->overlays.v4->remote_addr; - return 0; - } - if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_remote_addr)) { - DEBUG("remote addr v4 from global"); - *addr = cfg->global.overlays.v4->remote_addr; - return 0; - } - break; - case AF_INET6: - if ((override) && (override->overlays.v6) && (override->overlays.v6->is_remote_addr)) { - DEBUG("remote addr v6 from override"); - *addr = override->overlays.v6->remote_addr; - return 0; - } - if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_remote_addr)) { - DEBUG("remote addr v6 from global"); - *addr = cfg->global.overlays.v6->remote_addr; - return 0; - } - break; - case AF_UNSPEC: - break; - default: - return -1; - } +int facemgr_cfg_get_ipv4(const facemgr_cfg_t *cfg, const netdevice_t *netdevice, + netdevice_type_t netdevice_type, bool *ipv4) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; - DEBUG("remote addr empty"); - *addr = IP_ADDRESS_EMPTY; + if ((override) && (override->is_ipv4)) { + *ipv4 = override->ipv4; return 0; -} - -int facemgr_cfg_get_overlay_remote_port(const facemgr_cfg_t * cfg, - const netdevice_t * netdevice, netdevice_type_t netdevice_type, - int family, u16 * port) -{ - facemgr_cfg_override_t * override; - int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, - &override); - if (rc < 0) - return rc; - - switch (family) { - case AF_INET: - if ((override) && (override->overlays.v4) && (override->overlays.v4->is_remote_port)) { - *port = override->overlays.v4->remote_port; - return 0; - } - if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_remote_port)) { - *port = cfg->global.overlays.v4->remote_port; - return 0; - } - break; - case AF_INET6: - if ((override) && (override->overlays.v6) && (override->overlays.v6->is_remote_port)) { - *port = override->overlays.v6->remote_port; - return 0; - } - if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_remote_port)) { - *port = cfg->global.overlays.v6->remote_port; - return 0; - } - break; - case AF_UNSPEC: - break; - default: - return -1; - } + } - *port = HICN_DEFAULT_PORT; - return 0; + *ipv4 = cfg->global.is_ipv4 ? cfg->global.ipv4 : FACEMGR_CFG_DEFAULT_IPV4; + return 0; } -int facemgr_cfg_rule_get(const facemgr_cfg_t * cfg, const netdevice_t netdevice, netdevice_type_t - netdevice_type, facemgr_cfg_rule_t ** rule) -{ - facemgr_cfg_rule_t **rule_array; - *rule = NULL; - int n = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); - if (n < 0) { - ERROR("facemgr_cfg_rule_set_get_array failed"); - return n; - } - for (unsigned i = 0; i < n; i++) { - const char * interface_name = rule_array[i]->match.interface_name; - /* Check match for interface name */ - if (netdevice.name[0] != '\0') { - if (!interface_name) - continue; - if (strcmp(netdevice.name, interface_name) != 0) - continue; - } else { - if (interface_name && interface_name[0] != '\0') - continue; - } - - /* Check match for netdevice_type */ - if (netdevice_type != rule_array[i]->match.interface_type) - continue; - - /* Found */ - *rule = rule_array[i]; - break; - } - return 0; -} +int facemgr_cfg_get_ipv6(const facemgr_cfg_t *cfg, const netdevice_t *netdevice, + netdevice_type_t netdevice_type, bool *ipv6) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; -int facemgr_cfg_rule_get_face_type(const facemgr_cfg_rule_t * rule, - facemgr_face_type_t * face_type) -{ - if (!rule->override.is_face_type) - return -1; - *face_type = rule->override.face_type; + if ((override) && (override->is_ipv6)) { + *ipv6 = override->ipv6; return 0; -} + } -int facemgr_cfg_rule_get_discovery(const facemgr_cfg_rule_t * rule, bool * discovery) -{ - if (!rule->override.is_discovery) - return -1; - *discovery = rule->override.discovery; - return 0; + *ipv6 = cfg->global.is_ipv6 ? cfg->global.ipv6 : FACEMGR_CFG_DEFAULT_IPV6; + return 0; } -int facemgr_cfg_rule_get_ignore(const facemgr_cfg_rule_t * rule, bool * ignore) -{ - if (!rule->override.is_ignore) - return -1; - *ignore = rule->override.ignore; - return 0; -} +int facemgr_cfg_get_ignore(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, bool *ignore) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; -int facemgr_cfg_rule_get_ipv4(const facemgr_cfg_rule_t * rule, bool * ipv4) -{ - if (!rule->override.is_ipv4) - return -1; - *ipv4 = rule->override.ipv4; + if ((override) && (override->is_ignore)) { + *ignore = override->ignore; return 0; -} + } -int facemgr_cfg_rule_get_ipv6(const facemgr_cfg_rule_t * rule, bool * ipv6) -{ - if (!rule->override.is_ipv6) - return -1; - *ipv6 = rule->override.ipv6; - return 0; -} + assert(!cfg->global.is_ignore); -int facemgr_cfg_rule_get_overlay_local_addr(const facemgr_cfg_rule_t * rule, int family, - ip_address_t * addr) -{ - facemgr_cfg_overlay_t * overlay = NULL; - switch(family) { - case AF_INET: - overlay = rule->override.overlays.v4; - break; - case AF_INET6: - overlay = rule->override.overlays.v6; - break; - default: - return -1; - } - if (!overlay->is_local_addr) - return -1; - *addr = overlay->local_addr; - return 0; -} + *ignore = (netdevice && (netdevice->name[0] != '\0') && + strcmp(netdevice->name, "lo") == 0); -int facemgr_cfg_rule_get_overlay_local_port(const facemgr_cfg_rule_t * rule, int family, - uint16_t * port) -{ - facemgr_cfg_overlay_t * overlay = NULL; - switch(family) { - case AF_INET: - overlay = rule->override.overlays.v4; - break; - case AF_INET6: - overlay = rule->override.overlays.v6; - break; - default: - return -1; - } - if (!overlay->is_local_port) - return -1; - *port = overlay->local_port; - return 0; + return 0; } -int facemgr_cfg_rule_get_overlay_remote_addr(const facemgr_cfg_rule_t * rule, int family, - ip_address_t * addr) -{ - facemgr_cfg_overlay_t * overlay = NULL; - switch(family) { - case AF_INET: - overlay = rule->override.overlays.v4; - break; - case AF_INET6: - overlay = rule->override.overlays.v6; - break; - default: - return -1; - } - if (!overlay->is_remote_addr) - return -1; - *addr = overlay->remote_addr; - return 0; -} +int facemgr_cfg_get_overlay_local_addr(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + int family, ip_address_t *addr) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; -int facemgr_cfg_rule_get_overlay_remote_port(const facemgr_cfg_rule_t * rule, int family, - uint16_t * port) -{ - facemgr_cfg_overlay_t * overlay = NULL; - switch(family) { - case AF_INET: - overlay = rule->override.overlays.v4; - break; - case AF_INET6: - overlay = rule->override.overlays.v6; - break; - default: - return -1; + switch (family) { + case AF_INET: + if ((override) && (override->overlays.v4) && + (override->overlays.v4->is_local_addr)) { + *addr = override->overlays.v4->local_addr; + return 0; + } + if ((cfg->global.overlays.v4) && + (cfg->global.overlays.v4->is_local_addr)) { + *addr = cfg->global.overlays.v4->local_addr; + return 0; + } + break; + case AF_INET6: + if ((override) && (override->overlays.v6) && + (override->overlays.v6->is_local_addr)) { + *addr = override->overlays.v6->local_addr; + return 0; + } + if ((cfg->global.overlays.v6) && + (cfg->global.overlays.v6->is_local_addr)) { + *addr = cfg->global.overlays.v6->local_addr; + return 0; + } + break; + case AF_UNSPEC: + break; + default: + return -1; + } + + *addr = IP_ADDRESS_EMPTY; + return 0; +} + +int facemgr_cfg_get_overlay_local_port(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + int family, u16 *port) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; + + switch (family) { + case AF_INET: + if ((override) && (override->overlays.v4) && + (override->overlays.v4->is_local_port)) { + *port = override->overlays.v4->local_port; + return 0; + } + if ((cfg->global.overlays.v4) && + (cfg->global.overlays.v4->is_local_port)) { + *port = cfg->global.overlays.v4->local_port; + return 0; + } + break; + case AF_INET6: + if ((override) && (override->overlays.v6) && + (override->overlays.v6->is_local_port)) { + *port = override->overlays.v6->local_port; + return 0; + } + if ((cfg->global.overlays.v6) && + (cfg->global.overlays.v6->is_local_port)) { + *port = cfg->global.overlays.v6->local_port; + return 0; + } + break; + case AF_UNSPEC: + break; + default: + return -1; + } + + *port = HICN_DEFAULT_PORT; + return 0; +} + +int facemgr_cfg_get_overlay_remote_addr(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + int family, ip_address_t *addr) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; + + switch (family) { + case AF_INET: + if ((override) && (override->overlays.v4) && + (override->overlays.v4->is_remote_addr)) { + DEBUG("remote addr v4 from override"); + *addr = override->overlays.v4->remote_addr; + return 0; + } + if ((cfg->global.overlays.v4) && + (cfg->global.overlays.v4->is_remote_addr)) { + DEBUG("remote addr v4 from global"); + *addr = cfg->global.overlays.v4->remote_addr; + return 0; + } + break; + case AF_INET6: + if ((override) && (override->overlays.v6) && + (override->overlays.v6->is_remote_addr)) { + DEBUG("remote addr v6 from override"); + *addr = override->overlays.v6->remote_addr; + return 0; + } + if ((cfg->global.overlays.v6) && + (cfg->global.overlays.v6->is_remote_addr)) { + DEBUG("remote addr v6 from global"); + *addr = cfg->global.overlays.v6->remote_addr; + return 0; + } + break; + case AF_UNSPEC: + break; + default: + return -1; + } + + DEBUG("remote addr empty"); + *addr = IP_ADDRESS_EMPTY; + return 0; +} + +int facemgr_cfg_get_overlay_remote_port(const facemgr_cfg_t *cfg, + const netdevice_t *netdevice, + netdevice_type_t netdevice_type, + int family, u16 *port) { + facemgr_cfg_override_t *override; + int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type, &override); + if (rc < 0) return rc; + + switch (family) { + case AF_INET: + if ((override) && (override->overlays.v4) && + (override->overlays.v4->is_remote_port)) { + *port = override->overlays.v4->remote_port; + return 0; + } + if ((cfg->global.overlays.v4) && + (cfg->global.overlays.v4->is_remote_port)) { + *port = cfg->global.overlays.v4->remote_port; + return 0; + } + break; + case AF_INET6: + if ((override) && (override->overlays.v6) && + (override->overlays.v6->is_remote_port)) { + *port = override->overlays.v6->remote_port; + return 0; + } + if ((cfg->global.overlays.v6) && + (cfg->global.overlays.v6->is_remote_port)) { + *port = cfg->global.overlays.v6->remote_port; + return 0; + } + break; + case AF_UNSPEC: + break; + default: + return -1; + } + + *port = HICN_DEFAULT_PORT; + return 0; +} + +int facemgr_cfg_rule_get(const facemgr_cfg_t *cfg, const netdevice_t netdevice, + netdevice_type_t netdevice_type, + facemgr_cfg_rule_t **rule_p) { + facemgr_cfg_rule_t **rule_array; + *rule_p = NULL; + int n = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array); + if (n < 0) { + ERROR("facemgr_cfg_rule_set_get_array failed"); + return n; + } + for (unsigned i = 0; i < n; i++) { + facemgr_cfg_rule_t *rule = rule_array[i]; + if (!rule) continue; /* Should not occur */ + const char *interface_name = rule->match.interface_name; + /* Check match for interface name */ + if (netdevice.name[0] != '\0') { + if (!interface_name) continue; + if (strcmp(netdevice.name, interface_name) != 0) continue; + } else { + if (interface_name && interface_name[0] != '\0') continue; } - if (!overlay->is_remote_port) - return -1; - *port = overlay->remote_port; - return 0; -} -int facemgr_cfg_add_static_facelet(facemgr_cfg_t * cfg, facelet_t * facelet) -{ - char buf[MAXSZ_FACELET]; - facelet_snprintf(buf, MAXSZ_FACELET, facelet); - DEBUG("STATIC FACELET: %s", buf); - return facelet_array_add(cfg->static_facelets, facelet); -} - -int facemgr_cfg_remove_static_facelet(facemgr_cfg_t * cfg, facelet_t * facelet, - facelet_t ** removed_facelet) -{ - return facelet_array_remove(cfg->static_facelets, facelet, removed_facelet); -} - -int facemgr_cfg_get_static_facelet_array(const facemgr_cfg_t * cfg, facelet_t *** array) -{ - if (facelet_array_get_elements(cfg->static_facelets, array) < 0) { - ERROR("[facemgr_cfg_get_static_facelet_array] Error getting array elements"); - return -1; - } - return (int)facelet_array_len(cfg->static_facelets); + /* Check match for netdevice_type */ + if (netdevice_type != rule->match.interface_type) continue; + + /* Found */ + *rule_p = rule; + break; + } + return 0; +} + +int facemgr_cfg_rule_get_face_type(const facemgr_cfg_rule_t *rule, + facemgr_face_type_t *face_type) { + if (!rule->override.is_face_type) return -1; + *face_type = rule->override.face_type; + return 0; +} + +int facemgr_cfg_rule_get_discovery(const facemgr_cfg_rule_t *rule, + bool *discovery) { + if (!rule->override.is_discovery) return -1; + *discovery = rule->override.discovery; + return 0; +} + +int facemgr_cfg_rule_get_ignore(const facemgr_cfg_rule_t *rule, bool *ignore) { + if (!rule->override.is_ignore) return -1; + *ignore = rule->override.ignore; + return 0; +} + +int facemgr_cfg_rule_get_ipv4(const facemgr_cfg_rule_t *rule, bool *ipv4) { + if (!rule->override.is_ipv4) return -1; + *ipv4 = rule->override.ipv4; + return 0; +} + +int facemgr_cfg_rule_get_ipv6(const facemgr_cfg_rule_t *rule, bool *ipv6) { + if (!rule->override.is_ipv6) return -1; + *ipv6 = rule->override.ipv6; + return 0; +} + +int facemgr_cfg_rule_get_overlay_local_addr(const facemgr_cfg_rule_t *rule, + int family, ip_address_t *addr) { + facemgr_cfg_overlay_t *overlay = NULL; + switch (family) { + case AF_INET: + overlay = rule->override.overlays.v4; + break; + case AF_INET6: + overlay = rule->override.overlays.v6; + break; + default: + return -1; + } + if (!overlay->is_local_addr) return -1; + *addr = overlay->local_addr; + return 0; +} + +int facemgr_cfg_rule_get_overlay_local_port(const facemgr_cfg_rule_t *rule, + int family, uint16_t *port) { + facemgr_cfg_overlay_t *overlay = NULL; + switch (family) { + case AF_INET: + overlay = rule->override.overlays.v4; + break; + case AF_INET6: + overlay = rule->override.overlays.v6; + break; + default: + return -1; + } + if (!overlay->is_local_port) return -1; + *port = overlay->local_port; + return 0; +} + +int facemgr_cfg_rule_get_overlay_remote_addr(const facemgr_cfg_rule_t *rule, + int family, ip_address_t *addr) { + facemgr_cfg_overlay_t *overlay = NULL; + switch (family) { + case AF_INET: + overlay = rule->override.overlays.v4; + break; + case AF_INET6: + overlay = rule->override.overlays.v6; + break; + default: + return -1; + } + if (!overlay->is_remote_addr) return -1; + *addr = overlay->remote_addr; + return 0; +} + +int facemgr_cfg_rule_get_overlay_remote_port(const facemgr_cfg_rule_t *rule, + int family, uint16_t *port) { + facemgr_cfg_overlay_t *overlay = NULL; + switch (family) { + case AF_INET: + overlay = rule->override.overlays.v4; + break; + case AF_INET6: + overlay = rule->override.overlays.v6; + break; + default: + return -1; + } + if (!overlay->is_remote_port) return -1; + *port = overlay->remote_port; + return 0; +} + +int facemgr_cfg_add_static_facelet(facemgr_cfg_t *cfg, facelet_t *facelet) { + char buf[MAXSZ_FACELET]; + facelet_snprintf(buf, MAXSZ_FACELET, facelet); + DEBUG("STATIC FACELET: %s", buf); + return facelet_array_add(cfg->static_facelets, facelet); +} + +int facemgr_cfg_remove_static_facelet(facemgr_cfg_t *cfg, facelet_t *facelet, + facelet_t **removed_facelet) { + return facelet_array_remove(cfg->static_facelets, facelet, removed_facelet); +} + +int facemgr_cfg_get_static_facelet_array(const facemgr_cfg_t *cfg, + facelet_t ***array) { + if (facelet_array_get_elements(cfg->static_facelets, array) < 0) { + ERROR( + "[facemgr_cfg_get_static_facelet_array] Error getting array elements"); + return -1; + } + return (int)facelet_array_len(cfg->static_facelets); } diff --git a/ctrl/facemgr/src/cfg_file.c b/ctrl/facemgr/src/cfg_file.c index cb1ded1c9..966e35816 100644 --- a/ctrl/facemgr/src/cfg_file.c +++ b/ctrl/facemgr/src/cfg_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -18,338 +18,311 @@ * \brief Implementation of configuration file parsing */ -#include <unistd.h> // access +#include <unistd.h> // access #include <libconfig.h> #include <hicn/ctrl/route.h> #include "cfg_file.h" -#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x)) +#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x)) -static const char * DEFAULT_CFGFILES[] = { +static const char *DEFAULT_CFGFILES[] = { "/etc/facemgr.conf", "~/facemgr.conf", }; -int -probe_cfgfile(char * f) -{ - for (unsigned i = 0; i < ARRAYSIZE(DEFAULT_CFGFILES); i++) { - if (access(DEFAULT_CFGFILES[i], F_OK ) != -1) { - if (!realpath(DEFAULT_CFGFILES[i], f)) - continue; - return 0; - } +int probe_cfgfile(char *f) { + for (unsigned i = 0; i < ARRAYSIZE(DEFAULT_CFGFILES); i++) { + if (access(DEFAULT_CFGFILES[i], F_OK) != -1) { + if (!realpath(DEFAULT_CFGFILES[i], f)) continue; + return 0; } - return -1; + } + return -1; } -int -parse_config_global(facemgr_cfg_t * cfg, config_setting_t * setting) -{ - /* - face_type */ - - const char *face_type_str; - facemgr_face_type_t face_type; - if (config_setting_lookup_string(setting, "face_type", &face_type_str)) { - if (strcasecmp(face_type_str, "auto") == 0) { - face_type = FACEMGR_FACE_TYPE_DEFAULT; - } else - if (strcasecmp(face_type_str, "native-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; - } else - if (strcasecmp(face_type_str, "native-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; - } else - if (strcasecmp(face_type_str, "overlay-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; - } else - if (strcasecmp(face_type_str, "overlay-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; - } else { - ERROR("Invalid face type in section 'global'"); - return -1; - } - - int rc = facemgr_cfg_set_face_type(cfg, &face_type); - if (rc < 0) - goto ERR; +int parse_config_global(facemgr_cfg_t *cfg, config_setting_t *setting) { + /* - face_type */ + + const char *face_type_str; + facemgr_face_type_t face_type; + if (config_setting_lookup_string(setting, "face_type", &face_type_str)) { + if (strcasecmp(face_type_str, "auto") == 0) { + face_type = FACEMGR_FACE_TYPE_DEFAULT; + } else if (strcasecmp(face_type_str, "native-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; + } else if (strcasecmp(face_type_str, "native-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; + } else if (strcasecmp(face_type_str, "overlay-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; + } else if (strcasecmp(face_type_str, "overlay-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; + } else { + ERROR("Invalid face type in section 'global'"); + return -1; } - /* - disable_discovery */ - - int disable_discovery; - if (config_setting_lookup_bool(setting, "disable_discovery", - &disable_discovery)) { - int rc = facemgr_cfg_set_discovery(cfg, !disable_discovery); - if (rc < 0) - goto ERR; - } - - /* - disable_ipv4 */ - - int disable_ipv4; - if (config_setting_lookup_bool(setting, "disable_ipv4", - &disable_ipv4)) { - int rc = facemgr_cfg_set_ipv4(cfg, !disable_ipv4); - if (rc < 0) - goto ERR; - } - - /* - disable ipv6 */ - - int disable_ipv6; - if (config_setting_lookup_bool(setting, "disable_ipv6", - &disable_ipv6)) { - int rc = facemgr_cfg_set_ipv6(cfg, !disable_ipv6); - if (rc < 0) - goto ERR; + int rc = facemgr_cfg_set_face_type(cfg, &face_type); + if (rc < 0) goto ERR; + } + + /* - disable_discovery */ + + int disable_discovery; + if (config_setting_lookup_bool(setting, "disable_discovery", + &disable_discovery)) { + int rc = facemgr_cfg_set_discovery(cfg, !disable_discovery); + if (rc < 0) goto ERR; + } + + /* - disable_ipv4 */ + + int disable_ipv4; + if (config_setting_lookup_bool(setting, "disable_ipv4", &disable_ipv4)) { + int rc = facemgr_cfg_set_ipv4(cfg, !disable_ipv4); + if (rc < 0) goto ERR; + } + + /* - disable ipv6 */ + + int disable_ipv6; + if (config_setting_lookup_bool(setting, "disable_ipv6", &disable_ipv6)) { + int rc = facemgr_cfg_set_ipv6(cfg, !disable_ipv6); + if (rc < 0) goto ERR; + } + + /* - overlay */ + config_setting_t *overlay = config_setting_get_member(setting, "overlay"); + if (overlay) { + /* ipv4 */ + config_setting_t *overlay_v4 = config_setting_get_member(overlay, "ipv4"); + if (overlay_v4) { + const char *local_addr_str, *remote_addr_str; + ip_address_t local_addr = IP_ADDRESS_EMPTY; + ip_address_t remote_addr = IP_ADDRESS_EMPTY; + ip_address_t *local_addr_p = NULL; + ip_address_t *remote_addr_p = NULL; + int local_port = 0; + int remote_port = 0; + + if (config_setting_lookup_string(overlay_v4, "local_addr", + &local_addr_str)) { + if (ip_address_pton(local_addr_str, &local_addr) < 0) { + ERROR("Error parsing v4 local addr"); + goto ERR; + } + local_addr_p = &local_addr; + } + + if (config_setting_lookup_int(overlay_v4, "local_port", &local_port)) { + if (!IS_VALID_PORT(local_port)) goto ERR; + } + + if (config_setting_lookup_string(overlay_v4, "remote_addr", + &remote_addr_str)) { + if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { + ERROR("Error parsing v4 remote addr"); + goto ERR; + } + remote_addr_p = &remote_addr; + } + + if (config_setting_lookup_int(overlay_v4, "remote_port", &remote_port)) { + if (!IS_VALID_PORT(remote_port)) goto ERR; + } + int rc = facemgr_cfg_set_overlay(cfg, AF_INET, local_addr_p, local_port, + remote_addr_p, remote_port); + if (rc < 0) goto ERR; } - /* - overlay */ - config_setting_t *overlay = config_setting_get_member(setting, "overlay"); - if (overlay) { - - /* ipv4 */ - config_setting_t *overlay_v4 = config_setting_get_member(overlay, "ipv4"); - if (overlay_v4) { - const char * local_addr_str, * remote_addr_str; - ip_address_t local_addr = IP_ADDRESS_EMPTY; - ip_address_t remote_addr = IP_ADDRESS_EMPTY; - ip_address_t * local_addr_p = NULL; - ip_address_t * remote_addr_p = NULL; - int local_port = 0; - int remote_port = 0; - - if (config_setting_lookup_string(overlay_v4, "local_addr", &local_addr_str)) { - if (ip_address_pton(local_addr_str, &local_addr) < 0) { - ERROR("Error parsing v4 local addr"); - goto ERR; - } - local_addr_p = &local_addr; - } - - if (config_setting_lookup_int(overlay_v4, "local_port", &local_port)) { - if (!IS_VALID_PORT(local_port)) - goto ERR; - } - - if (config_setting_lookup_string(overlay_v4, "remote_addr", &remote_addr_str)) { - if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { - ERROR("Error parsing v4 remote addr"); - goto ERR; - } - remote_addr_p = &remote_addr; - } - - if (config_setting_lookup_int(overlay_v4, "remote_port", &remote_port)) { - if (!IS_VALID_PORT(remote_port)) - goto ERR; - } - int rc = facemgr_cfg_set_overlay(cfg, AF_INET, - local_addr_p, local_port, - remote_addr_p, remote_port); - if (rc < 0) - goto ERR; + /* ipv6 */ + config_setting_t *overlay_v6 = config_setting_get_member(overlay, "ipv6"); + if (overlay_v6) { + const char *local_addr_str, *remote_addr_str; + ip_address_t local_addr = IP_ADDRESS_EMPTY; + ip_address_t remote_addr = IP_ADDRESS_EMPTY; + ip_address_t *local_addr_p = NULL; + ip_address_t *remote_addr_p = NULL; + int local_port = 0; + int remote_port = 0; + + if (config_setting_lookup_string(overlay_v6, "local_addr", + &local_addr_str)) { + if (ip_address_pton(local_addr_str, &local_addr) < 0) { + ERROR("Error parsing v6 local addr"); + goto ERR; } - - /* ipv6 */ - config_setting_t *overlay_v6 = config_setting_get_member(overlay, "ipv6"); - if (overlay_v6) { - const char * local_addr_str, * remote_addr_str; - ip_address_t local_addr = IP_ADDRESS_EMPTY; - ip_address_t remote_addr = IP_ADDRESS_EMPTY; - ip_address_t * local_addr_p = NULL; - ip_address_t * remote_addr_p = NULL; - int local_port = 0; - int remote_port = 0; - - if (config_setting_lookup_string(overlay_v6, "local_addr", &local_addr_str)) { - if (ip_address_pton(local_addr_str, &local_addr) < 0) { - ERROR("Error parsing v6 local addr"); - goto ERR; - } - local_addr_p = &local_addr; - } - - if (config_setting_lookup_int(overlay_v6, "local_port", &local_port)) { - if (!IS_VALID_PORT(local_port)) - goto ERR; - } - - if (config_setting_lookup_string(overlay_v6, "remote_addr", &remote_addr_str)) { - if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { - ERROR("Error parsing v6 remote addr"); - goto ERR; - } - remote_addr_p = &remote_addr; - } - - if (config_setting_lookup_int(overlay_v6, "remote_port", &remote_port)) { - if (!IS_VALID_PORT(remote_port)) - goto ERR; - } - int rc = facemgr_cfg_set_overlay(cfg, AF_INET6, - local_addr_p, local_port, - remote_addr_p, remote_port); - if (rc < 0) - goto ERR; + local_addr_p = &local_addr; + } + + if (config_setting_lookup_int(overlay_v6, "local_port", &local_port)) { + if (!IS_VALID_PORT(local_port)) goto ERR; + } + + if (config_setting_lookup_string(overlay_v6, "remote_addr", + &remote_addr_str)) { + if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { + ERROR("Error parsing v6 remote addr"); + goto ERR; } + remote_addr_p = &remote_addr; + } + + if (config_setting_lookup_int(overlay_v6, "remote_port", &remote_port)) { + if (!IS_VALID_PORT(remote_port)) goto ERR; + } + int rc = facemgr_cfg_set_overlay(cfg, AF_INET6, local_addr_p, local_port, + remote_addr_p, remote_port); + if (rc < 0) goto ERR; + } - } /* overlay */ + } /* overlay */ - return 0; + return 0; ERR: - return -1; + return -1; } -int -parse_config_rules(facemgr_cfg_t * cfg, config_setting_t * setting) -{ - /* List of match-override tuples */ - facemgr_cfg_rule_t * rule; +int parse_config_rules(facemgr_cfg_t *cfg, config_setting_t *setting) { + /* List of match-override tuples */ + facemgr_cfg_rule_t *rule; - int count = config_setting_length(setting); - for (unsigned i = 0; i < count; ++i) { - config_setting_t * rule_setting = config_setting_get_elem(setting, i); + int count = config_setting_length(setting); + for (unsigned i = 0; i < count; ++i) { + config_setting_t *rule_setting = config_setting_get_elem(setting, i); - /* Sanity check */ + /* Sanity check */ - config_setting_t * match_setting = config_setting_get_member(rule_setting, "match"); - if (!match_setting) { - ERROR("Missing match section in rule #%d", i); - goto ERR_CHECK; - } + config_setting_t *match_setting = + config_setting_get_member(rule_setting, "match"); + if (!match_setting) { + ERROR("Missing match section in rule #%d", i); + goto ERR_CHECK; + } - config_setting_t * override_setting = config_setting_get_member(rule_setting, "override"); - if (!override_setting) { - ERROR("Missing override section in rule #%d", i); - goto ERR_CHECK; - } + config_setting_t *override_setting = + config_setting_get_member(rule_setting, "override"); + if (!override_setting) { + ERROR("Missing override section in rule #%d", i); + goto ERR_CHECK; + } - rule = facemgr_cfg_rule_create(); - if (!rule) - goto ERR_RULE; - - /* Parse match */ - - const char * interface_name = NULL; - config_setting_lookup_string(match_setting, "interface_name", &interface_name); - - const char * interface_type_str; - netdevice_type_t interface_type = NETDEVICE_TYPE_UNDEFINED; - if (config_setting_lookup_string(match_setting, "interface_type", &interface_type_str)) { - if (strcasecmp(interface_type_str, "wired") == 0) { - interface_type = NETDEVICE_TYPE_WIRED; - } else - if (strcasecmp(interface_type_str, "wifi") == 0) { - interface_type = NETDEVICE_TYPE_WIFI; - } else - if (strcasecmp(interface_type_str, "cellular") == 0) { - interface_type = NETDEVICE_TYPE_CELLULAR; - } else { - ERROR("Unknown interface type in rule #%d", i); - goto ERR; - } - } + rule = facemgr_cfg_rule_create(); + if (!rule) goto ERR_RULE; + + /* Parse match */ + + const char *interface_name = NULL; + config_setting_lookup_string(match_setting, "interface_name", + &interface_name); + + const char *interface_type_str; + netdevice_type_t interface_type = NETDEVICE_TYPE_UNDEFINED; + if (config_setting_lookup_string(match_setting, "interface_type", + &interface_type_str)) { + if (strcasecmp(interface_type_str, "wired") == 0) { + interface_type = NETDEVICE_TYPE_WIRED; + } else if (strcasecmp(interface_type_str, "wifi") == 0) { + interface_type = NETDEVICE_TYPE_WIFI; + } else if (strcasecmp(interface_type_str, "cellular") == 0) { + interface_type = NETDEVICE_TYPE_CELLULAR; + } else { + ERROR("Unknown interface type in rule #%d", i); + goto ERR; + } + } - if ((!interface_name) && (interface_type == NETDEVICE_TYPE_UNDEFINED)) { - ERROR("Empty match section in rule #%d", i); - goto ERR; - } + if ((!interface_name) && (interface_type == NETDEVICE_TYPE_UNDEFINED)) { + ERROR("Empty match section in rule #%d", i); + goto ERR; + } - /* Associate match to rule */ + /* Associate match to rule */ - int rc = facemgr_cfg_rule_set_match(rule, interface_name, interface_type); - if (rc < 0) - goto ERR; + int rc = facemgr_cfg_rule_set_match(rule, interface_name, interface_type); + if (rc < 0) goto ERR; - /* Parse override */ + /* Parse override */ - /* - face_type */ + /* - face_type */ - const char *face_type_str; - facemgr_face_type_t face_type; - if (config_setting_lookup_string(override_setting, "face_type", &face_type_str)) { - if (strcasecmp(face_type_str, "auto")) { - /* We currently hardcode different behaviours based on the OS */ + const char *face_type_str; + facemgr_face_type_t face_type; + if (config_setting_lookup_string(override_setting, "face_type", + &face_type_str)) { + if (strcasecmp(face_type_str, "auto")) { + /* We currently hardcode different behaviours based on the OS */ #ifdef __ANDROID__ - face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; + face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; #else - face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; + face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; #endif - } else - if (strcasecmp(face_type_str, "native-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; - } else - if (strcasecmp(face_type_str, "native-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; - } else - if (strcasecmp(face_type_str, "overlay-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; - } else - if (strcasecmp(face_type_str, "overlay-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; - } else { - ERROR("Invalid face type in section 'global'"); - return -1; - } + } else if (strcasecmp(face_type_str, "native-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; + } else if (strcasecmp(face_type_str, "native-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; + } else if (strcasecmp(face_type_str, "overlay-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; + } else if (strcasecmp(face_type_str, "overlay-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; + } else { + ERROR("Invalid face type in section 'global'"); + return -1; + } - int rc = facemgr_cfg_rule_set_face_type(rule, &face_type); - if (rc < 0) - goto ERR; - } + int rc = facemgr_cfg_rule_set_face_type(rule, &face_type); + if (rc < 0) goto ERR; + } - /* - disable_discovery */ + /* - disable_discovery */ - int disable_discovery; - if (config_setting_lookup_bool(override_setting, "disable_discovery", - &disable_discovery)) { - int rc = facemgr_cfg_rule_set_discovery(rule, !disable_discovery); - if (rc < 0) - goto ERR; - } + int disable_discovery; + if (config_setting_lookup_bool(override_setting, "disable_discovery", + &disable_discovery)) { + int rc = facemgr_cfg_rule_set_discovery(rule, !disable_discovery); + if (rc < 0) goto ERR; + } - /* - disable_ipv4 */ + /* - disable_ipv4 */ - int disable_ipv4; - if (config_setting_lookup_bool(override_setting, "disable_ipv4", - &disable_ipv4)) { - INFO("Ignored setting 'disable_ipv4' in rule #%d (not implemented).", i); + int disable_ipv4; + if (config_setting_lookup_bool(override_setting, "disable_ipv4", + &disable_ipv4)) { + INFO("Ignored setting 'disable_ipv4' in rule #%d (not implemented).", i); #if 0 int rc = facemgr_cfg_rule_set_ipv4(rule, !disable_ipv4); if (rc < 0) goto ERR; #endif - } + } - /* - disable ipv6 */ + /* - disable ipv6 */ - int disable_ipv6; - if (config_setting_lookup_bool(override_setting, "disable_ipv6", - &disable_ipv6)) { - INFO("Ignored setting 'disable_ipv6' in rule #%d (not implemented).", i); + int disable_ipv6; + if (config_setting_lookup_bool(override_setting, "disable_ipv6", + &disable_ipv6)) { + INFO("Ignored setting 'disable_ipv6' in rule #%d (not implemented).", i); #if 0 int rc = facemgr_cfg_rule_set_ipv6(rule, !disable_ipv6); if (rc < 0) goto ERR; #endif - } + } - /* - ignore */ - int ignore; - if (config_setting_lookup_bool(override_setting, "ignore", &ignore)) { - int rc = facemgr_cfg_rule_set_ignore(rule, !!ignore); - if (rc < 0) - goto ERR; - } + /* - ignore */ + int ignore; + if (config_setting_lookup_bool(override_setting, "ignore", &ignore)) { + int rc = facemgr_cfg_rule_set_ignore(rule, !!ignore); + if (rc < 0) goto ERR; + } - /* - tags */ - config_setting_t *tag_settings = config_setting_get_member(override_setting, "tags"); - if (tag_settings) { - INFO("Ignored setting 'tags' in rule #%d (not implemented).", i); + /* - tags */ + config_setting_t *tag_settings = + config_setting_get_member(override_setting, "tags"); + if (tag_settings) { + INFO("Ignored setting 'tags' in rule #%d (not implemented).", i); #if 0 policy_tags_t tags = POLICY_TAGS_EMPTY; for (unsigned j = 0; j < config_setting_length(tag_settings); j++) { @@ -370,361 +343,337 @@ parse_config_rules(facemgr_cfg_t * cfg, config_setting_t * setting) DEBUG("Added tags tags=%s", tags_str); #endif #endif + } + + /* - overlay */ + config_setting_t *overlay = + config_setting_get_member(override_setting, "overlay"); + if (overlay) { + /* ipv4 */ + config_setting_t *overlay_v4 = config_setting_get_member(overlay, "ipv4"); + if (overlay_v4) { + const char *local_addr_str, *remote_addr_str; + ip_address_t local_addr = IP_ADDRESS_EMPTY; + ip_address_t remote_addr = IP_ADDRESS_EMPTY; + ip_address_t *local_addr_p = NULL; + ip_address_t *remote_addr_p = NULL; + int local_port = 0; + int remote_port = 0; + + if (config_setting_lookup_string(overlay_v4, "local_addr", + &local_addr_str)) { + ip_address_pton(local_addr_str, &local_addr); + local_addr_p = &local_addr; } - /* - overlay */ - config_setting_t *overlay = config_setting_get_member(override_setting, "overlay"); - if (overlay) { - - /* ipv4 */ - config_setting_t *overlay_v4 = config_setting_get_member(overlay, "ipv4"); - if (overlay_v4) { - const char * local_addr_str, * remote_addr_str; - ip_address_t local_addr = IP_ADDRESS_EMPTY; - ip_address_t remote_addr = IP_ADDRESS_EMPTY; - ip_address_t * local_addr_p = NULL; - ip_address_t * remote_addr_p = NULL; - int local_port = 0; - int remote_port = 0; - - if (config_setting_lookup_string(overlay_v4, "local_addr", &local_addr_str)) { - ip_address_pton(local_addr_str, &local_addr); - local_addr_p = &local_addr; - } - - if (config_setting_lookup_int(overlay_v4, "local_port", &local_port)) { - if (!IS_VALID_PORT(local_port)) - goto ERR; - } - - if (config_setting_lookup_string(overlay_v4, "remote_addr", &remote_addr_str)) { - ip_address_pton(remote_addr_str, &remote_addr); - remote_addr_p = &remote_addr; - } - - if (config_setting_lookup_int(overlay_v4, "remote_port", &remote_port)) { - if (!IS_VALID_PORT(remote_port)) - goto ERR; - } - int rc = facemgr_cfg_rule_set_overlay(rule, AF_INET, - local_addr_p, local_port, - remote_addr_p, remote_port); - if (rc < 0) - goto ERR; - } + if (config_setting_lookup_int(overlay_v4, "local_port", &local_port)) { + if (!IS_VALID_PORT(local_port)) goto ERR; + } - /* ipv6 */ - config_setting_t *overlay_v6 = config_setting_get_member(overlay, "ipv6"); - if (overlay_v6) { - const char * local_addr_str, * remote_addr_str; - ip_address_t local_addr = IP_ADDRESS_EMPTY; - ip_address_t remote_addr = IP_ADDRESS_EMPTY; - ip_address_t * local_addr_p = NULL; - ip_address_t * remote_addr_p = NULL; - int local_port = 0; - int remote_port = 0; - - if (config_setting_lookup_string(overlay_v6, "local_addr", &local_addr_str)) { - ip_address_pton(local_addr_str, &local_addr); - local_addr_p = &local_addr; - } - - if (config_setting_lookup_int(overlay_v6, "local_port", &local_port)) { - if (!IS_VALID_PORT(local_port)) - goto ERR; - } - - if (config_setting_lookup_string(overlay_v6, "remote_addr", &remote_addr_str)) { - ip_address_pton(remote_addr_str, &remote_addr); - remote_addr_p = &remote_addr; - } - - if (config_setting_lookup_int(overlay_v6, "remote_port", &remote_port)) { - if (!IS_VALID_PORT(remote_port)) - goto ERR; - } - int rc = facemgr_cfg_rule_set_overlay(rule, AF_INET6, - local_addr_p, local_port, - remote_addr_p, remote_port); - if (rc < 0) - goto ERR; - } + if (config_setting_lookup_string(overlay_v4, "remote_addr", + &remote_addr_str)) { + ip_address_pton(remote_addr_str, &remote_addr); + remote_addr_p = &remote_addr; + } - } /* overlay */ + if (config_setting_lookup_int(overlay_v4, "remote_port", + &remote_port)) { + if (!IS_VALID_PORT(remote_port)) goto ERR; + } + int rc = facemgr_cfg_rule_set_overlay(rule, AF_INET, local_addr_p, + local_port, remote_addr_p, + remote_port); + if (rc < 0) goto ERR; + } + + /* ipv6 */ + config_setting_t *overlay_v6 = config_setting_get_member(overlay, "ipv6"); + if (overlay_v6) { + const char *local_addr_str, *remote_addr_str; + ip_address_t local_addr = IP_ADDRESS_EMPTY; + ip_address_t remote_addr = IP_ADDRESS_EMPTY; + ip_address_t *local_addr_p = NULL; + ip_address_t *remote_addr_p = NULL; + int local_port = 0; + int remote_port = 0; - /* Add newly created rule */ + if (config_setting_lookup_string(overlay_v6, "local_addr", + &local_addr_str)) { + ip_address_pton(local_addr_str, &local_addr); + local_addr_p = &local_addr; + } - rc = facemgr_cfg_add_rule(cfg, rule); - if (rc < 0) - goto ERR; - } - return 0; + if (config_setting_lookup_int(overlay_v6, "local_port", &local_port)) { + if (!IS_VALID_PORT(local_port)) goto ERR; + } + + if (config_setting_lookup_string(overlay_v6, "remote_addr", + &remote_addr_str)) { + ip_address_pton(remote_addr_str, &remote_addr); + remote_addr_p = &remote_addr; + } + + if (config_setting_lookup_int(overlay_v6, "remote_port", + &remote_port)) { + if (!IS_VALID_PORT(remote_port)) goto ERR; + } + int rc = facemgr_cfg_rule_set_overlay(rule, AF_INET6, local_addr_p, + local_port, remote_addr_p, + remote_port); + if (rc < 0) goto ERR; + } + + } /* overlay */ + + /* Add newly created rule */ + + rc = facemgr_cfg_add_rule(cfg, rule); + if (rc < 0) goto ERR; + } + return 0; ERR: - facemgr_cfg_rule_free(rule); + facemgr_cfg_rule_free(rule); ERR_RULE: ERR_CHECK: - return -1; + return -1; } -int parse_config_static_facelets(facemgr_cfg_t * cfg, config_setting_t * setting) -{ - int count = config_setting_length(setting); - for (unsigned i = 0; i < count; ++i) { - config_setting_t * static_setting = config_setting_get_elem(setting, i); - - const char *face_type_str; - facemgr_face_type_t face_type; - const char * family_str; - int family; - const char * remote_addr_str; - ip_address_t remote_addr = IP_ADDRESS_EMPTY; - int remote_port = 0; - const char * interface_name; - const char * interface_type_str; - - facelet_t * facelet = facelet_create(); - - /* Face type */ - if (config_setting_lookup_string(static_setting, "face_type", &face_type_str)) { - if (strcasecmp(face_type_str, "auto") == 0) { - face_type = FACEMGR_FACE_TYPE_DEFAULT; - } else - if (strcasecmp(face_type_str, "native-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; - } else - if (strcasecmp(face_type_str, "native-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; - } else - if (strcasecmp(face_type_str, "overlay-udp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; - } else - if (strcasecmp(face_type_str, "overlay-tcp") == 0) { - face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; - } else { - ERROR("Invalid face type in section 'global'"); - goto ERR_FACELET; - } +int parse_config_static_facelets(facemgr_cfg_t *cfg, + config_setting_t *setting) { + int count = config_setting_length(setting); + for (unsigned i = 0; i < count; ++i) { + config_setting_t *static_setting = config_setting_get_elem(setting, i); - int rc = facelet_set_face_type(facelet, face_type); - if (rc < 0) - goto ERR_FACELET; - } + const char *face_type_str; + facemgr_face_type_t face_type; + const char *family_str; + int family; + const char *remote_addr_str; + ip_address_t remote_addr = IP_ADDRESS_EMPTY; + int remote_port = 0; + const char *interface_name; + const char *interface_type_str; + + facelet_t *facelet = facelet_create(); + + /* Face type */ + if (config_setting_lookup_string(static_setting, "face_type", + &face_type_str)) { + if (strcasecmp(face_type_str, "auto") == 0) { + face_type = FACEMGR_FACE_TYPE_DEFAULT; + } else if (strcasecmp(face_type_str, "native-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_UDP; + } else if (strcasecmp(face_type_str, "native-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; + } else if (strcasecmp(face_type_str, "overlay-udp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; + } else if (strcasecmp(face_type_str, "overlay-tcp") == 0) { + face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; + } else { + ERROR("Invalid face type in section 'global'"); + goto ERR_FACELET; + } + + int rc = facelet_set_face_type(facelet, face_type); + if (rc < 0) goto ERR_FACELET; + } - /* Family */ - if (config_setting_lookup_string(static_setting, "family", &family_str)) { - if (strcasecmp(family_str, "AF_INET") == 0) { - family = AF_INET; - } else - if (strcasecmp(family_str, "AF_INET6") == 0) { - family = AF_INET6; - } else { - ERROR("Invalid family in section 'static', items #%d", i+1); - goto ERR_FACELET; - } - int rc = facelet_set_family(facelet, family); - if (rc < 0) - goto ERR_FACELET; - } + /* Family */ + if (config_setting_lookup_string(static_setting, "family", &family_str)) { + if (strcasecmp(family_str, "AF_INET") == 0) { + family = AF_INET; + } else if (strcasecmp(family_str, "AF_INET6") == 0) { + family = AF_INET6; + } else { + ERROR("Invalid family in section 'static', items #%d", i + 1); + goto ERR_FACELET; + } + int rc = facelet_set_family(facelet, family); + if (rc < 0) goto ERR_FACELET; + } - /* Remote address */ - if (config_setting_lookup_string(static_setting, "remote_addr", &remote_addr_str)) { - if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { - ERROR("Error parsing v4 remote addr"); - goto ERR_FACELET; - } + /* Remote address */ + if (config_setting_lookup_string(static_setting, "remote_addr", + &remote_addr_str)) { + if (ip_address_pton(remote_addr_str, &remote_addr) < 0) { + ERROR("Error parsing v4 remote addr"); + goto ERR_FACELET; + } - int rc = facelet_set_remote_addr(facelet, remote_addr); - if (rc < 0) - goto ERR_FACELET; - } + int rc = facelet_set_remote_addr(facelet, remote_addr); + if (rc < 0) goto ERR_FACELET; + } - /* Remote port */ - if (config_setting_lookup_int(static_setting, "remote_port", &remote_port)) { - if (!IS_VALID_PORT(remote_port)) - goto ERR_FACELET; - int rc = facelet_set_remote_port(facelet, remote_port); - if (rc < 0) - goto ERR_FACELET; - } + /* Remote port */ + if (config_setting_lookup_int(static_setting, "remote_port", + &remote_port)) { + if (!IS_VALID_PORT(remote_port)) goto ERR_FACELET; + int rc = facelet_set_remote_port(facelet, remote_port); + if (rc < 0) goto ERR_FACELET; + } - /* Interface name */ - if (config_setting_lookup_string(static_setting, "interface_name", &interface_name)) { - netdevice_t netdevice; - /* Warning: interface might not exist when we create the facelet */ - snprintf(netdevice.name, IFNAMSIZ, "%s", interface_name); - netdevice.index = 0; - int rc = facelet_set_netdevice(facelet, netdevice); - if (rc < 0) - goto ERR_FACELET; - } + /* Interface name */ + if (config_setting_lookup_string(static_setting, "interface_name", + &interface_name)) { + netdevice_t netdevice; + /* Warning: interface might not exist when we create the facelet */ + snprintf(netdevice.name, IFNAMSIZ, "%s", interface_name); + netdevice.index = 0; + int rc = facelet_set_netdevice(facelet, netdevice); + if (rc < 0) goto ERR_FACELET; + } - /* Interface type */ - netdevice_type_t interface_type = NETDEVICE_TYPE_UNDEFINED; - if (config_setting_lookup_string(static_setting, "interface_type", &interface_type_str)) { - if (strcasecmp(interface_type_str, "wired") == 0) { - interface_type = NETDEVICE_TYPE_WIRED; - } else - if (strcasecmp(interface_type_str, "wifi") == 0) { - interface_type = NETDEVICE_TYPE_WIFI; - } else - if (strcasecmp(interface_type_str, "cellular") == 0) { - interface_type = NETDEVICE_TYPE_CELLULAR; - } else { - ERROR("Unknown interface type in rule #%d", i); - goto ERR_FACELET; - } + /* Interface type */ + netdevice_type_t interface_type = NETDEVICE_TYPE_UNDEFINED; + if (config_setting_lookup_string(static_setting, "interface_type", + &interface_type_str)) { + if (strcasecmp(interface_type_str, "wired") == 0) { + interface_type = NETDEVICE_TYPE_WIRED; + } else if (strcasecmp(interface_type_str, "wifi") == 0) { + interface_type = NETDEVICE_TYPE_WIFI; + } else if (strcasecmp(interface_type_str, "cellular") == 0) { + interface_type = NETDEVICE_TYPE_CELLULAR; + } else { + ERROR("Unknown interface type in rule #%d", i); + goto ERR_FACELET; + } + + int rc = facelet_set_netdevice_type(facelet, interface_type); + if (rc < 0) goto ERR_FACELET; + } - int rc = facelet_set_netdevice_type(facelet, interface_type); - if (rc < 0) - goto ERR_FACELET; + /* Routes */ + config_setting_t *routes_static_setting = + config_setting_get_member(static_setting, "routes"); + if (routes_static_setting) { + /* ... */ + int count_routes = config_setting_length(routes_static_setting); + for (unsigned j = 0; j < count_routes; ++j) { + config_setting_t *route_static_setting = + config_setting_get_elem(routes_static_setting, j); + + const char *prefix_str; + ip_prefix_t prefix; + int cost = 0; /* default */ + + if (config_setting_lookup_string(route_static_setting, "prefix", + &prefix_str)) { + if (ip_prefix_pton(prefix_str, &prefix) < 0) { + ERROR("Error parsing prefix in route #%d, rule #%d", j, i); + goto ERR_FACELET; + } + } else { + ERROR("Cannot add route without prefix"); + goto ERR_FACELET; } - /* Routes */ - config_setting_t * routes_static_setting = config_setting_get_member(static_setting, "routes"); - if (routes_static_setting) { - /* ... */ - int count_routes = config_setting_length(routes_static_setting); - for (unsigned j = 0; j < count_routes; ++j) { - config_setting_t * route_static_setting = config_setting_get_elem(routes_static_setting, j); - - const char * prefix_str; - ip_prefix_t prefix; - int cost = 0; /* default */ - - if (config_setting_lookup_string(route_static_setting, "prefix", &prefix_str)) { - if (ip_prefix_pton(prefix_str, &prefix) < 0) { - ERROR("Error parsing prefix in route #%d, rule #%d", j, i); - goto ERR_FACELET; - } - } else { - ERROR("Cannot add route without prefix"); - goto ERR_FACELET; - } - - config_setting_lookup_int(static_setting, "cost", &cost); - - hicn_route_t * route = hicn_route_create(&prefix, 0, cost); - if (!route) { - ERROR("Could not create hICN route"); - goto ERR_FACELET; - } - - int rc = facelet_add_route(facelet, route); - if (rc < 0) { - ERROR("Could not add route to facelet"); - goto ERR_ROUTE; - } - - continue; - -ERR_ROUTE: - hicn_route_free(route); - goto ERR_FACELET; - } + config_setting_lookup_int(static_setting, "cost", &cost); + + hicn_route_t *route = hicn_route_create(&prefix, 0, cost); + if (!route) { + ERROR("Could not create hICN route"); + goto ERR_FACELET; } - if (facemgr_cfg_add_static_facelet(cfg, facelet) < 0) { - ERROR("Could not add static facelet to configuration"); - goto ERR_FACELET; + int rc = facelet_add_route(facelet, route); + if (rc < 0) { + ERROR("Could not add route to facelet"); + goto ERR_ROUTE; } continue; -ERR_FACELET: - facelet_free(facelet); - return -1; + ERR_ROUTE: + hicn_route_free(route); + goto ERR_FACELET; + } + } - } - return 0; + if (facemgr_cfg_add_static_facelet(cfg, facelet) < 0) { + ERROR("Could not add static facelet to configuration"); + goto ERR_FACELET; + } + + continue; + + ERR_FACELET: + facelet_free(facelet); + return -1; + } + return 0; } /* Currently not using facemgr_cfg_t */ -int -parse_config_log(facemgr_cfg_t * cfg, config_setting_t * setting) -{ - const char *log_level_str; - if (config_setting_lookup_string(setting, "log_level", &log_level_str)) { - if (strcasecmp(log_level_str, "FATAL") == 0) { - log_conf.log_level = LOG_FATAL; - } else - if (strcasecmp(log_level_str, "ERROR") == 0) { - log_conf.log_level = LOG_ERROR; - } else - if (strcasecmp(log_level_str, "WARN") == 0) { - log_conf.log_level = LOG_WARN; - } else - if (strcasecmp(log_level_str, "INFO") == 0) { - log_conf.log_level = LOG_INFO; - } else - if (strcasecmp(log_level_str, "DEBUG") == 0) { - log_conf.log_level = LOG_DEBUG; - } else - if (strcasecmp(log_level_str, "TRACE") == 0) { - log_conf.log_level = LOG_TRACE; - } else { - ERROR("Invalid log level in section 'log'"); - return -1; - } +int parse_config_log(facemgr_cfg_t *cfg, config_setting_t *setting) { + const char *log_level_str; + if (config_setting_lookup_string(setting, "log_level", &log_level_str)) { + if (strcasecmp(log_level_str, "FATAL") == 0) { + log_conf.log_level = LOG_FATAL; + } else if (strcasecmp(log_level_str, "ERROR") == 0) { + log_conf.log_level = LOG_ERROR; + } else if (strcasecmp(log_level_str, "WARN") == 0) { + log_conf.log_level = LOG_WARN; + } else if (strcasecmp(log_level_str, "INFO") == 0) { + log_conf.log_level = LOG_INFO; + } else if (strcasecmp(log_level_str, "DEBUG") == 0) { + log_conf.log_level = LOG_DEBUG; + } else if (strcasecmp(log_level_str, "TRACE") == 0) { + log_conf.log_level = LOG_TRACE; + } else { + ERROR("Invalid log level in section 'log'"); + return -1; } - return 0; + } + return 0; } -int -parse_config_file(const char * cfgpath, facemgr_cfg_t * cfg) -{ - /* Reading configuration file */ - config_t cfgfile; - config_setting_t *setting; +int parse_config_file(const char *cfgpath, facemgr_cfg_t *cfg) { + /* Reading configuration file */ + config_t cfgfile; + config_setting_t *setting; - config_init(&cfgfile); + config_init(&cfgfile); - /* Read the file. If there is an error, report it and exit. */ - if(!config_read_file(&cfgfile, cfgpath)) - goto ERR_FILE; + /* Read the file. If there is an error, report it and exit. */ + if (!config_read_file(&cfgfile, cfgpath)) goto ERR_FILE; - setting = config_lookup(&cfgfile, "global"); - if (setting) { - int rc = parse_config_global(cfg, setting); - if (rc < 0) - goto ERR_PARSE; - } + setting = config_lookup(&cfgfile, "global"); + if (setting) { + int rc = parse_config_global(cfg, setting); + if (rc < 0) goto ERR_PARSE; + } - setting = config_lookup(&cfgfile, "rules"); - if (setting) { - int rc = parse_config_rules(cfg, setting); - if (rc < 0) - goto ERR_PARSE; - } + setting = config_lookup(&cfgfile, "rules"); + if (setting) { + int rc = parse_config_rules(cfg, setting); + if (rc < 0) goto ERR_PARSE; + } - setting = config_lookup(&cfgfile, "static"); - if (setting) { - int rc = parse_config_static_facelets(cfg, setting); - if (rc < 0) - goto ERR_PARSE; - } + setting = config_lookup(&cfgfile, "static"); + if (setting) { + int rc = parse_config_static_facelets(cfg, setting); + if (rc < 0) goto ERR_PARSE; + } - setting = config_lookup(&cfgfile, "log"); - if (setting) { - int rc = parse_config_log(cfg, setting); - if (rc < 0) - goto ERR_PARSE; - } + setting = config_lookup(&cfgfile, "log"); + if (setting) { + int rc = parse_config_log(cfg, setting); + if (rc < 0) goto ERR_PARSE; + } - config_destroy(&cfgfile); - return 0; + config_destroy(&cfgfile); + return 0; ERR_FILE: - ERROR("Could not read configuration file %s", cfgpath); - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfgfile), - config_error_line(&cfgfile), config_error_text(&cfgfile)); - config_destroy(&cfgfile); - exit(EXIT_FAILURE); - return -1; + ERROR("Could not read configuration file %s", cfgpath); + fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfgfile), + config_error_line(&cfgfile), config_error_text(&cfgfile)); + config_destroy(&cfgfile); + return -1; ERR_PARSE: - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfgfile), - config_error_line(&cfgfile), config_error_text(&cfgfile)); - config_destroy(&cfgfile); - return -1; + fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfgfile), + config_error_line(&cfgfile), config_error_text(&cfgfile)); + config_destroy(&cfgfile); + return -1; } - diff --git a/ctrl/facemgr/src/cfg_file.h b/ctrl/facemgr/src/cfg_file.h index dfce041d8..fea6a84a6 100644 --- a/ctrl/facemgr/src/cfg_file.h +++ b/ctrl/facemgr/src/cfg_file.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -28,7 +28,7 @@ * \param [in] f - File name * \return 0 in case of success, -1 otherwise. */ -int probe_cfgfile(char * f); +int probe_cfgfile(char* f); /** * \brief Parses the provided configuration file into the facemgr configuration @@ -37,6 +37,6 @@ int probe_cfgfile(char * f); * \param [out] cfg - Pre-allocated configuration data structure * \return 0 in case of success, -1 otherwise. */ -int parse_config_file(const char * cfgpath, facemgr_cfg_t * cfg); +int parse_config_file(const char* cfgpath, facemgr_cfg_t* cfg); #endif /* FACEMGR_CFG_FILE_H */ diff --git a/ctrl/facemgr/src/common.h b/ctrl/facemgr/src/common.h index 56bd706f1..2fda668c8 100644 --- a/ctrl/facemgr/src/common.h +++ b/ctrl/facemgr/src/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,71 +32,58 @@ /* Dump with indent */ #define INDENT(n, fmt) "%*s" fmt, n, "" -#define printfi(n, fmt, ...) printf(INDENT(n*4, fmt), ##__VA_ARGS__) +#define printfi(n, fmt, ...) printf(INDENT(n * 4, fmt), ##__VA_ARGS__) #define _unused(x) ((void)(x)) /* Random strings */ -static inline -void rand_str(char *dest, size_t length) { - char charset[] = "0123456789" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - while (length-- > 0) { - size_t index = (double) rand() / RAND_MAX * (sizeof charset - 1); - *dest++ = charset[index]; - } - *dest = '\0'; +static inline void rand_str(char *dest, size_t length) { + char charset[] = + "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + while (length-- > 0) { + size_t index = (double)rand() / RAND_MAX * (sizeof charset - 1); + *dest++ = charset[index]; + } + *dest = '\0'; } /* Boilerplate code */ -#define NO_INITIALIZE(NAME) \ -int \ -NAME ## _initialize(NAME ## _t * obj) { \ - return 0; \ -} - -#define NO_FINALIZE(NAME) \ -int \ -NAME ## _finalize(NAME ## _t * obj) { \ - return 0; \ -} - -#define AUTOGENERATE_CREATE_FREE(NAME) \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * obj = malloc(sizeof(NAME ## _t)); \ - if (!obj) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(obj) < 0) \ - goto ERR_INIT; \ - \ - return obj; \ - \ -ERR_INIT: \ - free(obj); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * obj) \ -{ \ - if (NAME ## _finalize(obj) < 0) \ - (void)0; /* XXX */ \ - free(obj); \ -} \ - -#define AUTOGENERATE_DEFS(NAME) \ -int NAME ## _initialize(NAME ## _t *); \ -int NAME ## _finalize(NAME ## _t *); \ -NAME ## _t * NAME ## _create(); \ -void NAME ## _free(NAME ## _t *); \ +#define NO_INITIALIZE(NAME) \ + int NAME##_initialize(NAME##_t *obj) { return 0; } + +#define NO_FINALIZE(NAME) \ + int NAME##_finalize(NAME##_t *obj) { return 0; } + +#define AUTOGENERATE_CREATE_FREE(NAME) \ + \ + NAME##_t *NAME##_create() { \ + NAME##_t *obj = malloc(sizeof(NAME##_t)); \ + if (!obj) goto ERR_MALLOC; \ + \ + if (NAME##_initialize(obj) < 0) goto ERR_INIT; \ + \ + return obj; \ + \ + ERR_INIT: \ + free(obj); \ + ERR_MALLOC: \ + return NULL; \ + } \ + \ + void NAME##_free(NAME##_t *obj) { \ + if (NAME##_finalize(obj) < 0) (void)0; /* XXX */ \ + free(obj); \ + } + +#define AUTOGENERATE_DEFS(NAME) \ + int NAME##_initialize(NAME##_t *); \ + int NAME##_finalize(NAME##_t *); \ + NAME##_t *NAME##_create(); \ + void NAME##_free(NAME##_t *); #endif /* FACEMGR_COMMON_H */ diff --git a/ctrl/facemgr/src/error.c b/ctrl/facemgr/src/error.c index 4dcea6e1f..36ce5f561 100644 --- a/ctrl/facemgr/src/error.c +++ b/ctrl/facemgr/src/error.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -21,8 +21,7 @@ #include "error.h" const char *FACEMGR_ERROR_STRING[] = { -#define _(a,b,c) [b] = c, - foreach_facemgr_error +#define _(a, b, c) [b] = c, + foreach_facemgr_error #undef _ }; - diff --git a/ctrl/facemgr/src/error.h b/ctrl/facemgr/src/error.h index a0d76b3e5..7fadea49f 100644 --- a/ctrl/facemgr/src/error.h +++ b/ctrl/facemgr/src/error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -16,15 +16,13 @@ #ifndef FACEMGR_ERROR_H #define FACEMGR_ERROR_H -#define foreach_facemgr_error \ -_(NONE, 0, "OK") \ - +#define foreach_facemgr_error _(NONE, 0, "OK") typedef enum { -#define _(a,b,c) FACEMGR_ERROR_##a = (-b), - foreach_facemgr_error +#define _(a, b, c) FACEMGR_ERROR_##a = (-b), + foreach_facemgr_error #undef _ - FACEMGR_ERROR_N, + FACEMGR_ERROR_N, } facemgr_error_t; extern const char *HICN_LIB_ERROR_STRING[]; diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c index 9e9f3f67f..609950f75 100644 --- a/ctrl/facemgr/src/facelet.c +++ b/ctrl/facemgr/src/facelet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,7 +20,7 @@ #include <assert.h> #include <stdbool.h> -#include <hicn/ctrl/face.h> +#include <hicn/face.h> #include <hicn/ctrl/route.h> #include <hicn/facemgr/cfg.h> #include <hicn/facemgr/facelet.h> @@ -32,152 +32,132 @@ TYPEDEF_SET_H(route_set, hicn_route_t *); TYPEDEF_SET(route_set, hicn_route_t *, hicn_route_cmp, generic_snprintf); -const char * face_type_layer_str[] = { -#define _(x) [FACE_TYPE_LAYER_ ## x] = STRINGIZE(x), +const char *face_type_layer_str[] = { +#define _(x) [FACE_TYPE_LAYER_##x] = STRINGIZE(x), foreach_face_type_layer #undef _ }; -const char * face_type_encap_str[] = { -#define _(x) [FACE_TYPE_ENCAP_ ## x] = STRINGIZE(x), +const char *face_type_encap_str[] = { +#define _(x) [FACE_TYPE_ENCAP_##x] = STRINGIZE(x), foreach_face_type_encap #undef _ }; -const char * facelet_status_str[] = { -#define _(x) [FACELET_STATUS_ ## x] = STRINGIZE(x), +const char *facelet_status_str[] = { +#define _(x) [FACELET_STATUS_##x] = STRINGIZE(x), foreach_facelet_status #undef _ }; -const char * facelet_error_reason_str[] = { -#define _(x) [FACELET_ERROR_REASON_ ## x] = STRINGIZE(x), +const char *facelet_error_reason_str[] = { +#define _(x) [FACELET_ERROR_REASON_##x] = STRINGIZE(x), foreach_facelet_error_reason #undef _ }; /* Facelet attribute status */ -const char * facelet_attr_status_str[] = { -#define _(x, str) [FACELET_ATTR_STATUS_ ## x] = STRINGIZE(x), +const char *facelet_attr_status_str[] = { +#define _(x, str) [FACELET_ATTR_STATUS_##x] = STRINGIZE(x), foreach_facelet_attr_status #undef _ }; -const char * facelet_attr_status_str_short[] = { -#define _(x, str) [FACELET_ATTR_STATUS_ ## x] = STRINGIZE(str), +const char *facelet_attr_status_str_short[] = { +#define _(x, str) [FACELET_ATTR_STATUS_##x] = STRINGIZE(str), foreach_facelet_attr_status #undef _ }; - /* Facelet */ struct facelet_s { - unsigned id; + unsigned id; #define _(TYPE, NAME) TYPE NAME; - foreach_facelet_attr + foreach_facelet_attr #undef _ -#define _(TYPE, NAME) facelet_attr_status_t NAME ## _status; - foreach_facelet_attr +#define _(TYPE, NAME) facelet_attr_status_t NAME##_status; + foreach_facelet_attr #undef _ + facelet_status_t status; + int error; + facelet_event_t event; - facelet_status_t status; - int error; - - facelet_event_t event; - - route_set_t * routes; - bool routes_done; + route_set_t *routes; + bool routes_done; - bool bj_done; - bool au_done; + bool bj_done; }; -const char * facelet_event_str[] = { -#define _(x) [FACELET_EVENT_ ## x] = STRINGIZE(x), -foreach_facelet_event +const char *facelet_event_str[] = { +#define _(x) [FACELET_EVENT_##x] = STRINGIZE(x), + foreach_facelet_event #undef _ }; -facelet_t * -facelet_create() -{ - facelet_t * facelet = calloc(1, sizeof(facelet_t)); - if (!facelet) - goto ERR_MALLOC; - - facelet->id = 0; - - facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET; - facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET; - facelet->family_status = FACELET_ATTR_STATUS_UNSET; - facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; - facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; - facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; - facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; - facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET; - facelet->state_status = FACELET_ATTR_STATUS_UNSET; +facelet_t *facelet_create() { + facelet_t *facelet = calloc(1, sizeof(facelet_t)); + if (!facelet) goto ERR_MALLOC; + + facelet->id = 0; + + facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET; + facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET; + facelet->family_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; + facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET; + facelet->state_status = FACELET_ATTR_STATUS_UNSET; #ifdef WITH_POLICY - facelet->priority_status = FACELET_ATTR_STATUS_UNSET; + facelet->priority_status = FACELET_ATTR_STATUS_UNSET; #endif /* WITH_POLICY */ - facelet->face_type_status = FACELET_ATTR_STATUS_UNSET; + facelet->face_type_status = FACELET_ATTR_STATUS_UNSET; - facelet->status = FACELET_STATUS_UNDEFINED; - facelet->error = 0; + facelet->status = FACELET_STATUS_UNDEFINED; + facelet->error = 0; - facelet->bj_done = false; - facelet->au_done = false; + facelet->bj_done = false; - facelet->event = FACELET_EVENT_UNDEFINED; + facelet->event = FACELET_EVENT_UNDEFINED; - facelet->routes = route_set_create(); - if (!facelet->routes) { - ERROR("[facelet_create] Cannot create route set"); - goto ERR_ROUTE_SET; - } - facelet->routes_done = false; + facelet->routes = route_set_create(); + if (!facelet->routes) { + ERROR("[facelet_create] Cannot create route set"); + goto ERR_ROUTE_SET; + } + facelet->routes_done = false; - return facelet; + return facelet; ERR_ROUTE_SET: - free(facelet); + free(facelet); ERR_MALLOC: - return NULL; + return NULL; } -unsigned -facelet_get_id(facelet_t * facelet) -{ - return facelet->id; -} +unsigned facelet_get_id(facelet_t *facelet) { return facelet->id; } -void -facelet_set_id(facelet_t * facelet, unsigned id) -{ - facelet->id = id; -} +void facelet_set_id(facelet_t *facelet, unsigned id) { facelet->id = id; } -facelet_t * -facelet_create_from_netdevice(netdevice_t * netdevice) -{ - facelet_t * facelet = facelet_create(); - if (!facelet) - goto ERR_FACELET; +facelet_t *facelet_create_from_netdevice(netdevice_t *netdevice) { + facelet_t *facelet = facelet_create(); + if (!facelet) goto ERR_FACELET; - int rc = facelet_set_netdevice(facelet, *netdevice); - if (rc < 0) - goto ERR_NETDEV; + int rc = facelet_set_netdevice(facelet, *netdevice); + if (rc < 0) goto ERR_NETDEV; - return facelet; + return facelet; ERR_NETDEV: - facelet_free(facelet); + facelet_free(facelet); ERR_FACELET: - return NULL; + return NULL; } /** @@ -186,368 +166,339 @@ ERR_FACELET: * \param [in] facelet - Pointer to the facelet to verify * \return 0 in case of success, -1 otherwise */ -int -facelet_validate_face(const facelet_t * facelet) -{ - if (!facelet_has_face_type(facelet)) - return false; - switch(facelet->face_type.layer) { - case FACE_TYPE_LAYER_4: - if (!facelet_has_remote_port(facelet)) - return false; - if (!facelet_has_remote_addr(facelet)) - return false; - case FACE_TYPE_LAYER_3: - if (!facelet_has_local_port(facelet)) - return false; - if (!facelet_has_local_addr(facelet)) - return false; - if (!facelet_has_netdevice(facelet)) - return false; - return true; - - default: - return false; /* Error */ - } - // FIXME Not implemented - return 0; +int facelet_validate_face(const facelet_t *facelet) { + if (!facelet_has_face_type(facelet)) return false; + + switch (facelet->face_type.layer) { + case FACE_TYPE_LAYER_4: + if (!facelet_has_remote_port(facelet)) return false; + if (!facelet_has_remote_addr(facelet)) return false; + case FACE_TYPE_LAYER_3: + if (!facelet_has_local_port(facelet)) return false; + if (!facelet_has_local_addr(facelet)) return false; + if (!facelet_has_netdevice(facelet)) return false; + break; + + default: + return false; + } + + return true; } - -netdevice_type_t -netdevice_type_from_face_tags(const face_t * face) -{ - policy_tags_t tags = face->tags; - if (policy_tags_has(tags, POLICY_TAG_WIRED)) - return NETDEVICE_TYPE_WIRED; - else if (policy_tags_has(tags, POLICY_TAG_WIFI)) - return NETDEVICE_TYPE_WIFI; - else if (policy_tags_has(tags, POLICY_TAG_CELLULAR)) - return NETDEVICE_TYPE_CELLULAR; - return NETDEVICE_TYPE_UNDEFINED; +netdevice_type_t netdevice_type_from_face_tags(const face_t *face) { +#ifdef WITH_POLICY + policy_tags_t tags = face->tags; + if (policy_tags_has(tags, POLICY_TAG_WIRED)) + return NETDEVICE_TYPE_WIRED; + else if (policy_tags_has(tags, POLICY_TAG_WIFI)) + return NETDEVICE_TYPE_WIFI; + else if (policy_tags_has(tags, POLICY_TAG_CELLULAR)) + return NETDEVICE_TYPE_CELLULAR; +#endif /* WITH_POLICY */ + return NETDEVICE_TYPE_UNDEFINED; } -facelet_t * -facelet_create_from_face(face_t * face) -{ - facelet_t * facelet = malloc(sizeof(facelet_t)); - if (!facelet) - goto ERR_MALLOC; +facelet_t *facelet_create_from_face(face_t *face) { + facelet_t *facelet = malloc(sizeof(facelet_t)); + if (!facelet) goto ERR_MALLOC; - facelet->id = 0; + facelet->id = 0; - /* Go through the face attributes to update the local representation */ + /* Go through the face attributes to update the local representation */ - /* Attribute : netdevice */ - /* NOTE index is not set */ - if (IS_VALID_NETDEVICE(face->netdevice)) { - /* /!\ A face has only the netdevice name */ - netdevice_set_name(&facelet->netdevice, face->netdevice.name); - facelet->netdevice_status = FACELET_ATTR_STATUS_CLEAN; + /* Attribute : netdevice */ + /* NOTE index is not set */ + if (IS_VALID_NETDEVICE(face->netdevice)) { + /* /!\ A face has only the netdevice name */ + netdevice_set_name(&facelet->netdevice, face->netdevice.name); + facelet->netdevice_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET; + } + + /* Attribute : netdevice_type */ + facelet->netdevice_type = netdevice_type_from_face_tags(face); + if (facelet->netdevice_type != NETDEVICE_TYPE_UNDEFINED) { + facelet->netdevice_type_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->netdevice_type = NETDEVICE_TYPE_UNDEFINED; + facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET; + } + + /* Attribute : family */ + if (IS_VALID_FAMILY(face->family)) { + facelet->family = face->family; + facelet->family_status = FACELET_ATTR_STATUS_CLEAN; + + /* Attribute : local_addr */ + if (ip_address_cmp(&face->local_addr, &IP_ADDRESS_EMPTY, face->family) != + 0) { + facelet->local_addr = face->local_addr; + facelet->local_addr_status = FACELET_ATTR_STATUS_CLEAN; } else { - facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; } - /* Attribute : netdevice_type */ - facelet->netdevice_type = netdevice_type_from_face_tags(face); - if (facelet->netdevice_type != NETDEVICE_TYPE_UNDEFINED) { - facelet->netdevice_type_status = FACELET_ATTR_STATUS_CLEAN; + /* Attribute : local_port */ + if (IS_VALID_PORT(face->local_port)) { + facelet->local_port = face->local_port; + facelet->local_port_status = FACELET_ATTR_STATUS_CLEAN; } else { - facelet->netdevice_type = NETDEVICE_TYPE_UNDEFINED; - facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; } - /* Attribute : family */ - if (IS_VALID_FAMILY(face->family)) { - facelet->family = face->family; - facelet->family_status = FACELET_ATTR_STATUS_CLEAN; - - /* Attribute : local_addr */ - if (ip_address_cmp(&face->local_addr, &IP_ADDRESS_EMPTY, face->family) != 0) { - facelet->local_addr = face->local_addr; - facelet->local_addr_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; - } - - /* Attribute : local_port */ - if (IS_VALID_PORT(face->local_port)) { - facelet->local_port = face->local_port; - facelet->local_port_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; - } - - /* Attribute : remote_addr */ - if (ip_address_cmp(&face->remote_addr, &IP_ADDRESS_EMPTY, face->family) != 0) { - facelet->remote_addr = face->remote_addr; - facelet->remote_addr_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; - } - - /* Attribute : remote_port */ - if (IS_VALID_PORT(face->remote_port)) { - facelet->remote_port = face->remote_port; - facelet->remote_port_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; - } - + /* Attribute : remote_addr */ + if (ip_address_cmp(&face->remote_addr, &IP_ADDRESS_EMPTY, face->family) != + 0) { + facelet->remote_addr = face->remote_addr; + facelet->remote_addr_status = FACELET_ATTR_STATUS_CLEAN; } else { - facelet->family_status = FACELET_ATTR_STATUS_UNSET; - facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; - facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; - facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; - facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; } - /* Attribute : admin_state */ - if ((face->admin_state == FACE_STATE_UP) || - (face->admin_state == FACE_STATE_DOWN)) { - facelet->admin_state = face->admin_state; - facelet->admin_state_status = FACELET_ATTR_STATUS_CLEAN; + /* Attribute : remote_port */ + if (IS_VALID_PORT(face->remote_port)) { + facelet->remote_port = face->remote_port; + facelet->remote_port_status = FACELET_ATTR_STATUS_CLEAN; } else { - facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; } - /* Attribute : state */ - if ((face->state == FACE_STATE_UP) || - (face->state == FACE_STATE_DOWN)) { - facelet->state = face->state; - facelet->state_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->state_status = FACELET_ATTR_STATUS_UNSET; - } + } else { + facelet->family_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_addr_status = FACELET_ATTR_STATUS_UNSET; + facelet->local_port_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_addr_status = FACELET_ATTR_STATUS_UNSET; + facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; + } + + /* Attribute : admin_state */ + if ((face->admin_state == FACE_STATE_UP) || + (face->admin_state == FACE_STATE_DOWN)) { + facelet->admin_state = face->admin_state; + facelet->admin_state_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET; + } + + /* Attribute : state */ + if ((face->state == FACE_STATE_UP) || (face->state == FACE_STATE_DOWN)) { + facelet->state = face->state; + facelet->state_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->state_status = FACELET_ATTR_STATUS_UNSET; + } #ifdef WITH_POLICY - /* Attribute : priority */ - if (face->priority > 0) { - facelet->priority = face->priority; - facelet->priority_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->priority_status = FACELET_ATTR_STATUS_UNSET; - } + /* Attribute : priority */ + if (face->priority > 0) { + facelet->priority = face->priority; + facelet->priority_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->priority_status = FACELET_ATTR_STATUS_UNSET; + } #endif /* WITH_POLICY */ - /* Attribute : face_type */ - if ((face->type != FACE_TYPE_UNDEFINED) && (face->type != FACE_TYPE_N)) { - switch(face->type) { - case FACE_TYPE_UDP: - facelet->face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; - break; - case FACE_TYPE_TCP: - facelet->face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; - break; - case FACE_TYPE_HICN: - facelet->face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; - break; - default: - ERROR("[facelet_create_from_face] Face type not (yet) implemented"); - goto ERR_FACE; - } - facelet->face_type_status = FACELET_ATTR_STATUS_CLEAN; - } else { - facelet->face_type_status = FACELET_ATTR_STATUS_UNSET; + /* Attribute : face_type */ + if ((face->type != FACE_TYPE_UNDEFINED) && (face->type != FACE_TYPE_N)) { + switch (face->type) { + case FACE_TYPE_UDP: + facelet->face_type = FACEMGR_FACE_TYPE_OVERLAY_UDP; + break; + case FACE_TYPE_TCP: + facelet->face_type = FACEMGR_FACE_TYPE_OVERLAY_TCP; + break; + case FACE_TYPE_HICN: + facelet->face_type = FACEMGR_FACE_TYPE_NATIVE_TCP; + break; + default: + ERROR("[facelet_create_from_face] Face type not (yet) implemented"); + goto ERR_FACE; } + facelet->face_type_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->face_type_status = FACELET_ATTR_STATUS_UNSET; + } - /* Status */ - facelet->status = FACELET_STATUS_CLEAN; - facelet->error = 0; + /* Status */ + facelet->status = FACELET_STATUS_CLEAN; + facelet->error = 0; - /* TODO Consistency check between face type and found attributes */ - if (facelet_validate_face(facelet) < 0) { - ERROR("[facelet_create_from_face] Cannot validate face"); - goto ERR_FACE; - } + /* TODO Consistency check between face type and found attributes */ + if (facelet_validate_face(facelet) < 0) { + ERROR("[facelet_create_from_face] Cannot validate face"); + goto ERR_FACE; + } - facelet->bj_done = false; - facelet->au_done = false; + facelet->bj_done = false; - facelet->event = FACELET_EVENT_UNDEFINED; + facelet->event = FACELET_EVENT_UNDEFINED; - /* We need to get route set */ - facelet->routes = route_set_create(); - if (!facelet->routes) { - ERROR("[facelet_create_from_face] Cannot create route set"); - goto ERR_ROUTE_SET; - } - facelet->routes_done = false; + /* We need to get route set */ + facelet->routes = route_set_create(); + if (!facelet->routes) { + ERROR("[facelet_create_from_face] Cannot create route set"); + goto ERR_ROUTE_SET; + } + facelet->routes_done = false; - return facelet; + return facelet; ERR_ROUTE_SET: ERR_FACE: - free(facelet); + free(facelet); ERR_MALLOC: - return NULL; + return NULL; } +void facelet_free(facelet_t *facelet) { + /* Workaround: investigate how routes could be NULL */ + if (!facelet->routes) return; -void -facelet_free(facelet_t * facelet) -{ - /* Free up routes */ - route_set_clear(facelet->routes); - route_set_free(facelet->routes); - free(facelet); + /* Free up routes */ + route_set_clear(facelet->routes); + route_set_free(facelet->routes); + free(facelet); } -facelet_t * -facelet_dup(const facelet_t * current_facelet) -{ - facelet_t * facelet = facelet_create(); - if (!facelet) - goto ERR_CREATE; +facelet_t *facelet_dup(const facelet_t *current_facelet) { + facelet_t *facelet = facelet_create(); + if (!facelet) goto ERR_CREATE; -#define _(TYPE, NAME) facelet-> NAME = current_facelet-> NAME; - foreach_facelet_attr +#define _(TYPE, NAME) facelet->NAME = current_facelet->NAME; + foreach_facelet_attr #undef _ -#define _(TYPE, NAME) facelet-> NAME ## _status = current_facelet-> NAME ## _status; - foreach_facelet_attr +#define _(TYPE, NAME) facelet->NAME##_status = current_facelet->NAME##_status; + foreach_facelet_attr #undef _ - facelet->status = current_facelet->status; - facelet->event = current_facelet->event; - - facelet->bj_done = current_facelet->bj_done; - facelet->au_done = current_facelet->au_done; - - /* Routes */ - hicn_route_t ** route_array; - int n = route_set_get_array(current_facelet->routes, &route_array); - if (n < 0) { - ERROR("[facelet_free] Error getting route set associated to facelet"); - } else { - for (unsigned i = 0; i < n; i++) { - hicn_route_t * route = route_array[i]; - hicn_route_t * new_route = hicn_route_dup(route); - if (!new_route) - goto ERR_ROUTE; - route_set_add(facelet->routes, new_route); - } + facelet->status = current_facelet->status; + facelet->event = current_facelet->event; + + facelet->bj_done = current_facelet->bj_done; + + /* Routes */ + hicn_route_t **route_array; + int n = route_set_get_array(current_facelet->routes, &route_array); + if (n < 0) { + ERROR("[facelet_free] Error getting route set associated to facelet"); + } else { + for (unsigned i = 0; i < n; i++) { + hicn_route_t *route = route_array[i]; + if (!route) continue; /* Should not occur */ + hicn_route_t *new_route = hicn_route_dup(route); + if (!new_route) goto ERR_ROUTE; + route_set_add(facelet->routes, new_route); } - free(route_array); + } + free(route_array); - return facelet; + return facelet; ERR_ROUTE: - /* This will free all routes */ - facelet_free(facelet); + /* This will free all routes */ + facelet_free(facelet); ERR_CREATE: - return NULL; + return NULL; } -int -facelet_cmp(const facelet_t * f1, const facelet_t * f2) -{ - /* - * Under the assumption we only create a face per physical interface, a - * facelet is uniquely identified by its netdevice attribute, and address - * family if any. - * - * Because of additional static faces, we introduce a unique facelet id - * - * This function is mostly used for lookups into the cache, and the face - * thus needs to have a netdevice associated, and optionally, an address - * family. - * - * For other situations, the `facelet_match` function is more appropriate. +int facelet_cmp(const facelet_t *f1, const facelet_t *f2) { + /* + * Under the assumption we only create a face per physical interface, a + * facelet is uniquely identified by its netdevice attribute, and address + * family if any. + * + * Because of additional static faces, we introduce a unique facelet id + * + * This function is mostly used for lookups into the cache, and the face + * thus needs to have a netdevice associated, and optionally, an address + * family. + * + * For other situations, the `facelet_match` function is more appropriate. + */ + + if (f1->id != f2->id) return f1->id > f2->id ? 1 : -1; + + if ((f1->netdevice_status != FACELET_ATTR_STATUS_UNSET) && + (f2->netdevice_status != FACELET_ATTR_STATUS_UNSET)) { + int rc = netdevice_cmp(&f1->netdevice, &f2->netdevice); + if (rc != 0) return rc; + + } else { + /* Both unset : we might have the face without netdevice due to hicn + * light not returning it currently, but we cannot skip it in the match + * otherwise we cannot distinguish with other faces except matching on + * other fields which might unfortunately not be determined yet... */ + return (f1->netdevice_status == FACELET_ATTR_STATUS_UNSET) ? -1 : 1; + } - if (f1->id != f2->id) - return f1->id > f2->id ? 1 : -1; - - if ((f1->netdevice_status != FACELET_ATTR_STATUS_UNSET) && - (f2->netdevice_status != FACELET_ATTR_STATUS_UNSET)) { - int rc = netdevice_cmp(&f1->netdevice, &f2->netdevice); - if (rc != 0) - return rc; - - } else { - /* Both unset : we might have the face without netdevice due to hicn - * light not returning it currently, but we cannot skip it in the match - * otherwise we cannot distinguish with other faces except matching on - * other fields which might unfortunately not be determined yet... - */ - return (f1->netdevice_status == FACELET_ATTR_STATUS_UNSET) ? -1 : 1; - } - - assert(f1->family_status != FACELET_ATTR_STATUS_UNSET); - assert(f2->family_status != FACELET_ATTR_STATUS_UNSET); + assert(f1->family_status != FACELET_ATTR_STATUS_UNSET); + assert(f2->family_status != FACELET_ATTR_STATUS_UNSET); - if ((f1->family == AF_UNSPEC) || (f2->family == AF_UNSPEC)) - return 0; - int diff = f1->family - f2->family; - return (diff > 0) ? 1 : - (diff < 0) ? -1 : 0; + if ((f1->family == AF_UNSPEC) || (f2->family == AF_UNSPEC)) return 0; + int diff = f1->family - f2->family; + return (diff > 0) ? 1 : (diff < 0) ? -1 : 0; } /* * If the match has a field set, then the facelet only matches iif it has the * same field set, and both values are equal */ -#define EQUALS_ATTRIBUTE(TYPE, NAME) \ -do { \ - if (facelet_has_ ## NAME(facelet1)) { \ - if (facelet_has_ ## NAME(facelet2)) { \ - TYPE NAME ## 1; \ - TYPE NAME ## 2; \ - if (facelet_get_ ## NAME (facelet1, & NAME ## 1) < 0) \ - return false; \ - if (facelet_get_ ## NAME (facelet2, & NAME ## 2) < 0) \ - return false; \ - if (memcmp(& NAME ## 1, & NAME ## 2, sizeof(TYPE)) != 0) \ - return false; \ - } else { \ - return false; \ - } \ - } else { \ - if (facelet_has_ ## NAME(facelet2)) { \ - return false; \ - } \ - } \ -} while(0) - -bool -facelet_equals(const facelet_t * facelet1, const facelet_t * facelet2) -{ +#define EQUALS_ATTRIBUTE(TYPE, NAME) \ + do { \ + if (facelet_has_##NAME(facelet1)) { \ + if (facelet_has_##NAME(facelet2)) { \ + TYPE NAME##1; \ + TYPE NAME##2; \ + if (facelet_get_##NAME(facelet1, &NAME##1) < 0) return false; \ + if (facelet_get_##NAME(facelet2, &NAME##2) < 0) return false; \ + if (memcmp(&NAME##1, &NAME##2, sizeof(TYPE)) != 0) return false; \ + } else { \ + return false; \ + } \ + } else { \ + if (facelet_has_##NAME(facelet2)) { \ + return false; \ + } \ + } \ + } while (0) + +bool facelet_equals(const facelet_t *facelet1, const facelet_t *facelet2) { #define _(TYPE, NAME) EQUALS_ATTRIBUTE(TYPE, NAME); - foreach_facelet_attr + foreach_facelet_attr #undef _ - return true; + return true; } /* * If the match has a field set, then the facelet only matches iif it has the * same field set, and both values are equal */ -#define MATCH_ATTRIBUTE(TYPE, NAME) \ -do { \ - if (facelet_match->NAME ## _status == FACELET_ATTR_STATUS_CLEAN) { \ - if (facelet_has_ ## NAME(facelet_match)) { \ - TYPE NAME; \ - TYPE NAME ## _match; \ - if (!facelet_has_ ## NAME(facelet)) { \ - continue; /* return false; */ \ - } \ - if (facelet_get_ ## NAME (facelet, & NAME) < 0) \ - return false; \ - if (facelet_get_ ## NAME (facelet_match, & NAME ## _match) < 0) \ - return false; \ - if (memcmp(& NAME, & NAME ## _match, sizeof(NAME)) != 0) { \ - return false; \ - } \ - } \ - } \ -} while(0) +#define MATCH_ATTRIBUTE(TYPE, NAME) \ + do { \ + if (facelet_match->NAME##_status == FACELET_ATTR_STATUS_CLEAN) { \ + if (facelet_has_##NAME(facelet_match)) { \ + TYPE NAME; \ + TYPE NAME##_match; \ + if (!facelet_has_##NAME(facelet)) { \ + continue; /* return false; */ \ + } \ + if (facelet_get_##NAME(facelet, &NAME) < 0) return false; \ + if (facelet_get_##NAME(facelet_match, &NAME##_match) < 0) \ + return false; \ + if (memcmp(&NAME, &NAME##_match, sizeof(NAME)) != 0) { \ + return false; \ + } \ + } \ + } \ + } while (0) /* facelet_match is the incoming one */ -bool -facelet_match(const facelet_t * facelet, const facelet_t * facelet_match) -{ +bool facelet_match(const facelet_t *facelet, const facelet_t *facelet_match) { #define _(TYPE, NAME) MATCH_ATTRIBUTE(TYPE, NAME); - foreach_facelet_attr + foreach_facelet_attr #undef _ #if 0 @@ -557,117 +508,101 @@ facelet_match(const facelet_t * facelet, const facelet_t * facelet_match) facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); DEBUG(" WITH %s", facelet_s); #endif - return true; + return true; } -bool facelet_has_key(const facelet_t * facelet) { - return (facelet_has_netdevice(facelet) && facelet_has_family(facelet)); +bool facelet_has_key(const facelet_t *facelet) { + return (facelet_has_netdevice(facelet) && facelet_has_family(facelet)); } /* * Implementation note: * - facelet_set_* is equivalent to merge with a CLEAN remote attribute */ -#define FACELET_ACCESSORS(TYPE, NAME) \ -bool \ -facelet_has_ ## NAME(const facelet_t * facelet) \ -{ \ - assert(facelet); \ - assert(facelet->NAME ## _status != FACELET_ATTR_STATUS_UNDEFINED); \ - assert(facelet->NAME ## _status != FACELET_ATTR_STATUS_N); \ - return ((facelet-> NAME ## _status != FACELET_ATTR_STATUS_UNSET)); \ -} \ - \ -facelet_attr_status_t \ -facelet_get_ ## NAME ## _status(const facelet_t * facelet) \ -{ \ - return (facelet->NAME ## _status); \ -} \ - \ -void \ -facelet_set_ ## NAME ## _status(facelet_t * facelet, \ - facelet_attr_status_t status) \ -{ \ - facelet->NAME ## _status = status; \ -} \ - \ -int \ -facelet_get_ ## NAME(const facelet_t * facelet, TYPE * NAME) \ -{ \ - assert(facelet); \ - if (!facelet_has_ ## NAME(facelet)) \ - return -1; \ - *NAME = facelet-> NAME; \ - return 0; \ -} \ - \ -int \ -facelet_set_local_ ## NAME(facelet_t * facelet, TYPE NAME) \ -{ \ - assert(facelet); \ - switch(facelet->NAME ## _status) { \ - case FACELET_ATTR_STATUS_UNSET: \ - case FACELET_ATTR_STATUS_CLEAN: \ - case FACELET_ATTR_STATUS_DIRTY: \ - case FACELET_ATTR_STATUS_PENDING: \ - facelet-> NAME = NAME; \ - facelet->NAME ## _status = FACELET_ATTR_STATUS_DIRTY; \ - if (facelet->status == FACELET_STATUS_CLEAN) \ - facelet->status = FACELET_STATUS_UPDATE; \ - break; \ - case FACELET_ATTR_STATUS_CONFLICT: \ - break; \ - case FACELET_ATTR_STATUS_UNDEFINED: \ - case FACELET_ATTR_STATUS_N: \ - ERROR("Unexpected attribute status value"); \ - return -1; \ - } \ - return 0; \ -} \ - \ -int \ -facelet_set_remote_ ## NAME(facelet_t * facelet, TYPE NAME) \ -{ \ - assert(facelet); \ - switch(facelet->NAME ## _status) { \ - case FACELET_ATTR_STATUS_UNSET: \ - facelet-> NAME = NAME; \ - facelet->NAME ## _status = FACELET_ATTR_STATUS_CLEAN; \ - break; \ - case FACELET_ATTR_STATUS_CLEAN: \ - facelet->NAME = NAME; \ - break; \ - case FACELET_ATTR_STATUS_DIRTY: \ - ERROR("Discarded remote value for status reasons"); \ - break; \ - case FACELET_ATTR_STATUS_PENDING: \ - ERROR("Received remote value on pending attribute"); \ - facelet->NAME ## _status = FACELET_ATTR_STATUS_CONFLICT; \ - /* We need to proceed to an update of the face */ \ - if (facelet->status != FACELET_STATUS_UPDATE) \ - facelet->status = FACELET_STATUS_UPDATE; \ - break; \ - case FACELET_ATTR_STATUS_CONFLICT: \ - return -1; \ - case FACELET_ATTR_STATUS_UNDEFINED: \ - case FACELET_ATTR_STATUS_N: \ - ERROR("Unexpected attribute status value"); \ - return -1; \ - } \ - return 0; \ -} \ - \ -int \ -facelet_set_ ## NAME(facelet_t * facelet, TYPE NAME) \ -{ \ - return facelet_set_local_ ## NAME(facelet, NAME); \ -} \ - \ -int \ -facelet_unset_ ## NAME(facelet_t * facelet) \ -{ \ - return facelet->NAME ## _status = FACELET_ATTR_STATUS_UNSET; \ -} +#define FACELET_ACCESSORS(TYPE, NAME) \ + bool facelet_has_##NAME(const facelet_t *facelet) { \ + assert(facelet); \ + assert(facelet->NAME##_status != FACELET_ATTR_STATUS_UNDEFINED); \ + assert(facelet->NAME##_status != FACELET_ATTR_STATUS_N); \ + return ((facelet->NAME##_status != FACELET_ATTR_STATUS_UNSET)); \ + } \ + \ + facelet_attr_status_t facelet_get_##NAME##_status( \ + const facelet_t *facelet) { \ + return (facelet->NAME##_status); \ + } \ + \ + void facelet_set_##NAME##_status(facelet_t *facelet, \ + facelet_attr_status_t status) { \ + facelet->NAME##_status = status; \ + } \ + \ + int facelet_get_##NAME(const facelet_t *facelet, TYPE *NAME) { \ + assert(facelet); \ + if (!facelet_has_##NAME(facelet)) return -1; \ + *NAME = facelet->NAME; \ + return 0; \ + } \ + \ + int facelet_set_local_##NAME(facelet_t *facelet, TYPE NAME) { \ + assert(facelet); \ + switch (facelet->NAME##_status) { \ + case FACELET_ATTR_STATUS_UNSET: \ + case FACELET_ATTR_STATUS_CLEAN: \ + case FACELET_ATTR_STATUS_DIRTY: \ + case FACELET_ATTR_STATUS_PENDING: \ + facelet->NAME = NAME; \ + facelet->NAME##_status = FACELET_ATTR_STATUS_DIRTY; \ + if (facelet->status == FACELET_STATUS_CLEAN) \ + facelet->status = FACELET_STATUS_UPDATE; \ + break; \ + case FACELET_ATTR_STATUS_CONFLICT: \ + break; \ + case FACELET_ATTR_STATUS_UNDEFINED: \ + case FACELET_ATTR_STATUS_N: \ + ERROR("Unexpected attribute status value"); \ + return -1; \ + } \ + return 0; \ + } \ + \ + int facelet_set_remote_##NAME(facelet_t *facelet, TYPE NAME) { \ + assert(facelet); \ + switch (facelet->NAME##_status) { \ + case FACELET_ATTR_STATUS_UNSET: \ + facelet->NAME = NAME; \ + facelet->NAME##_status = FACELET_ATTR_STATUS_CLEAN; \ + break; \ + case FACELET_ATTR_STATUS_CLEAN: \ + facelet->NAME = NAME; \ + break; \ + case FACELET_ATTR_STATUS_DIRTY: \ + ERROR("Discarded remote value for status reasons"); \ + break; \ + case FACELET_ATTR_STATUS_PENDING: \ + ERROR("Received remote value on pending attribute"); \ + facelet->NAME##_status = FACELET_ATTR_STATUS_CONFLICT; \ + /* We need to proceed to an update of the face */ \ + if (facelet->status != FACELET_STATUS_UPDATE) \ + facelet->status = FACELET_STATUS_UPDATE; \ + break; \ + case FACELET_ATTR_STATUS_CONFLICT: \ + return -1; \ + case FACELET_ATTR_STATUS_UNDEFINED: \ + case FACELET_ATTR_STATUS_N: \ + ERROR("Unexpected attribute status value"); \ + return -1; \ + } \ + return 0; \ + } \ + \ + int facelet_set_##NAME(facelet_t *facelet, TYPE NAME) { \ + return facelet_set_local_##NAME(facelet, NAME); \ + } \ + \ + int facelet_unset_##NAME(facelet_t *facelet) { \ + return facelet->NAME##_status = FACELET_ATTR_STATUS_UNSET; \ + } #define _(TYPE, NAME) FACELET_ACCESSORS(TYPE, NAME) foreach_facelet_attr @@ -681,773 +616,630 @@ foreach_facelet_attr // FIXME CLEAN for key fields, dirty for fields to update. -#define MERGE_ATTRIBUTE(TYPE, NAME) \ -do { \ - switch(facelet_to_merge->NAME ## _status) { \ - case FACELET_ATTR_STATUS_UNDEFINED: \ - case FACELET_ATTR_STATUS_N: \ - case FACELET_ATTR_STATUS_PENDING: \ - case FACELET_ATTR_STATUS_CONFLICT: \ - ERROR("Unexpected facelet attribute status"); \ - return -1; \ - case FACELET_ATTR_STATUS_UNSET: \ - break; \ - case FACELET_ATTR_STATUS_CLEAN: \ - case FACELET_ATTR_STATUS_DIRTY: \ - facelet_set_ ## NAME(facelet, facelet_to_merge-> NAME); \ - break; \ - } \ -} while (0) - -int facelet_merge(facelet_t * facelet, facelet_t * facelet_to_merge) -{ - assert(facelet && facelet_to_merge); +#define MERGE_ATTRIBUTE(TYPE, NAME) \ + do { \ + switch (facelet_to_merge->NAME##_status) { \ + case FACELET_ATTR_STATUS_UNDEFINED: \ + case FACELET_ATTR_STATUS_N: \ + case FACELET_ATTR_STATUS_PENDING: \ + case FACELET_ATTR_STATUS_CONFLICT: \ + ERROR("Unexpected facelet attribute status"); \ + return -1; \ + case FACELET_ATTR_STATUS_UNSET: \ + break; \ + case FACELET_ATTR_STATUS_CLEAN: \ + case FACELET_ATTR_STATUS_DIRTY: \ + facelet_set_##NAME(facelet, facelet_to_merge->NAME); \ + break; \ + } \ + } while (0) + + int + facelet_merge(facelet_t *facelet, facelet_t *facelet_to_merge) { + assert(facelet && facelet_to_merge); #define _(TYPE, NAME) MERGE_ATTRIBUTE(TYPE, NAME); - foreach_facelet_attr + foreach_facelet_attr #undef _ - facelet->event = facelet_to_merge->event; - - /* Routes */ - hicn_route_t ** route_array; - int n = route_set_get_array(facelet_to_merge->routes, &route_array); - if (n < 0) { - ERROR("[facelet_free] Error getting route set associated to facelet"); - } else { - for (unsigned i = 0; i < n; i++) { - hicn_route_t * route = route_array[i]; - hicn_route_t * route_found = NULL; - if (route_set_get(facelet->routes, route, &route_found) < 0) { - ERROR("Error searching for route"); - continue; - } - if (route_found) - continue; - route_set_add(facelet->routes, hicn_route_dup(route)); - } + facelet->event = facelet_to_merge->event; + + /* Routes */ + hicn_route_t **route_array; + int n = route_set_get_array(facelet_to_merge->routes, &route_array); + if (n < 0) { + ERROR("[facelet_free] Error getting route set associated to facelet"); + } else { + for (unsigned i = 0; i < n; i++) { + hicn_route_t *route = route_array[i]; + if (!route) continue; /* Should not occur */ + hicn_route_t *route_found = NULL; + if (route_set_get(facelet->routes, route, &route_found) < 0) { + ERROR("Error searching for route"); + continue; + } + if (route_found) continue; + route_set_add(facelet->routes, hicn_route_dup(route)); } - free(route_array); + } + free(route_array); - return 0; + return 0; } -#define MERGE_ATTRIBUTE_REMOTE(TYPE, NAME) \ -do { \ - switch(facelet_to_merge->NAME ## _status) { \ - case FACELET_ATTR_STATUS_UNDEFINED: \ - case FACELET_ATTR_STATUS_N: \ - case FACELET_ATTR_STATUS_DIRTY: \ - case FACELET_ATTR_STATUS_PENDING: \ - case FACELET_ATTR_STATUS_CONFLICT: \ - ERROR("Unexpected facelet attribute status"); \ - return -1; \ - case FACELET_ATTR_STATUS_UNSET: \ - break; \ - case FACELET_ATTR_STATUS_CLEAN: \ - facelet_set_ ## NAME(facelet, facelet_to_merge-> NAME); \ - break; \ - \ - } \ -} while (0) - -int facelet_merge_remote(facelet_t * facelet, const facelet_t * facelet_to_merge) -{ - assert(facelet && facelet_to_merge); +#define MERGE_ATTRIBUTE_REMOTE(TYPE, NAME) \ + do { \ + switch (facelet_to_merge->NAME##_status) { \ + case FACELET_ATTR_STATUS_UNDEFINED: \ + case FACELET_ATTR_STATUS_N: \ + case FACELET_ATTR_STATUS_DIRTY: \ + case FACELET_ATTR_STATUS_PENDING: \ + case FACELET_ATTR_STATUS_CONFLICT: \ + ERROR("Unexpected facelet attribute status"); \ + return -1; \ + case FACELET_ATTR_STATUS_UNSET: \ + break; \ + case FACELET_ATTR_STATUS_CLEAN: \ + facelet_set_##NAME(facelet, facelet_to_merge->NAME); \ + break; \ + } \ + } while (0) + +int facelet_merge_remote(facelet_t *facelet, + const facelet_t *facelet_to_merge) { + assert(facelet && facelet_to_merge); #define _(TYPE, NAME) MERGE_ATTRIBUTE_REMOTE(TYPE, NAME); - foreach_facelet_attr + foreach_facelet_attr #undef _ - facelet->event = facelet_to_merge->event; - return 0; + facelet->event = facelet_to_merge->event; + return 0; } -int -facelet_get_face(const facelet_t * facelet, face_t ** pface) -{ - assert(pface); - - /* Facelet has all the required information to create a face */ - if (facelet_validate_face(facelet) < 0) { - ERROR("[facelet_get_face] Face does not validate"); - return 0; - } +int facelet_get_face(const facelet_t *facelet, face_t **pface) { + assert(pface); - face_t * face = face_create(); - if (!face) - goto ERR_CREATE; - - assert(facelet_has_netdevice(facelet)); - face->netdevice = facelet->netdevice; - - /* Face type */ - switch(facelet->face_type.layer) { - case FACE_TYPE_LAYER_4: - switch(facelet->face_type.encap) { - case FACE_TYPE_ENCAP_UDP: - face->type = FACE_TYPE_UDP; - break; - case FACE_TYPE_ENCAP_TCP: - face->type = FACE_TYPE_TCP; - break; - case FACE_TYPE_ENCAP_UNDEFINED: - case FACE_TYPE_ENCAP_N: - ERROR("[facelet_get_face] Unsupported face encapsulation"); - goto ERR; - } - - if (facelet_get_family(facelet, &face->family) < 0) { - ERROR("[facelet_get_face] Error retrieving face family"); - goto ERR; - } - if (facelet_get_local_addr(facelet, &face->local_addr) < 0) { - ERROR("[facelet_get_face] Error retrieving face local address"); - goto ERR; - } - if (facelet_get_local_port(facelet, &face->local_port) < 0) { - ERROR("[facelet_get_face] Error retrieving face local port"); - goto ERR; - } - if (facelet_get_remote_addr(facelet, &face->remote_addr) < 0) { - ERROR("[facelet_get_face] Error retrieving face remote address"); - goto ERR; - } - if (facelet_get_remote_port(facelet, &face->remote_port) < 0) { - ERROR("[facelet_get_face] Error retrieving face remote port"); - goto ERR; - } - break; - - case FACE_TYPE_LAYER_3: - ERROR("{facelet_get_face] hICN face not (yet) implemented"); - goto ERR; - - case FACE_TYPE_LAYER_UNDEFINED: - case FACE_TYPE_LAYER_N: - ERROR("[facelet_get_face] Unsupported face type"); - goto ERR; - } - - if (facelet_has_admin_state(facelet)) { - if (facelet_get_admin_state(facelet, &face->admin_state) < 0) { - ERROR("[facelet_get_face] Error getting face admin state"); - goto ERR; - } - } else { - face->admin_state = FACE_STATE_UP; + /* Facelet has all the required information to create a face */ + if (facelet_validate_face(facelet) < 0) { + ERROR("[facelet_get_face] Face does not validate"); + return 0; + } + + face_t *face = face_create(); + if (!face) goto ERR_CREATE; + + assert(facelet_has_netdevice(facelet)); + face->netdevice = facelet->netdevice; + + /* Face type */ + switch (facelet->face_type.layer) { + case FACE_TYPE_LAYER_4: + switch (facelet->face_type.encap) { + case FACE_TYPE_ENCAP_UDP: + face->type = FACE_TYPE_UDP; + break; + case FACE_TYPE_ENCAP_TCP: + face->type = FACE_TYPE_TCP; + break; + case FACE_TYPE_ENCAP_UNDEFINED: + case FACE_TYPE_ENCAP_N: + ERROR("[facelet_get_face] Unsupported face encapsulation"); + goto ERR; + } + + if (facelet_get_family(facelet, &face->family) < 0) { + ERROR("[facelet_get_face] Error retrieving face family"); + goto ERR; + } + if (facelet_get_local_addr(facelet, &face->local_addr) < 0) { + ERROR("[facelet_get_face] Error retrieving face local address"); + goto ERR; + } + if (facelet_get_local_port(facelet, &face->local_port) < 0) { + ERROR("[facelet_get_face] Error retrieving face local port"); + goto ERR; + } + if (facelet_get_remote_addr(facelet, &face->remote_addr) < 0) { + ERROR("[facelet_get_face] Error retrieving face remote address"); + goto ERR; + } + if (facelet_get_remote_port(facelet, &face->remote_port) < 0) { + ERROR("[facelet_get_face] Error retrieving face remote port"); + goto ERR; + } + break; + + case FACE_TYPE_LAYER_3: + ERROR("{facelet_get_face] hICN face not (yet) implemented"); + goto ERR; + + case FACE_TYPE_LAYER_UNDEFINED: + case FACE_TYPE_LAYER_N: + ERROR("[facelet_get_face] Unsupported face type"); + goto ERR; + } + + if (facelet_has_admin_state(facelet)) { + if (facelet_get_admin_state(facelet, &face->admin_state) < 0) { + ERROR("[facelet_get_face] Error getting face admin state"); + goto ERR; } - - if (facelet_has_state(facelet)) { - if (facelet_get_state(facelet, &face->state) < 0) { - ERROR("[facelet_get_face] Error getting face state"); - goto ERR; - } - } else { - face->state = FACE_STATE_UP; + } else { + face->admin_state = FACE_STATE_UP; + } + + if (facelet_has_state(facelet)) { + if (facelet_get_state(facelet, &face->state) < 0) { + ERROR("[facelet_get_face] Error getting face state"); + goto ERR; } + } else { + face->state = FACE_STATE_UP; + } #ifdef WITH_POLICY - /* Priority */ - if (facelet_has_priority(facelet)) { - if (facelet_get_priority(facelet, &face->priority) < 0) { - ERROR("[facelet_get_face] Error getting face priority"); - goto ERR; - } - } else { - face->priority = 0; + /* Priority */ + if (facelet_has_priority(facelet)) { + if (facelet_get_priority(facelet, &face->priority) < 0) { + ERROR("[facelet_get_face] Error getting face priority"); + goto ERR; + } + } else { + face->priority = 0; + } + + /* Tags */ + + /* - based on netdevice type */ + policy_tags_t tags = POLICY_TAGS_EMPTY; + if (facelet_has_netdevice_type(facelet)) { + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR("error getting netdevice_type"); + goto ERR; } - /* Tags */ - - /* - based on netdevice type */ - policy_tags_t tags = POLICY_TAGS_EMPTY; - if (facelet_has_netdevice_type(facelet)) { - netdevice_type_t netdevice_type; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - ERROR("error getting netdevice_type"); - goto ERR; - } - - - switch(netdevice_type) { - case NETDEVICE_TYPE_UNDEFINED: - case NETDEVICE_TYPE_LOOPBACK: - break; - case NETDEVICE_TYPE_WIRED: - policy_tags_add(&tags, POLICY_TAG_WIRED); - break; - case NETDEVICE_TYPE_WIFI: - policy_tags_add(&tags, POLICY_TAG_WIFI); - break; - case NETDEVICE_TYPE_CELLULAR: - policy_tags_add(&tags, POLICY_TAG_CELLULAR); - break; - default: - goto ERR; - } + switch (netdevice_type) { + case NETDEVICE_TYPE_UNDEFINED: + case NETDEVICE_TYPE_LOOPBACK: + break; + case NETDEVICE_TYPE_WIRED: + policy_tags_add(&tags, POLICY_TAG_WIRED); + break; + case NETDEVICE_TYPE_WIFI: + policy_tags_add(&tags, POLICY_TAG_WIFI); + break; + case NETDEVICE_TYPE_CELLULAR: + policy_tags_add(&tags, POLICY_TAG_CELLULAR); + break; + default: + goto ERR; } - face->tags = tags; + } + face->tags = tags; #endif /* WITH_POLICY */ - *pface = face; + *pface = face; - return 0; + return 0; ERR: - free(face); + free(face); ERR_CREATE: - *pface = NULL; - return -1; + *pface = NULL; + return -1; } -facelet_status_t -facelet_get_status(const facelet_t * facelet) -{ - return facelet->status; +facelet_status_t facelet_get_status(const facelet_t *facelet) { + return facelet->status; } -void -facelet_set_status(facelet_t * facelet, facelet_status_t status) -{ - facelet->status = status; +void facelet_set_status(facelet_t *facelet, facelet_status_t status) { + facelet->status = status; } -#define SET_ATTR_STATUS_CLEAN(TYPE, NAME) \ -do { \ - if (facelet->NAME ## _status == FACELET_ATTR_STATUS_DIRTY) \ - facelet->NAME ## _status = FACELET_ATTR_STATUS_CLEAN; \ -} while (0) +#define SET_ATTR_STATUS_CLEAN(TYPE, NAME) \ + do { \ + if (facelet->NAME##_status == FACELET_ATTR_STATUS_DIRTY) \ + facelet->NAME##_status = FACELET_ATTR_STATUS_CLEAN; \ + } while (0) -void -facelet_set_attr_clean(facelet_t * facelet) -{ +void facelet_set_attr_clean(facelet_t *facelet) { #define _(TYPE, NAME) SET_ATTR_STATUS_CLEAN(TYPE, NAME); - foreach_facelet_attr + foreach_facelet_attr #undef _ } -void -facelet_set_error(facelet_t * facelet, facelet_error_reason_t reason) -{ - facelet->error++; - switch(reason) { - case FACELET_ERROR_REASON_UNSPECIFIED_ERROR: - case FACELET_ERROR_REASON_INTERNAL_ERROR: - case FACELET_ERROR_REASON_PERMISSION_DENIED: - if (facelet->error >= FACELET_MAX_ERRORS) - facelet_set_status(facelet, FACELET_STATUS_IGNORED); - break; - case FACELET_ERROR_REASON_FORWARDER_OFFLINE: - break; - case FACELET_ERROR_REASON_UNDEFINED: - case FACELET_ERROR_REASON_N: - ERROR("facelet_set_error] Unexpected error reason"); - break; - } +void facelet_set_error(facelet_t *facelet, facelet_error_reason_t reason) { + facelet->error++; + switch (reason) { + case FACELET_ERROR_REASON_UNSPECIFIED_ERROR: + case FACELET_ERROR_REASON_INTERNAL_ERROR: + case FACELET_ERROR_REASON_PERMISSION_DENIED: + if (facelet->error >= FACELET_MAX_ERRORS) + facelet_set_status(facelet, FACELET_STATUS_IGNORED); + break; + case FACELET_ERROR_REASON_FORWARDER_OFFLINE: + break; + case FACELET_ERROR_REASON_UNDEFINED: + case FACELET_ERROR_REASON_N: + ERROR("facelet_set_error] Unexpected error reason"); + break; + } } -void -facelet_unset_error(facelet_t * facelet) -{ - facelet->error = 0; -} +void facelet_unset_error(facelet_t *facelet) { facelet->error = 0; } -bool -facelet_get_error(const facelet_t * facelet) -{ - return facelet->error; -} +bool facelet_get_error(const facelet_t *facelet) { return facelet->error; } -void -facelet_set_bj_done(facelet_t * facelet) -{ - facelet->bj_done = true; -} - -void -facelet_unset_bj_done(facelet_t * facelet) -{ - facelet->bj_done = false; -} - -bool -facelet_is_bj_done(const facelet_t * facelet) -{ - return facelet->bj_done; -} +void facelet_set_bj_done(facelet_t *facelet) { facelet->bj_done = true; } -void -facelet_set_au_done(facelet_t * facelet) -{ - facelet->au_done = true; -} +void facelet_unset_bj_done(facelet_t *facelet) { facelet->bj_done = false; } -bool -facelet_is_au_done(const facelet_t * facelet) -{ - return facelet->au_done; -} +bool facelet_is_bj_done(const facelet_t *facelet) { return facelet->bj_done; } -facelet_event_t -facelet_get_event(const facelet_t * facelet) -{ - return facelet->event; +facelet_event_t facelet_get_event(const facelet_t *facelet) { + return facelet->event; } -void -facelet_set_event(facelet_t * facelet, facelet_event_t event) -{ - facelet->event = event; +void facelet_set_event(facelet_t *facelet, facelet_event_t event) { + facelet->event = event; } -int -facelet_add_route(facelet_t * facelet, hicn_route_t * route) -{ - return route_set_add(facelet->routes, route); +int facelet_add_route(facelet_t *facelet, hicn_route_t *route) { + return route_set_add(facelet->routes, route); } -int -facelet_remove_route(facelet_t * facelet, hicn_route_t * route, hicn_route_t ** route_removed) -{ - return route_set_remove(facelet->routes, route, route_removed); +int facelet_remove_route(facelet_t *facelet, hicn_route_t *route, + hicn_route_t **route_removed) { + return route_set_remove(facelet->routes, route, route_removed); } -int -facelet_clear_routes(facelet_t * facelet) -{ - return route_set_clear(facelet->routes); +int facelet_clear_routes(facelet_t *facelet) { + return route_set_clear(facelet->routes); } -int -facelet_get_route_array(const facelet_t * facelet, hicn_route_t *** route_array) -{ - return route_set_get_array(facelet->routes, route_array); +int facelet_get_route_array(const facelet_t *facelet, + hicn_route_t ***route_array) { + return route_set_get_array(facelet->routes, route_array); } -int -facelet_snprintf(char * s, size_t size, const facelet_t * facelet) -{ - char * cur = s; - int rc; - - assert(facelet); - - /* Header + key attributes (netdevice + family) */ - rc = snprintf(cur, s + size - cur, "<Facelet [%d] %s %s (%s)", - facelet->id, - facelet_status_str[facelet->status], - facelet_get_error(facelet) ? "/!\\" : "", - (facelet->family == AF_INET) ? "AF_INET" : - (facelet->family == AF_INET6) ? "AF_INET6" : - (facelet->family == AF_UNSPEC) ? "AF_UNSPEC" : - "unknown"); - if (rc < 0) - return rc; +int facelet_snprintf(char *s, size_t size, const facelet_t *facelet) { + char *cur = s; + int rc; + + assert(facelet); + + /* Header + key attributes (netdevice + family) */ + rc = snprintf(cur, s + size - cur, "<Facelet [%d] %s %s (%s)", facelet->id, + facelet_status_str[facelet->status], + facelet_get_error(facelet) ? "/!\\" : "", + (facelet->family == AF_INET) ? "AF_INET" + : (facelet->family == AF_INET6) ? "AF_INET6" + : (facelet->family == AF_UNSPEC) ? "AF_UNSPEC" + : "unknown"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + /* Netdevice */ + if (facelet_has_netdevice(facelet)) { + rc = snprintf(cur, s + size - cur, " netdevice=%s", + facelet->netdevice.name[0] ? facelet->netdevice.name : "*"); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - /* Netdevice */ - if (facelet_has_netdevice(facelet)) { - rc = snprintf(cur, s + size - cur, " netdevice=%s", - facelet->netdevice.name[0] ? facelet->netdevice.name : "*"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = snprintf(cur, s + size - cur, "/%d", facelet->netdevice.index); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); + if (cur >= s + size) return (int)(cur - s); - } else { - rc = snprintf(cur, s + size - cur, " netdevice=*/*"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = snprintf(cur, s + size - cur, "/%d", facelet->netdevice.index); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* Netdevice type */ - if (facelet_has_netdevice_type(facelet)) { - rc = snprintf(cur, s + size - cur, " type=%s", - netdevice_type_str[facelet->netdevice_type]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + } else { + rc = snprintf(cur, s + size - cur, " netdevice=*/*"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Netdevice type */ + if (facelet_has_netdevice_type(facelet)) { + rc = snprintf(cur, s + size - cur, " type=%s", + netdevice_type_str(facelet->netdevice_type)); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } - /* Local ip address */ - if (facelet_has_local_addr(facelet)) { - rc = snprintf(cur, s + size - cur, " local_addr="); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = ip_address_snprintf(cur, s + size - cur, &facelet->local_addr, - facelet->family); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Local ip address */ + if (facelet_has_local_addr(facelet)) { + rc = snprintf(cur, s + size - cur, " local_addr="); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* Local port */ - if (facelet_has_local_port(facelet)) { - rc = snprintf(cur, s + size - cur, " local_port=%d", - facelet->local_port); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = ip_address_snprintf(cur, s + size - cur, &facelet->local_addr, + facelet->family); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } - /* Remote ip address */ - if (facelet_has_remote_addr(facelet)) { - rc = snprintf(cur, s + size - cur, " remote_addr="); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = ip_address_snprintf(cur, s + size - cur, &facelet->remote_addr, - facelet->family); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Local port */ + if (facelet_has_local_port(facelet)) { + rc = snprintf(cur, s + size - cur, " local_port=%d", facelet->local_port); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } - /* Remote port */ - if (facelet_has_remote_port(facelet)) { - rc = snprintf(cur, s + size - cur, " remote_port=%d", - facelet->remote_port); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Remote ip address */ + if (facelet_has_remote_addr(facelet)) { + rc = snprintf(cur, s + size - cur, " remote_addr="); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* Admin state */ - if (facelet_has_admin_state(facelet)) { - rc = snprintf(cur, s + size - cur, " admin_state=%s", - face_state_str[facelet->admin_state]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = ip_address_snprintf(cur, s + size - cur, &facelet->remote_addr, + facelet->family); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } - /* State */ - if (facelet_has_state(facelet)) { - rc = snprintf(cur, s + size - cur, " state=%s", - face_state_str[facelet->state]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Remote port */ + if (facelet_has_remote_port(facelet)) { + rc = snprintf(cur, s + size - cur, " remote_port=%d", facelet->remote_port); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Admin state */ + if (facelet_has_admin_state(facelet)) { + rc = snprintf(cur, s + size - cur, " admin_state=%s", + face_state_str(facelet->admin_state)); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* State */ + if (facelet_has_state(facelet)) { + rc = snprintf(cur, s + size - cur, " state=%s", + face_state_str(facelet->state)); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } #ifdef WITH_POLICY - /* Priority */ - if (facelet_has_priority(facelet)) { - rc = snprintf(cur, s + size - cur, " priority=%d", facelet->priority); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Priority */ + if (facelet_has_priority(facelet)) { + rc = snprintf(cur, s + size - cur, " priority=%d", facelet->priority); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } #endif /* WITH_POLICY */ - /* Face type */ - if (facelet_has_face_type(facelet)) { - rc = snprintf(cur, s + size - cur, " face_type=LAYER%s/%s", - FACEMGR_FACE_TYPE_STR(facelet->face_type)); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } - - /* Routes */ - rc = snprintf(cur, s + size - cur, " routes={ "); - if (rc < 0) - return rc; + /* Face type */ + if (facelet_has_face_type(facelet)) { + rc = snprintf(cur, s + size - cur, " face_type=LAYER%s/%s", + FACEMGR_FACE_TYPE_STR(facelet->face_type)); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - hicn_route_t ** route_array; - int n = route_set_get_array(facelet->routes, &route_array); - if (n < 0) { - ERROR("[facelet_free] Error getting route set associated to facelet"); - } else { - for (unsigned i = 0; i < n; i++) { - hicn_route_t * route = route_array[i]; - rc = (int)hicn_route_snprintf(cur, s + size - cur, route); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = snprintf(cur, s + size - cur, ", "); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + if (cur >= s + size) return (int)(cur - s); + } + + /* Routes */ + rc = snprintf(cur, s + size - cur, " routes={ "); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + hicn_route_t **route_array; + int n = route_set_get_array(facelet->routes, &route_array); + if (n < 0) { + ERROR("[facelet_free] Error getting route set associated to facelet"); + } else { + for (unsigned i = 0; i < n; i++) { + hicn_route_t *route = route_array[i]; + if (!route) continue; /* Should not occur */ + rc = (int)hicn_route_snprintf(cur, s + size - cur, route); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + rc = snprintf(cur, s + size - cur, ", "); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); } - free(route_array); + } + free(route_array); - rc = snprintf(cur, s + size - cur, "}>"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); + rc = snprintf(cur, s + size - cur, "}>"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - return (int)(cur - s); + return (int)(cur - s); } -int facelet_snprintf_json(char * s, size_t size, const facelet_t * facelet, int indent) -{ - char * cur = s; - int rc; - - assert(facelet); - - /* Header + key attributes (netdevice + family) */ - rc = snprintf(cur, s + size - cur, "%*s%s", 4 * indent, "", "{\n"); - if (rc < 0) - return rc; +int facelet_snprintf_json(char *s, size_t size, const facelet_t *facelet, + int indent) { + char *cur = s; + int rc; + + assert(facelet); + + /* Header + key attributes (netdevice + family) */ + rc = snprintf(cur, s + size - cur, "%*s%s", 4 * indent, "", "{\n"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + /* id */ + rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent + 1), "", + "\"id\"", facelet->id); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + /* Status */ + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"status\"", facelet_status_str[facelet->status]); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + /* Family */ + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"family\"", + (facelet->family == AF_INET) ? "AF_INET" + : (facelet->family == AF_INET6) ? "AF_INET6" + : (facelet->family == AF_UNSPEC) ? "AF_UNSPEC" + : "unknown"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + + /* Netdevice */ + if (facelet_has_netdevice(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"netdevice\"", + facelet->netdevice.name[0] ? facelet->netdevice.name : "*"); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - /* id */ - rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "", "\"id\"", - facelet->id); - if (rc < 0) - return rc; + if (cur >= s + size) return (int)(cur - s); + + } else { + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"netdevice\"", "*"); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - /* Status */ - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", "\"status\"", - facelet_status_str[facelet->status]); - if (rc < 0) - return rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Netdevice type */ + if (facelet_has_netdevice_type(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"netdevice_type\"", + netdevice_type_str(facelet->netdevice_type)); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - /* Family */ - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", "\"family\"", - (facelet->family == AF_INET) ? "AF_INET" : - (facelet->family == AF_INET6) ? "AF_INET6" : - (facelet->family == AF_UNSPEC) ? "AF_UNSPEC" : - "unknown"); - if (rc < 0) - return rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Local ip address */ + if (facelet_has_local_addr(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"", 4 * (indent + 1), "", + "\"local_addr\""); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - /* Netdevice */ - if (facelet_has_netdevice(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", - "\"netdevice\"", - facelet->netdevice.name[0] ? facelet->netdevice.name : "*"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - } else { - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", - "\"netdevice\"", "*"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + if (cur >= s + size) return (int)(cur - s); - /* Netdevice type */ - if (facelet_has_netdevice_type(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", - "\"netdevice_type\"", - netdevice_type_str[facelet->netdevice_type]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } - - /* Local ip address */ - if (facelet_has_local_addr(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"", 4 * (indent+1), "", - "\"local_addr\""); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = ip_address_snprintf(cur, s + size - cur, &facelet->local_addr, - facelet->family); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = snprintf(cur, s + size - cur, "\",\n"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } - - /* Local port */ - if (facelet_has_local_port(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "", - "\"local_port\"", - facelet->local_port); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } - - /* Remote ip address */ - if (facelet_has_remote_addr(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"", 4 * (indent+1), "", - "\"remote_addr\""); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = ip_address_snprintf(cur, s + size - cur, &facelet->remote_addr, - facelet->family); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - - rc = snprintf(cur, s + size - cur, "\",\n"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = ip_address_snprintf(cur, s + size - cur, &facelet->local_addr, + facelet->family); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* Remote port */ - if (facelet_has_remote_port(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "", - "\"remote_port\"", - facelet->remote_port); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = snprintf(cur, s + size - cur, "\",\n"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Local port */ + if (facelet_has_local_port(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent + 1), "", + "\"local_port\"", facelet->local_port); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Remote ip address */ + if (facelet_has_remote_addr(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"", 4 * (indent + 1), "", + "\"remote_addr\""); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* Admin state */ - if (facelet_has_admin_state(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", - "\"admin_state\"", - face_state_str[facelet->admin_state]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = ip_address_snprintf(cur, s + size - cur, &facelet->remote_addr, + facelet->family); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - /* State */ - if (facelet_has_state(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent+1), "", - "\"state\"", - face_state_str[facelet->state]); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + rc = snprintf(cur, s + size - cur, "\",\n"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Remote port */ + if (facelet_has_remote_port(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent + 1), "", + "\"remote_port\"", facelet->remote_port); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* Admin state */ + if (facelet_has_admin_state(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"admin_state\"", face_state_str(facelet->admin_state)); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } + + /* State */ + if (facelet_has_state(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\",\n", 4 * (indent + 1), "", + "\"state\"", face_state_str(facelet->state)); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } #ifdef WITH_POLICY - /* Priority */ - if (facelet_has_priority(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "", - "\"priority\"", facelet->priority); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } + /* Priority */ + if (facelet_has_priority(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent + 1), "", + "\"priority\"", facelet->priority); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); + } #endif /* WITH_POLICY */ - if (facelet_has_face_type(facelet)) { - rc = snprintf(cur, s + size - cur, "%*s%s: \"LAYER%s/%s\",\n", 4 * (indent+1), "", - "\"face_type\"", - FACEMGR_FACE_TYPE_STR(facelet->face_type)); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); - } - - /* Status error */ - rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\"\n", 4 * (indent+1), "", - "\"error\"", - facelet_get_error(facelet) ? "true" : "false"); - if (rc < 0) - return rc; + if (facelet_has_face_type(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: \"LAYER%s/%s\",\n", + 4 * (indent + 1), "", "\"face_type\"", + FACEMGR_FACE_TYPE_STR(facelet->face_type)); + if (rc < 0) return rc; cur += rc; - if (cur >= s + size) - return (int)(cur - s); + if (cur >= s + size) return (int)(cur - s); + } - /* Routes */ - // TODO + /* Status error */ + rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\"\n", 4 * (indent + 1), "", + "\"error\"", facelet_get_error(facelet) ? "true" : "false"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - rc = snprintf(cur, s + size - cur, "%*s%s", 4 * indent, "", "}"); - if (rc < 0) - return rc; - cur += rc; - if (cur >= s + size) - return (int)(cur - s); + /* Routes */ + // TODO + + rc = snprintf(cur, s + size - cur, "%*s%s", 4 * indent, "", "}"); + if (rc < 0) return rc; + cur += rc; + if (cur >= s + size) return (int)(cur - s); - return (int)(cur - s); + return (int)(cur - s); } diff --git a/ctrl/facemgr/src/facelet_array.c b/ctrl/facemgr/src/facelet_array.c index 3ee110b8e..d48625979 100644 --- a/ctrl/facemgr/src/facelet_array.c +++ b/ctrl/facemgr/src/facelet_array.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -23,4 +23,3 @@ #include "facelet_array.h" TYPEDEF_ARRAY(facelet_array, facelet_t *, facelet_equals, facelet_snprintf); - diff --git a/ctrl/facemgr/src/facelet_array.h b/ctrl/facemgr/src/facelet_array.h index 099774691..b3b17e88b 100644 --- a/ctrl/facemgr/src/facelet_array.h +++ b/ctrl/facemgr/src/facelet_array.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interface.c b/ctrl/facemgr/src/interface.c index 7f95be4ce..a9aeeaf33 100644 --- a/ctrl/facemgr/src/interface.c +++ b/ctrl/facemgr/src/interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -29,170 +29,144 @@ #include "interface.h" TYPEDEF_MAP_H(interface_ops_map, const char *, const interface_ops_t *); -TYPEDEF_MAP(interface_ops_map, const char *, const interface_ops_t *, strcmp, string_snprintf, generic_snprintf); - -static interface_ops_map_t * interface_ops_map = NULL; - -int -interface_register(const interface_ops_t * ops) -{ - if (!interface_ops_map) { - interface_ops_map = interface_ops_map_create(); - if (!interface_ops_map) - return -1; - } - interface_ops_map_add(interface_ops_map, ops->type, ops); - return 0; +TYPEDEF_MAP(interface_ops_map, const char *, const interface_ops_t *, strcmp, + string_snprintf, generic_snprintf); + +static interface_ops_map_t *interface_ops_map = NULL; + +int interface_register(const interface_ops_t *ops) { + if (!interface_ops_map) { + interface_ops_map = interface_ops_map_create(); + if (!interface_ops_map) return -1; + } + interface_ops_map_add(interface_ops_map, ops->type, ops); + return 0; } -int -interface_unregister_all() -{ - int ret = 0; - const char ** ops_name_array = NULL; - int n = interface_ops_map_get_key_array(interface_ops_map, &ops_name_array); - if (n < 0) { - ERROR("[interface_unregister_all] Could not get interface ops array"); - return -1; - } - - for (unsigned i = 0; i < n; i++) { - const char * ops_name = ops_name_array[i]; - if (interface_ops_map_remove(interface_ops_map, ops_name, NULL) < 0) { - ERROR("[interface_unregister_all] Could not remove %s from interface ops map", ops_name); - ret = -1; - } +int interface_unregister_all() { + int ret = 0; + const char **ops_name_array = NULL; + int n = interface_ops_map_get_key_array(interface_ops_map, &ops_name_array); + if (n < 0) { + ERROR("[interface_unregister_all] Could not get interface ops array"); + return -1; + } + + for (unsigned i = 0; i < n; i++) { + const char *ops_name = ops_name_array[i]; + if (interface_ops_map_remove(interface_ops_map, ops_name, NULL) < 0) { + ERROR( + "[interface_unregister_all] Could not remove %s from interface ops " + "map", + ops_name); + ret = -1; } - free(ops_name_array); + } + free(ops_name_array); - interface_ops_map_free(interface_ops_map); - interface_ops_map = NULL; + interface_ops_map_free(interface_ops_map); + interface_ops_map = NULL; - return ret; + return ret; } -interface_t * -interface_create(const char * name, const char * type) -{ - - const interface_ops_t * ops = NULL; - int rc = interface_ops_map_get(interface_ops_map, type, &ops); - if (rc < 0) { - printf("Interface type not found %s\n", type); - return NULL; - } - - interface_t * interface = malloc(sizeof(interface_t)); - if (!interface) - return NULL; - - interface->name = strdup(name); - /* this should use type */ - interface->ops = ops; - interface->callback = NULL; - interface->callback_owner = NULL; - interface->data = NULL; - - return interface; +interface_t *interface_create(const char *name, const char *type) { + const interface_ops_t *ops = NULL; + int rc = interface_ops_map_get(interface_ops_map, type, &ops); + if (rc < 0) { + printf("Interface type not found %s\n", type); + return NULL; + } + + interface_t *interface = malloc(sizeof(interface_t)); + if (!interface) return NULL; + + interface->name = strdup(name); + /* this should use type */ + interface->ops = ops; + interface->callback = NULL; + interface->callback_owner = NULL; + interface->data = NULL; + + return interface; } -void -interface_free(interface_t * interface) -{ - free(interface->name); - free(interface); +void interface_free(interface_t *interface) { + free(interface->name); + free(interface); } -void -interface_set_callback(interface_t * interface, void * callback_owner, - interface_cb_t callback) -{ - interface->callback = callback; - interface->callback_owner = callback_owner; +void interface_set_callback(interface_t *interface, void *callback_owner, + interface_cb_t callback) { + interface->callback = callback; + interface->callback_owner = callback_owner; } -int -interface_initialize(interface_t * interface, void * cfg) -{ - if (!interface->ops->initialize) - return -1; - return interface->ops->initialize(interface, cfg); +int interface_initialize(interface_t *interface, void *cfg) { + if (!interface->ops->initialize) return -1; + return interface->ops->initialize(interface, cfg); } -int -interface_finalize(interface_t * interface) -{ - if (!interface->ops->finalize) - return -1; - return interface->ops->finalize(interface); +int interface_finalize(interface_t *interface) { + if (!interface->ops->finalize) return -1; + return interface->ops->finalize(interface); } -int -interface_on_event(interface_t * interface, facelet_t * facelet) -{ - if (!interface->ops->on_event) - return -1; - return interface->ops->on_event(interface, facelet); +int interface_on_event(interface_t *interface, facelet_t *facelet) { + if (!interface->ops->on_event) return -1; + return interface->ops->on_event(interface, facelet); } -int -interface_raise_event(interface_t * interface, facelet_t * facelet) -{ - assert(interface->callback); - return interface->callback(interface->callback_owner, - INTERFACE_CB_TYPE_RAISE_EVENT, facelet); +int interface_raise_event(interface_t *interface, facelet_t *facelet) { + assert(interface->callback); + return interface->callback(interface->callback_owner, + INTERFACE_CB_TYPE_RAISE_EVENT, facelet); } -int -interface_register_fd(interface_t * interface, int fd, void * data) -{ - assert(interface->callback); - fd_callback_data_t fd_callback = { - .fd = fd, - .owner = interface, - .callback = (fd_callback_t)interface->ops->callback, - .data = data, - }; - return interface->callback(interface->callback_owner, - INTERFACE_CB_TYPE_REGISTER_FD, &fd_callback); +int interface_register_fd(interface_t *interface, int fd, void *data) { + assert(interface->callback); + fd_callback_data_t fd_callback = { + .fd = fd, + .owner = interface, + .callback = (fd_callback_t)interface->ops->callback, + .data = data, + }; + return interface->callback(interface->callback_owner, + INTERFACE_CB_TYPE_REGISTER_FD, &fd_callback); } -int -interface_unregister_fd(interface_t * interface, int fd) -{ - assert(interface->callback); - fd_callback_data_t fd_callback = { - .fd = fd, - .owner = interface, - .callback = NULL, - .data = NULL, - }; - return interface->callback(interface->callback_owner, - INTERFACE_CB_TYPE_UNREGISTER_FD, &fd_callback); +int interface_unregister_fd(interface_t *interface, int fd) { + assert(interface->callback); + fd_callback_data_t fd_callback = { + .fd = fd, + .owner = interface, + .callback = NULL, + .data = NULL, + }; + return interface->callback(interface->callback_owner, + INTERFACE_CB_TYPE_UNREGISTER_FD, &fd_callback); } -typedef int (*interface_fd_callback_t)(interface_t * interface, int fd, void * unused); - -int -interface_register_timer(interface_t * interface, unsigned delay_ms, - interface_fd_callback_t callback, void * data) -{ - assert(interface->callback); - timer_callback_data_t timer_callback = { - .delay_ms = delay_ms, - .owner = interface, - .callback = (fd_callback_t)callback, - .data = data, - }; - int rc = interface->callback(interface->callback_owner, - INTERFACE_CB_TYPE_REGISTER_TIMER, &timer_callback); - return rc; +typedef int (*interface_fd_callback_t)(interface_t *interface, int fd, + void *unused); + +int interface_register_timer(interface_t *interface, unsigned delay_ms, + interface_fd_callback_t callback, void *data) { + assert(interface->callback); + timer_callback_data_t timer_callback = { + .delay_ms = delay_ms, + .owner = interface, + .callback = (fd_callback_t)callback, + .data = data, + }; + int rc = + interface->callback(interface->callback_owner, + INTERFACE_CB_TYPE_REGISTER_TIMER, &timer_callback); + return rc; } -int -interface_unregister_timer(interface_t * interface, int fd) -{ - assert(interface->callback); - return interface->callback(interface->callback_owner, - INTERFACE_CB_TYPE_UNREGISTER_TIMER, &fd); +int interface_unregister_timer(interface_t *interface, int fd) { + assert(interface->callback); + return interface->callback(interface->callback_owner, + INTERFACE_CB_TYPE_UNREGISTER_TIMER, &fd); } diff --git a/ctrl/facemgr/src/interface.h b/ctrl/facemgr/src/interface.h index a4fbda1fb..a999036d5 100644 --- a/ctrl/facemgr/src/interface.h +++ b/ctrl/facemgr/src/interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,40 +32,41 @@ #include <hicn/facemgr/loop.h> typedef enum { - INTERFACE_CB_TYPE_REGISTER_FD, - INTERFACE_CB_TYPE_UNREGISTER_FD, - INTERFACE_CB_TYPE_RAISE_EVENT, - INTERFACE_CB_TYPE_REGISTER_TIMER, - INTERFACE_CB_TYPE_UNREGISTER_TIMER, + INTERFACE_CB_TYPE_REGISTER_FD, + INTERFACE_CB_TYPE_UNREGISTER_FD, + INTERFACE_CB_TYPE_RAISE_EVENT, + INTERFACE_CB_TYPE_REGISTER_TIMER, + INTERFACE_CB_TYPE_UNREGISTER_TIMER, } interface_cb_type_t; -typedef int (*interface_cb_t)(facemgr_t * facemgr, interface_cb_type_t type, void * data); +typedef int (*interface_cb_t)(facemgr_t* facemgr, interface_cb_type_t type, + void* data); /** * \brief Interface operations */ struct interface_s; typedef struct { - /** The type given to the interfaces */ - char * type; - /* Constructor */ - int (*initialize)(struct interface_s * interface, void * cfg); - /* Destructor */ - int (*finalize)(struct interface_s * interface); - /* Callback upon file descriptor event (iif previously registered) */ - int (*callback)(struct interface_s * interface, int fd, void * data); - /* Callback upon face events coming from the face manager */ - int (*on_event)(struct interface_s * interface, struct facelet_s * facelet); + /** The type given to the interfaces */ + char* type; + /* Constructor */ + int (*initialize)(struct interface_s* interface, void* cfg); + /* Destructor */ + int (*finalize)(struct interface_s* interface); + /* Callback upon file descriptor event (iif previously registered) */ + int (*callback)(struct interface_s* interface, int fd, void* data); + /* Callback upon face events coming from the face manager */ + int (*on_event)(struct interface_s* interface, struct facelet_s* facelet); } interface_ops_t; typedef struct interface_s { - char * name; - const interface_ops_t * ops; + char* name; + const interface_ops_t* ops; - interface_cb_t callback; - void * callback_owner; + interface_cb_t callback; + void* callback_owner; - void * data; + void* data; } interface_t; /** @@ -75,7 +76,7 @@ typedef struct interface_s { * \return Flag indicating the success (FACEMGR_SUCCESS=0), or failure (any * other value) of the operation. */ -int interface_register(const interface_ops_t * ops); +int interface_register(const interface_ops_t* ops); int interface_unregister_all(); @@ -91,22 +92,22 @@ int interface_unregister_all(); * \return A a pointer to the newly created instance of the requested type, or * NULL in case of failure. */ -interface_t * interface_create(const char * name, const char * type); +interface_t* interface_create(const char* name, const char* type); /** * \brief Free an interface instance. * \param [in] interface - Pointer to the instance to free. */ -void interface_free(interface_t * interface); +void interface_free(interface_t* interface); +void interface_set_callback(interface_t* interface, void* callback_owner, + interface_cb_t callback); -void interface_set_callback(interface_t * interface, void * callback_owner, interface_cb_t callback); +int interface_initialize(interface_t* interface, void* cfg); -int interface_initialize(interface_t * interface, void * cfg); +int interface_finalize(interface_t* interface); -int interface_finalize(interface_t * interface); - -int interface_on_event(interface_t * interface, struct facelet_s * facelet); +int interface_on_event(interface_t* interface, struct facelet_s* facelet); /** * \brief Raises a facelet event to the face manager @@ -115,15 +116,17 @@ int interface_on_event(interface_t * interface, struct facelet_s * facelet); * \param [in] facelet - Facelet to communicate with the event * \return Error code */ -int interface_callback(interface_t * interface, interface_cb_type_t type, void * data); +int interface_callback(interface_t* interface, interface_cb_type_t type, + void* data); -int interface_raise_event(interface_t * interface, facelet_t * facelet); +int interface_raise_event(interface_t* interface, facelet_t* facelet); -int interface_register_fd(interface_t * interface, int fd, void * data); +int interface_register_fd(interface_t* interface, int fd, void* data); -int interface_unregister_fd(interface_t * interface, int fd); +int interface_unregister_fd(interface_t* interface, int fd); -typedef int (*interface_fd_callback_t)(interface_t * interface, int fd, void * unused); +typedef int (*interface_fd_callback_t)(interface_t* interface, int fd, + void* unused); /** * \brief Registers a timer event @@ -135,8 +138,8 @@ typedef int (*interface_fd_callback_t)(interface_t * interface, int fd, void * u * \return A positive value uniquely identifying the timer, or -1 in case of * error */ -int interface_register_timer(interface_t * interface, unsigned delay_ms, - interface_fd_callback_t callback, void * data); +int interface_register_timer(interface_t* interface, unsigned delay_ms, + interface_fd_callback_t callback, void* data); /** * \brief Unregisters a timer event @@ -144,6 +147,6 @@ int interface_register_timer(interface_t * interface, unsigned delay_ms, * \param [in] fd - Timer identifier * \return 0 in case of success, -1 otherwise */ -int interface_unregister_timer(interface_t * interface, int fd); +int interface_unregister_timer(interface_t* interface, int fd); #endif /* FACEMGR_INTERFACE_H */ diff --git a/ctrl/facemgr/src/interfaces/CMakeLists.txt b/ctrl/facemgr/src/interfaces/CMakeLists.txt index e4d4423e9..02fb0eb48 100644 --- a/ctrl/facemgr/src/interfaces/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021-2022 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -16,28 +16,33 @@ list(APPEND SOURCE_FILES) list(APPEND INCLUDE_DIRS) list(APPEND LIBRARIES) + +############################################################## +# Add components +############################################################## add_subdirectory(hicn_light) if(APPLE) -add_subdirectory(network_framework) + add_subdirectory(network_framework) endif() if(LINUX) -add_subdirectory(netlink) -add_subdirectory(bonjour) -endif() - -if(ANDROID) -add_subdirectory(android_utility) -add_subdirectory(priority_controller) + if(ANDROID) + add_subdirectory(android) + add_subdirectory(priority_controller) + else() + add_subdirectory(netlink) + endif() + + add_subdirectory(bonjour) endif() if(WITH_EXAMPLE_DUMMY) -add_subdirectory(dummy) + add_subdirectory(dummy) endif() if(WITH_EXAMPLE_UPDOWN) -add_subdirectory(updown) + add_subdirectory(updown) endif() set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) diff --git a/ctrl/facemgr/src/interfaces/android_utility/CMakeLists.txt b/ctrl/facemgr/src/interfaces/android/CMakeLists.txt index 0ebe87745..beabc1280 100644 --- a/ctrl/facemgr/src/interfaces/android_utility/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/android/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -11,16 +11,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/android_utility.c +list(APPEND HEADER_FILES ) -list(APPEND INCLUDE_DIRS +list(APPEND SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/android.c ) list(APPEND LIBRARIES ) +list(APPEND INCLUDE_DIRS +) + set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) set(INCLUDE_DIRS ${INCLUDE_DIRS} PARENT_SCOPE) diff --git a/ctrl/facemgr/src/interfaces/android/android.c b/ctrl/facemgr/src/interfaces/android/android.c new file mode 100644 index 000000000..4e084d76d --- /dev/null +++ b/ctrl/facemgr/src/interfaces/android/android.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file interfaces/android/android.c + * \brief Netlink interface + */ + +#include <assert.h> +#include <pthread.h> +#include <sys/eventfd.h> +#include <unistd.h> // close + +#include <hicn/facemgr.h> +#include <hicn/util/ip_address.h> +#include <hicn/util/log.h> + +#include "../../common.h" +#include "../../interface.h" +#include "../../facelet_array.h" + +#include "android.h" + +/* + * aar_modules/FaceMgrLibrary/facemgrLibrary/src/main/java/com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility.java + */ +#define FACEMGR_ANDROID_CLASS \ + "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" + +/* Internal data storage */ +typedef struct { + int fd; + android_cfg_t cfg; + JNIEnv *env; + jclass cls; + bool attached_to_vm; + facelet_array_t *facelets; + pthread_mutex_t mutex; +} android_data_t; + +// might replace android utility + +jclass find_class_global(JNIEnv *env, const char *name) { + jclass c = (*env)->FindClass(env, name); + jclass c_global = 0; + if (c) { + c_global = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + } + return c_global; +} + +int android_on_network_event(interface_t *interface, const char *interface_name, + netdevice_type_t netdevice_type, bool up, + int family, const char *ip_address) { + android_data_t *data = (android_data_t *)interface->data; + + netdevice_t *netdevice = netdevice_create_from_name(interface_name); + if (!netdevice) { + ERROR("[android_on_network_event] error creating netdevice '%s'", + interface_name); + goto ERR_ND; + } + + ip_address_t local_addr = IP_ADDRESS_EMPTY; + if (ip_address) { + if (ip_address_pton(ip_address, &local_addr) < 0) { + ERROR("[android_on_network_event] error processing IP address"); + goto ERR_IP_ADDRESS; + } + } + + facelet_t *facelet = facelet_create(); + if (!facelet) { + ERROR("[android_on_network_event] error creating facelet"); + goto ERR_FACELET; + } + + if (facelet_set_netdevice(facelet, *netdevice) < 0) { + ERROR("[android_on_network_event] error setting netdevice"); + goto ERR; + } + + if (netdevice_type != NETDEVICE_TYPE_UNDEFINED) { + if (facelet_set_netdevice_type(facelet, netdevice_type) < 0) { + ERROR("[android_on_network_event] error setting netdevice type"); + goto ERR; + } + } + + if (facelet_set_family(facelet, family) < 0) { + ERROR("[android_on_network_event] error setting family"); + goto ERR; + } + + if (ip_address) { + if (facelet_set_local_addr(facelet, local_addr) < 0) { + ERROR("[android_on_network_event] error setting local address"); + goto ERR; + } + } + netdevice_free(netdevice); + + facelet_set_event(facelet, up ? FACELET_EVENT_CREATE : FACELET_EVENT_DELETE); + // FACELET_EVENT_UPDATE, FACELET_EVENT_SET_DOWN + facelet_set_attr_clean(facelet); + + pthread_mutex_lock(&data->mutex); + if (facelet_array_add(data->facelets, facelet)) { + ERROR("[android_on_network_event] Could not add facelet to buffer"); + goto ERR_ADD; + } + + pthread_mutex_unlock(&data->mutex); + + eventfd_write(data->fd, 1); + return 0; + +ERR_ADD: + pthread_mutex_unlock(&data->mutex); +ERR: + facelet_free(facelet); +ERR_FACELET: +ERR_IP_ADDRESS: + netdevice_free(netdevice); +ERR_ND: + return -1; +} + +bool get_jni_env(JavaVM *jvm, JNIEnv **env) { + bool did_attach_thread = false; + INFO("initialize: get_jni_env"); + *env = NULL; + // Check if the current thread is attached to the VM + int get_env_result = (*jvm)->GetEnv(jvm, (void **)env, JNI_VERSION_1_6); + if (get_env_result == JNI_EDETACHED) { + INFO("initialize: detached!"); + if ((*jvm)->AttachCurrentThread(jvm, env, NULL) == JNI_OK) { + INFO("initialize: attached..."); + did_attach_thread = true; + } else { + INFO("initialize: failed to attach"); + // Failed to attach thread. Throw an exception if you want to. + } + } else if (get_env_result == JNI_EVERSION) { + // Unsupported JNI version. Throw an exception if you want to. + INFO("initialize: unsupported"); + } + return did_attach_thread; +} + +int android_initialize(interface_t *interface, void *cfg) { + android_data_t *data = malloc(sizeof(android_data_t)); + if (!data) goto ERR_MALLOC; + interface->data = data; + + if (!cfg) goto ERR_CFG; + data->cfg = *(android_cfg_t *)cfg; + + JavaVM *jvm = data->cfg.jvm; + if (!jvm) goto ERR_JVM; + + data->facelets = facelet_array_create(); + if (!data->facelets) goto ERR_FACELETS; + + if ((data->fd = eventfd(0, EFD_SEMAPHORE)) == -1) goto ERR_EVENTFD; + + if (interface_register_fd(interface, data->fd, NULL) < 0) { + ERROR("[android_initialize] Error registering fd"); + goto ERR_REGISTER_FD; + } + + pthread_mutex_init(&data->mutex, NULL); + + data->attached_to_vm = get_jni_env(jvm, &data->env); + + if (!data->env) goto ERR_ENV; + + data->cls = find_class_global(data->env, FACEMGR_ANDROID_CLASS); + if (data->cls == 0) goto ERR_CLS; + + jmethodID mid_initialize = + (*data->env) + ->GetStaticMethodID(data->env, data->cls, "initialize", "()I"); + if (!mid_initialize) goto ERR_MID; + + (*data->env) + ->CallStaticIntMethod(data->env, data->cls, mid_initialize, + &android_on_network_event, interface); + + return 0; + +ERR_MID: + (*data->env)->DeleteGlobalRef(data->env, data->cls); +ERR_CLS: + if (data->attached_to_vm) { + (*jvm)->DetachCurrentThread(jvm); + data->attached_to_vm = false; + } + data->env = NULL; +ERR_ENV: + interface_unregister_fd(interface, data->fd); +ERR_REGISTER_FD: + close(data->fd); +ERR_EVENTFD: + facelet_array_free(data->facelets); +ERR_FACELETS: +ERR_JVM: +ERR_CFG: + free(data); +ERR_MALLOC: + return -1; +} + +int android_finalize(interface_t *interface) { + android_data_t *data = (android_data_t *)interface->data; + + jmethodID mid_terminate = + (*data->env)->GetStaticMethodID(data->env, data->cls, "terminate", "()I"); + if (mid_terminate) { + (*data->env) + ->CallStaticIntMethod(data->env, data->cls, mid_terminate, + &android_on_network_event, interface); + } + + (*data->env)->DeleteGlobalRef(data->env, data->cls); + + JavaVM *jvm = data->cfg.jvm; + if (data->attached_to_vm) { + (*jvm)->DetachCurrentThread(jvm); + data->attached_to_vm = false; + } + data->env = NULL; + + pthread_mutex_destroy(&data->mutex); + + // interface_unregister_fd(interface, data->fd); // XXX done in + // facemgr_delete_interface... + close(data->fd); + facelet_array_free(data->facelets); + + free(data); + + return 0; +} + +int android_callback(interface_t *interface, int fd, void *unused) { + android_data_t *data = (android_data_t *)interface->data; + + uint64_t ret; + if (read(data->fd, &ret, sizeof(ret)) < 0) return -1; + if (ret == 0) // EOF + return 0; + + pthread_mutex_lock(&data->mutex); + for (unsigned i = 0; i < facelet_array_len(data->facelets); i++) { + facelet_t *facelet; + if (facelet_array_get_index(data->facelets, i, &facelet) < 0) { + ERROR("[android_callback] Error getting facelet in array"); + continue; + } + + interface_raise_event(interface, facelet); + } + + for (unsigned i = 0; i < facelet_array_len(data->facelets); i++) { + if (facelet_array_remove_index(data->facelets, i, NULL) < 0) { + ERROR("[android_callback] Could not purge facelet from array"); + } + } + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +const interface_ops_t android_ops = { + .type = "android", + .initialize = android_initialize, + .callback = android_callback, + .finalize = android_finalize, + .on_event = NULL, +}; diff --git a/ctrl/facemgr/src/interfaces/android/android.h b/ctrl/facemgr/src/interfaces/android/android.h new file mode 100644 index 000000000..319bfe10a --- /dev/null +++ b/ctrl/facemgr/src/interfaces/android/android.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file android/android.h + * \brief Android utility. + */ + +#ifndef FACEMGR_INTERFACE_ANDROID_H +#define FACEMGR_INTERFACE_ANDROID_H + +#ifdef __ANDROID__ + +#include <jni.h> +#include "../../interface.h" + +typedef struct { + JavaVM *jvm; +} android_cfg_t; + +int android_on_network_event(interface_t *interface, const char *interface_name, + netdevice_type_t netdevice_type, bool up, + int family, const char *ip_address); + +#endif /* __ANDROID__ */ + +#endif /* FACEMGR_INTERFACE_ANDROID_H */ diff --git a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c b/ctrl/facemgr/src/interfaces/android_utility/android_utility.c deleted file mode 100644 index d8e20659a..000000000 --- a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c +++ /dev/null @@ -1,138 +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. - */ - -/** - * \file interfaces/android_utility/android_utility.c - * \brief Implementation of Android utility. - */ - -#include <assert.h> - -#include <hicn/facemgr.h> -#include <hicn/ctrl/face.h> -#include <hicn/util/log.h> -#include "../../common.h" -#include "../../interface.h" - -#include "android_utility.h" - -#define FACEMGR_UTILITY_CLASS "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" - - -#define AU_INTERFACE_TYPE_UNDEFINED 0 -#define AU_INTERFACE_TYPE_WIRED 1 -#define AU_INTERFACE_TYPE_WIFI 2 -#define AU_INTERFACE_TYPE_CELLULAR 3 -#define AU_INTERFACE_TYPE_LOOPBACK 4 -#define AU_INTERFACE_TYPE_UNAVAILABLE 5 - -#define ERR_STR_JAVA "Java VM parameters are required in the interface configuration." - -typedef struct { - android_utility_cfg_t cfg; -} au_data_t; - -int au_initialize(interface_t * interface, void * cfg) -{ - au_data_t * data = malloc(sizeof(au_data_t)); - if (!data) - return -1; - interface->data = data; - - if (!cfg) - goto ERR_CFG; - - data->cfg = * (android_utility_cfg_t *) cfg; - - if (!data->cfg.jvm) - goto ERR_CFG; - - return 0; - -ERR_CFG: - fprintf(stderr, ERR_STR_JAVA); - return -1; -} - -int au_finalize(interface_t * interface) -{ - /* Nothing to do */ - return 0; -} - -int au_on_event(interface_t * interface, facelet_t * facelet) -{ - /* - * This function is responsible to annotate every face we receive with the - * correct interface type, based on the value returned by the Android - * utility shipped with the Android forwarder. - */ - au_data_t * data = (au_data_t*)interface->data; - - netdevice_t netdevice = NETDEVICE_EMPTY; - int rc = facelet_get_netdevice(facelet, &netdevice); - if (rc < 0) - return -1; - - JNIEnv *env; - JavaVM *jvm = data->cfg.jvm; - (*jvm)->AttachCurrentThread(jvm, &env, NULL); - jclass cls = (*env)->FindClass(env, FACEMGR_UTILITY_CLASS); - jmethodID getNetworkType = (*env)->GetStaticMethodID(env, cls, - "getNetworkType", "(Ljava/lang/String;)I"); - jint interface_type = (*env)->CallStaticIntMethod(env, cls, getNetworkType, - (*env)->NewStringUTF(env, netdevice.name)); - - netdevice_type_t netdevice_type = AU_INTERFACE_TYPE_UNDEFINED; - switch(interface_type) { - case AU_INTERFACE_TYPE_UNDEFINED: - break; - case AU_INTERFACE_TYPE_WIRED: - netdevice_type = NETDEVICE_TYPE_WIRED; - break; - case AU_INTERFACE_TYPE_WIFI: - netdevice_type = NETDEVICE_TYPE_WIFI; - break; - case AU_INTERFACE_TYPE_CELLULAR: - netdevice_type = NETDEVICE_TYPE_CELLULAR; - break; - case AU_INTERFACE_TYPE_LOOPBACK: - netdevice_type = NETDEVICE_TYPE_LOOPBACK; - break; - default: - DEBUG("AU RETURNED ERROR"); - return -1; - } - - DEBUG("AU RETURNED %s : %s", netdevice.name, netdevice_type_str[netdevice_type]); - - facelet_t * facelet_new = facelet_create(); - facelet_set_netdevice(facelet_new, netdevice); - facelet_set_attr_clean(facelet_new); - facelet_set_netdevice_type(facelet_new, netdevice_type); - - facelet_set_event(facelet_new, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet_new); - - return 0; -} - -const interface_ops_t android_utility_ops = { - .type = "android_utility", - .initialize = au_initialize, - .finalize = au_finalize, - .callback = NULL, - .on_event = au_on_event, -}; diff --git a/ctrl/facemgr/src/interfaces/android_utility/android_utility.h b/ctrl/facemgr/src/interfaces/android_utility/android_utility.h deleted file mode 100644 index 53adfedf6..000000000 --- a/ctrl/facemgr/src/interfaces/android_utility/android_utility.h +++ /dev/null @@ -1,48 +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. - */ - -/** - * \file android_utility/android_utility.h - * \brief Android utility. - * - * This class relies on a small utility wrapper shipped with the Android - * application to access to Java SDK APIs for information not available to - * native code. - * - * For instance, we currently don't have on Linux any mean to get the type - * associated to an interface, especially for cellular interfaces. WiFi and - * Bluetooth information is for instance available through specific netlink - * subsystems, or by means of a support library, but cellular detection mostly - * relies on heuristics based on interface names (eg. in network manager). - * - * Android ship a Radio Interface Layer (RIL) daemon that exposes a control - * socket to the Java API to control the radio layer, but there is no working - * code exploiting it and no proper documentation. - */ - -#ifndef FACEMGR_INTERFACE_ANDROID_UTILITY_H -#define FACEMGR_INTERFACE_ANDROID_UTILITY_H - -#ifdef __ANDROID__ - -#include <jni.h> - -typedef struct { - JavaVM *jvm; -} android_utility_cfg_t; - -#endif /* __ANDROID__ */ - -#endif /* FACEMGR_INTERFACE_ANDROID_UTILITY_H */ diff --git a/ctrl/facemgr/src/interfaces/bonjour/CMakeLists.txt b/ctrl/facemgr/src/interfaces/bonjour/CMakeLists.txt index 8a0ddc888..90ca0e47f 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/bonjour/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c index 40b7f5f90..90f18c299 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c +++ b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -25,6 +25,7 @@ #include <hicn/facemgr.h> #include <hicn/util/log.h> #include <hicn/util/map.h> +#include <hicn/util/sstrncpy.h> #include "../../common.h" #include "../../interface.h" @@ -40,368 +41,357 @@ #define DEFAULT_SERVICE_DOMAIN "local" typedef struct { - bonjour_cfg_t cfg; - int sock; - size_t buffer_size; - void* buffer; + bonjour_cfg_t cfg; + int sock; + size_t buffer_size; + void* buffer; - /* The face being resolved, non-NULL values indicate interface is busy... */ - face_t * face; + /* The face being resolved, non-NULL values indicate interface is busy... */ + face_t* face; } bj_data_t; -int bj_initialize(interface_t * interface, void * cfg) -{ - bj_data_t * data = malloc(sizeof(bj_data_t)); - if (!data) - goto ERR_MALLOC; - interface->data = data; +int bj_initialize(interface_t* interface, void* cfg) { + bj_data_t* data = malloc(sizeof(bj_data_t)); + if (!data) goto ERR_MALLOC; + interface->data = data; - if (cfg) { + if (cfg) { #ifndef __linux__ - if (cfg->netdevice) - WARN("Binding to interface is (currently) only supported on Linux"); + if (cfg->netdevice) + WARN("Binding to interface is (currently) only supported on Linux"); #endif /* ! __linux__ */ - data->cfg = * (bonjour_cfg_t *) cfg; - } else { - memset(&data->cfg, 0, sizeof(bonjour_cfg_t)); - } + data->cfg = *(bonjour_cfg_t*)cfg; + } else { + memset(&data->cfg, 0, sizeof(bonjour_cfg_t)); + } - if (!data->cfg.service_name) - data->cfg.service_name = DEFAULT_SERVICE_NAME; + if (!data->cfg.service_name) data->cfg.service_name = DEFAULT_SERVICE_NAME; - if (!data->cfg.service_protocol) - data->cfg.service_protocol = DEFAULT_SERVICE_PROTOCOL; + if (!data->cfg.service_protocol) + data->cfg.service_protocol = DEFAULT_SERVICE_PROTOCOL; - if (!data->cfg.service_domain) - data->cfg.service_domain = DEFAULT_SERVICE_DOMAIN; + if (!data->cfg.service_domain) + data->cfg.service_domain = DEFAULT_SERVICE_DOMAIN; - data->sock = mdns_socket_open_ipv4(); - if (data->sock < 0) { - printf("Failed to open socket: %s\n", strerror(errno)); - goto ERR_SOCK; - } + data->sock = mdns_socket_open_ipv4(); + if (data->sock < 0) { + printf("Failed to open socket: %s\n", strerror(errno)); + goto ERR_SOCK; + } - /* Netdevice configuration */ + /* Netdevice configuration */ #ifdef __linux__ #ifndef __ANDROID__ - if (IS_VALID_NETDEVICE(data->cfg.netdevice)) { - int rc = setsockopt(data->sock, SOL_SOCKET, SO_BINDTODEVICE, - &data->cfg.netdevice.name, strlen(data->cfg.netdevice.name) + 1); - if (rc == -1) { - ERROR("setsockopt"); - goto ERR_SOCK_OPT; - } + if (IS_VALID_NETDEVICE(data->cfg.netdevice)) { + int rc = setsockopt(data->sock, SOL_SOCKET, SO_BINDTODEVICE, + &data->cfg.netdevice.name, + strnlen_s(data->cfg.netdevice.name, IFNAMSIZ)); + if (rc == -1) { + ERROR("setsockopt"); + goto ERR_SOCK_OPT; } + } #endif #endif /* __linux__ */ - data->buffer_size = DEFAULT_BUFFER_SIZE; - data->buffer = malloc(data->buffer_size); - if (!data->buffer) - goto ERR_BUFFER; + data->buffer_size = DEFAULT_BUFFER_SIZE; + data->buffer = malloc(data->buffer_size); + if (!data->buffer) goto ERR_BUFFER; #ifdef _WIN32 - WORD versionWanted = MAKEWORD(1, 1); - WSADATA wsaData; - WSAStartup(versionWanted, &wsaData); + WORD versionWanted = MAKEWORD(1, 1); + WSADATA wsaData; + WSAStartup(versionWanted, &wsaData); #endif - if (interface_register_fd(interface, data->sock, NULL) < 0) { - ERROR("[bj_initialize] Error registering fd"); - goto ERR_FD; - } + if (interface_register_fd(interface, data->sock, NULL) < 0) { + ERROR("[bj_initialize] Error registering fd"); + goto ERR_FD; + } - return 0; + return 0; ERR_FD: - free(data->buffer); + free(data->buffer); ERR_BUFFER: #ifndef __ANDROID__ ERR_SOCK_OPT: #endif - mdns_socket_close(data->sock); + mdns_socket_close(data->sock); #ifdef _WIN32 - WSACleanup(); + WSACleanup(); #endif ERR_SOCK: - free(data); + free(data); ERR_MALLOC: - return -1; + return -1; } /* * We reuse the callback to be triggered upon external events * TODO: move to a cleaner interface architecture later... */ -int bj_on_event(interface_t * interface, facelet_t * facelet) -{ - bj_data_t * data = (bj_data_t*)interface->data; - - /* - printf("Sending DNS-SD discovery\n"); - if (mdns_discovery_send(sock)) { - printf("Failed to send DNS-DS discovery: %s\n", strerror(errno)); - goto quit; - } - - printf("Reading DNS-SD replies\n"); - for (int i = 0; i < 10; ++i) { - records = mdns_discovery_recv(sock, buffer, capacity, callback, - user_data); - sleep(1); - } - */ - - DEBUG("Sending mDNS query"); - char service_string[SERVICE_STRING_SIZE]; - - int rc = snprintf(service_string, SERVICE_STRING_SIZE, "_%s._%s.%s.", - data->cfg.service_name, data->cfg.service_protocol, - data->cfg.service_domain); - if (rc < 0) - ; // error - else if (rc >= SERVICE_STRING_SIZE) - ; //truncated - - if (mdns_query_send(data->sock, MDNS_RECORDTYPE_PTR, - service_string, - strlen(service_string), - data->buffer, data->buffer_size)) { - printf("Failed to send mDNS query: %s\n", strerror(errno)); - return -1; - } - return 0; +int bj_on_event(interface_t* interface, facelet_t* facelet) { + bj_data_t* data = (bj_data_t*)interface->data; + + /* + printf("Sending DNS-SD discovery\n"); + if (mdns_discovery_send(sock)) { + printf("Failed to send DNS-DS discovery: %s\n", strerror(errno)); + goto quit; + } + + printf("Reading DNS-SD replies\n"); + for (int i = 0; i < 10; ++i) { + records = mdns_discovery_recv(sock, buffer, capacity, callback, + user_data); + sleep(1); + } + */ + + DEBUG("Sending mDNS query"); + char service_string[SERVICE_STRING_SIZE]; + + int rc = snprintf(service_string, SERVICE_STRING_SIZE, "_%s._%s.%s.", + data->cfg.service_name, data->cfg.service_protocol, + data->cfg.service_domain); + if (rc < 0) + ; // error + else if (rc >= SERVICE_STRING_SIZE) + ; // truncated + + if (mdns_query_send(data->sock, MDNS_RECORDTYPE_PTR, service_string, + strnlen_s(service_string, SERVICE_STRING_SIZE), + data->buffer, data->buffer_size)) { + printf("Failed to send mDNS query: %s\n", strerror(errno)); + return -1; + } + return 0; } static char addrbuffer[64]; static char namebuffer[256]; static mdns_record_txt_t txtbuffer[128]; -static mdns_string_t -ipv4_address_to_string(char* buffer, size_t capacity, const struct sockaddr_in* addr) { - char host[NI_MAXHOST] = {0}; - char service[NI_MAXSERV] = {0}; - int ret = getnameinfo((const struct sockaddr*)addr, sizeof(struct sockaddr_in), - host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICSERV | NI_NUMERICHOST); - int len = 0; - if (ret == 0) { - if (addr->sin_port != 0) - len = snprintf(buffer, capacity, "%s:%s", host, service); - else - len = snprintf(buffer, capacity, "%s", host); - } - if (len >= (int)capacity) - len = (int)capacity - 1; - mdns_string_t str = {buffer, len}; - return str; +static mdns_string_t ipv4_address_to_string(char* buffer, size_t capacity, + const struct sockaddr_in* addr) { + char host[NI_MAXHOST] = {0}; + char service[NI_MAXSERV] = {0}; + int ret = getnameinfo((const struct sockaddr*)addr, + sizeof(struct sockaddr_in), host, NI_MAXHOST, service, + NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST); + int len = 0; + if (ret == 0) { + if (addr->sin_port != 0) + len = snprintf(buffer, capacity, "%s:%s", host, service); + else + len = snprintf(buffer, capacity, "%s", host); + } + if (len >= (int)capacity) len = (int)capacity - 1; + mdns_string_t str = {buffer, len}; + return str; } -static mdns_string_t -ipv6_address_to_string(char* buffer, size_t capacity, const struct sockaddr_in6* addr) { - char host[NI_MAXHOST] = {0}; - char service[NI_MAXSERV] = {0}; - int ret = getnameinfo((const struct sockaddr*)addr, sizeof(struct sockaddr_in6), - host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICSERV | NI_NUMERICHOST); - int len = 0; - if (ret == 0) { - if (addr->sin6_port != 0) - len = snprintf(buffer, capacity, "[%s]:%s", host, service); - else - len = snprintf(buffer, capacity, "%s", host); - } - if (len >= (int)capacity) - len = (int)capacity - 1; - mdns_string_t str = {buffer, len}; - return str; +static mdns_string_t ipv6_address_to_string(char* buffer, size_t capacity, + const struct sockaddr_in6* addr) { + char host[NI_MAXHOST] = {0}; + char service[NI_MAXSERV] = {0}; + int ret = getnameinfo((const struct sockaddr*)addr, + sizeof(struct sockaddr_in6), host, NI_MAXHOST, service, + NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST); + int len = 0; + if (ret == 0) { + if (addr->sin6_port != 0) + len = snprintf(buffer, capacity, "[%s]:%s", host, service); + else + len = snprintf(buffer, capacity, "%s", host); + } + if (len >= (int)capacity) len = (int)capacity - 1; + mdns_string_t str = {buffer, len}; + return str; } -static mdns_string_t -ip_address_to_string(char* buffer, size_t capacity, const struct sockaddr* addr) { - if (addr->sa_family == AF_INET6) - return ipv6_address_to_string(buffer, capacity, (const struct sockaddr_in6*)addr); - return ipv4_address_to_string(buffer, capacity, (const struct sockaddr_in*)addr); +static mdns_string_t ip_address_to_string(char* buffer, size_t capacity, + const struct sockaddr* addr) { + if (addr->sa_family == AF_INET6) + return ipv6_address_to_string(buffer, capacity, + (const struct sockaddr_in6*)addr); + return ipv4_address_to_string(buffer, capacity, + (const struct sockaddr_in*)addr); } -int -ip_address_set_sockaddr(ip_address_t * ip_address, struct sockaddr * sa) -{ - switch(sa->sa_family) { - case AF_INET: - ip_address->v4.as_inaddr = ((struct sockaddr_in *)sa)->sin_addr; - break; - case AF_INET6: - ip_address->v6.as_in6addr = ((struct sockaddr_in6 *)sa)->sin6_addr; - break; - default: - return -1; - } - - return 0; +int ip_address_set_sockaddr(ip_address_t* ip_address, struct sockaddr* sa) { + switch (sa->sa_family) { + case AF_INET: + ip_address->v4.as_inaddr = ((struct sockaddr_in*)sa)->sin_addr; + break; + case AF_INET6: + ip_address->v6.as_in6addr = ((struct sockaddr_in6*)sa)->sin6_addr; + break; + default: + return -1; + } + + return 0; } -static int -callback(const struct sockaddr* from, mdns_entry_type_t entry, uint16_t type, - uint16_t rclass, uint32_t ttl, const void* data, size_t size, size_t - offset, size_t length, void* user_data) -{ - interface_t * interface = (interface_t*)user_data; - bj_data_t * bj_data = (bj_data_t *)interface->data; - - struct sockaddr_storage addr; - - mdns_string_t fromaddrstr = ip_address_to_string(addrbuffer, sizeof(addrbuffer), from); - const char* entrytype = (entry == MDNS_ENTRYTYPE_ANSWER) ? "answer" : - ((entry == MDNS_ENTRYTYPE_AUTHORITY) ? "authority" : "additional"); - - switch(type) { - case MDNS_RECORDTYPE_A: - { - ip_address_t ip_address; - mdns_record_parse_a(data, size, offset, length, (struct sockaddr_in*)&addr); - ip_address_set_sockaddr(&ip_address, (struct sockaddr *)&addr); - - mdns_string_t addrstr = ipv4_address_to_string(namebuffer, sizeof(namebuffer), (struct sockaddr_in *)&addr); - DEBUG("%.*s : %s A %.*s", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(addrstr)); - - facelet_t * facelet = facelet_create(); - facelet_set_netdevice(facelet, bj_data->cfg.netdevice); - facelet_set_family(facelet, AF_INET); - facelet_set_remote_addr(facelet, ip_address); - //facelet_set_remote_port(facelet, ((struct sockaddr_in*)&addr)->sin_port); - - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet); - break; - } +static int callback(const struct sockaddr* from, mdns_entry_type_t entry, + uint16_t type, uint16_t rclass, uint32_t ttl, + const void* data, size_t size, size_t offset, size_t length, + void* user_data) { + interface_t* interface = (interface_t*)user_data; + bj_data_t* bj_data = (bj_data_t*)interface->data; + + struct sockaddr_storage addr; + + mdns_string_t fromaddrstr = + ip_address_to_string(addrbuffer, sizeof(addrbuffer), from); + const char* entrytype = + (entry == MDNS_ENTRYTYPE_ANSWER) + ? "answer" + : ((entry == MDNS_ENTRYTYPE_AUTHORITY) ? "authority" : "additional"); + + switch (type) { + case MDNS_RECORDTYPE_A: { + ip_address_t ip_address; + mdns_record_parse_a(data, size, offset, length, + (struct sockaddr_in*)&addr); + ip_address_set_sockaddr(&ip_address, (struct sockaddr*)&addr); + + mdns_string_t addrstr = ipv4_address_to_string( + namebuffer, sizeof(namebuffer), (struct sockaddr_in*)&addr); + DEBUG("%.*s : %s A %.*s", MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(addrstr)); + + facelet_t* facelet = facelet_create(); + facelet_set_netdevice(facelet, bj_data->cfg.netdevice); + facelet_set_family(facelet, AF_INET); + facelet_set_remote_addr(facelet, ip_address); + // facelet_set_remote_port(facelet, ((struct + // sockaddr_in*)&addr)->sin_port); + + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + interface_raise_event(interface, facelet); + break; + } - case MDNS_RECORDTYPE_AAAA: - { - ip_address_t ip_address; - mdns_record_parse_aaaa(data, size, offset, length, (struct sockaddr_in6*)&addr); - ip_address_set_sockaddr(&ip_address, (struct sockaddr *)&addr); - - mdns_string_t addrstr = ipv6_address_to_string(namebuffer, - sizeof(namebuffer), (struct sockaddr_in6*)&addr); - DEBUG("%.*s : %s AAAA %.*s", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(addrstr)); - - facelet_t * facelet = facelet_create(); - facelet_set_netdevice(facelet, bj_data->cfg.netdevice); - facelet_set_family(facelet, AF_INET6); - facelet_set_remote_addr(facelet, ip_address); - //facelet_set_remote_port(facelet, ((struct sockaddr_in6*)&addr)->sin6_port); - - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet); - break; - } + case MDNS_RECORDTYPE_AAAA: { + ip_address_t ip_address; + mdns_record_parse_aaaa(data, size, offset, length, + (struct sockaddr_in6*)&addr); + ip_address_set_sockaddr(&ip_address, (struct sockaddr*)&addr); + + mdns_string_t addrstr = ipv6_address_to_string( + namebuffer, sizeof(namebuffer), (struct sockaddr_in6*)&addr); + DEBUG("%.*s : %s AAAA %.*s", MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(addrstr)); + + facelet_t* facelet = facelet_create(); + facelet_set_netdevice(facelet, bj_data->cfg.netdevice); + facelet_set_family(facelet, AF_INET6); + facelet_set_remote_addr(facelet, ip_address); + // facelet_set_remote_port(facelet, ((struct + // sockaddr_in6*)&addr)->sin6_port); + + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + interface_raise_event(interface, facelet); + break; + } - case MDNS_RECORDTYPE_SRV: /* same port for both v4 and v6 */ - { - mdns_record_srv_t srv = mdns_record_parse_srv(data, size, offset, length, - namebuffer, sizeof(namebuffer)); - - DEBUG("%.*s : %s SRV %.*s priority %d weight %d port %d", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); - - /* We raise both v4 and v6 - * - * Unless we choose whether we query A and/or AAAA, this might leave - * us with an unused pending facelet, eg. we might not have an IPv6 - * but we raise an IPv6 bonjour event... - */ - - facelet_t * facelet = facelet_create(); - facelet_set_netdevice(facelet, bj_data->cfg.netdevice); - facelet_set_family(facelet, AF_INET); - facelet_set_remote_port(facelet, srv.port); - - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet); - - facelet = facelet_create(); - facelet_set_netdevice(facelet, bj_data->cfg.netdevice); - facelet_set_family(facelet, AF_INET6); - facelet_set_remote_port(facelet, srv.port); - - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet); - break; - } + case MDNS_RECORDTYPE_SRV: /* same port for both v4 and v6 */ + { + mdns_record_srv_t srv = mdns_record_parse_srv( + data, size, offset, length, namebuffer, sizeof(namebuffer)); + + DEBUG("%.*s : %s SRV %.*s priority %d weight %d port %d", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); + + /* We raise both v4 and v6 + * + * Unless we choose whether we query A and/or AAAA, this might leave + * us with an unused pending facelet, eg. we might not have an IPv6 + * but we raise an IPv6 bonjour event... + */ + + facelet_t* facelet = facelet_create(); + facelet_set_netdevice(facelet, bj_data->cfg.netdevice); + facelet_set_family(facelet, AF_INET); + facelet_set_remote_port(facelet, srv.port); + + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + interface_raise_event(interface, facelet); + + facelet = facelet_create(); + facelet_set_netdevice(facelet, bj_data->cfg.netdevice); + facelet_set_family(facelet, AF_INET6); + facelet_set_remote_port(facelet, srv.port); + + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + interface_raise_event(interface, facelet); + break; + } - case MDNS_RECORDTYPE_PTR: - { - mdns_string_t namestr = mdns_record_parse_ptr(data, size, offset, length, - namebuffer, sizeof(namebuffer)); - DEBUG("%.*s : %s PTR %.*s type %u rclass 0x%x ttl %u length %d", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(namestr), type, rclass, ttl, (int)length); - break; - } + case MDNS_RECORDTYPE_PTR: { + mdns_string_t namestr = mdns_record_parse_ptr( + data, size, offset, length, namebuffer, sizeof(namebuffer)); + DEBUG("%.*s : %s PTR %.*s type %u rclass 0x%x ttl %u length %d", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(namestr), type, rclass, ttl, (int)length); + break; + } - case MDNS_RECORDTYPE_TXT: - { - size_t parsed = mdns_record_parse_txt(data, size, offset, length, - txtbuffer, sizeof(txtbuffer) / sizeof(mdns_record_txt_t)); - for (size_t itxt = 0; itxt < parsed; ++itxt) { - if (txtbuffer[itxt].value.length) { - DEBUG("%.*s : %s TXT %.*s = %.*s", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(txtbuffer[itxt].key), - MDNS_STRING_FORMAT(txtbuffer[itxt].value)); - } - else { - DEBUG("%.*s : %s TXT %.*s", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(txtbuffer[itxt].key)); - } - } - break; + case MDNS_RECORDTYPE_TXT: { + size_t parsed = + mdns_record_parse_txt(data, size, offset, length, txtbuffer, + sizeof(txtbuffer) / sizeof(mdns_record_txt_t)); + for (size_t itxt = 0; itxt < parsed; ++itxt) { + if (txtbuffer[itxt].value.length) { + DEBUG("%.*s : %s TXT %.*s = %.*s", MDNS_STRING_FORMAT(fromaddrstr), + entrytype, MDNS_STRING_FORMAT(txtbuffer[itxt].key), + MDNS_STRING_FORMAT(txtbuffer[itxt].value)); + } else { + DEBUG("%.*s : %s TXT %.*s", MDNS_STRING_FORMAT(fromaddrstr), + entrytype, MDNS_STRING_FORMAT(txtbuffer[itxt].key)); } - - default: - /* Silently ignore the received record */ - DEBUG("%.*s : %s type %u rclass 0x%x ttl %u length %d", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - type, rclass, ttl, (int)length); - return 0; + } + break; } - return 0; + default: + /* Silently ignore the received record */ + DEBUG("%.*s : %s type %u rclass 0x%x ttl %u length %d", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, type, rclass, ttl, + (int)length); + return 0; + } + return 0; } /* * The fact we use a single fd does not allow us to get user_data associated to * the query. */ -int bj_callback(interface_t * interface, int fd, void * unused) -{ - bj_data_t * data = (bj_data_t*)interface->data; - DEBUG("Got an mDNS reply"); - /* size_t records = */ mdns_query_recv(data->sock, data->buffer, data->buffer_size, callback, interface, 1); +int bj_callback(interface_t* interface, int fd, void* unused) { + bj_data_t* data = (bj_data_t*)interface->data; + DEBUG("Got an mDNS reply"); + /* size_t records = */ mdns_query_recv( + data->sock, data->buffer, data->buffer_size, callback, interface, 1); - return 0; + return 0; } -int bj_finalize(interface_t * interface) -{ - bj_data_t * data = (bj_data_t*)interface->data; +int bj_finalize(interface_t* interface) { + bj_data_t* data = (bj_data_t*)interface->data; - free(data->buffer); - mdns_socket_close(data->sock); + free(data->buffer); + mdns_socket_close(data->sock); #ifdef _WIN32 - WSACleanup(); + WSACleanup(); #endif - return 0; - + return 0; } const interface_ops_t bonjour_ops = { @@ -410,5 +400,5 @@ const interface_ops_t bonjour_ops = { .on_event = bj_on_event, .callback = bj_callback, .finalize = bj_finalize, - // .on_event = NULL, + // .on_event = NULL, }; diff --git a/ctrl/facemgr/src/interfaces/bonjour/bonjour.h b/ctrl/facemgr/src/interfaces/bonjour/bonjour.h index fe053079d..6458423ea 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/bonjour.h +++ b/ctrl/facemgr/src/interfaces/bonjour/bonjour.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -25,11 +25,11 @@ * queries... */ -#include <hicn/ctrl/face.h> /* netdevice_t */ +#include <hicn/face.h> /* netdevice_t */ typedef struct { - netdevice_t netdevice; - char * service_name; - char * service_protocol; - char * service_domain; + netdevice_t netdevice; + char* service_name; + char* service_protocol; + char* service_domain; } bonjour_cfg_t; diff --git a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.c b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.c index a8e97e8e0..e2bb4f432 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.c +++ b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.c @@ -1,6 +1,6 @@ #ifdef _WIN32 -# define _CRT_SECURE_NO_WARNINGS 1 +#define _CRT_SECURE_NO_WARNINGS 1 #endif #include "mdns.h" @@ -9,184 +9,176 @@ #include <errno.h> #ifdef _WIN32 -# define sleep(x) Sleep(x * 1000) +#define sleep(x) Sleep(x * 1000) #else -# include <netdb.h> +#include <netdb.h> #endif static char addrbuffer[64]; static char namebuffer[256]; static mdns_record_txt_t txtbuffer[128]; -static mdns_string_t -ipv4_address_to_string(char* buffer, size_t capacity, const struct sockaddr_in* addr) { - char host[NI_MAXHOST] = {0}; - char service[NI_MAXSERV] = {0}; - int ret = getnameinfo((const struct sockaddr*)addr, sizeof(struct sockaddr_in), - host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICSERV | NI_NUMERICHOST); - int len = 0; - if (ret == 0) { - if (addr->sin_port != 0) - len = snprintf(buffer, capacity, "%s:%s", host, service); - else - len = snprintf(buffer, capacity, "%s", host); - } - if (len >= (int)capacity) - len = (int)capacity - 1; - mdns_string_t str = {buffer, len}; - return str; +static mdns_string_t ipv4_address_to_string(char* buffer, size_t capacity, + const struct sockaddr_in* addr) { + char host[NI_MAXHOST] = {0}; + char service[NI_MAXSERV] = {0}; + int ret = getnameinfo((const struct sockaddr*)addr, + sizeof(struct sockaddr_in), host, NI_MAXHOST, service, + NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST); + int len = 0; + if (ret == 0) { + if (addr->sin_port != 0) + len = snprintf(buffer, capacity, "%s:%s", host, service); + else + len = snprintf(buffer, capacity, "%s", host); + } + if (len >= (int)capacity) len = (int)capacity - 1; + mdns_string_t str = {buffer, len}; + return str; } -static mdns_string_t -ipv6_address_to_string(char* buffer, size_t capacity, const struct sockaddr_in6* addr) { - char host[NI_MAXHOST] = {0}; - char service[NI_MAXSERV] = {0}; - int ret = getnameinfo((const struct sockaddr*)addr, sizeof(struct sockaddr_in6), - host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICSERV | NI_NUMERICHOST); - int len = 0; - if (ret == 0) { - if (addr->sin6_port != 0) - len = snprintf(buffer, capacity, "[%s]:%s", host, service); - else - len = snprintf(buffer, capacity, "%s", host); - } - if (len >= (int)capacity) - len = (int)capacity - 1; - mdns_string_t str = {buffer, len}; - return str; +static mdns_string_t ipv6_address_to_string(char* buffer, size_t capacity, + const struct sockaddr_in6* addr) { + char host[NI_MAXHOST] = {0}; + char service[NI_MAXSERV] = {0}; + int ret = getnameinfo((const struct sockaddr*)addr, + sizeof(struct sockaddr_in6), host, NI_MAXHOST, service, + NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST); + int len = 0; + if (ret == 0) { + if (addr->sin6_port != 0) + len = snprintf(buffer, capacity, "[%s]:%s", host, service); + else + len = snprintf(buffer, capacity, "%s", host); + } + if (len >= (int)capacity) len = (int)capacity - 1; + mdns_string_t str = {buffer, len}; + return str; } -static mdns_string_t -ip_address_to_string(char* buffer, size_t capacity, const struct sockaddr* addr) { - if (addr->sa_family == AF_INET6) - return ipv6_address_to_string(buffer, capacity, (const struct sockaddr_in6*)addr); - return ipv4_address_to_string(buffer, capacity, (const struct sockaddr_in*)addr); +static mdns_string_t ip_address_to_string(char* buffer, size_t capacity, + const struct sockaddr* addr) { + if (addr->sa_family == AF_INET6) + return ipv6_address_to_string(buffer, capacity, + (const struct sockaddr_in6*)addr); + return ipv4_address_to_string(buffer, capacity, + (const struct sockaddr_in*)addr); } -static int -callback(const struct sockaddr* from, - mdns_entry_type_t entry, uint16_t type, - uint16_t rclass, uint32_t ttl, - const void* data, size_t size, size_t offset, size_t length, - void* user_data) { - mdns_string_t fromaddrstr = ip_address_to_string(addrbuffer, sizeof(addrbuffer), from); - const char* entrytype = (entry == MDNS_ENTRYTYPE_ANSWER) ? "answer" : - ((entry == MDNS_ENTRYTYPE_AUTHORITY) ? "authority" : "additional"); - if (type == MDNS_RECORDTYPE_PTR) { - mdns_string_t namestr = mdns_record_parse_ptr(data, size, offset, length, - namebuffer, sizeof(namebuffer)); - INFO("%.*s : %s PTR %.*s type %u rclass 0x%x ttl %u length %d\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(namestr), type, rclass, ttl, (int)length); - } - else if (type == MDNS_RECORDTYPE_SRV) { - mdns_record_srv_t srv = mdns_record_parse_srv(data, size, offset, length, - namebuffer, sizeof(namebuffer)); - INFO("%.*s : %s SRV %.*s priority %d weight %d port %d\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); - } - else if (type == MDNS_RECORDTYPE_A) { - struct sockaddr_in addr; - mdns_record_parse_a(data, size, offset, length, &addr); - mdns_string_t addrstr = ipv4_address_to_string(namebuffer, sizeof(namebuffer), &addr); - INFO("%.*s : %s A %.*s\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(addrstr)); - } - else if (type == MDNS_RECORDTYPE_AAAA) { - struct sockaddr_in6 addr; - mdns_record_parse_aaaa(data, size, offset, length, &addr); - mdns_string_t addrstr = ipv6_address_to_string(namebuffer, sizeof(namebuffer), &addr); - INFO("%.*s : %s AAAA %.*s\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(addrstr)); - } - else if (type == MDNS_RECORDTYPE_TXT) { - size_t parsed = mdns_record_parse_txt(data, size, offset, length, - txtbuffer, sizeof(txtbuffer) / sizeof(mdns_record_txt_t)); - for (size_t itxt = 0; itxt < parsed; ++itxt) { - if (txtbuffer[itxt].value.length) { - INFO("%.*s : %s TXT %.*s = %.*s\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(txtbuffer[itxt].key), - MDNS_STRING_FORMAT(txtbuffer[itxt].value)); - } - else { - INFO("%.*s : %s TXT %.*s\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - MDNS_STRING_FORMAT(txtbuffer[itxt].key)); - } - } - } - else { - INFO("%.*s : %s type %u rclass 0x%x ttl %u length %d\n", - MDNS_STRING_FORMAT(fromaddrstr), entrytype, - type, rclass, ttl, (int)length); - } - return 0; +static int callback(const struct sockaddr* from, mdns_entry_type_t entry, + uint16_t type, uint16_t rclass, uint32_t ttl, + const void* data, size_t size, size_t offset, size_t length, + void* user_data) { + mdns_string_t fromaddrstr = + ip_address_to_string(addrbuffer, sizeof(addrbuffer), from); + const char* entrytype = + (entry == MDNS_ENTRYTYPE_ANSWER) + ? "answer" + : ((entry == MDNS_ENTRYTYPE_AUTHORITY) ? "authority" : "additional"); + if (type == MDNS_RECORDTYPE_PTR) { + mdns_string_t namestr = mdns_record_parse_ptr( + data, size, offset, length, namebuffer, sizeof(namebuffer)); + INFO("%.*s : %s PTR %.*s type %u rclass 0x%x ttl %u length %d\n", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(namestr), type, rclass, ttl, (int)length); + } else if (type == MDNS_RECORDTYPE_SRV) { + mdns_record_srv_t srv = mdns_record_parse_srv( + data, size, offset, length, namebuffer, sizeof(namebuffer)); + INFO("%.*s : %s SRV %.*s priority %d weight %d port %d\n", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(srv.name), srv.priority, srv.weight, srv.port); + } else if (type == MDNS_RECORDTYPE_A) { + struct sockaddr_in addr; + mdns_record_parse_a(data, size, offset, length, &addr); + mdns_string_t addrstr = + ipv4_address_to_string(namebuffer, sizeof(namebuffer), &addr); + INFO("%.*s : %s A %.*s\n", MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(addrstr)); + } else if (type == MDNS_RECORDTYPE_AAAA) { + struct sockaddr_in6 addr; + mdns_record_parse_aaaa(data, size, offset, length, &addr); + mdns_string_t addrstr = + ipv6_address_to_string(namebuffer, sizeof(namebuffer), &addr); + INFO("%.*s : %s AAAA %.*s\n", MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(addrstr)); + } else if (type == MDNS_RECORDTYPE_TXT) { + size_t parsed = + mdns_record_parse_txt(data, size, offset, length, txtbuffer, + sizeof(txtbuffer) / sizeof(mdns_record_txt_t)); + for (size_t itxt = 0; itxt < parsed; ++itxt) { + if (txtbuffer[itxt].value.length) { + INFO("%.*s : %s TXT %.*s = %.*s\n", MDNS_STRING_FORMAT(fromaddrstr), + entrytype, MDNS_STRING_FORMAT(txtbuffer[itxt].key), + MDNS_STRING_FORMAT(txtbuffer[itxt].value)); + } else { + INFO("%.*s : %s TXT %.*s\n", MDNS_STRING_FORMAT(fromaddrstr), entrytype, + MDNS_STRING_FORMAT(txtbuffer[itxt].key)); + } + } + } else { + INFO("%.*s : %s type %u rclass 0x%x ttl %u length %d\n", + MDNS_STRING_FORMAT(fromaddrstr), entrytype, type, rclass, ttl, + (int)length); + } + return 0; } -int -main() { - size_t capacity = 2048; - void* buffer = 0; - void* user_data = 0; - size_t records; +int main() { + size_t capacity = 2048; + void* buffer = 0; + void* user_data = 0; + size_t records; #ifdef _WIN32 - WORD versionWanted = MAKEWORD(1, 1); - WSADATA wsaData; - WSAStartup(versionWanted, &wsaData); + WORD versionWanted = MAKEWORD(1, 1); + WSADATA wsaData; + WSAStartup(versionWanted, &wsaData); #endif - int sock = mdns_socket_open_ipv4(); - if (sock < 0) { - INFO("Failed to open socket: %s\n", strerror(errno)); - return -1; - } - INFO("Opened IPv4 socket for mDNS/DNS-SD\n"); - buffer = malloc(capacity); -/* - INFO("Sending DNS-SD discovery\n"); - if (mdns_discovery_send(sock)) { - INFO("Failed to send DNS-DS discovery: %s\n", strerror(errno)); - goto quit; - } - - INFO("Reading DNS-SD replies\n"); - for (int i = 0; i < 10; ++i) { - records = mdns_discovery_recv(sock, buffer, capacity, callback, - user_data); - sleep(1); - } - */ - - INFO("Sending mDNS query\n"); - if (mdns_query_send(sock, MDNS_RECORDTYPE_PTR, - MDNS_STRING_CONST("_hicn._udp.local."), - buffer, capacity)) { - INFO("Failed to send mDNS query: %s\n", strerror(errno)); - goto quit; - } - - INFO("Reading mDNS replies\n"); - for (int i = 0; i < 10; ++i) { - records = mdns_query_recv(sock, buffer, capacity, callback, user_data, 1); - sleep(1); - } + int sock = mdns_socket_open_ipv4(); + if (sock < 0) { + INFO("Failed to open socket: %s\n", strerror(errno)); + return -1; + } + INFO("Opened IPv4 socket for mDNS/DNS-SD\n"); + buffer = malloc(capacity); + /* + INFO("Sending DNS-SD discovery\n"); + if (mdns_discovery_send(sock)) { + INFO("Failed to send DNS-DS discovery: %s\n", + strerror(errno)); goto quit; + } + + INFO("Reading DNS-SD replies\n"); + for (int i = 0; i < 10; ++i) { + records = mdns_discovery_recv(sock, buffer, capacity, + callback, user_data); sleep(1); + } + */ + + INFO("Sending mDNS query\n"); + if (mdns_query_send(sock, MDNS_RECORDTYPE_PTR, + MDNS_STRING_CONST("_hicn._udp.local."), buffer, + capacity)) { + INFO("Failed to send mDNS query: %s\n", strerror(errno)); + goto quit; + } + + INFO("Reading mDNS replies\n"); + for (int i = 0; i < 10; ++i) { + records = mdns_query_recv(sock, buffer, capacity, callback, user_data, 1); + sleep(1); + } quit: - free(buffer); + free(buffer); - mdns_socket_close(sock); - INFO("Closed socket\n"); + mdns_socket_close(sock); + INFO("Closed socket\n"); #ifdef _WIN32 - WSACleanup(); + WSACleanup(); #endif - return 0; + return 0; } diff --git a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h index ff04b5d72..4b8e7a7f4 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h +++ b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h @@ -7,7 +7,8 @@ * * https://github.com/mjansson/mdns * - * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. + * This library is put in the public domain; you can redistribute it and/or + * modify it without any restrictions. * */ @@ -31,76 +32,73 @@ #define MDNS_INVALID_POS ((size_t)-1) -#define MDNS_STRING_CONST(s) (s), (sizeof((s))-1) +#define MDNS_STRING_CONST(s) (s), (sizeof((s)) - 1) #define MDNS_STRING_FORMAT(s) (int)((s).length), s.str enum mdns_record_type { - MDNS_RECORDTYPE_IGNORE = 0, - //Address - MDNS_RECORDTYPE_A = 1, - //Domain Name pointer - MDNS_RECORDTYPE_PTR = 12, - //Arbitrary text string - MDNS_RECORDTYPE_TXT = 16, - //IP6 Address [Thomson] - MDNS_RECORDTYPE_AAAA = 28, - //Server Selection [RFC2782] - MDNS_RECORDTYPE_SRV = 33 + MDNS_RECORDTYPE_IGNORE = 0, + // Address + MDNS_RECORDTYPE_A = 1, + // Domain Name pointer + MDNS_RECORDTYPE_PTR = 12, + // Arbitrary text string + MDNS_RECORDTYPE_TXT = 16, + // IP6 Address [Thomson] + MDNS_RECORDTYPE_AAAA = 28, + // Server Selection [RFC2782] + MDNS_RECORDTYPE_SRV = 33 }; enum mdns_entry_type { - MDNS_ENTRYTYPE_ANSWER = 1, - MDNS_ENTRYTYPE_AUTHORITY = 2, - MDNS_ENTRYTYPE_ADDITIONAL = 3 + MDNS_ENTRYTYPE_ANSWER = 1, + MDNS_ENTRYTYPE_AUTHORITY = 2, + MDNS_ENTRYTYPE_ADDITIONAL = 3 }; -enum mdns_class { - MDNS_CLASS_IN = 1 -}; +enum mdns_class { MDNS_CLASS_IN = 1 }; -typedef enum mdns_record_type mdns_record_type_t; -typedef enum mdns_entry_type mdns_entry_type_t; -typedef enum mdns_class mdns_class_t; +typedef enum mdns_record_type mdns_record_type_t; +typedef enum mdns_entry_type mdns_entry_type_t; +typedef enum mdns_class mdns_class_t; -typedef int (* mdns_record_callback_fn)(const struct sockaddr* from, - mdns_entry_type_t entry, uint16_t type, - uint16_t rclass, uint32_t ttl, - const void* data, size_t size, size_t offset, size_t length, - void* user_data); +typedef int (*mdns_record_callback_fn)(const struct sockaddr* from, + mdns_entry_type_t entry, uint16_t type, + uint16_t rclass, uint32_t ttl, + const void* data, size_t size, + size_t offset, size_t length, + void* user_data); -typedef struct mdns_string_t mdns_string_t; -typedef struct mdns_string_pair_t mdns_string_pair_t; -typedef struct mdns_record_srv_t mdns_record_srv_t; -typedef struct mdns_record_txt_t mdns_record_txt_t; +typedef struct mdns_string_t mdns_string_t; +typedef struct mdns_string_pair_t mdns_string_pair_t; +typedef struct mdns_record_srv_t mdns_record_srv_t; +typedef struct mdns_record_txt_t mdns_record_txt_t; struct mdns_string_t { - const char* str; - size_t length; + const char* str; + size_t length; }; struct mdns_string_pair_t { - size_t offset; - size_t length; - int ref; + size_t offset; + size_t length; + int ref; }; struct mdns_record_srv_t { - uint16_t priority; - uint16_t weight; - uint16_t port; - mdns_string_t name; + uint16_t priority; + uint16_t weight; + uint16_t port; + mdns_string_t name; }; struct mdns_record_txt_t { - mdns_string_t key; - mdns_string_t value; + mdns_string_t key; + mdns_string_t value; }; -static int -mdns_socket_open_ipv4(void); +static int mdns_socket_open_ipv4(void); -static int -mdns_socket_setup_ipv4(int sock); +static int mdns_socket_setup_ipv4(int sock); #if 0 static int @@ -112,8 +110,7 @@ static int mdns_socket_setup_ipv6(int sock); #endif -static void -mdns_socket_close(int sock); +static void mdns_socket_close(int sock); #if 0 static int @@ -125,21 +122,18 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback, void* user_data); #endif -static int -mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, - void* buffer, size_t capacity); +static int mdns_query_send(int sock, mdns_record_type_t type, const char* name, + size_t length, void* buffer, size_t capacity); -static size_t -mdns_query_recv(int sock, void* buffer, size_t capacity, - mdns_record_callback_fn callback, void* user_data, - uint8_t one_shot); +static size_t mdns_query_recv(int sock, void* buffer, size_t capacity, + mdns_record_callback_fn callback, void* user_data, + uint8_t one_shot); -static mdns_string_t -mdns_string_extract(const void* buffer, size_t size, size_t* offset, - char* str, size_t capacity); +static mdns_string_t mdns_string_extract(const void* buffer, size_t size, + size_t* offset, char* str, + size_t capacity); -static int -mdns_string_skip(const void* buffer, size_t size, size_t* offset); +static int mdns_string_skip(const void* buffer, size_t size, size_t* offset); #if 0 static int @@ -147,78 +141,80 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, const void* buffer_rhs, size_t size_rhs, size_t* ofs_rhs); #endif -static void* -mdns_string_make(void* data, size_t capacity, const char* name, size_t length); +static void* mdns_string_make(void* data, size_t capacity, const char* name, + size_t length); -static mdns_string_t -mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length, - char* strbuffer, size_t capacity); +static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size, + size_t offset, size_t length, + char* strbuffer, size_t capacity); -static mdns_record_srv_t -mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length, - char* strbuffer, size_t capacity); +static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size, + size_t offset, size_t length, + char* strbuffer, + size_t capacity); -static struct sockaddr_in* -mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length, - struct sockaddr_in* addr); +static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size, + size_t offset, size_t length, + struct sockaddr_in* addr); -static struct sockaddr_in6* -mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length, - struct sockaddr_in6* addr); +static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer, + size_t size, size_t offset, + size_t length, + struct sockaddr_in6* addr); -static size_t -mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length, - mdns_record_txt_t* records, size_t capacity); +static size_t mdns_record_parse_txt(const void* buffer, size_t size, + size_t offset, size_t length, + mdns_record_txt_t* records, + size_t capacity); // Implementations -static int -mdns_socket_open_ipv4(void) { - int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) - return -1; - if (mdns_socket_setup_ipv4(sock)) { - mdns_socket_close(sock); - return -1; - } - return sock; +static int mdns_socket_open_ipv4(void) { + int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) return -1; + if (mdns_socket_setup_ipv4(sock)) { + mdns_socket_close(sock); + return -1; + } + return sock; } -static int -mdns_socket_setup_ipv4(int sock) { - struct sockaddr_in saddr; - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = INADDR_ANY; +static int mdns_socket_setup_ipv4(int sock) { + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = INADDR_ANY; #ifdef __APPLE__ - saddr.sin_len = sizeof(saddr); + saddr.sin_len = sizeof(saddr); #endif - if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))) - return -1; + if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))) return -1; #ifdef _WIN32 - unsigned long param = 1; - ioctlsocket(sock, FIONBIO, ¶m); + unsigned long param = 1; + ioctlsocket(sock, FIONBIO, ¶m); #else - const int flags = fcntl(sock, F_GETFL, 0); - fcntl(sock, F_SETFL, flags | O_NONBLOCK); + const int flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, flags | O_NONBLOCK); #endif - unsigned char ttl = 1; - unsigned char loopback = 1; - struct ip_mreq req; + unsigned char ttl = 1; + unsigned char loopback = 1; + struct ip_mreq req; - setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)); - setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)); + setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, + sizeof(ttl)); + setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, + sizeof(loopback)); - memset(&req, 0, sizeof(req)); - req.imr_multiaddr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)); - req.imr_interface.s_addr = INADDR_ANY; - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req))) - return -1; + memset(&req, 0, sizeof(req)); + req.imr_multiaddr.s_addr = + htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)); + req.imr_interface.s_addr = INADDR_ANY; + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req))) + return -1; - return 0; + return 0; } #if 0 @@ -274,67 +270,58 @@ mdns_socket_setup_ipv6(int sock) { } #endif -static void -mdns_socket_close(int sock) { +static void mdns_socket_close(int sock) { #ifdef _WIN32 - closesocket(sock); + closesocket(sock); #else - close(sock); + close(sock); #endif } -static int -mdns_is_string_ref(uint8_t val) { - return (0xC0 == (val & 0xC0)); -} +static int mdns_is_string_ref(uint8_t val) { return (0xC0 == (val & 0xC0)); } -static mdns_string_pair_t -mdns_get_next_substring(const void* rawdata, size_t size, size_t offset) { - const uint8_t* buffer = rawdata; - mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0}; - if (!buffer[offset]) { - pair.offset = offset; - return pair; - } - if (mdns_is_string_ref(buffer[offset])) { - if (size < offset + 2) - return pair; +static mdns_string_pair_t mdns_get_next_substring(const void* rawdata, + size_t size, size_t offset) { + const uint8_t* buffer = rawdata; + mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0}; + if (!buffer[offset]) { + pair.offset = offset; + return pair; + } + if (mdns_is_string_ref(buffer[offset])) { + if (size < offset + 2) return pair; - offset = (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]); - if (offset >= size) - return pair; + offset = + (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]); + if (offset >= size) return pair; - pair.ref = 1; - } + pair.ref = 1; + } - size_t length = (size_t)buffer[offset++]; - if (size < offset + length) - return pair; + size_t length = (size_t)buffer[offset++]; + if (size < offset + length) return pair; - pair.offset = offset; - pair.length = length; + pair.offset = offset; + pair.length = length; - return pair; + return pair; } -static int -mdns_string_skip(const void* buffer, size_t size, size_t* offset) { - size_t cur = *offset; - mdns_string_pair_t substr; - do { - substr = mdns_get_next_substring(buffer, size, cur); - if (substr.offset == MDNS_INVALID_POS) - return 0; - if (substr.ref) { - *offset = cur + 2; - return 1; - } - cur = substr.offset + substr.length; - } - while (substr.length); - - *offset = cur + 1; - return 1; +static int mdns_string_skip(const void* buffer, size_t size, size_t* offset) { + size_t cur = *offset; + mdns_string_pair_t substr; + do { + substr = mdns_get_next_substring(buffer, size, cur); + if (substr.offset == MDNS_INVALID_POS) return 0; + if (substr.ref) { + *offset = cur + 2; + return 1; + } + cur = substr.offset + substr.length; + } while (substr.length); + + *offset = cur + 1; + return 1; } #if 0 @@ -378,142 +365,133 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, } #endif -static mdns_string_t -mdns_string_extract(const void* buffer, size_t size, size_t* offset, - char* str, size_t capacity) { - size_t cur = *offset; - size_t end = MDNS_INVALID_POS; - mdns_string_pair_t substr; - mdns_string_t result = {str, 0}; - char* dst = str; - size_t remain = capacity; - do { - substr = mdns_get_next_substring(buffer, size, cur); - if (substr.offset == MDNS_INVALID_POS) - return result; - if (substr.ref && (end == MDNS_INVALID_POS)) - end = cur + 2; - if (substr.length) { - size_t to_copy = (substr.length < remain) ? substr.length : remain; - memcpy(dst, (const char*)buffer + substr.offset, to_copy); - dst += to_copy; - remain -= to_copy; - if (remain) { - *dst++ = '.'; - --remain; - } - } - cur = substr.offset + substr.length; - } - while (substr.length); - - if (end == MDNS_INVALID_POS) - end = cur + 1; - *offset = end; - - result.length = capacity - remain; - return result; +static mdns_string_t mdns_string_extract(const void* buffer, size_t size, + size_t* offset, char* str, + size_t capacity) { + size_t cur = *offset; + size_t end = MDNS_INVALID_POS; + mdns_string_pair_t substr; + mdns_string_t result = {str, 0}; + char* dst = str; + size_t remain = capacity; + do { + substr = mdns_get_next_substring(buffer, size, cur); + if (substr.offset == MDNS_INVALID_POS) return result; + if (substr.ref && (end == MDNS_INVALID_POS)) end = cur + 2; + if (substr.length) { + size_t to_copy = (substr.length < remain) ? substr.length : remain; + memcpy(dst, (const char*)buffer + substr.offset, to_copy); + dst += to_copy; + remain -= to_copy; + if (remain) { + *dst++ = '.'; + --remain; + } + } + cur = substr.offset + substr.length; + } while (substr.length); + + if (end == MDNS_INVALID_POS) end = cur + 1; + *offset = end; + + result.length = capacity - remain; + return result; } -static size_t -mdns_string_find(const char* str, size_t length, char c, size_t offset) { - const void* found; - if (offset >= length) - return MDNS_INVALID_POS; - found = memchr(str + offset, c, length - offset); - if (found) - return (size_t)((const char*)found - str); - return MDNS_INVALID_POS; +static size_t mdns_string_find(const char* str, size_t length, char c, + size_t offset) { + const void* found; + if (offset >= length) return MDNS_INVALID_POS; + found = memchr(str + offset, c, length - offset); + if (found) return (size_t)((const char*)found - str); + return MDNS_INVALID_POS; } -static void* -mdns_string_make(void* data, size_t capacity, const char* name, size_t length) { - size_t pos = 0; - size_t last_pos = 0; - size_t remain = capacity; - unsigned char* dest = data; - while ((last_pos < length) && ((pos = mdns_string_find(name, length, '.', last_pos)) != MDNS_INVALID_POS)) { - size_t sublength = pos - last_pos; - if (sublength < remain) { - *dest = (unsigned char)sublength; - memcpy(dest + 1, name + last_pos, sublength); - dest += sublength + 1; - remain -= sublength + 1; - } - else { - return 0; - } - last_pos = pos + 1; - } - if (last_pos < length) { - size_t sublength = length - last_pos; - if (sublength < capacity) { - *dest = (unsigned char)sublength; - memcpy(dest + 1, name + last_pos, sublength); - dest += sublength + 1; - remain -= sublength + 1; - } - else { - return 0; - } - } - if (!remain) - return 0; - *dest++ = 0; - return dest; +static void* mdns_string_make(void* data, size_t capacity, const char* name, + size_t length) { + size_t pos = 0; + size_t last_pos = 0; + size_t remain = capacity; + unsigned char* dest = data; + while ((last_pos < length) && + ((pos = mdns_string_find(name, length, '.', last_pos)) != + MDNS_INVALID_POS)) { + size_t sublength = pos - last_pos; + if (sublength < remain) { + *dest = (unsigned char)sublength; + memcpy(dest + 1, name + last_pos, sublength); + dest += sublength + 1; + remain -= sublength + 1; + } else { + return 0; + } + last_pos = pos + 1; + } + if (last_pos < length) { + size_t sublength = length - last_pos; + if (sublength < capacity) { + *dest = (unsigned char)sublength; + memcpy(dest + 1, name + last_pos, sublength); + dest += sublength + 1; + remain -= sublength + 1; + } else { + return 0; + } + } + if (!remain) return 0; + *dest++ = 0; + return dest; } -static size_t -mdns_records_parse(const struct sockaddr* from, const void* buffer, size_t size, size_t* offset, - mdns_entry_type_t type, size_t records, mdns_record_callback_fn callback, - void* user_data) { - size_t parsed = 0; - int do_callback = 1; - for (size_t i = 0; i < records; ++i) { - mdns_string_skip(buffer, size, offset); - const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset)); - - uint16_t rtype = ntohs(*data++); - uint16_t rclass = ntohs(*data++); - uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data); data += 2; - uint16_t length = ntohs(*data++); - - *offset += 10; - - if (do_callback) { - ++parsed; - if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset, length, - user_data)) - do_callback = 0; - } - - *offset += length; - } - return parsed; +static size_t mdns_records_parse(const struct sockaddr* from, + const void* buffer, size_t size, + size_t* offset, mdns_entry_type_t type, + size_t records, + mdns_record_callback_fn callback, + void* user_data) { + size_t parsed = 0; + int do_callback = 1; + for (size_t i = 0; i < records; ++i) { + mdns_string_skip(buffer, size, offset); + const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset)); + + uint16_t rtype = ntohs(*data++); + uint16_t rclass = ntohs(*data++); + uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data); + data += 2; + uint16_t length = ntohs(*data++); + + *offset += 10; + + if (do_callback) { + ++parsed; + if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset, + length, user_data)) + do_callback = 0; + } + + *offset += length; + } + return parsed; } static const uint8_t mdns_services_query[] = { - // Transaction ID - 0x00, 0x00, - // Flags - 0x00, 0x00, - // 1 question - 0x00, 0x01, - // No answer, authority or additional RRs - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - // _services._dns-sd._udp.local. - 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', - 0x07, '_', 'd', 'n', 's', '-', 's', 'd', - 0x04, '_', 'u', 'd', 'p', - 0x05, 'l', 'o', 'c', 'a', 'l', - 0x00, - // PTR record - 0x00, MDNS_RECORDTYPE_PTR, - // QU (unicast response) and class IN - 0x80, MDNS_CLASS_IN -}; + // Transaction ID + 0x00, 0x00, + // Flags + 0x00, 0x00, + // 1 question + 0x00, 0x01, + // No answer, authority or additional RRs + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // _services._dns-sd._udp.local. + 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', 0x07, '_', 'd', 'n', 's', + '-', 's', 'd', 0x04, '_', 'u', 'd', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + // PTR record + 0x00, MDNS_RECORDTYPE_PTR, + // QU (unicast response) and class IN + 0x80, MDNS_CLASS_IN}; #if 0 static int @@ -645,233 +623,223 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity, static uint16_t mdns_transaction_id = 0; -static int -mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, - void* buffer, size_t capacity) { - if (capacity < (17 + length)) - return -1; - - uint16_t* data = buffer; - //Transaction ID - *data++ = htons(++mdns_transaction_id); - //Flags - *data++ = 0; - //Questions - *data++ = htons(1); - //No answer, authority or additional RRs - *data++ = 0; - *data++ = 0; - *data++ = 0; - //Name string - data = mdns_string_make(data, capacity - 17, name, length); - if (!data) - return -1; - //Record type - *data++ = htons(type); - //! Unicast response, class IN - *data++ = htons(0x8000U | MDNS_CLASS_IN); - - struct sockaddr_storage addr_storage; - struct sockaddr_in addr; - struct sockaddr_in6 addr6; - struct sockaddr* saddr = (struct sockaddr*)&addr_storage; - socklen_t saddrlen = sizeof(struct sockaddr_storage); - if (getsockname(sock, saddr, &saddrlen)) - return -1; - if (saddr->sa_family == AF_INET6) { - memset(&addr6, 0, sizeof(struct sockaddr_in6)); - addr6.sin6_family = AF_INET6; +static int mdns_query_send(int sock, mdns_record_type_t type, const char* name, + size_t length, void* buffer, size_t capacity) { + if (capacity < (17 + length)) return -1; + + uint16_t* data = buffer; + // Transaction ID + *data++ = htons(++mdns_transaction_id); + // Flags + *data++ = 0; + // Questions + *data++ = htons(1); + // No answer, authority or additional RRs + *data++ = 0; + *data++ = 0; + *data++ = 0; + // Name string + data = mdns_string_make(data, capacity - 17, name, length); + if (!data) return -1; + // Record type + *data++ = htons(type); + //! Unicast response, class IN + *data++ = htons(0x8000U | MDNS_CLASS_IN); + + struct sockaddr_storage addr_storage; + struct sockaddr_in addr; + struct sockaddr_in6 addr6; + struct sockaddr* saddr = (struct sockaddr*)&addr_storage; + socklen_t saddrlen = sizeof(struct sockaddr_storage); + if (getsockname(sock, saddr, &saddrlen)) return -1; + if (saddr->sa_family == AF_INET6) { + memset(&addr6, 0, sizeof(struct sockaddr_in6)); + addr6.sin6_family = AF_INET6; #ifdef __APPLE__ - addr6.sin6_len = sizeof(struct sockaddr_in6); + addr6.sin6_len = sizeof(struct sockaddr_in6); #endif - addr6.sin6_addr.s6_addr[0] = 0xFF; - addr6.sin6_addr.s6_addr[1] = 0x02; - addr6.sin6_addr.s6_addr[15] = 0xFB; - addr6.sin6_port = htons((unsigned short)5353); - saddr = (struct sockaddr*)&addr6; - saddrlen = sizeof(struct sockaddr_in6); - } - else { - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; + addr6.sin6_addr.s6_addr[0] = 0xFF; + addr6.sin6_addr.s6_addr[1] = 0x02; + addr6.sin6_addr.s6_addr[15] = 0xFB; + addr6.sin6_port = htons((unsigned short)5353); + saddr = (struct sockaddr*)&addr6; + saddrlen = sizeof(struct sockaddr_in6); + } else { + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; #ifdef __APPLE__ - addr.sin_len = sizeof(struct sockaddr_in); + addr.sin_len = sizeof(struct sockaddr_in); #endif - addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)); - addr.sin_port = htons((unsigned short)5353); - saddr = (struct sockaddr*)&addr; - saddrlen = sizeof(struct sockaddr_in); - } - - if (sendto(sock, buffer, (char*)data - (char*)buffer, 0, - saddr, saddrlen) < 0) - return -1; - return 0; + addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)); + addr.sin_port = htons((unsigned short)5353); + saddr = (struct sockaddr*)&addr; + saddrlen = sizeof(struct sockaddr_in); + } + + if (sendto(sock, buffer, (char*)data - (char*)buffer, 0, saddr, saddrlen) < 0) + return -1; + return 0; } -static size_t -mdns_query_recv(int sock, void* buffer, size_t capacity, - mdns_record_callback_fn callback, void* user_data, - uint8_t one_shot) { - struct sockaddr_in6 addr; - struct sockaddr* saddr = (struct sockaddr*)&addr; - memset(&addr, 0, sizeof(addr)); - saddr->sa_family = AF_INET; +static size_t mdns_query_recv(int sock, void* buffer, size_t capacity, + mdns_record_callback_fn callback, void* user_data, + uint8_t one_shot) { + struct sockaddr_in6 addr; + struct sockaddr* saddr = (struct sockaddr*)&addr; + memset(&addr, 0, sizeof(addr)); + saddr->sa_family = AF_INET; #ifdef __APPLE__ - saddr->sa_len = sizeof(addr); + saddr->sa_len = sizeof(addr); #endif - socklen_t addrlen = sizeof(addr); - int ret = recvfrom(sock, buffer, capacity, 0, - saddr, &addrlen); - if (ret <= 0) - return 0; - - size_t data_size = (size_t)ret; - uint16_t* data = (uint16_t*)buffer; - - uint16_t transaction_id = ntohs(*data++); - ++data;// uint16_t flags = ntohs(*data++); - uint16_t questions = ntohs(*data++); - uint16_t answer_rrs = ntohs(*data++); - uint16_t authority_rrs = ntohs(*data++); - uint16_t additional_rrs = ntohs(*data++); - - if (one_shot && transaction_id != mdns_transaction_id)// || (flags != 0x8400)) - return 0; //Not a reply to our last question - - if (questions > 1) - return 0; - - //Skip questions part - int i; - for (i = 0; i < questions; ++i) { - size_t ofs = (size_t)((char*)data - (char*)buffer); - if (!mdns_string_skip(buffer, data_size, &ofs)) - return 0; - data = (void*)((char*)buffer + ofs); - ++data; - ++data; - } - - size_t records = 0; - size_t offset = (size_t)((char*)data - (char*)buffer); - records += mdns_records_parse(saddr, buffer, data_size, &offset, - MDNS_ENTRYTYPE_ANSWER, answer_rrs, - callback, user_data); - records += mdns_records_parse(saddr, buffer, data_size, &offset, - MDNS_ENTRYTYPE_AUTHORITY, authority_rrs, - callback, user_data); - records += mdns_records_parse(saddr, buffer, data_size, &offset, - MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs, - callback, user_data); - return records; + socklen_t addrlen = sizeof(addr); + int ret = recvfrom(sock, buffer, capacity, 0, saddr, &addrlen); + if (ret <= 0) return 0; + + size_t data_size = (size_t)ret; + uint16_t* data = (uint16_t*)buffer; + + uint16_t transaction_id = ntohs(*data++); + ++data; // uint16_t flags = ntohs(*data++); + uint16_t questions = ntohs(*data++); + uint16_t answer_rrs = ntohs(*data++); + uint16_t authority_rrs = ntohs(*data++); + uint16_t additional_rrs = ntohs(*data++); + + if (one_shot && + transaction_id != mdns_transaction_id) // || (flags != 0x8400)) + return 0; // Not a reply to our last question + + if (questions > 1) return 0; + + // Skip questions part + int i; + for (i = 0; i < questions; ++i) { + size_t ofs = (size_t)((char*)data - (char*)buffer); + if (!mdns_string_skip(buffer, data_size, &ofs)) return 0; + data = (void*)((char*)buffer + ofs); + ++data; + ++data; + } + + size_t records = 0; + size_t offset = (size_t)((char*)data - (char*)buffer); + records += mdns_records_parse(saddr, buffer, data_size, &offset, + MDNS_ENTRYTYPE_ANSWER, answer_rrs, callback, + user_data); + records += mdns_records_parse(saddr, buffer, data_size, &offset, + MDNS_ENTRYTYPE_AUTHORITY, authority_rrs, + callback, user_data); + records += mdns_records_parse(saddr, buffer, data_size, &offset, + MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs, + callback, user_data); + return records; } -static mdns_string_t -mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length, - char* strbuffer, size_t capacity) { - //PTR record is just a string - if ((size >= offset + length) && (length >= 2)) - return mdns_string_extract(buffer, size, &offset, strbuffer, capacity); - mdns_string_t empty = {0, 0}; - return empty; +static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size, + size_t offset, size_t length, + char* strbuffer, size_t capacity) { + // PTR record is just a string + if ((size >= offset + length) && (length >= 2)) + return mdns_string_extract(buffer, size, &offset, strbuffer, capacity); + mdns_string_t empty = {0, 0}; + return empty; } -static mdns_record_srv_t -mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length, - char* strbuffer, size_t capacity) { - mdns_record_srv_t srv; - memset(&srv, 0, sizeof(mdns_record_srv_t)); - // Read the priority, weight, port number and the discovery name - // SRV record format (http://www.ietf.org/rfc/rfc2782.txt): - // 2 bytes network-order unsigned priority - // 2 bytes network-order unsigned weight - // 2 bytes network-order unsigned port - // string: discovery (domain) name, minimum 2 bytes when compressed - if ((size >= offset + length) && (length >= 8)) { - const uint16_t* recorddata = (const uint16_t*)((const char*)buffer + offset); - srv.priority = ntohs(*recorddata++); - srv.weight = ntohs(*recorddata++); - srv.port = ntohs(*recorddata++); - offset += 6; - srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity); - } - return srv; +static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size, + size_t offset, size_t length, + char* strbuffer, + size_t capacity) { + mdns_record_srv_t srv; + memset(&srv, 0, sizeof(mdns_record_srv_t)); + // Read the priority, weight, port number and the discovery name + // SRV record format (http://www.ietf.org/rfc/rfc2782.txt): + // 2 bytes network-order unsigned priority + // 2 bytes network-order unsigned weight + // 2 bytes network-order unsigned port + // string: discovery (domain) name, minimum 2 bytes when compressed + if ((size >= offset + length) && (length >= 8)) { + const uint16_t* recorddata = + (const uint16_t*)((const char*)buffer + offset); + srv.priority = ntohs(*recorddata++); + srv.weight = ntohs(*recorddata++); + srv.port = ntohs(*recorddata++); + offset += 6; + srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity); + } + return srv; } -static struct sockaddr_in* -mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length, - struct sockaddr_in* addr) { - memset(addr, 0, sizeof(struct sockaddr_in)); - addr->sin_family = AF_INET; +static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size, + size_t offset, size_t length, + struct sockaddr_in* addr) { + memset(addr, 0, sizeof(struct sockaddr_in)); + addr->sin_family = AF_INET; #ifdef __APPLE__ - addr->sin_len = sizeof(struct sockaddr_in); + addr->sin_len = sizeof(struct sockaddr_in); #endif - if ((size >= offset + length) && (length == 4)) - addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset); - return addr; + if ((size >= offset + length) && (length == 4)) + addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset); + return addr; } -static struct sockaddr_in6* -mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length, - struct sockaddr_in6* addr) { - memset(addr, 0, sizeof(struct sockaddr_in6)); - addr->sin6_family = AF_INET6; +static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer, + size_t size, size_t offset, + size_t length, + struct sockaddr_in6* addr) { + memset(addr, 0, sizeof(struct sockaddr_in6)); + addr->sin6_family = AF_INET6; #ifdef __APPLE__ - addr->sin6_len = sizeof(struct sockaddr_in6); + addr->sin6_len = sizeof(struct sockaddr_in6); #endif - if ((size >= offset + length) && (length == 16)) - addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset); - return addr; + if ((size >= offset + length) && (length == 16)) + addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset); + return addr; } -static size_t -mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length, - mdns_record_txt_t* records, size_t capacity) { - size_t parsed = 0; - const char* strdata; - size_t separator, sublength; - size_t end = offset + length; - - if (size < end) - end = size; - - while ((offset < end) && (parsed < capacity)) { - strdata = (const char*)buffer + offset; - sublength = *(const unsigned char*)strdata; - - ++strdata; - offset += sublength + 1; - - separator = 0; - for (size_t c = 0; c < sublength; ++c) { - //DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E] - if ((strdata[c] < 0x20) || (strdata[c] > 0x7E)) - break; - if (strdata[c] == '=') { - separator = c; - break; - } - } - - if (!separator) - continue; - - if (separator < sublength) { - records[parsed].key.str = strdata; - records[parsed].key.length = separator; - records[parsed].value.str = strdata + separator + 1; - records[parsed].value.length = sublength - (separator + 1); - } - else { - records[parsed].key.str = strdata; - records[parsed].key.length = sublength; - } - - ++parsed; - } - - return parsed; +static size_t mdns_record_parse_txt(const void* buffer, size_t size, + size_t offset, size_t length, + mdns_record_txt_t* records, + size_t capacity) { + size_t parsed = 0; + const char* strdata; + size_t separator, sublength; + size_t end = offset + length; + + if (size < end) end = size; + + while ((offset < end) && (parsed < capacity)) { + strdata = (const char*)buffer + offset; + sublength = *(const unsigned char*)strdata; + + ++strdata; + offset += sublength + 1; + + separator = 0; + for (size_t c = 0; c < sublength; ++c) { + // DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E] + if ((strdata[c] < 0x20) || (strdata[c] > 0x7E)) break; + if (strdata[c] == '=') { + separator = c; + break; + } + } + + if (!separator) continue; + + if (separator < sublength) { + records[parsed].key.str = strdata; + records[parsed].key.length = separator; + records[parsed].value.str = strdata + separator + 1; + records[parsed].value.length = sublength - (separator + 1); + } else { + records[parsed].key.str = strdata; + records[parsed].key.length = sublength; + } + + ++parsed; + } + + return parsed; } #ifdef _WIN32 diff --git a/ctrl/facemgr/src/interfaces/dummy/CMakeLists.txt b/ctrl/facemgr/src/interfaces/dummy/CMakeLists.txt index 05276bc5a..c68c39273 100644 --- a/ctrl/facemgr/src/interfaces/dummy/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/dummy/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/dummy/dummy.c b/ctrl/facemgr/src/interfaces/dummy/dummy.c index 69c336e57..df63eef17 100644 --- a/ctrl/facemgr/src/interfaces/dummy/dummy.c +++ b/ctrl/facemgr/src/interfaces/dummy/dummy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -19,7 +19,7 @@ */ #include <stdlib.h> -#include <unistd.h> // close +#include <unistd.h> // close #include <hicn/facemgr.h> @@ -36,34 +36,32 @@ * Internal data */ typedef struct { - /* The configuration data will likely be allocated on the stack (or should - * be freed) by the caller, we recommend to make a copy of this data. - * This copy can further be altered with default values. - */ - dummy_cfg_t cfg; + /* The configuration data will likely be allocated on the stack (or should + * be freed) by the caller, we recommend to make a copy of this data. + * This copy can further be altered with default values. + */ + dummy_cfg_t cfg; - /* ... */ + /* ... */ - int fd; /* Sample internal data: file descriptor */ + int fd; /* Sample internal data: file descriptor */ } dummy_data_t; -int dummy_initialize(interface_t * interface, void * cfg) -{ - dummy_data_t * data = malloc(sizeof(dummy_data_t)); - if (!data) - goto ERR_MALLOC; - interface->data = data; - - /* Use default values for unspecified configuration parameters */ - if (cfg) { - data->cfg = *(dummy_cfg_t *)cfg; - } else { - memset(&data->cfg, 0, sizeof(data->cfg)); - } +int dummy_initialize(interface_t *interface, void *cfg) { + dummy_data_t *data = malloc(sizeof(dummy_data_t)); + if (!data) goto ERR_MALLOC; + interface->data = data; + + /* Use default values for unspecified configuration parameters */ + if (cfg) { + data->cfg = *(dummy_cfg_t *)cfg; + } else { + memset(&data->cfg, 0, sizeof(data->cfg)); + } - /* ... */ + /* ... */ - data->fd = 0; + data->fd = 0; #if 0 if (interface_register_fd(interface, data->fd, NULL) < 0) { ERROR("[dummy_initialize] Error registering fd"); @@ -71,49 +69,45 @@ int dummy_initialize(interface_t * interface, void * cfg) } #endif - /* ... */ + /* ... */ - /* - * We should return a negative value in case of error, and a positive value - * otherwise: - * - a file descriptor (>0) will be added to the event loop; or - * - 0 if we don't use any file descriptor - */ - return 0; + /* + * We should return a negative value in case of error, and a positive value + * otherwise: + * - a file descriptor (>0) will be added to the event loop; or + * - 0 if we don't use any file descriptor + */ + return 0; ERR_FD: ERR_MALLOC: - return -1; + return -1; } -int dummy_finalize(interface_t * interface) -{ - dummy_data_t * data = (dummy_data_t*)interface->data; +int dummy_finalize(interface_t *interface) { + dummy_data_t *data = (dummy_data_t *)interface->data; - if (data->fd > 0) - close(data->fd); + if (data->fd > 0) close(data->fd); - return 0; + return 0; } -int dummy_callback(interface_t * interface) -{ - dummy_data_t * data = (dummy_data_t*)interface->data; - UNUSED(data); +int dummy_callback(interface_t *interface) { + dummy_data_t *data = (dummy_data_t *)interface->data; + UNUSED(data); - /* ... */ + /* ... */ - return 0; + return 0; } -int dummy_on_event(interface_t * interface, facelet_t * facelet) -{ - dummy_data_t * data = (dummy_data_t*)interface->data; - UNUSED(data); +int dummy_on_event(interface_t *interface, facelet_t *facelet) { + dummy_data_t *data = (dummy_data_t *)interface->data; + UNUSED(data); - /* ... */ + /* ... */ - return 0; + return 0; } interface_ops_t dummy_ops = { diff --git a/ctrl/facemgr/src/interfaces/dummy/dummy.h b/ctrl/facemgr/src/interfaces/dummy/dummy.h index 22fe5d1a6..f930ead58 100644 --- a/ctrl/facemgr/src/interfaces/dummy/dummy.h +++ b/ctrl/facemgr/src/interfaces/dummy/dummy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -28,7 +28,7 @@ * Configuration data */ typedef struct { - /* ... */ + /* ... */ } dummy_cfg_t; #endif /* FACEMGR_INTERFACE_DUMMY_H */ diff --git a/ctrl/facemgr/src/interfaces/hicn_light/CMakeLists.txt b/ctrl/facemgr/src/interfaces/hicn_light/CMakeLists.txt index ef839a69c..a0fb3e351 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/hicn_light/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021-2022 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -11,20 +11,23 @@ # See the License for the specific language governing permissions and # limitations under the License. + +############################################################## +# Sources +############################################################## list(APPEND HEADER_FILES ) list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light.c + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light.c ) list(APPEND LIBRARIES - ${HICNCTRL_LIBRARIES} + ${LIBHICNCTRL_LIBRARIES} ) - list(APPEND INCLUDE_DIRS - ${HICNCTRL_INCLUDE_DIR} + ${LIBHICNCTRL_INCLUDE_DIR} ) set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c index b6e0e605a..b396782f5 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c +++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -19,8 +19,8 @@ */ #include <assert.h> #include <stdbool.h> -#include <stdio.h> // snprintf -#include <time.h> // time +#include <stdio.h> // snprintf +#include <time.h> // time #include <hicn/ctrl.h> #include <hicn/facemgr.h> @@ -38,578 +38,636 @@ #define WITH_POLL typedef enum { - HL_STATE_UNDEFINED, - HL_STATE_IDLE, - HL_STATE_ROUTES_SENT, - HL_STATE_ROUTES_RECEIVED, - HL_STATE_FACES_SENT, - HL_STATE_FACES_RECEIVED, - HL_STATE_N + HL_STATE_UNDEFINED, + HL_STATE_IDLE, + HL_STATE_ROUTES_SENT, + HL_STATE_ROUTES_RECEIVED, + HL_STATE_FACES_SENT, + HL_STATE_FACES_RECEIVED, + HL_STATE_N } hl_state_t; typedef struct { - hc_sock_t * s; /* NULL means no active socket */ - hl_state_t state; + hc_sock_t *s; /* NULL means no active socket */ - /* Timer used for forwarder reconnection */ - int reconnect_timer_fd; /* 0 means no active timer */ + /* Socket for polling, dependent on s */ + hc_sock_t *sp; /* NULL means no active socket */ - /* Timer used to periodically poll the forwarder face and routing tables */ - int poll_timer_fd; - hc_data_t * polled_routes; -} hl_data_t; + hl_state_t state; + + /* Timer used for forwarder reconnection */ + int reconnect_timer_fd; /* 0 means no active timer */ -/* Forward declarations */ -int hl_timeout(interface_t * interface, int fd, void * unused); + /* Timer used to periodically poll the forwarder face and routing tables */ + int poll_timer_fd; + hc_data_t *polled_routes; +} hl_data_t; #ifdef WITH_POLL -int hl_process_state(interface_t * interface, int fd, void * unused) +int hl_process_state(interface_t *interface, int fd, void *unused); #else -int hl_process_state(interface_t * interface) +int hl_process_state(interface_t *interface); #endif -{ - hl_data_t * data = (hl_data_t *)interface->data; - - /* - * Every tick we need to probe the forwarder for the list of faces and - * associated routes. - * - * This is used to guess manually added faces and routes - * - * TODO ensure we are idle at tick time - */ - - switch(data->state) - { - case HL_STATE_IDLE: - assert(!data->polled_routes); - - //DEBUG("[hl_process_state] Querying route list"); - if (hc_route_list_async(data->s) < 0) { - DEBUG("[hl_process_state] Error querying route list"); - return -1; - } - data->state = HL_STATE_ROUTES_SENT; - break; +void start_poll_timer(interface_t *interface) { + hl_data_t *data = (hl_data_t *)interface->data; - case HL_STATE_ROUTES_RECEIVED: - //DEBUG("[hl_process_state] Querying face list"); - if (hc_face_list_async(data->s) < 0) { - DEBUG("[hl_process_state] Error querying face list"); - return -1; - } - data->state = HL_STATE_FACES_SENT; - break; - - case HL_STATE_FACES_RECEIVED: - data->state = HL_STATE_IDLE; - break; - - case HL_STATE_ROUTES_SENT: - case HL_STATE_FACES_SENT: - INFO("[hl_process_state] Out of sync... resetting state"); - if (data->polled_routes) { - hc_data_free(data->polled_routes); - data->polled_routes = NULL; - } - data->state = HL_STATE_IDLE; - break; + data->poll_timer_fd = interface_register_timer(interface, INTERVAL_MS, + hl_process_state, interface); + if (data->poll_timer_fd < 0) { + ERROR("[start_poll_timer) Could not start polling timer"); + } +} - case HL_STATE_UNDEFINED: - case HL_STATE_N: - ERROR("[hl_process_state] Unexpected state"); - return -1; - } +void stop_poll_timer(interface_t *interface) { + hl_data_t *data = (hl_data_t *)interface->data; - return 0; + if (data->poll_timer_fd > 0) + if (interface_unregister_timer(interface, data->poll_timer_fd) < 0) { + ERROR("[stop_poll_timer] Could not stop polling timer"); + } } - -int -hl_after_connect(interface_t * interface) +#ifdef WITH_POLL +int hl_process_state(interface_t *interface, int fd, void *unused) +#else +int hl_process_state(interface_t *interface) +#endif { - hl_data_t * data = interface->data; + hl_data_t *data = (hl_data_t *)interface->data; + + /* + * Every tick we need to probe the forwarder for the list of faces and + * associated routes. + * + * This is used to guess manually added faces and routes + * + * TODO ensure we are idle at tick time + */ + + switch (data->state) { + case HL_STATE_IDLE: + assert(!data->polled_routes); + stop_poll_timer(interface); + + // DEBUG("[hl_process_state] Querying route list"); + if (hc_route_list_async(data->sp) < 0) { + DEBUG("[hl_process_state] Error querying route list"); + return -1; + } + data->state = HL_STATE_ROUTES_SENT; + break; + + case HL_STATE_ROUTES_RECEIVED: + // DEBUG("[hl_process_state] Querying face list"); + if (hc_face_list_async(data->sp) < 0) { + DEBUG("[hl_process_state] Error querying face list"); + return -1; + } + data->state = HL_STATE_FACES_SENT; + break; + + case HL_STATE_FACES_RECEIVED: + data->state = HL_STATE_IDLE; + start_poll_timer(interface); + break; + + case HL_STATE_ROUTES_SENT: + case HL_STATE_FACES_SENT: + WARN("[hl_process_state] Out of sync... resetting state"); + if (data->polled_routes) { + hc_data_free(data->polled_routes); + data->polled_routes = NULL; + } + data->state = HL_STATE_IDLE; + start_poll_timer(interface); + break; + + case HL_STATE_UNDEFINED: + case HL_STATE_N: + ERROR("[hl_process_state] Unexpected state"); + return -1; + } + + return 0; +} - /* File descriptor for control socket operations */ - if (interface_register_fd(interface, hc_sock_get_fd(data->s), NULL) < 0) { - ERROR("[hc_connect] Error registering fd"); - goto ERR_FD; - } +/* + * Called whenever a connection to both sockets succeeds. + * Polling will be useful to detect when connection to the forwarder is lost, + * and will allow to try reconnect both sockets (the control socket being UDP / + * in blocking mode will not detect such loss of connection). Operations on the + * control socket that will fail will be reattempted by higher layers. + */ +int hl_after_connect(interface_t *interface) { + hl_data_t *data = interface->data; - /* We always restart from the idle phase */ - data->state = HL_STATE_IDLE; + /* File descriptor for polling socket operations */ + if (interface_register_fd(interface, hc_sock_get_fd(data->sp), NULL) < 0) { + ERROR("[hc_connect] Error registering fd"); + goto ERR_FD; + } + /* We always restart from the idle phase */ + data->state = HL_STATE_IDLE; /* poll will replace the original get, ideally we would get notifications */ #ifdef WITH_POLL - data->poll_timer_fd = interface_register_timer(interface, INTERVAL_MS, - hl_process_state, interface); - if (data->poll_timer_fd < 0) { - ERROR("[hc_connect] Could not initialize polling timer"); - return -1; - } + start_poll_timer(interface); #else - hl_process_state(interface); + hl_process_state(interface); #endif - return 0; + return 0; - //interface_unregister_fd(interface, hc_sock_get_fd(data->s)); + // interface_unregister_fd(interface, hc_sock_get_fd(data->sp)); ERR_FD: - return -1; + return -1; } -int _hl_connect(interface_t * interface); +int _hl_connect(interface_t *interface); -int -hl_connect_timeout(interface_t * interface, int fd, void * unused) -{ - hl_data_t * data = interface->data; - assert(fd == data->reconnect_timer_fd); - _unused(data); +int hl_connect_timeout(interface_t *interface, int fd, void *unused) { + hl_data_t *data = interface->data; + assert(fd == data->reconnect_timer_fd); + _unused(data); - int rc = _hl_connect(interface); - if (rc < 0) { - DEBUG("[hl_initialize] Error during connection reattempt; next attempt in %ds", INTERVAL_MS / 1000); - return -1; - } + int rc = _hl_connect(interface); + if (rc < 0) { + DEBUG( + "[hl_initialize] Error during connection reattempt; next attempt in " + "%ds", + INTERVAL_MS / 1000); + return -1; + } - if (interface_unregister_timer(interface, fd) < 0) { - ERROR("[hl_connect_timeout] Could not cancel timer after successful connect"); - } + if (interface_unregister_timer(interface, fd) < 0) { + ERROR( + "[hl_connect_timeout] Could not cancel timer after successful connect"); + } - /* Connect success */ - return hl_after_connect(interface); + /* Connect success */ + return hl_after_connect(interface); } - -int -_hl_connect(interface_t * interface) -{ - hl_data_t * data = interface->data; - assert(!data->s); - - data->s = hc_sock_create(); - if (data->s <= 0) { - ERROR("[hc_connect] Could not create control socket"); - goto ERR_SOCK; - } - - if (hc_sock_connect(data->s) < 0) { - DEBUG("[hc_connect] Could not connect control socket"); - goto ERR_CONNECT; - } - - return 0; - +/* + * Connection without reattempt. Both control and polling sockets should be + * connected to succeed. + */ +int _hl_connect(interface_t *interface) { + hl_data_t *data = interface->data; + assert(!data->s); + assert(!data->sp); + + data->s = hc_sock_create(); + if (data->s <= 0) { + ERROR("[hc_connect] Could not create control socket"); + goto ERR_SOCK; + } + + if (hc_sock_connect(data->s) < 0) { + DEBUG("[hc_connect] Could not connect control socket"); + goto ERR_CONNECT; + } + + data->sp = hc_sock_create(); + if (data->sp <= 0) { + ERROR("[hc_connect] Could not create polling socket"); + goto ERR_SOCK_POLL; + } + + if (hc_sock_connect(data->sp) < 0) { + DEBUG("[hc_connect] Could not connect polling socket"); + goto ERR_CONNECT_POLL; + } + + return 0; + +ERR_CONNECT_POLL: + hc_sock_free(data->sp); + data->sp = NULL; +ERR_SOCK_POLL: ERR_CONNECT: - hc_sock_free(data->s); - data->s = NULL; + hc_sock_free(data->s); + data->s = NULL; ERR_SOCK: - return -1; - + return -1; } -int hl_disconnect(interface_t * interface) -{ - hl_data_t * data = (hl_data_t *) interface->data; - if (data->reconnect_timer_fd > 0) - interface_unregister_timer(interface, data->reconnect_timer_fd); +int hl_disconnect(interface_t *interface) { + hl_data_t *data = (hl_data_t *)interface->data; + if (data->reconnect_timer_fd > 0) + interface_unregister_timer(interface, data->reconnect_timer_fd); - if (data->poll_timer_fd > 0) - interface_unregister_timer(interface, data->poll_timer_fd); + stop_poll_timer(interface); - if (data->polled_routes) - hc_data_free(data->polled_routes); + if (data->polled_routes) hc_data_free(data->polled_routes); - if (data->s) { - interface_unregister_fd(interface, hc_sock_get_fd(data->s)); - hc_sock_free(data->s); - } + if (data->s) { + hc_sock_free(data->s); + data->s = NULL; + } - return 0; + if (data->sp) { + interface_unregister_fd(interface, hc_sock_get_fd(data->sp)); + hc_sock_free(data->sp); + data->sp = NULL; + } + + return 0; } -int -hl_connect(interface_t * interface) -{ - hl_data_t * data = interface->data; +/* Connection with reattempts */ +int hl_connect(interface_t *interface) { + hl_data_t *data = interface->data; - if (_hl_connect(interface) >= 0) - return hl_after_connect(interface); + if (_hl_connect(interface) >= 0) return hl_after_connect(interface); - /* Timer for managing the connection to the forwarder */ - DEBUG("Connection to forwarder failed... next retry in %ds", INTERVAL_MS / 1000); - data->reconnect_timer_fd = interface_register_timer(interface, INTERVAL_MS, hl_connect_timeout, NULL); - if (data->reconnect_timer_fd < 0) { - ERROR("[hc_connect] Could not initialize reattempt timer"); - return -1; - } + /* Timer for managing the connection to the forwarder */ + DEBUG("Connection to forwarder failed... next retry in %ds", + INTERVAL_MS / 1000); + data->reconnect_timer_fd = interface_register_timer(interface, INTERVAL_MS, + hl_connect_timeout, NULL); + if (data->reconnect_timer_fd < 0) { + ERROR("[hc_connect] Could not initialize reattempt timer"); + return -1; + } - return 0; + return 0; } -int -hl_initialize(interface_t * interface, void * cfg) -{ - hl_data_t * data = malloc(sizeof(hl_data_t)); - if (!data) { - ERROR("[hicn_light] Out of memory!"); - goto ERR_MALLOC; - } - - data->s = NULL; - data->reconnect_timer_fd = 0; - data->poll_timer_fd = 0; +int hl_initialize(interface_t *interface, void *cfg) { + hl_data_t *data = malloc(sizeof(hl_data_t)); + if (!data) { + ERROR("[hicn_light] Out of memory!"); + goto ERR_MALLOC; + } - interface->data = data; + data->s = NULL; + data->sp = NULL; + data->reconnect_timer_fd = 0; + data->poll_timer_fd = 0; + data->polled_routes = NULL; + data->state = HL_STATE_UNDEFINED; - if (hl_connect(interface) < 0) { - ERROR("[hl_initialize] Error during connection to forwarder"); - goto ERR_CONNECT; - } + interface->data = data; - data->polled_routes = NULL; + /* Connect both control and polling sockets */ + if (hl_connect(interface) < 0) { + ERROR("[hl_initialize] Error during connection to forwarder"); + goto ERR_CONNECT; + } - return 0; + return 0; ERR_CONNECT: - free(data); + free(data); ERR_MALLOC: - return -1; + return -1; } -int hl_finalize(interface_t * interface) -{ - hl_data_t * data = (hl_data_t *) interface->data; +int hl_finalize(interface_t *interface) { + hl_data_t *data = (hl_data_t *)interface->data; - hl_disconnect(interface); + hl_disconnect(interface); - if (data->polled_routes) - hc_data_free(data->polled_routes); + if (data->polled_routes) hc_data_free(data->polled_routes); - free(data); + free(data); - return 0; + return 0; } -int hl_on_event(interface_t * interface, facelet_t * facelet) -{ - hc_face_t hc_face; - hc_route_t route; - int rc; - int ret = 0; - hl_data_t * data = (hl_data_t *)interface->data; - face_t * face = NULL; - - hc_face.id = 0; - memset(hc_face.name, 0, sizeof(hc_face.name)); - - - /* NOTE - * - One example where this fails (and it is normal) is when we delete a - * face that was not completely created, because for instance bonjour did - * not give any data - */ - if (facelet_get_face(facelet, &face) < 0) { - ERROR("Could not retrieve face from facelet"); - ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; - goto ERR_FACE; +int hl_on_event(interface_t *interface, facelet_t *facelet) { + hc_face_t hc_face; + hc_route_t route; + int rc; + int ret = 0; + hl_data_t *data = (hl_data_t *)interface->data; + face_t *face = NULL; + + hc_face.id = 0; + memset(hc_face.name, 0, sizeof(hc_face.name)); + + /* NOTE + * - One example where this fails (and it is normal) is when we delete a + * face that was not completely created, because for instance bonjour did + * not give any data + */ + if (facelet_get_face(facelet, &face) < 0) { + ERROR("Could not retrieve face from facelet"); + ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; + goto ERR_FACE; + } + + if (!data->s) { + /* We are not connected to the forwarder */ + ret = -FACELET_ERROR_REASON_FORWARDER_OFFLINE; + goto ERR; + } + + switch (facelet_get_event(facelet)) { + case FACELET_EVENT_CREATE: { + /* Create face */ + char buf[MAXSZ_FACELET]; + facelet_snprintf(buf, MAXSZ_FACELET, facelet); + DEBUG("Create facelet %s", buf); + + hc_face.face = *face; + rc = hc_face_create(data->s, &hc_face); + if (rc < 0) { + ERROR("Failed to create face\n"); + ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; + goto ERR; + } + INFO("Created face id=%d - %s", hc_face.id, buf); } - if (!data->s) { - /* We are not connected to the forwarder */ - ret = -FACELET_ERROR_REASON_FORWARDER_OFFLINE; + hicn_route_t **route_array; + int n = facelet_get_route_array(facelet, &route_array); + if (n < 0) { + ERROR("Failed to create default hICN/IPv4 route"); + ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; goto ERR; - } + } + if (n == 0) { + /* Adding default routes */ + route = (hc_route_t){ + .face_id = hc_face.id, + .family = AF_INET, + .remote_addr = IPV4_ANY, + .len = 0, + .cost = DEFAULT_ROUTE_COST, + + }; + if (hc_route_create(data->s, &route) < 0) { + ERROR("Failed to create default hICN/IPv4 route"); + ret = -1; + } - switch(facelet_get_event(facelet)) { - - case FACELET_EVENT_CREATE: - { - /* Create face */ - char buf[MAXSZ_FACELET]; - facelet_snprintf(buf, MAXSZ_FACELET, facelet); - DEBUG("Create facelet %s", buf); - - hc_face.face = *face; - rc = hc_face_create(data->s, &hc_face); - if (rc < 0) { - ERROR("Failed to create face\n"); - ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; - goto ERR; - } - INFO("Created face id=%d - %s", hc_face.id, buf); - } + route = (hc_route_t){ + .face_id = hc_face.id, + .family = AF_INET6, + .remote_addr = IPV6_ANY, + .len = 0, + .cost = DEFAULT_ROUTE_COST, + }; + if (hc_route_create(data->s, &route) < 0) { + ERROR("Failed to create default hICN/IPv6 route"); + ret = -1; + } - hicn_route_t ** route_array; - int n = facelet_get_route_array(facelet, &route_array); - if (n < 0) { - ERROR("Failed to create default hICN/IPv4 route"); - ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; - goto ERR; - } - if (n == 0) { - /* Adding default routes */ - route = (hc_route_t) { - .face_id = hc_face.id, - .family = AF_INET, - .remote_addr = IPV4_ANY, - .len = 0, - .cost = DEFAULT_ROUTE_COST, - - }; - if (hc_route_create(data->s, &route) < 0) { - ERROR("Failed to create default hICN/IPv4 route"); - ret = -1; - } - - route = (hc_route_t) { - .face_id = hc_face.id, - .family = AF_INET6, - .remote_addr = IPV6_ANY, - .len = 0, - .cost = DEFAULT_ROUTE_COST, - }; - if (hc_route_create(data->s, &route) < 0) { - ERROR("Failed to create default hICN/IPv6 route"); - ret = -1; - } - - INFO("Successfully created default route(s)."); - } else { - for (unsigned i = 0; i < n; i++) { - hicn_route_t * hicn_route = route_array[i]; - ip_prefix_t prefix; - int cost; - if (hicn_route_get_prefix(hicn_route, &prefix) < 0) { - ERROR("Failed to get route prefix"); - ret = -1; - continue; - } - if (hicn_route_get_cost(hicn_route, &cost) < 0) { - ERROR("Failed to get route cost"); - ret = -1; - continue; - } - route = (hc_route_t) { - .face_id = hc_face.id, - .family = prefix.family, - .remote_addr = prefix.address, - .len = prefix.len, - .cost = cost, - }; - if (hc_route_create(data->s, &route) < 0) { - ERROR("Failed to create static route route"); - ret = -1; - continue; - } - } - } - free(route_array); - - break; - - case FACELET_EVENT_DELETE: - /* Removing a face should also remove associated routes */ - hc_face.face = *face; - rc = hc_face_delete(data->s, &hc_face); - if (rc < 0) { - ERROR("Failed to delete face\n"); - ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; - goto ERR; - } + INFO("Successfully created default route(s)."); + } else { + for (unsigned i = 0; i < n; i++) { + hicn_route_t *hicn_route = route_array[i]; + ip_prefix_t prefix; + int cost; + if (hicn_route_get_prefix(hicn_route, &prefix) < 0) { + ERROR("Failed to get route prefix"); + ret = -1; + continue; + } + if (hicn_route_get_cost(hicn_route, &cost) < 0) { + ERROR("Failed to get route cost"); + ret = -1; + continue; + } + route = (hc_route_t){ + .face_id = hc_face.id, + .name = "", /* take face_id into account */ + .family = prefix.family, + .remote_addr = prefix.address, + .len = prefix.len, + .cost = cost, + }; + if (hc_route_create(data->s, &route) < 0) { + ERROR("Failed to create static route route"); + ret = -1; + continue; + } + } + } + free(route_array); + + break; + + case FACELET_EVENT_DELETE: + /* Removing a face should also remove associated routes */ + hc_face.face = *face; + rc = hc_face_delete(data->s, &hc_face, 1); + if (rc < 0) { + ERROR("Failed to delete face\n"); + ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; + goto ERR; + } + + char buf[MAXSZ_FACELET]; + facelet_snprintf(buf, MAXSZ_FACELET, facelet); + INFO("Deleted face id=%d", hc_face.id); + + break; + + case FACELET_EVENT_UPDATE: + /* Currently, only admin_state & priority are supported */ + if (facelet_get_admin_state_status(facelet) == + FACELET_ATTR_STATUS_DIRTY) { + hc_face.face = *face; + hc_face_t *face_found; + + rc = hc_face_get(data->s, &hc_face, &face_found); + if (rc < 0) { + ERROR("Failed to find face\n"); + ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; + goto ERR; + } + if (!face_found) { + ERROR("Face to update has not been found"); + ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; + goto ERR; + } + char conn_id_or_name[SYMBOLIC_NAME_LEN]; + snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); + free(face_found); + + face_state_t admin_state; + if (facelet_get_admin_state(facelet, &admin_state) < 0) { + ERROR("Failed to retrieve facelet admin state"); + ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; + goto ERR; + } - char buf[MAXSZ_FACELET]; - facelet_snprintf(buf, MAXSZ_FACELET, facelet); - INFO("Deleted face id=%d", hc_face.id); - - break; - - case FACELET_EVENT_UPDATE: - /* Currently, only admin_state & priority are supported */ - if (facelet_get_admin_state_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { - hc_face.face = *face; - hc_face_t * face_found; - - rc = hc_face_get(data->s, &hc_face, &face_found); - if (rc < 0) { - ERROR("Failed to find face\n"); - ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; - goto ERR; - } - if (!face_found) { - ERROR("Face to update has not been found"); - ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; - goto ERR; - } - char conn_id_or_name[SYMBOLIC_NAME_LEN]; - snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); - free(face_found); - - face_state_t admin_state; - if (facelet_get_admin_state(facelet, &admin_state) < 0) { - ERROR("Failed to retrieve facelet admin state"); - ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; - goto ERR; - } - - if (hc_connection_set_admin_state(data->s, conn_id_or_name, admin_state) < 0) { - ERROR("Failed to update admin state"); - ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; - goto ERR; - } - facelet_set_admin_state_status(facelet, FACELET_ATTR_STATUS_CLEAN); - INFO("Updated face id=%d - admin_state=%s", hc_face.id, - face_state_str[admin_state]); - } + if (hc_connection_set_admin_state(data->s, conn_id_or_name, + admin_state) < 0) { + ERROR("Failed to update admin state"); + ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; + goto ERR; + } + facelet_set_admin_state_status(facelet, FACELET_ATTR_STATUS_CLEAN); + INFO("Updated face id=%d - admin_state=%s", hc_face.id, + face_state_str(admin_state)); + } #ifdef WITH_POLICY - if (facelet_get_netdevice_type_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { - hc_face.face = *face; - hc_face_t * face_found; - - rc = hc_face_get(data->s, &hc_face, &face_found); - if (rc < 0) { - ERROR("Failed to find face\n"); - goto ERR; - } - if (!face_found) { - ERROR("Face to update has not been found"); - goto ERR; - } - char conn_id_or_name[SYMBOLIC_NAME_LEN]; - snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); - free(face_found); - - netdevice_type_t netdevice_type; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - ERROR("Failed to retrieve facelet netdevice_type"); - goto ERR; - } - - /* Encode netdevice type into tags */ - policy_tags_t tags = POLICY_TAGS_EMPTY; - if (facelet_has_netdevice_type(facelet)) { - netdevice_type_t netdevice_type; - if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { - ERROR("error getting netdevice_type"); - goto ERR; - } - - - switch(netdevice_type) { - case NETDEVICE_TYPE_UNDEFINED: - case NETDEVICE_TYPE_LOOPBACK: - break; - case NETDEVICE_TYPE_WIRED: - policy_tags_add(&tags, POLICY_TAG_WIRED); - break; - case NETDEVICE_TYPE_WIFI: - policy_tags_add(&tags, POLICY_TAG_WIFI); - break; - case NETDEVICE_TYPE_CELLULAR: - policy_tags_add(&tags, POLICY_TAG_CELLULAR); - break; - default: - goto ERR; - } - } - //face->tags = tags; - - if (hc_connection_set_tags(data->s, conn_id_or_name, tags) < 0) { - ERROR("Failed to update tags"); - goto ERR; - } - facelet_set_netdevice_type_status(facelet, FACELET_ATTR_STATUS_CLEAN); - INFO("Updated face id=%d - netdevice_type=%s", hc_face.id, - netdevice_type_str[netdevice_type]); - } - if (facelet_get_priority_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { - INFO("Updating priority..."); - hc_face.face = *face; - hc_face_t * face_found; - - rc = hc_face_get(data->s, &hc_face, &face_found); - if (rc < 0) { - ERROR("Failed to find face\n"); - goto ERR; - } - if (!face_found) { - ERROR("Face to update has not been found"); - goto ERR; - } - char conn_id_or_name[SYMBOLIC_NAME_LEN]; - snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); - free(face_found); - - uint32_t priority; - if (facelet_get_priority(facelet, &priority) < 0) { - ERROR("Failed to retrieve facelet priority"); - goto ERR; - } - - INFO("Changing connection %s priority to %d", conn_id_or_name, priority); - if (hc_connection_set_priority(data->s, conn_id_or_name, priority) < 0) { - ERROR("Failed to update priority"); - goto ERR; - } - facelet_set_priority_status(facelet, FACELET_ATTR_STATUS_CLEAN); - - INFO("Updated face id=%d - priority=%d", hc_face.id, priority); - } -#endif /* WITH_POLICY */ - break; + if (facelet_get_netdevice_type_status(facelet) == + FACELET_ATTR_STATUS_DIRTY) { + hc_face.face = *face; + hc_face_t *face_found; + + rc = hc_face_get(data->s, &hc_face, &face_found); + if (rc < 0) { + ERROR("Failed to find face\n"); + goto ERR; + } + if (!face_found) { + ERROR("Face to update has not been found"); + goto ERR; + } + char conn_id_or_name[SYMBOLIC_NAME_LEN]; + snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); + free(face_found); + + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR("Failed to retrieve facelet netdevice_type"); + goto ERR; + } - default: - ERROR("Unknown event %s\n", facelet_event_str[facelet_get_event(facelet)]); - /* Unsupported events */ - ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; + /* Encode netdevice type into tags */ + policy_tags_t tags = POLICY_TAGS_EMPTY; + if (facelet_has_netdevice_type(facelet)) { + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR("error getting netdevice_type"); goto ERR; - } + } + + switch (netdevice_type) { + case NETDEVICE_TYPE_UNDEFINED: + case NETDEVICE_TYPE_LOOPBACK: + break; + case NETDEVICE_TYPE_WIRED: + policy_tags_add(&tags, POLICY_TAG_WIRED); + break; + case NETDEVICE_TYPE_WIFI: + policy_tags_add(&tags, POLICY_TAG_WIFI); + break; + case NETDEVICE_TYPE_CELLULAR: + policy_tags_add(&tags, POLICY_TAG_CELLULAR); + break; + default: + goto ERR; + } + } + // face->tags = tags; + + if (hc_connection_set_tags(data->s, conn_id_or_name, tags) < 0) { + ERROR("Failed to update tags"); + goto ERR; + } + facelet_set_netdevice_type_status(facelet, FACELET_ATTR_STATUS_CLEAN); + INFO("Updated face id=%d - netdevice_type=%s", hc_face.id, + netdevice_type_str(netdevice_type)); + } + if (facelet_get_priority_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { + INFO("Updating priority..."); + hc_face.face = *face; + hc_face_t *face_found; + + rc = hc_face_get(data->s, &hc_face, &face_found); + if (rc < 0) { + ERROR("Failed to find face\n"); + goto ERR; + } + if (!face_found) { + ERROR("Face to update has not been found"); + goto ERR; + } + char conn_id_or_name[SYMBOLIC_NAME_LEN]; + snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); + free(face_found); + + uint32_t priority; + if (facelet_get_priority(facelet, &priority) < 0) { + ERROR("Failed to retrieve facelet priority"); + goto ERR; + } + + INFO("Changing connection %s priority to %d", conn_id_or_name, + priority); + if (hc_connection_set_priority(data->s, conn_id_or_name, priority) < + 0) { + ERROR("Failed to update priority"); + goto ERR; + } + facelet_set_priority_status(facelet, FACELET_ATTR_STATUS_CLEAN); + + INFO("Updated face id=%d - priority=%d", hc_face.id, priority); + } +#endif /* WITH_POLICY */ + break; + + default: + ERROR("Unknown event %s\n", + facelet_event_str[facelet_get_event(facelet)]); + /* Unsupported events */ + ret = -FACELET_ERROR_REASON_INTERNAL_ERROR; + goto ERR; + } ERR: - face_free(face); + face_free(face); ERR_FACE: - return ret; + return ret; } -int hl_callback(interface_t * interface, int fd, void * unused) -{ - hl_data_t * data = (hl_data_t*)interface->data; - hc_data_t * results; - int ret = 0; - - /* In case of error, reconnect to forwarder */ - if (hc_sock_callback(data->s, &results) < 0) { - DEBUG("Closing socket... reconnecting..."); - if (interface_unregister_fd(interface, hc_sock_get_fd(data->s)) < 0) { - ERROR("[hl_callback] Error unregistering fd"); - } - - /* Stopping poll timer */ - if (interface_unregister_timer(interface, data->poll_timer_fd) < 0) { - ERROR("[hl_callback] Could not cancel polling timer after forwarder disconnect"); - } - if (data->polled_routes) - hc_data_free(data->polled_routes); +/* + * This should only receive data from the polling socket which is asynchronous, + * while all face creation, etc. operations are done synchronously in this + * version. + */ +int hl_callback(interface_t *interface, int fd, void *unused) { + hl_data_t *data = (hl_data_t *)interface->data; + hc_data_t *results; + int ret = 0; + + /* Workaround: sometimes this is called with data = NULL */ + if (!data) { + INFO("[hl_callback] no data"); + return 0; + } - hc_sock_free(data->s); - data->s = NULL; - hl_connect(interface); - return ret; + /* In case of error, reconnect to forwarder */ + if (hc_sock_callback(data->sp, &results) < 0) { + INFO("Closing socket... reconnecting..."); + if (interface_unregister_fd(interface, hc_sock_get_fd(data->sp)) < 0) { + ERROR("[hl_callback] Error unregistering fd"); } - /* Shall we wait for more data ? */ - if (!results->complete) - return ret; + /* Stopping poll timer */ + stop_poll_timer(interface); + if (data->polled_routes) hc_data_free(data->polled_routes); - /* Process returned data */ - switch(data->state) { + hc_sock_free(data->s); + data->s = NULL; + hc_sock_free(data->sp); + data->sp = NULL; - case HL_STATE_ROUTES_SENT: - //DEBUG("[hl_callback] Processing routes"); - data->polled_routes = results; + hl_connect(interface); + return ret; + } + + /* Shall we wait for more data ? */ + if (!results->complete) { + INFO("[hl_callback] results incomplete"); + return ret; + } + + /* Process returned data */ + // DEBUG("Processing data"); + switch (data->state) { + case HL_STATE_ROUTES_SENT: + // DEBUG("[hl_callback] Processing routes"); + data->polled_routes = results; #if 0 foreach_route(r, results) { @@ -622,19 +680,17 @@ int hl_callback(interface_t * interface, int fd, void * unused) DEBUG("Route: %s", buf); } #endif - data->state = HL_STATE_ROUTES_RECEIVED; - if (hl_process_state(interface, fd, unused) < 0) { - ERROR("[hl_callback] Error processing state after routes received"); - ret = -1; - } - break; - - - case HL_STATE_FACES_SENT: - //DEBUG("[hl_callback] Processing faces"); - assert(data->polled_routes); - foreach_face(f, results) { - + data->state = HL_STATE_ROUTES_RECEIVED; + if (hl_process_state(interface, fd, unused) < 0) { + ERROR("[hl_callback] Error processing state after routes received"); + ret = -1; + } + break; + + case HL_STATE_FACES_SENT: + // DEBUG("[hl_callback] Processing faces"); + assert(data->polled_routes); + foreach_face(f, results) { #if 0 char buf[MAXSZ_FACE]; int rc = hc_face_snprintf(buf, MAXSZ_FACE, f); @@ -646,17 +702,16 @@ int hl_callback(interface_t * interface, int fd, void * unused) DEBUG("Face: %s", buf); #endif - /* We can ignore faces on localhost */ + /* We can ignore faces on localhost */ - facelet_t * facelet = facelet_create_from_face(&f->face); - if (!facelet) { - ERROR("[hl_callback] Could not create facelet... skipping"); - continue; - } + facelet_t *facelet = facelet_create_from_face(&f->face); + if (!facelet) { + ERROR("[hl_callback] Could not create facelet... skipping"); + continue; + } - foreach_route(r, data->polled_routes) { - if (r->face_id != f->id) - continue; + foreach_route(r, data->polled_routes) { + if (r->face_id != f->id) continue; #if 0 char route_s[MAXSZ_HC_ROUTE]; @@ -668,41 +723,40 @@ int hl_callback(interface_t * interface, int fd, void * unused) DEBUG("Associated route: %s", route_s); #endif - if (r->len == 0) - continue; - - ip_prefix_t prefix = { - .family = r->family, - .address = r->remote_addr, - .len = r->len, - }; - hicn_route_t * route = hicn_route_create(&prefix, r->face_id, r->cost); - facelet_add_route(facelet, route); - } + if (r->len == 0) continue; - facelet_set_event(facelet, FACELET_EVENT_GET); - interface_raise_event(interface, facelet); - } - hc_data_free(results); - hc_data_free(data->polled_routes); - data->polled_routes = NULL; - data->state = HL_STATE_FACES_RECEIVED; - if (hl_process_state(interface, fd, unused) < 0) { - ERROR("[hl_callback] Error processing state after faces received"); - ret = -1; - } - break; - - case HL_STATE_IDLE: - case HL_STATE_FACES_RECEIVED: - case HL_STATE_ROUTES_RECEIVED: - case HL_STATE_UNDEFINED: - case HL_STATE_N: - ERROR("[hl_callback] Unexpected state"); - ret = -1; - } + ip_prefix_t prefix = { + .family = r->family, + .address = r->remote_addr, + .len = r->len, + }; + hicn_route_t *route = hicn_route_create(&prefix, r->face_id, r->cost); + facelet_add_route(facelet, route); + } - return ret; + facelet_set_event(facelet, FACELET_EVENT_GET); + interface_raise_event(interface, facelet); + } + hc_data_free(results); + hc_data_free(data->polled_routes); + data->polled_routes = NULL; + data->state = HL_STATE_FACES_RECEIVED; + if (hl_process_state(interface, fd, unused) < 0) { + ERROR("[hl_callback] Error processing state after faces received"); + ret = -1; + } + break; + + case HL_STATE_IDLE: + case HL_STATE_FACES_RECEIVED: + case HL_STATE_ROUTES_RECEIVED: + case HL_STATE_UNDEFINED: + case HL_STATE_N: + ERROR("[hl_callback] Unexpected state"); + ret = -1; + } + + return ret; } const interface_ops_t hicn_light_ops = { diff --git a/ctrl/facemgr/src/interfaces/netlink/CMakeLists.txt b/ctrl/facemgr/src/interfaces/netlink/CMakeLists.txt index 7f44d87fe..5d46cb8b6 100644 --- a/ctrl/facemgr/src/interfaces/netlink/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/netlink/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/netlink/netlink.c b/ctrl/facemgr/src/interfaces/netlink/netlink.c index a1affd719..11738d7ac 100644 --- a/ctrl/facemgr/src/interfaces/netlink/netlink.c +++ b/ctrl/facemgr/src/interfaces/netlink/netlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,9 +20,9 @@ #include <assert.h> #include <linux/rtnetlink.h> -#include <net/if_arp.h> // ARPHRD_LOOPBACK -#include <sys/types.h> // getpid -#include <unistd.h> // getpid +#include <net/if_arp.h> // ARPHRD_LOOPBACK +#include <sys/types.h> // getpid +#include <unistd.h> // getpid #include <hicn/facemgr.h> #include <hicn/util/ip_address.h> @@ -32,202 +32,188 @@ #include "../../interface.h" typedef enum { - NL_STATE_UNDEFINED, - NL_STATE_LINK_SENT, - NL_STATE_ADDR_SENT, - NL_STATE_DONE, + NL_STATE_UNDEFINED, + NL_STATE_LINK_SENT, + NL_STATE_ADDR_SENT, + NL_STATE_DONE, } nl_state_t; /* Internal data storage */ typedef struct { - int fd; - nl_state_t state; + int fd; + nl_state_t state; } nl_data_t; -static inline void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len, - unsigned short flags) -{ - unsigned short type; - - memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); - while (RTA_OK(rta, len)) { - type = rta->rta_type & ~flags; - if (type <= max) - tb[type] = rta; - rta = RTA_NEXT(rta, len); - } +static inline void parse_rtattr(struct rtattr *tb[], int max, + struct rtattr *rta, int len, + unsigned short flags) { + unsigned short type; + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) { + type = rta->rta_type & ~flags; + if (type <= max) tb[type] = rta; + rta = RTA_NEXT(rta, len); + } } -int nl_process_state(interface_t * interface) -{ - nl_data_t * data = (nl_data_t*)interface->data; - int rc; - - switch(data->state) { - case NL_STATE_UNDEFINED: - { - DEBUG("[nl_process_state] UNDEFINED->LINK_SENT"); - struct { - struct nlmsghdr header; - struct rtgenmsg payload; - } msg2 = { - .header = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, - .nlmsg_type = RTM_GETLINK, - .nlmsg_pid = getpid(), - .nlmsg_seq = 3, - }, +int nl_process_state(interface_t *interface) { + nl_data_t *data = (nl_data_t *)interface->data; + int rc; + + switch (data->state) { + case NL_STATE_UNDEFINED: { + DEBUG("[nl_process_state] UNDEFINED->LINK_SENT"); + struct { + struct nlmsghdr header; + struct rtgenmsg payload; + } msg2 = {.header = + { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, + .nlmsg_type = RTM_GETLINK, + .nlmsg_pid = getpid(), + .nlmsg_seq = 3, + }, .payload = { .rtgen_family = AF_PACKET, - } - }; - - rc = send(data->fd, &msg2, msg2.header.nlmsg_len, 0); - if (rc < 0) - printf("E: Error sending netlink query\n"); + }}; - data->state = NL_STATE_LINK_SENT; - break; - } - - case NL_STATE_LINK_SENT: - { - DEBUG("[nl_process_state] LINK_SENT->ADDR_SENT"); - /* Issue a first query to receive static state */ - struct { - struct nlmsghdr header; - struct ifaddrmsg payload; - } msg = { - .header = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, - .nlmsg_type = RTM_GETADDR, - .nlmsg_pid = getpid(), - .nlmsg_seq = 7, - }, - .payload = { - .ifa_family = AF_INET, - } - }; + rc = send(data->fd, &msg2, msg2.header.nlmsg_len, 0); + if (rc < 0) printf("E: Error sending netlink query\n"); - rc = send(data->fd, &msg, msg.header.nlmsg_len, 0); - if (rc < 0) - printf("E: Error sending netlink query\n"); - - data->state = NL_STATE_ADDR_SENT; - break; - } + data->state = NL_STATE_LINK_SENT; + break; + } - case NL_STATE_ADDR_SENT: - { - DEBUG("[nl_process_state] ADDR_SENT->DONE"); - data->state = NL_STATE_DONE; - break; - } + case NL_STATE_LINK_SENT: { + DEBUG("[nl_process_state] LINK_SENT->ADDR_SENT"); + /* Issue a first query to receive static state */ + struct { + struct nlmsghdr header; + struct ifaddrmsg payload; + } msg = {.header = + { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP, + .nlmsg_type = RTM_GETADDR, + .nlmsg_pid = getpid(), + .nlmsg_seq = 7, + }, + .payload = { + .ifa_family = AF_INET, + }}; + + rc = send(data->fd, &msg, msg.header.nlmsg_len, 0); + if (rc < 0) printf("E: Error sending netlink query\n"); + + data->state = NL_STATE_ADDR_SENT; + break; + } - default: /* NL_STATE_DONE never called */ - break; + case NL_STATE_ADDR_SENT: { + DEBUG("[nl_process_state] ADDR_SENT->DONE"); + data->state = NL_STATE_DONE; + break; } - return 0; + default: /* NL_STATE_DONE never called */ + break; + } + + return 0; } -int nl_initialize(interface_t * interface, void * cfg) -{ - nl_data_t * data = malloc(sizeof(nl_data_t)); - if (!data) - goto ERR_MALLOC; +int nl_initialize(interface_t *interface, void *cfg) { + nl_data_t *data = malloc(sizeof(nl_data_t)); + if (!data) goto ERR_MALLOC; - data->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (data->fd < 0) { - ERROR("[nl_initialize] Failed to create netlink socket: %s", (char*)strerror(errno)); - goto ERR_SOCKET; - } + data->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (data->fd < 0) { + ERROR("[nl_initialize] Failed to create netlink socket: %s", + (char *)strerror(errno)); + goto ERR_SOCKET; + } - data->state = NL_STATE_UNDEFINED; + data->state = NL_STATE_UNDEFINED; - struct sockaddr_nl local; // local addr struct - memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; // set protocol family - // NOTE: RTNLGRP_LINK replaces obsolete RTMGRP_LINK, etc - local.nl_groups = 0 - | RTMGRP_LINK - | RTMGRP_IPV4_IFADDR - | RTMGRP_IPV6_IFADDR + struct sockaddr_nl local; // local addr struct + memset(&local, 0, sizeof(local)); + local.nl_family = AF_NETLINK; // set protocol family + // NOTE: RTNLGRP_LINK replaces obsolete RTMGRP_LINK, etc + local.nl_groups = 0 | RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR #if 0 | RTMGRP_IPV4_ROUTE; | RTMGRP_IPV6_ROUTE; #endif - ; - local.nl_pid = getpid(); // set out id using current process id + ; + local.nl_pid = getpid(); // set out id using current process id - if (bind(data->fd, (struct sockaddr*)&local, sizeof(local)) < 0) { // bind socket - ERROR("[nl_initialize] Failed to bind netlink socket: %s", (char*)strerror(errno)); - goto ERR_BIND; - } + if (bind(data->fd, (struct sockaddr *)&local, sizeof(local)) < + 0) { // bind socket + ERROR("[nl_initialize] Failed to bind netlink socket: %s", + (char *)strerror(errno)); + goto ERR_BIND; + } - interface->data = data; + interface->data = data; - if (interface_register_fd(interface, data->fd, NULL) < 0) { - ERROR("[nl_initialize] Error registering fd"); - goto ERR_FD; - } + if (interface_register_fd(interface, data->fd, NULL) < 0) { + ERROR("[nl_initialize] Error registering fd"); + goto ERR_FD; + } #if 1 - nl_process_state(interface); + nl_process_state(interface); #endif - return 0; + return 0; ERR_FD: ERR_BIND: - close(data->fd); + close(data->fd); ERR_SOCKET: - free(data); + free(data); ERR_MALLOC: - return -1; + return -1; } -int parse_link(struct nlmsghdr * h, facelet_t ** facelet, - char * interface_name, size_t interface_name_size, - bool * up, bool * running) -{ - struct ifinfomsg *ifi; // structure for network interface info - struct rtattr *tb[IFLA_MAX + 1]; +int parse_link(struct nlmsghdr *h, facelet_t **facelet, char *interface_name, + size_t interface_name_size, bool *up, bool *running) { + struct ifinfomsg *ifi; // structure for network interface info + struct rtattr *tb[IFLA_MAX + 1]; - assert(facelet); + assert(facelet); - ifi = (struct ifinfomsg*) NLMSG_DATA(h); // get information about changed network interface - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(h), 1<<15); + ifi = (struct ifinfomsg *)NLMSG_DATA( + h); // get information about changed network interface + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(h), 1 << 15); - if (interface_name) { - assert(tb[IFLA_IFNAME]); - snprintf(interface_name, interface_name_size, "%s", (char*)RTA_DATA(tb[IFLA_IFNAME])); - } + if (interface_name) { + assert(tb[IFLA_IFNAME]); + snprintf(interface_name, interface_name_size, "%s", + (char *)RTA_DATA(tb[IFLA_IFNAME])); + } - if (up) - *up = ifi->ifi_flags & IFF_UP; - if (running) - *running = ifi->ifi_flags & IFF_RUNNING; + if (up) *up = ifi->ifi_flags & IFF_UP; + if (running) *running = ifi->ifi_flags & IFF_RUNNING; + netdevice_t *netdevice = netdevice_create_from_name(interface_name); + if (!netdevice) { + ERROR("[netlink.parse_link] error creating netdevice '%s'", interface_name); + goto ERR_ND; + } - netdevice_t * netdevice = netdevice_create_from_name(interface_name); - if (!netdevice) { - ERROR("[netlink.parse_link] error creating netdevice '%s'", interface_name); - goto ERR_ND; - } + *facelet = facelet_create(); + if (!*facelet) { + ERROR("[netlink.parse_link] error creating facelet"); + goto ERR_FACELET; + } - *facelet = facelet_create(); - if (!*facelet) { - ERROR("[netlink.parse_link] error creating facelet"); - goto ERR_FACELET; - } - - if (facelet_set_netdevice(*facelet, *netdevice) < 0) { - ERROR("[netlink.parse_link] error setting netdevice"); - goto ERR; - } + if (facelet_set_netdevice(*facelet, *netdevice) < 0) { + ERROR("[netlink.parse_link] error setting netdevice"); + goto ERR; + } // FIXME Tags #if 0 @@ -252,160 +238,162 @@ int parse_link(struct nlmsghdr * h, facelet_t ** facelet, #endif - // TODO - // - ifi_change - // - IFLA_PROTINFO + // TODO + // - ifi_change + // - IFLA_PROTINFO - netdevice_free(netdevice); - return 0; + netdevice_free(netdevice); + return 0; ERR: - facelet_free(*facelet); - *facelet = NULL; + facelet_free(*facelet); + *facelet = NULL; ERR_FACELET: - netdevice_free(netdevice); + netdevice_free(netdevice); ERR_ND: - return -1; + return -1; } -int parse_addr(struct nlmsghdr * h, facelet_t ** facelet, - char * interface_name, size_t interface_name_size, - char * interface_address, size_t interface_address_size) -{ - ip_address_t local_addr = IP_ADDRESS_EMPTY; - struct ifaddrmsg *ifa; // structure for network interface data - struct rtattr *tba[IFA_MAX+1]; - - assert(facelet); - - ifa = (struct ifaddrmsg*)NLMSG_DATA(h); // get data from the network interface - - parse_rtattr(tba, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h), 0); - - /* FIXME - * - * IFA_LOCAL ok for v4, not there for v6 - * - * IFA_ADDRESS seems to work for both but with the following precaution - * - * IFA_ADDRESS is prefix address, rather than local interface address. - * It makes no difference for normally configured broadcast interfaces, - * but for point-to-point IFA_ADDRESS is DESTINATION address, - * local address is supplied in IFA_LOCAL attribute. - */ - if (!tba[IFA_ADDRESS]) { - ERROR("[netlink.parse_addr] No local address"); - return -1; - } - - switch(ifa->ifa_family) { - case AF_INET: - local_addr.v4.as_inaddr = *(struct in_addr*)RTA_DATA(tba[IFA_ADDRESS]); - break; - case AF_INET6: - local_addr.v6.as_in6addr = *(struct in6_addr*)RTA_DATA(tba[IFA_ADDRESS]); - break; - default: - return 0; - } - - /* See comment in parse_link */ - if (interface_address) { - assert(tba[IFA_ADDRESS]); - ip_address_snprintf(interface_address, interface_address_size, &local_addr, ifa->ifa_family); - } - - netdevice_t * netdevice = netdevice_create_from_index(ifa->ifa_index); - if (!netdevice) { - ERROR("[netlink.parse_addr] error creating netdevice from index '%d'", ifa->ifa_index); - goto ERR_ND; - } - - if (interface_name) { - snprintf(interface_name, interface_name_size, "%s", netdevice->name); - } - - *facelet = facelet_create(); - if (!*facelet) { - ERROR("[netlink.parse_addr] error creating facelet"); - goto ERR_FACELET; - } - if (facelet_set_netdevice(*facelet, *netdevice) < 0) { - ERROR("[netlink.parse_addr] error setting netdevice"); - goto ERR; - } - if (facelet_set_family(*facelet, ifa->ifa_family) < 0) { - ERROR("[netlink.parse_addr] error setting family"); - goto ERR; - } - if (facelet_set_local_addr(*facelet, local_addr) < 0) { - ERROR("[netlink.parse_addr] error setting local address"); - goto ERR; - } - - netdevice_free(netdevice); - return 0; +int parse_addr(struct nlmsghdr *h, facelet_t **facelet, char *interface_name, + size_t interface_name_size, char *interface_address, + size_t interface_address_size) { + ip_address_t local_addr = IP_ADDRESS_EMPTY; + struct ifaddrmsg *ifa; // structure for network interface data + struct rtattr *tba[IFA_MAX + 1]; + + assert(facelet); + + ifa = + (struct ifaddrmsg *)NLMSG_DATA(h); // get data from the network interface + + parse_rtattr(tba, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(h), 0); + + /* FIXME + * + * IFA_LOCAL ok for v4, not there for v6 + * + * IFA_ADDRESS seems to work for both but with the following precaution + * + * IFA_ADDRESS is prefix address, rather than local interface address. + * It makes no difference for normally configured broadcast interfaces, + * but for point-to-point IFA_ADDRESS is DESTINATION address, + * local address is supplied in IFA_LOCAL attribute. + */ + if (!tba[IFA_ADDRESS]) { + ERROR("[netlink.parse_addr] No local address"); + return -1; + } + + switch (ifa->ifa_family) { + case AF_INET: + local_addr.v4.as_inaddr = *(struct in_addr *)RTA_DATA(tba[IFA_ADDRESS]); + break; + case AF_INET6: + local_addr.v6.as_in6addr = *(struct in6_addr *)RTA_DATA(tba[IFA_ADDRESS]); + break; + default: + return 0; + } + + /* See comment in parse_link */ + if (interface_address) { + assert(tba[IFA_ADDRESS]); + ip_address_snprintf(interface_address, interface_address_size, &local_addr, + ifa->ifa_family); + } + + netdevice_t *netdevice = netdevice_create_from_index(ifa->ifa_index); + if (!netdevice) { + ERROR("[netlink.parse_addr] error creating netdevice from index '%d'", + ifa->ifa_index); + goto ERR_ND; + } + + if (interface_name) { + snprintf(interface_name, interface_name_size, "%s", netdevice->name); + } + + *facelet = facelet_create(); + if (!*facelet) { + ERROR("[netlink.parse_addr] error creating facelet"); + goto ERR_FACELET; + } + if (facelet_set_netdevice(*facelet, *netdevice) < 0) { + ERROR("[netlink.parse_addr] error setting netdevice"); + goto ERR; + } + if (facelet_set_family(*facelet, ifa->ifa_family) < 0) { + ERROR("[netlink.parse_addr] error setting family"); + goto ERR; + } + if (facelet_set_local_addr(*facelet, local_addr) < 0) { + ERROR("[netlink.parse_addr] error setting local address"); + goto ERR; + } + + netdevice_free(netdevice); + return 0; ERR: - facelet_free(*facelet); - *facelet = NULL; + facelet_free(*facelet); + *facelet = NULL; ERR_FACELET: - netdevice_free(netdevice); + netdevice_free(netdevice); ERR_ND: - return -1; + return -1; } -int nl_callback(interface_t * interface, int fd, void * unused) -{ - nl_data_t * data = (nl_data_t*)interface->data; +int nl_callback(interface_t *interface, int fd, void *unused) { + nl_data_t *data = (nl_data_t *)interface->data; - struct sockaddr_nl local; // local addr struct - memset(&local, 0, sizeof(local)); + struct sockaddr_nl local; // local addr struct + memset(&local, 0, sizeof(local)); - char buf[8192]; // message buffer - struct iovec iov; // message structure - iov.iov_base = buf; // set message buffer as io - iov.iov_len = sizeof(buf); // set size + char buf[8192]; // message buffer + struct iovec iov; // message structure + iov.iov_base = buf; // set message buffer as io + iov.iov_len = sizeof(buf); // set size - // initialize protocol message header - struct msghdr msg = { - .msg_name = &local, // local address - .msg_namelen = sizeof(local), // address size - .msg_iov = &iov, // io vector - .msg_iovlen = 1, // io size - }; + // initialize protocol message header + struct msghdr msg = { + .msg_name = &local, // local address + .msg_namelen = sizeof(local), // address size + .msg_iov = &iov, // io vector + .msg_iovlen = 1, // io size + }; - ssize_t status = recvmsg(data->fd, &msg, 0); + ssize_t status = recvmsg(data->fd, &msg, 0); - // check status - if (status < 0) { -/* - if (errno == EINTR || errno == EAGAIN) - continue; -*/ + // check status + if (status < 0) { + /* + if (errno == EINTR || errno == EAGAIN) + continue; + */ - printf("Failed to read netlink: %s", (char*)strerror(errno)); - return -1; - } + printf("Failed to read netlink: %s", (char *)strerror(errno)); + return -1; + } - if (msg.msg_namelen != sizeof(local)) { // check message length, just in case - printf("Invalid length of the sender address struct\n"); - return -1; - } + if (msg.msg_namelen != sizeof(local)) { // check message length, just in case + printf("Invalid length of the sender address struct\n"); + return -1; + } - // message parser - struct nlmsghdr *h; + // message parser + struct nlmsghdr *h; - for (h = (struct nlmsghdr*)buf; status >= (ssize_t)sizeof(*h); ) { // read all messagess headers - int len = h->nlmsg_len; - int l = len - sizeof(*h); + for (h = (struct nlmsghdr *)buf; + status >= (ssize_t)sizeof(*h);) { // read all messagess headers + int len = h->nlmsg_len; + int l = len - sizeof(*h); - if ((l < 0) || (len > status)) { - printf("Invalid message length: %i\n", len); - continue; - } + if ((l < 0) || (len > status)) { + printf("Invalid message length: %i\n", len); + continue; + } - switch(h->nlmsg_type) { + switch (h->nlmsg_type) { #if 0 case RTM_NEWROUTE: case RTM_DELROUTE: @@ -413,147 +401,123 @@ int nl_callback(interface_t * interface, int fd, void * unused) break; #endif - case RTM_DELADDR: - { - facelet_t * facelet = NULL; - char interface_name[IFNAMSIZ]; - char interface_address[MAXSZ_IP_ADDRESS] = {0}; - - if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, - interface_address, MAXSZ_IP_ADDRESS) < 0) { - ERROR("Error parsing address message"); - break; - } - - DEBUG("[NETLINK] Interface %s: address was removed", interface_name); - if (facelet) { - facelet_set_event(facelet, FACELET_EVENT_SET_DOWN); - facelet_set_attr_clean(facelet); - interface_raise_event(interface, facelet); - } - break; - } - - case RTM_NEWADDR: - { - facelet_t * facelet = NULL; - char interface_name[IFNAMSIZ]; - char interface_address[MAXSZ_IP_ADDRESS] = {0}; - - if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, - interface_address, MAXSZ_IP_ADDRESS) < 0) { - ERROR("Error parsing address message"); - break; - } - - DEBUG("[NETLINK] Interface %s: new address was assigned: %s", interface_name, interface_address); - - if (facelet) { - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - facelet_set_attr_clean(facelet); - interface_raise_event(interface, facelet); - } - break; - } + case RTM_DELADDR: { + facelet_t *facelet = NULL; + char interface_name[IFNAMSIZ]; + char interface_address[MAXSZ_IP_ADDRESS] = {0}; - case RTM_DELLINK: - { - /* This does not always seem to be called, hence we rely on - * down, not running */ - facelet_t * facelet = NULL; - char interface_name[IFNAMSIZ]; - if (parse_link(h, &facelet, interface_name, IFNAMSIZ, - NULL, NULL) < 0) { - ERROR("Error parsing link message"); - break; - } + if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, interface_address, + MAXSZ_IP_ADDRESS) < 0) { + ERROR("Error parsing address message"); + break; + } - DEBUG("[NETLINK] Network interface %s was removed", interface_name); + DEBUG("[NETLINK] Interface %s: address was removed", interface_name); + if (facelet) { + facelet_set_event(facelet, FACELET_EVENT_SET_DOWN); + facelet_set_attr_clean(facelet); + interface_raise_event(interface, facelet); + } + break; + } + + case RTM_NEWADDR: { + facelet_t *facelet = NULL; + char interface_name[IFNAMSIZ]; + char interface_address[MAXSZ_IP_ADDRESS] = {0}; + + if (parse_addr(h, &facelet, interface_name, IFNAMSIZ, interface_address, + MAXSZ_IP_ADDRESS) < 0) { + ERROR("Error parsing address message"); + break; + } - if (!facelet) - break; + DEBUG("[NETLINK] Interface %s: new address was assigned: %s", + interface_name, interface_address); - facelet_set_event(facelet, FACELET_EVENT_DELETE); - facelet_set_attr_clean(facelet); - interface_raise_event(interface, facelet); + if (facelet) { + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + facelet_set_attr_clean(facelet); + interface_raise_event(interface, facelet); + } + break; + } + + case RTM_DELLINK: { + /* This does not always seem to be called, hence we rely on + * down, not running */ + facelet_t *facelet = NULL; + char interface_name[IFNAMSIZ]; + if (parse_link(h, &facelet, interface_name, IFNAMSIZ, NULL, NULL) < 0) { + ERROR("Error parsing link message"); + break; + } - break; - } - - case RTM_NEWLINK: - { - facelet_t * facelet = NULL; - char interface_name[IFNAMSIZ]; - bool up, running; - - if (parse_link(h, &facelet, interface_name, IFNAMSIZ, &up, &running) < 0) { - ERROR("Error parsing link message"); - break; - } - - // UP RUNNING - // UP NOT RUNNING - // DOWN NOT RUNNING -#if 1 - DEBUG("[NETLINK] New network interface %s, state: %s %s", interface_name, - up ? "UP" : "DOWN", - running ? "RUNNING" : "NOT_RUNNING"); -#endif + DEBUG("[NETLINK] Network interface %s was removed", interface_name); - if (!facelet) - break; - if (up && running) { - facelet_set_event(facelet, FACELET_EVENT_CREATE); - //facelet_set_family(facelet, AF_INET); - facelet_set_attr_clean(facelet); - interface_raise_event(interface, facelet); + if (!facelet) break; -#if 0 - facelet_t * facelet6 = facelet_dup(facelet); - if (!facelet6) { - ERROR("Could not duplicate face for v6"); - break; - } - facelet_set_family(facelet6, AF_INET6); - interface_raise_event(interface, facelet6); -#endif -// } else { -//#if 1 -// facelet_set_event(facelet, FACELET_EVENT_SET_DOWN); -// facelet_set_attr_clean(facelet); -// interface_raise_event(interface, facelet); -//#else -// facelet_free(facelet); -//#endif - } - break; - } + facelet_set_event(facelet, FACELET_EVENT_DELETE); + facelet_set_attr_clean(facelet); + interface_raise_event(interface, facelet); - case NLMSG_ERROR: - break; - case NLMSG_DONE: - nl_process_state(interface); - break; - default: - break; + break; + } + + case RTM_NEWLINK: { + facelet_t *facelet = NULL; + char interface_name[IFNAMSIZ]; + bool up, running; + if (parse_link(h, &facelet, interface_name, IFNAMSIZ, &up, &running) < + 0) { + ERROR("Error parsing link message"); + break; } - status -= NLMSG_ALIGN(len); // align offsets by the message length, this is important + // UP RUNNING + // UP NOT RUNNING + // DOWN NOT RUNNING +#if 1 + DEBUG("[NETLINK] New network interface %s, state: %s %s", + interface_name, up ? "UP" : "DOWN", + running ? "RUNNING" : "NOT_RUNNING"); +#endif - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); // get next message + if (!facelet) break; + if (up && running) { + facelet_set_event(facelet, FACELET_EVENT_CREATE); + facelet_set_attr_clean(facelet); + interface_raise_event(interface, facelet); + } else { + facelet_free(facelet); + } + break; + } + + case NLMSG_ERROR: + break; + case NLMSG_DONE: + nl_process_state(interface); + break; + default: + break; } - return 0; -} + status -= NLMSG_ALIGN( + len); // align offsets by the message length, this is important -int nl_finalize(interface_t * interface) -{ - nl_data_t * data = (nl_data_t*)interface->data; - close(data->fd); - free(interface->data); - return 0; + h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); // get next message + } + + return 0; +} +int nl_finalize(interface_t *interface) { + nl_data_t *data = (nl_data_t *)interface->data; + close(data->fd); + free(interface->data); + return 0; } const interface_ops_t netlink_ops = { diff --git a/ctrl/facemgr/src/interfaces/network_framework/CMakeLists.txt b/ctrl/facemgr/src/interfaces/network_framework/CMakeLists.txt index e8b0144b1..db96e390f 100644 --- a/ctrl/facemgr/src/interfaces/network_framework/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/network_framework/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/network_framework/network_framework.c b/ctrl/facemgr/src/interfaces/network_framework/network_framework.c index 2c4bff513..3adba0969 100644 --- a/ctrl/facemgr/src/interfaces/network_framework/network_framework.c +++ b/ctrl/facemgr/src/interfaces/network_framework/network_framework.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -32,7 +32,7 @@ #include <hicn/util/map.h> #include "../../common.h" -#include <hicn/ctrl/face.h> +#include <hicn/face.h> #include "../../interface.h" #include "network_framework.h" @@ -41,7 +41,6 @@ #error "Network frameork requires MacOSX 10.14+" #endif /* !defined(MAC_OS_X_VERSION_10_14) */ - /* * Bonjour service discovery for hICN forwarder * @@ -70,144 +69,147 @@ /* Generated variables */ #define BONJOUR_SERVICE_TYPE "_hicn._" STRINGIZE(BONJOUR_PROTOCOL) #define BONJOUR_PROTOCOL_NAME STRINGIZE(BONJOUR_PROTOCOL) -#define nw_parameters_create_fn PPCAT(nw_parameters_create_secure_, BONJOUR_PROTOCOL) +#define nw_parameters_create_fn \ + PPCAT(nw_parameters_create_secure_, BONJOUR_PROTOCOL) #define DEFAULT_PORT 9695 typedef enum { - INTERFACE_TYPE_OTHER, - INTERFACE_TYPE_WIFI, - INTERFACE_TYPE_CELLULAR, - INTERFACE_TYPE_WIRED, - INTERFACE_TYPE_LOOPBACK, + INTERFACE_TYPE_OTHER, + INTERFACE_TYPE_WIFI, + INTERFACE_TYPE_CELLULAR, + INTERFACE_TYPE_WIRED, + INTERFACE_TYPE_LOOPBACK, } _nw_interface_type_t; -const char * interface_type_str[] = { +const char *interface_type_str[] = { "OTHER", "WIFI", "CELLULAR", "WIRED", "LOOPBACK", }; #if 1 typedef enum { - PATH_STATUS_INVALID, - PATH_STATUS_SATISTIED, - PATH_STATUS_UNSATISFIED, - PATH_STATUS_SATISFIABLE, + PATH_STATUS_INVALID, + PATH_STATUS_SATISTIED, + PATH_STATUS_UNSATISFIED, + PATH_STATUS_SATISFIABLE, } _nw_path_status_t; #endif -const char * path_status_str[] = { - "INVALID", "SATISFIED", "UNSATISFIED", "SATISFIABLE", +const char *path_status_str[] = { + "INVALID", + "SATISFIED", + "UNSATISFIED", + "SATISFIABLE", }; -const char * endpoint_type_str[] = { - "INVALID", "ADDRESS", "HOST", "BONJOUR", +const char *endpoint_type_str[] = { + "INVALID", + "ADDRESS", + "HOST", + "BONJOUR", }; -const char * connection_state_str[] = { +const char *connection_state_str[] = { "INVALID", "WAITING", "PREPARING", "READY", "FAILED", "CANCELLED", }; -int -cmp_iface(const nw_interface_t iface1, const nw_interface_t iface2) -{ - return INT_CMP(nw_interface_get_index(iface1), nw_interface_get_index(iface2)); +int cmp_iface(const nw_interface_t iface1, const nw_interface_t iface2) { + return INT_CMP(nw_interface_get_index(iface1), + nw_interface_get_index(iface2)); } -//TYPEDEF_MAP(map_cnx, nw_interface_t, nw_connection_t, cmp_iface); +// TYPEDEF_MAP(map_cnx, nw_interface_t, nw_connection_t, cmp_iface); typedef struct { - network_framework_cfg_t cfg; - nw_path_monitor_t pm; /**< Main path monitor */ -// map_cnx_t map_cnx; /**< Map: interface -> connection for face status */ + network_framework_cfg_t cfg; + nw_path_monitor_t pm; /**< Main path monitor */ + // map_cnx_t map_cnx; /**< Map: interface -> connection for face status + // */ } nf_data_t; -void -dump_interface(nw_interface_t interface, int indent) -{ - uint32_t index = nw_interface_get_index(interface); - const char * name = nw_interface_get_name(interface); - nw_interface_type_t type = nw_interface_get_type(interface); +void dump_interface(nw_interface_t interface, int indent) { + uint32_t index = nw_interface_get_index(interface); + const char *name = nw_interface_get_name(interface); + nw_interface_type_t type = nw_interface_get_type(interface); - printfi(indent+1, "%d: %s [%s]\n", index, name, interface_type_str[type]); + printfi(indent + 1, "%d: %s [%s]\n", index, name, interface_type_str[type]); } -void -dump_endpoint(nw_endpoint_t endpoint, int indent) -{ - if (!endpoint) { - printfi(indent, "N/A\n"); - return; - } - - nw_endpoint_type_t endpoint_type = nw_endpoint_get_type(endpoint); - const char * hostname = nw_endpoint_get_hostname(endpoint); - short port = nw_endpoint_get_port(endpoint); - const struct sockaddr * address = nw_endpoint_get_address(endpoint); - - printfi(indent, "Type: %s\n", endpoint_type_str[endpoint_type]); - printfi(indent, "Hostname: %s\n", hostname); - printfi(indent, "Port: %d\n", port); - - if (address) { - char *s = NULL; - switch(address->sa_family) { - case AF_INET: { - struct sockaddr_in *addr_in = (struct sockaddr_in *)address; - s = malloc(INET_ADDRSTRLEN); - inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN); - break; - } - case AF_INET6: { - struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)address; - s = malloc(INET6_ADDRSTRLEN); - inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN); - break; - } - default: - break; - } +void dump_endpoint(nw_endpoint_t endpoint, int indent) { + if (!endpoint) { + printfi(indent, "N/A\n"); + return; + } + + nw_endpoint_type_t endpoint_type = nw_endpoint_get_type(endpoint); + const char *hostname = nw_endpoint_get_hostname(endpoint); + short port = nw_endpoint_get_port(endpoint); + const struct sockaddr *address = nw_endpoint_get_address(endpoint); + + printfi(indent, "Type: %s\n", endpoint_type_str[endpoint_type]); + printfi(indent, "Hostname: %s\n", hostname); + printfi(indent, "Port: %d\n", port); + + if (address) { + char *s = NULL; + switch (address->sa_family) { + case AF_INET: { + struct sockaddr_in *addr_in = (struct sockaddr_in *)address; + s = malloc(INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN); + break; + } + case AF_INET6: { + struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)address; + s = malloc(INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN); + break; + default: + break; + } printfi(indent, "IP address: %s\n", s); free(s); } -} + } -void -dump_path(nw_path_t path, int indent) -{ + void dump_path(nw_path_t path, int indent) { /* nw_path_enumerate_interfaces : not interesting */ nw_path_status_t path_status = nw_path_get_status(path); printfi(indent, "Status: %s\n", path_status_str[path_status]); - printfi(indent, "Expensive: %s\n", nw_path_is_expensive(path) ? "true" : "false"); - printfi(indent, "IPv4 enabled: %s\n", nw_path_has_ipv4(path) ? "true" : "false"); - printfi(indent, "IPv6 enabled: %s\n", nw_path_has_ipv6(path) ? "true" : "false"); + printfi(indent, "Expensive: %s\n", + nw_path_is_expensive(path) ? "true" : "false"); + printfi(indent, "IPv4 enabled: %s\n", + nw_path_has_ipv4(path) ? "true" : "false"); + printfi(indent, "IPv6 enabled: %s\n", + nw_path_has_ipv6(path) ? "true" : "false"); printfi(indent, "DNS: %s\n", nw_path_has_dns(path) ? "true" : "false"); printfi(indent, "Interfaces:\n"); - nw_path_enumerate_interfaces(path, (nw_path_enumerate_interfaces_block_t)^(nw_interface_t interface) { - dump_interface(interface, indent+1); - return true; - }); + nw_path_enumerate_interfaces( + path, + (nw_path_enumerate_interfaces_block_t) ^ (nw_interface_t interface) { + dump_interface(interface, indent + 1); + return true; + }); nw_endpoint_t local = nw_path_copy_effective_local_endpoint(path); printfi(indent, "Effective local endpoint:\n"); - dump_endpoint(local, indent+1); + dump_endpoint(local, indent + 1); nw_release(local); nw_endpoint_t remote = nw_path_copy_effective_remote_endpoint(path); printfi(indent, "Effective remote endpoint:\n"); - dump_endpoint(remote, indent+1); + dump_endpoint(remote, indent + 1); nw_release(remote); -} + } -void -dump_connection(nw_connection_t connection, int indent) -{ + void dump_connection(nw_connection_t connection, int indent) { nw_endpoint_t remote = nw_connection_copy_endpoint(connection); nw_path_t path = nw_connection_copy_current_path(connection); printfi(indent, "Remote endpoint:\n"); - dump_endpoint(remote, indent+1); + dump_endpoint(remote, indent + 1); printfi(indent, "Path:\n"); - dump_path(path, indent+1); + dump_path(path, indent + 1); /* nw_connection_copy_protocol_metadata(); @@ -216,34 +218,34 @@ dump_connection(nw_connection_t connection, int indent) nw_release(remote); nw_release(path); -} + } #if defined(MAC_OS_X_VERSION_10_15) -void -dump_browse_result(nw_browse_result_t result, int indent) -{ + void dump_browse_result(nw_browse_result_t result, int indent) { /* Endpoint */ nw_endpoint_t browse_endpoint = nw_browse_result_copy_endpoint(result); if (!browse_endpoint) { - ERROR("[network_framework.dump_result] Failed to retrieve endpoint from Bonjour browse result"); - return; + ERROR( + "[network_framework.dump_result] Failed to retrieve endpoint from " + "Bonjour browse result"); + return; } printfi(indent + 1, "Endpoint:"); dump_endpoint(browse_endpoint, indent + 2); /* Interfaces */ printfi(indent + 1, "Interfaces:"); - nw_browse_result_enumerate_interfaces(result, (nw_browse_result_enumerate_interface_t) ^(nw_interface_t interface) { - dump_interface(interface, indent + 2); - return true; - }); -} + nw_browse_result_enumerate_interfaces( + result, + (nw_browse_result_enumerate_interface_t) ^ (nw_interface_t interface) { + dump_interface(interface, indent + 2); + return true; + }); + } #endif /* defined(MAC_OS_X_VERSION_10_15) */ -facelet_t * -facelet_create_from_connection(nw_connection_t connection) -{ - facelet_t * facelet; + facelet_t *facelet_create_from_connection(nw_connection_t connection) { + facelet_t *facelet; ip_address_t local_addr, remote_addr; uint16_t remote_port; @@ -252,34 +254,36 @@ facelet_create_from_connection(nw_connection_t connection) nw_endpoint_t remote = nw_path_copy_effective_remote_endpoint(path); __block nw_interface_t interface; - const struct sockaddr * local_sa = nw_endpoint_get_address(local); - const struct sockaddr * remote_sa = nw_endpoint_get_address(remote); - - assert (local_sa->sa_family == remote_sa->sa_family); - switch(local_sa->sa_family) { - case AF_INET: - local_addr.v4.as_inaddr = ((struct sockaddr_in *)local_sa)->sin_addr; - remote_addr.v4.as_inaddr = ((struct sockaddr_in *)remote_sa)->sin_addr; - remote_port = ((struct sockaddr_in *)remote_sa)->sin_port; - break; - case AF_INET6: - local_addr.v6.as_in6addr = ((struct sockaddr_in6 *)local_sa)->sin6_addr; - remote_addr.v6.as_in6addr = ((struct sockaddr_in6 *)remote_sa)->sin6_addr; - remote_port = ((struct sockaddr_in6 *)remote_sa)->sin6_port; - break; - default: - ERROR("Unsupported address family: %d\n", local_sa->sa_family); - return NULL; + const struct sockaddr *local_sa = nw_endpoint_get_address(local); + const struct sockaddr *remote_sa = nw_endpoint_get_address(remote); + + assert(local_sa->sa_family == remote_sa->sa_family); + switch (local_sa->sa_family) { + case AF_INET: + local_addr.v4.as_inaddr = ((struct sockaddr_in *)local_sa)->sin_addr; + remote_addr.v4.as_inaddr = ((struct sockaddr_in *)remote_sa)->sin_addr; + remote_port = ((struct sockaddr_in *)remote_sa)->sin_port; + break; + case AF_INET6: + local_addr.v6.as_in6addr = ((struct sockaddr_in6 *)local_sa)->sin6_addr; + remote_addr.v6.as_in6addr = + ((struct sockaddr_in6 *)remote_sa)->sin6_addr; + remote_port = ((struct sockaddr_in6 *)remote_sa)->sin6_port; + break; + default: + ERROR("Unsupported address family: %d\n", local_sa->sa_family); + return NULL; } - /* Retrieving path interface type (a single one expected */ - nw_path_enumerate_interfaces(path, (nw_path_enumerate_interfaces_block_t)^(nw_interface_t path_interface) { - interface = path_interface; - return false; - }); - - const char * name = nw_interface_get_name(interface); + nw_path_enumerate_interfaces( + path, (nw_path_enumerate_interfaces_block_t) ^ + (nw_interface_t path_interface) { + interface = path_interface; + return false; + }); + + const char *name = nw_interface_get_name(interface); netdevice_t netdevice; snprintf(netdevice.name, IFNAMSIZ, "%s", name); netdevice_update_index(&netdevice); @@ -287,25 +291,24 @@ facelet_create_from_connection(nw_connection_t connection) netdevice_type_t netdevice_type; nw_interface_type_t type = nw_interface_get_type(interface); - switch(type) { - case INTERFACE_TYPE_OTHER: - netdevice_type = NETDEVICE_TYPE_UNDEFINED; - break; - case INTERFACE_TYPE_WIFI: - netdevice_type = NETDEVICE_TYPE_WIFI; - break; - case INTERFACE_TYPE_CELLULAR: - netdevice_type = NETDEVICE_TYPE_CELLULAR; - break; - case INTERFACE_TYPE_WIRED: - netdevice_type = NETDEVICE_TYPE_WIRED; - break; - case INTERFACE_TYPE_LOOPBACK: - netdevice_type = NETDEVICE_TYPE_LOOPBACK; - break; - default: - break; - + switch (type) { + case INTERFACE_TYPE_OTHER: + netdevice_type = NETDEVICE_TYPE_UNDEFINED; + break; + case INTERFACE_TYPE_WIFI: + netdevice_type = NETDEVICE_TYPE_WIFI; + break; + case INTERFACE_TYPE_CELLULAR: + netdevice_type = NETDEVICE_TYPE_CELLULAR; + break; + case INTERFACE_TYPE_WIRED: + netdevice_type = NETDEVICE_TYPE_WIRED; + break; + case INTERFACE_TYPE_LOOPBACK: + netdevice_type = NETDEVICE_TYPE_LOOPBACK; + break; + default: + break; } nw_release(local); @@ -313,8 +316,7 @@ facelet_create_from_connection(nw_connection_t connection) nw_release(path); facelet = facelet_create(); - if (!facelet) - return NULL; + if (!facelet) return NULL; facelet_set_netdevice(facelet, netdevice); facelet_set_netdevice_type(facelet, netdevice_type); @@ -324,20 +326,21 @@ facelet_create_from_connection(nw_connection_t connection) facelet_set_remote_port(facelet, remote_port); return facelet; -} + } -void -on_connection_state_event(interface_t * interface, nw_interface_t iface, - nw_connection_t cnx, nw_connection_state_t state, nw_error_t error) -{ + void on_connection_state_event( + interface_t * interface, nw_interface_t iface, nw_connection_t cnx, + nw_connection_state_t state, nw_error_t error) { #if 1 DEBUG("Connection [new state = %s]:\n", connection_state_str[state]); nw_path_t path = nw_connection_copy_current_path(cnx); - nw_path_enumerate_interfaces(path, (nw_path_enumerate_interfaces_block_t)^(nw_interface_t interface) { - const char * name = nw_interface_get_name(interface); - printf("NAME=%s\n", name); - return true; - }); + nw_path_enumerate_interfaces( + path, + (nw_path_enumerate_interfaces_block_t) ^ (nw_interface_t interface) { + const char *name = nw_interface_get_name(interface); + printf("NAME=%s\n", name); + return true; + }); #endif /* We should get enough information to create the face and set if up @@ -346,84 +349,71 @@ on_connection_state_event(interface_t * interface, nw_interface_t iface, nw_endpoint_t remote = nw_connection_copy_endpoint(cnx); errno = error ? nw_error_get_error_code(error) : 0; - switch(state) { - case nw_connection_state_waiting: - warn("connect to %s port %u (%s) failed, is waiting", - nw_endpoint_get_hostname(remote), - nw_endpoint_get_port(remote), - BONJOUR_PROTOCOL_NAME); - break; - - case nw_connection_state_preparing: - break; - - case nw_connection_state_ready: - { - printf("info:\n"); - warn("connection ready"); + switch (state) { + case nw_connection_state_waiting: + warn("connect to %s port %u (%s) failed, is waiting", + nw_endpoint_get_hostname(remote), nw_endpoint_get_port(remote), + BONJOUR_PROTOCOL_NAME); + break; + + case nw_connection_state_preparing: + break; + + case nw_connection_state_ready: { + printf("info:\n"); + warn("connection ready"); #if 1 - WITH_DEBUG({ - dump_connection(cnx, 1); - }); + WITH_DEBUG({ dump_connection(cnx, 1); }); #endif - facelet_t * facelet = facelet_create_from_connection(cnx); - if (!facelet) - return; - facelet_set_event(facelet, FACELET_EVENT_CREATE); - interface_raise_event(interface, facelet); - break; - } - case nw_connection_state_failed: - /* Can we fail with bonjour, or are we always waiting ? */ - warn("connect to %s port %u (%s) failed", - nw_endpoint_get_hostname(remote), - nw_endpoint_get_port(remote), - BONJOUR_PROTOCOL_NAME); - break; - - case nw_connection_state_cancelled: - // Release the primary reference on the connection - // that was taken at creation time - nw_release(cnx); - break; - - default: /* nw_connection_state_invalid */ - /* Should never be called */ - break; - + facelet_t *facelet = facelet_create_from_connection(cnx); + if (!facelet) return; + facelet_set_event(facelet, FACELET_EVENT_CREATE); + interface_raise_event(interface, facelet); + break; + } + case nw_connection_state_failed: + /* Can we fail with bonjour, or are we always waiting ? */ + warn("connect to %s port %u (%s) failed", + nw_endpoint_get_hostname(remote), nw_endpoint_get_port(remote), + BONJOUR_PROTOCOL_NAME); + break; + + case nw_connection_state_cancelled: + // Release the primary reference on the connection + // that was taken at creation time + nw_release(cnx); + break; + + default: /* nw_connection_state_invalid */ + /* Should never be called */ + break; } nw_release(remote); + } -} - -void -on_connection_path_event(interface_t * interface, nw_interface_t iface, - nw_connection_t cnx, nw_path_t path) -{ + void on_connection_path_event(interface_t * interface, nw_interface_t iface, + nw_connection_t cnx, nw_path_t path) { #if 1 DEBUG("Connection [path changed]:\n"); - WITH_DEBUG({ - dump_connection(cnx, 1); - }); + WITH_DEBUG({ dump_connection(cnx, 1); }); #endif - /* redundant *//* - DEBUG(1, "Path:\n"); - dump_path(path, 2); - */ -} - -/** - * Enumerate main path interfaces - * - * We need to create specific dummy connections for each newly discovered - * interface - * - * Currently we only use Bonjour/TCP for remote hICN discovery and connection - * path monitoring. - */ -void on_interface_event(interface_t * interface, nw_interface_t iface) -{ + /* redundant */ /* + DEBUG(1, "Path:\n"); + dump_path(path, 2); + */ + } + + /** + * Enumerate main path interfaces + * + * We need to create specific dummy connections for each newly discovered + * interface + * + * Currently we only use Bonjour/TCP for remote hICN discovery and connection + * path monitoring. + */ + void on_interface_event(interface_t * interface, nw_interface_t iface) { /* We can create an hICN face on this interface that will be down until * connected * It is however possible to have two default gateways on the same @@ -452,11 +442,10 @@ void on_interface_event(interface_t * interface, nw_interface_t iface) /* nw_parameters_create_secure_{udp,tcp} */ nw_parameters_t parameters = nw_parameters_create_fn( - NW_PARAMETERS_DISABLE_PROTOCOL, /* no (d)tls */ - NW_PARAMETERS_DEFAULT_CONFIGURATION /* default udp/tcp */); + NW_PARAMETERS_DISABLE_PROTOCOL, /* no (d)tls */ + NW_PARAMETERS_DEFAULT_CONFIGURATION /* default udp/tcp */); - if (!parameters) - goto ERR_PARAMETERS; + if (!parameters) goto ERR_PARAMETERS; nw_parameters_require_interface(parameters, iface); nw_parameters_set_reuse_local_address(parameters, true); @@ -467,49 +456,60 @@ void on_interface_event(interface_t * interface, nw_interface_t iface) * available services on the local network using the parameters specified * before. */ - nw_browse_descriptor_t descriptor = nw_browse_descriptor_create_bonjour_service(BONJOUR_SERVICE_TYPE, BONJOUR_SERVICE_DOMAIN); + nw_browse_descriptor_t descriptor = + nw_browse_descriptor_create_bonjour_service(BONJOUR_SERVICE_TYPE, + BONJOUR_SERVICE_DOMAIN); if (!descriptor) { - ERROR("[network_framework.on_interface_event] Failed to create a bonjour browse descriptor"); - goto ERR_DESCRIPTOR; + ERROR( + "[network_framework.on_interface_event] Failed to create a bonjour " + "browse descriptor"); + goto ERR_DESCRIPTOR; } nw_browser_t browser = nw_browser_create(descriptor, parameters); nw_browser_set_queue(browser, dispatch_get_main_queue()); - nw_browser_set_browse_results_changed_handler(browser, ^(nw_browse_result_t result, nw_browse_result_t result2, bool flag) { - /* Dump result */ - printfi(0, "NEW BROWSE RESULT"); - printfi(1, "Result:"); - dump_browse_result(result, 2); - printfi(1, "Result2:"); - dump_browse_result(result2, 2); - printfi(1, "Flag: %s\n", (flag?"ON":"OFF")); - - /* Changes */ - nw_browse_result_change_t change = nw_browse_result_get_changes(result, result2); - switch(change) { - case nw_browse_result_change_identical: - printfi(2, "The compared services are identical."); - break; - case nw_browse_result_change_result_added: - printfi(2, "A new service was discovered."); - break; - - case nw_browse_result_change_result_removed: - printfi(2, "A previously discovered service was removed."); - break; - - case nw_browse_result_change_txt_record_changed: - printfi(2, "The service's associated TXT record changed."); - break; - - case nw_browse_result_change_interface_added: - printfi(2, "The service was discovered over a new interface."); - break; - - case nw_browse_result_change_interface_removed: - printfi(2, "The service was no longer discovered over a certain interface."); - break; - } + nw_browser_set_browse_results_changed_handler(browser, ^( + nw_browse_result_t result, + nw_browse_result_t + result2, + bool flag) { + /* Dump result */ + printfi(0, "NEW BROWSE RESULT"); + printfi(1, "Result:"); + dump_browse_result(result, 2); + printfi(1, "Result2:"); + dump_browse_result(result2, 2); + printfi(1, "Flag: %s\n", (flag ? "ON" : "OFF")); + + /* Changes */ + nw_browse_result_change_t change = + nw_browse_result_get_changes(result, result2); + switch (change) { + case nw_browse_result_change_identical: + printfi(2, "The compared services are identical."); + break; + case nw_browse_result_change_result_added: + printfi(2, "A new service was discovered."); + break; + + case nw_browse_result_change_result_removed: + printfi(2, "A previously discovered service was removed."); + break; + + case nw_browse_result_change_txt_record_changed: + printfi(2, "The service's associated TXT record changed."); + break; + + case nw_browse_result_change_interface_added: + printfi(2, "The service was discovered over a new interface."); + break; + + case nw_browse_result_change_interface_removed: + printfi( + 2, + "The service was no longer discovered over a certain interface."); + break; + } }); nw_browser_start(browser); @@ -524,20 +524,20 @@ void on_interface_event(interface_t * interface, nw_interface_t iface) nw_endpoint_t endpoint; DEBUG("Creating bonjour service towards NAME=%s TYPE=%s DOMAIN=%s", - BONJOUR_SERVICE_NAME, BONJOUR_SERVICE_TYPE, BONJOUR_SERVICE_DOMAIN); + BONJOUR_SERVICE_NAME, BONJOUR_SERVICE_TYPE, BONJOUR_SERVICE_DOMAIN); endpoint = nw_endpoint_create_bonjour_service( - BONJOUR_SERVICE_NAME, - BONJOUR_SERVICE_TYPE, - BONJOUR_SERVICE_DOMAIN); + BONJOUR_SERVICE_NAME, BONJOUR_SERVICE_TYPE, BONJOUR_SERVICE_DOMAIN); if (!endpoint) { - ERROR("[network_framework.on_interface_event] Failed to create bound Bonjour connection"); - goto ERR_ENDPOINT; + ERROR( + "[network_framework.on_interface_event] Failed to create bound " + "Bonjour " + "connection"); + goto ERR_ENDPOINT; } nw_connection_t connection = nw_connection_create(endpoint, parameters); - if (!connection) - goto ERR_CONNECTION; + if (!connection) goto ERR_CONNECTION; nw_release(endpoint); nw_release(parameters); @@ -547,108 +547,98 @@ void on_interface_event(interface_t * interface, nw_interface_t iface) /* Setup connection handlers */ - nw_connection_set_state_changed_handler(connection, ^(nw_connection_state_t state, nw_error_t error) { - on_connection_state_event(interface, iface, connection, state, error); - }); + nw_connection_set_state_changed_handler( + connection, ^(nw_connection_state_t state, nw_error_t error) { + on_connection_state_event(interface, iface, connection, state, error); + }); nw_connection_set_path_changed_handler(connection, ^(nw_path_t path) { - on_connection_path_event(interface, iface, connection, path); + on_connection_path_event(interface, iface, connection, path); }); nw_connection_set_better_path_available_handler(connection, ^(bool value) { #if 1 - DEBUG("Connection [better path = %s]\n", (value ? "true" : "false")); - WITH_DEBUG({ - dump_connection(connection, 1); - }); + DEBUG("Connection [better path = %s]\n", (value ? "true" : "false")); + WITH_DEBUG({ dump_connection(connection, 1); }); #endif }); nw_connection_set_viability_changed_handler(connection, ^(bool value) { #if 1 - DEBUG("Connection [viable = %s]\n", (value ? "true" : "false")); - WITH_DEBUG({ - //dump_connection(connection, 1); - }); + DEBUG("Connection [viable = %s]\n", (value ? "true" : "false")); + WITH_DEBUG({ + // dump_connection(connection, 1); + }); #endif - /* - * This is the first time we have a connection with address and port - * and thus the full identification of an hICN face - */ - facelet_t * facelet = facelet_create_from_connection(connection); - if (!facelet) - return; - facelet_set_event(facelet, value ? FACELET_EVENT_CREATE : FACELET_EVENT_DELETE); - interface_raise_event(interface, facelet); - + /* + * This is the first time we have a connection with address and port + * and thus the full identification of an hICN face + */ + facelet_t *facelet = facelet_create_from_connection(connection); + if (!facelet) return; + facelet_set_event(facelet, + value ? FACELET_EVENT_CREATE : FACELET_EVENT_DELETE); + interface_raise_event(interface, facelet); }); nw_connection_start(connection); nw_connection_set_queue(connection, dispatch_get_main_queue()); - nw_retain(connection); // Hold a reference until cancelled + nw_retain(connection); // Hold a reference until cancelled #if 1 DEBUG("Created Bonjour cnx on interface:"); - WITH_DEBUG({ - dump_interface(iface, 1); - }); + WITH_DEBUG({ dump_interface(iface, 1); }); #endif return; - nw_release(connection); -ERR_CONNECTION: + nw_release(connection); + ERR_CONNECTION: nw_release(endpoint); -ERR_ENDPOINT: + ERR_ENDPOINT: #if defined(MAC_OS_X_VERSION_10_15) nw_release(descriptor); -ERR_DESCRIPTOR: + ERR_DESCRIPTOR: #endif /* defined(MAC_OS_X_VERSION_10_15) */ nw_release(parameters); -ERR_PARAMETERS: + ERR_PARAMETERS: return; -} + } -void on_path_event(interface_t * interface, nw_path_t path) -{ + void on_path_event(interface_t * interface, nw_path_t path) { /* Simplification: we handle path event only once. * Ideally, test whether we discover new interfaces or not */ #if 1 DEBUG("Path [event]:\n"); - WITH_DEBUG({ - dump_path(path, 1); - }); + WITH_DEBUG({ dump_path(path, 1); }); #endif - nw_path_enumerate_interfaces(path, (nw_path_enumerate_interfaces_block_t)^(nw_interface_t iface) { - on_interface_event(interface, iface); - return true; - }); - -} + nw_path_enumerate_interfaces( + path, (nw_path_enumerate_interfaces_block_t) ^ (nw_interface_t iface) { + on_interface_event(interface, iface); + return true; + }); + } -int nf_initialize(interface_t * interface, void * cfg) -{ - nf_data_t * data = malloc(sizeof(nf_data_t)); - if (!data) - goto ERR_MALLOC; + int nf_initialize(interface_t * interface, void *cfg) { + nf_data_t *data = malloc(sizeof(nf_data_t)); + if (!data) goto ERR_MALLOC; - if (cfg) - data->cfg = * (network_framework_cfg_t *)cfg; + if (cfg) data->cfg = *(network_framework_cfg_t *)cfg; data->pm = nw_path_monitor_create(); - if (!data->pm) - goto ERR_PM; + if (!data->pm) goto ERR_PM; nw_path_monitor_set_queue(data->pm, dispatch_get_main_queue()); - nw_path_monitor_set_cancel_handler(data->pm, ^() { }); + nw_path_monitor_set_cancel_handler(data->pm, ^(){ + }); nw_path_monitor_set_update_handler(data->pm, ^(nw_path_t path) { - on_path_event(interface, path); - }); + on_path_event(interface, path); + }); // XXX NEEDED ? nw_retain(data->pm); @@ -659,25 +649,24 @@ int nf_initialize(interface_t * interface, void * cfg) interface->data = data; return 0; -ERR_PM: + ERR_PM: free(data); -ERR_MALLOC: + ERR_MALLOC: return -1; -} + } -int nf_finalize(interface_t * interface) -{ - nf_data_t * data = (nf_data_t*)interface->data; + int nf_finalize(interface_t * interface) { + nf_data_t *data = (nf_data_t *)interface->data; if (data->pm) { - nw_path_monitor_cancel(data->pm); - data->pm = NULL; + nw_path_monitor_cancel(data->pm); + data->pm = NULL; } return 0; -} - -const interface_ops_t network_framework_ops = { - .type = "network_framework", - .initialize = nf_initialize, - .finalize = nf_finalize, - .on_event = NULL, -}; + } + + const interface_ops_t network_framework_ops = { + .type = "network_framework", + .initialize = nf_initialize, + .finalize = nf_finalize, + .on_event = NULL, + }; diff --git a/ctrl/facemgr/src/interfaces/network_framework/network_framework.h b/ctrl/facemgr/src/interfaces/network_framework/network_framework.h index edb35e904..768edc253 100644 --- a/ctrl/facemgr/src/interfaces/network_framework/network_framework.h +++ b/ctrl/facemgr/src/interfaces/network_framework/network_framework.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -19,4 +19,5 @@ */ typedef struct { + void *_; } network_framework_cfg_t; diff --git a/ctrl/facemgr/src/interfaces/priority_controller/CMakeLists.txt b/ctrl/facemgr/src/interfaces/priority_controller/CMakeLists.txt index 8d18800db..43ba31b0b 100644 --- a/ctrl/facemgr/src/interfaces/priority_controller/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/priority_controller/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c index 67edc5e39..5d2f695f9 100644 --- a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c +++ b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -34,20 +34,21 @@ #define PC_DEFAULT_PORT 9533 typedef struct { - priority_controller_cfg_t cfg; - int fd; + priority_controller_cfg_t cfg; + int fd; #ifdef PRIORITY_CONTROLLER_INTERNAL - unsigned state; - JNIEnv * env; - jclass cls; - jmethodID mid; + unsigned state; + JNIEnv *env; + jclass cls; + jmethodID mid; #endif /* PRIORITY_CONTROLLER_INTERNAL */ } pc_data_t; #ifdef PRIORITY_CONTROLLER_INTERNAL #include <jni.h> -#define ERR_STR_JAVA "Java VM parameters are required in the interface configuration." +#define ERR_STR_JAVA \ + "Java VM parameters are required in the interface configuration." #define PREFER_CELLULAR 0 #define PREFER_WIFI 1 @@ -55,147 +56,146 @@ typedef struct { #define INTERVAL_MS 500 -const char * prefer_str[] = { "Cellular", "WiFi", "both" }; +const char *prefer_str[] = {"Cellular", "WiFi", "both"}; -jclass find_class_global(JNIEnv* env, const char *name){ - jclass c = (*env)->FindClass(env, name); - jclass c_global = 0; - if (c){ - c_global = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - } - return c_global; +jclass find_class_global(JNIEnv *env, const char *name) { + jclass c = (*env)->FindClass(env, name); + jclass c_global = 0; + if (c) { + c_global = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + } + return c_global; } +int priority_controller_tick(interface_t *interface, int fd, void *unused) { + pc_data_t *data = (pc_data_t *)interface->data; + unsigned new_state = PREFER_BOTH; -int priority_controller_tick(interface_t * interface, int fd, void * unused) -{ - pc_data_t * data = (pc_data_t*)interface->data; - unsigned new_state = PREFER_BOTH; - - jint rssi = (*data->env)->CallStaticIntMethod(data->env, data->cls, data->mid); - DEBUG("[priority_controller_tick] rssi=%d\n", rssi); - if (rssi > -67) { - new_state = PREFER_WIFI; + jint rssi = + (*data->env)->CallStaticIntMethod(data->env, data->cls, data->mid); + DEBUG("[priority_controller_tick] rssi=%d\n", rssi); + if (rssi > -67) { + new_state = PREFER_WIFI; #if 0 } else if ((rssi < -67) && (rssi > -70)) { new_state = PREFER_BOTH; #endif - } else { /* rssi < -70 */ - new_state = PREFER_CELLULAR; - } + } else { /* rssi < -70 */ + new_state = PREFER_CELLULAR; + } - if (new_state == data->state) - return 0; + if (new_state == data->state) return 0; - ERROR("[priority_controller_tick] Setting priority to %s", prefer_str[new_state]); + ERROR("[priority_controller_tick] Setting priority to %s", + prefer_str[new_state]); - /* XXX Factor this */ + /* XXX Factor this */ - facelet_t * facelet_w = facelet_create(); - facelet_t * facelet_c = facelet_create(); - facelet_set_netdevice_type(facelet_w, NETDEVICE_TYPE_WIFI); - facelet_set_netdevice_type(facelet_c, NETDEVICE_TYPE_CELLULAR); - facelet_set_attr_clean(facelet_w); - facelet_set_attr_clean(facelet_c); + facelet_t *facelet_w = facelet_create(); + facelet_t *facelet_c = facelet_create(); + facelet_set_netdevice_type(facelet_w, NETDEVICE_TYPE_WIFI); + facelet_set_netdevice_type(facelet_c, NETDEVICE_TYPE_CELLULAR); + facelet_set_attr_clean(facelet_w); + facelet_set_attr_clean(facelet_c); - switch(new_state) { - case PREFER_CELLULAR: - facelet_set_priority(facelet_w, 0); - facelet_set_priority(facelet_c, 10); - break; - case PREFER_WIFI: - facelet_set_priority(facelet_w, 10); - facelet_set_priority(facelet_c, 0); - break; - case PREFER_BOTH: - facelet_set_priority(facelet_w, 0); - facelet_set_priority(facelet_c, 0); - break; - } + switch (new_state) { + case PREFER_CELLULAR: + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 10); + break; + case PREFER_WIFI: + facelet_set_priority(facelet_w, 10); + facelet_set_priority(facelet_c, 0); + break; + case PREFER_BOTH: + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 0); + break; + } - facelet_set_event(facelet_w, FACELET_EVENT_UPDATE); - facelet_set_event(facelet_c, FACELET_EVENT_UPDATE); + facelet_set_event(facelet_w, FACELET_EVENT_UPDATE); + facelet_set_event(facelet_c, FACELET_EVENT_UPDATE); - interface_raise_event(interface, facelet_w); - interface_raise_event(interface, facelet_c); + interface_raise_event(interface, facelet_w); + interface_raise_event(interface, facelet_c); - data->state = new_state; + data->state = new_state; - return 0; + return 0; } #endif /* PRIORITY_CONTROLLER_INTERNAL */ -int priority_controller_initialize(interface_t * interface, void * cfg) -{ - INFO("Initializing priority controller"); +int priority_controller_initialize(interface_t *interface, void *cfg) { + INFO("Initializing priority controller"); - pc_data_t * data = malloc(sizeof(pc_data_t)); - if (!data) { - INFO("Priority controller data memory allocation error"); - goto ERR_MALLOC; - } + pc_data_t *data = malloc(sizeof(pc_data_t)); + if (!data) { + INFO("Priority controller data memory allocation error"); + goto ERR_MALLOC; + } - interface->data = data; + interface->data = data; - data->cfg = * (priority_controller_cfg_t *) cfg; + data->cfg = *(priority_controller_cfg_t *)cfg; #ifdef PRIORITY_CONTROLLER_INTERNAL - if (!cfg) { - ERROR(ERR_STR_JAVA); - goto ERR_CFG; - } - - /* Retrieve RSSI information from SDK through AndroidUtility class */ - (*data->cfg.jvm)->AttachCurrentThread(data->cfg.jvm, &data->env, NULL); - data->cls = find_class_global(data->env, FACEMGR_ANDROID_UTILITY_CLASS); - if (data->cls == 0) - goto ERR_JAVA; - data->mid = (*data->env)->GetStaticMethodID(data->env, data->cls, "getWifiRSSI", "()I"); - - data->fd = interface_register_timer(interface, INTERVAL_MS, - priority_controller_tick, interface); - if (data->fd < 0) { - ERROR("[priority_controller_initialize] Could not initialize timer"); - goto ERR_FD; - } - data->state = PREFER_BOTH; + if (!cfg) { + ERROR(ERR_STR_JAVA); + goto ERR_CFG; + } + + /* Retrieve RSSI information from SDK through AndroidUtility class */ + (*data->cfg.jvm)->AttachCurrentThread(data->cfg.jvm, &data->env, NULL); + data->cls = find_class_global(data->env, FACEMGR_ANDROID_UTILITY_CLASS); + if (data->cls == 0) goto ERR_JAVA; + data->mid = + (*data->env) + ->GetStaticMethodID(data->env, data->cls, "getWifiRSSI", "()I"); + + data->fd = interface_register_timer(interface, INTERVAL_MS, + priority_controller_tick, interface); + if (data->fd < 0) { + ERROR("[priority_controller_initialize] Could not initialize timer"); + goto ERR_FD; + } + data->state = PREFER_BOTH; #else /* PRIORITY_CONTROLLER_INTERNAL */ - struct sockaddr_in addr; - - data->fd = socket(AF_INET, SOCK_DGRAM, 0); - //data->fd = socket(AF_INET, SOCK_STREAM, 0); - if (data->fd < 0) { - INFO("Priority controller socket error"); - perror("socket error"); - goto ERR_SOCKET; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = htons(PC_DEFAULT_PORT); - - if (bind(data->fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - INFO("Priority controller socket bind error"); - perror("bind error"); - goto ERR_BIND; - } - - DEBUG("[priority_controller_initialize] register fd"); - if (interface_register_fd(interface, data->fd, NULL) < 0) { - ERROR("[priority_controller_initialize] Error registering fd"); - goto ERR_FD; - } + struct sockaddr_in addr; + + data->fd = socket(AF_INET, SOCK_DGRAM, 0); + // data->fd = socket(AF_INET, SOCK_STREAM, 0); + if (data->fd < 0) { + INFO("Priority controller socket error"); + perror("socket error"); + goto ERR_SOCKET; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_port = htons(PC_DEFAULT_PORT); + + if (bind(data->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + INFO("Priority controller socket bind error"); + perror("bind error"); + goto ERR_BIND; + } + + DEBUG("[priority_controller_initialize] register fd"); + if (interface_register_fd(interface, data->fd, NULL) < 0) { + ERROR("[priority_controller_initialize] Error registering fd"); + goto ERR_FD; + } #endif /* PRIORITY_CONTROLLER_INTERNAL */ - INFO("Priority controller successfully initialized"); - return 0; + INFO("Priority controller successfully initialized"); + return 0; #ifdef PRIORITY_CONTROLLER_INTERNAL ERR_CFG: @@ -204,86 +204,86 @@ ERR_JAVA: ERR_FD: #ifndef PRIORITY_CONTROLLER_INTERNAL ERR_BIND: - close(data->fd); + close(data->fd); ERR_SOCKET: #endif /* ! PRIORITY_CONTROLLER_INTERNAL */ - free(data); + free(data); ERR_MALLOC: - return -1; + return -1; } -int priority_controller_finalize(interface_t * interface) -{ - pc_data_t * data = (pc_data_t*)interface->data; +int priority_controller_finalize(interface_t *interface) { + pc_data_t *data = (pc_data_t *)interface->data; #ifdef PRIORITY_CONTROLLER_INTERNAL - DEBUG("[priority_controller_finalize] unregister timer"); - interface_unregister_timer(interface, data->fd); + DEBUG("[priority_controller_finalize] unregister timer"); + interface_unregister_timer(interface, data->fd); #else - if (data->fd > 0) { - interface_unregister_fd(interface, data->fd); - close(data->fd); - } - free(data); + if (data->fd > 0) { + interface_unregister_fd(interface, data->fd); + close(data->fd); + } + free(data); #endif /* PRIORITY_CONTROLLER_INTERNAL */ - return 0; + return 0; } #ifndef PRIORITY_CONTROLLER_INTERNAL -int priority_controller_callback(interface_t * interface, int fd, void * unused) -{ - pc_data_t * data = (pc_data_t*)interface->data; - char buf[100]; - int rc; - - INFO("Priority controller receiving command"); - - rc = recv(data->fd, buf, 100, 0); - - if (rc < 0) { - INFO("Priority controller read error"); - return -1; - } - - INFO("Priority controller received command: %02X", buf[0]); - - facelet_t * facelet_w = facelet_create(); - facelet_t * facelet_c = facelet_create(); - facelet_set_netdevice_type(facelet_w, NETDEVICE_TYPE_WIFI); - facelet_set_netdevice_type(facelet_c, NETDEVICE_TYPE_CELLULAR); - facelet_set_attr_clean(facelet_w); - facelet_set_attr_clean(facelet_c); - switch(buf[0]) { - case '\0': - facelet_set_priority(facelet_w, 0); - facelet_set_priority(facelet_c, 10); - INFO("Priority controller configuring Cellular preferred"); - break; - case '\1': - facelet_set_priority(facelet_w, 10); - facelet_set_priority(facelet_c, 0); - INFO("Priority controller configuring Wi-Fi preferred"); - break; - case '\2': - facelet_set_priority(facelet_w, 0); - facelet_set_priority(facelet_c, 0); - INFO("Priority controller configuring both Cellular and Wi-Fi preferred"); - break; - default: - INFO("Priority controller invalid data received from updown server. Ignoring..."); - facelet_free(facelet_w); - facelet_free(facelet_c); - return 0; - } - - facelet_set_event(facelet_w, FACELET_EVENT_UPDATE); - facelet_set_event(facelet_c, FACELET_EVENT_UPDATE); - - interface_raise_event(interface, facelet_w); - interface_raise_event(interface, facelet_c); - - return 0; +int priority_controller_callback(interface_t *interface, int fd, void *unused) { + pc_data_t *data = (pc_data_t *)interface->data; + char buf[100]; + int rc; + + INFO("Priority controller receiving command"); + + rc = recv(data->fd, buf, 100, 0); + + if (rc < 0) { + INFO("Priority controller read error"); + return -1; + } + + INFO("Priority controller received command: %02X", buf[0]); + + facelet_t *facelet_w = facelet_create(); + facelet_t *facelet_c = facelet_create(); + facelet_set_netdevice_type(facelet_w, NETDEVICE_TYPE_WIFI); + facelet_set_netdevice_type(facelet_c, NETDEVICE_TYPE_CELLULAR); + facelet_set_attr_clean(facelet_w); + facelet_set_attr_clean(facelet_c); + switch (buf[0]) { + case '\0': + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 10); + INFO("Priority controller configuring Cellular preferred"); + break; + case '\1': + facelet_set_priority(facelet_w, 10); + facelet_set_priority(facelet_c, 0); + INFO("Priority controller configuring Wi-Fi preferred"); + break; + case '\2': + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 0); + INFO("Priority controller configuring both Cellular and Wi-Fi preferred"); + break; + default: + INFO( + "Priority controller invalid data received from updown server. " + "Ignoring..."); + facelet_free(facelet_w); + facelet_free(facelet_c); + return 0; + } + + facelet_set_event(facelet_w, FACELET_EVENT_UPDATE); + facelet_set_event(facelet_c, FACELET_EVENT_UPDATE); + + interface_raise_event(interface, facelet_w); + interface_raise_event(interface, facelet_c); + + return 0; } #endif /* ! PRIORITY_CONTROLLER_INTERNAL */ diff --git a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h index 247fc3c57..7f257ffcf 100644 --- a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h +++ b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -21,7 +21,8 @@ #ifndef FACEMGR_INTERFACE_PRIORITY_CONTROLLER #define FACEMGR_INTERFACE_PRIORITY_CONTROLLER -#define FACEMGR_UTILITY_CLASS "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" +#define FACEMGR_UTILITY_CLASS \ + "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" /* * Uncomment this line to use a Priority controller interface internal to the @@ -36,10 +37,9 @@ typedef struct { #ifdef __ANDROID__ #ifdef PRIORITY_CONTROLLER_INTERNAL - JavaVM * jvm; + JavaVM* jvm; #endif /* PRIORITY_CONTROLLER_INTERNAL */ #endif /* __ANDROID__ */ } priority_controller_cfg_t; - #endif /* FACEMGR_INTERFACE_PRIORITY_CONTROLLER */ diff --git a/ctrl/facemgr/src/interfaces/updown/CMakeLists.txt b/ctrl/facemgr/src/interfaces/updown/CMakeLists.txt index e5fd2167e..4c6c0ea6c 100644 --- a/ctrl/facemgr/src/interfaces/updown/CMakeLists.txt +++ b/ctrl/facemgr/src/interfaces/updown/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Copyright (c) 2021 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: diff --git a/ctrl/facemgr/src/interfaces/updown/updown.c b/ctrl/facemgr/src/interfaces/updown/updown.c index 7d305a5cd..8d31f6cd4 100644 --- a/ctrl/facemgr/src/interfaces/updown/updown.c +++ b/ctrl/facemgr/src/interfaces/updown/updown.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -26,6 +26,7 @@ #include <unistd.h> #include <hicn/facemgr.h> +#include <hicn/util/sstrncpy.h> #include "../../common.h" #include "../../interface.h" @@ -37,107 +38,101 @@ #define UNIX_PATH "\0updownsrv" typedef struct { - int fd; /* Unix client socket */ + int fd; /* Unix client socket */ } updown_data_t; -int updown_initialize(interface_t * interface, void * cfg) -{ - struct sockaddr_un addr; - char * socket_path = UNIX_PATH; - - updown_data_t * data = malloc(sizeof(updown_data_t)); - if (!data) - goto ERR_MALLOC; - interface->data = data; - - data->fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (data->fd == -1) { - perror("socket error"); - goto ERR_SOCKET; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - if (*socket_path == '\0') { - *addr.sun_path = '\0'; - strncpy(addr.sun_path+1, socket_path+1, sizeof(addr.sun_path)-2); - } else { - strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1); - } - - if (connect(data->fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { - perror("connect error"); - goto ERR_CONNECT; - } - - if (interface_register_fd(interface, data->fd, NULL) < 0) { - ERROR("[updown_initialize] Error registering fd"); - goto ERR_FD; - } - - return 0; +int updown_initialize(interface_t* interface, void* cfg) { + struct sockaddr_un addr; + char* socket_path = UNIX_PATH; + + updown_data_t* data = malloc(sizeof(updown_data_t)); + if (!data) goto ERR_MALLOC; + interface->data = data; + + data->fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (data->fd == -1) { + perror("socket error"); + goto ERR_SOCKET; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (*socket_path == '\0') { + *addr.sun_path = '\0'; + strcpy_s(addr.sun_path + 1, sizeof(addr.sun_path) - 2, socket_path + 1); + } else { + strcpy_s(addr.sun_path, sizeof(addr.sun_path) - 1, socket_path); + } + + if (connect(data->fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + perror("connect error"); + goto ERR_CONNECT; + } + + if (interface_register_fd(interface, data->fd, NULL) < 0) { + ERROR("[updown_initialize] Error registering fd"); + goto ERR_FD; + } + + return 0; ERR_FD: ERR_CONNECT: - close(data->fd); + close(data->fd); ERR_SOCKET: - free(data); + free(data); ERR_MALLOC: - return -1; + return -1; } -int updown_finalize(interface_t * interface) -{ - updown_data_t * data = (updown_data_t*)interface->data; +int updown_finalize(interface_t* interface) { + updown_data_t* data = (updown_data_t*)interface->data; - if (data->fd > 0) - close(data->fd); - free(data); + if (data->fd > 0) close(data->fd); + free(data); - return 0; + return 0; } -int updown_callback(interface_t * interface, int fd, void * unused) -{ - updown_data_t * data = (updown_data_t*)interface->data; - char buf[100]; - int rc; - - rc = read(data->fd, buf, sizeof(buf)); - if (rc < 0) - return -1; - - /* - * If the process is paused (eg. in a debugger, we might have more than one - * read. - * XXX how big is the buffer - * XXX shall we drain the queue if it exceeds buffer size ? - */ - //assert(rc == 1); - - /* Raise facelet update event */ - facelet_t * facelet = facelet_create(); - facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_WIFI); //CELLULAR); - facelet_set_attr_clean(facelet); - switch(buf[0]) { - case '\0': - facelet_set_admin_state(facelet, FACE_STATE_DOWN); - break; - case '\1': - facelet_set_admin_state(facelet, FACE_STATE_UP); - break; - break; - default: - ERROR("Invalid data received from updown server. Ignoring..."); - facelet_free(facelet); - return -1; - } - - facelet_set_event(facelet, FACELET_EVENT_UPDATE); - - interface_raise_event(interface, facelet); - - return 0; +int updown_callback(interface_t* interface, int fd, void* unused) { + updown_data_t* data = (updown_data_t*)interface->data; + char buf[100]; + int rc; + + rc = read(data->fd, buf, sizeof(buf)); + if (rc < 0) return -1; + + /* + * If the process is paused (eg. in a debugger, we might have more than one + * read. + * XXX how big is the buffer + * XXX shall we drain the queue if it exceeds buffer size ? + */ + // assert(rc == 1); + + /* Raise facelet update event */ + facelet_t* facelet = facelet_create(); + facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_WIFI); // CELLULAR); + facelet_set_attr_clean(facelet); + switch (buf[0]) { + case '\0': + facelet_set_admin_state(facelet, FACE_STATE_DOWN); + break; + case '\1': + facelet_set_admin_state(facelet, FACE_STATE_UP); + break; + break; + default: + ERROR("Invalid data received from updown server. Ignoring..."); + facelet_free(facelet); + return -1; + } + + facelet_set_event(facelet, FACELET_EVENT_UPDATE); + + interface_raise_event(interface, facelet); + + return 0; } interface_ops_t updown_ops = { diff --git a/ctrl/facemgr/src/loop_dispatcher.c b/ctrl/facemgr/src/loop_dispatcher.c index 499a1ccac..ed4540f5c 100644 --- a/ctrl/facemgr/src/loop_dispatcher.c +++ b/ctrl/facemgr/src/loop_dispatcher.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -33,52 +33,36 @@ #include <hicn/facemgr/loop.h> #include <hicn/util/log.h> -struct loop_s { -}; +struct loop_s {}; -loop_t * -loop_create() -{ - loop_t * loop = malloc(sizeof(loop_t)); - if (!loop) { - ERROR("[loop_create] Failed to allocate memory"); - goto ERR_MALLOC; - } - return loop; +loop_t* loop_create() { + loop_t* loop = malloc(sizeof(loop_t)); + if (!loop) { + ERROR("[loop_create] Failed to allocate memory"); + goto ERR_MALLOC; + } + return loop; ERR_MALLOC: - return NULL; + return NULL; } -void -loop_free(loop_t * loop) -{ - /* Nothing to do */ +void loop_free(loop_t* loop) { /* Nothing to do */ } -int -loop_dispatch(loop_t * loop) -{ - dispatch_main(); - return 0; +int loop_dispatch(loop_t* loop) { + dispatch_main(); + return 0; } -int -loop_undispatch(loop_t * loop) -{ - /* Nothing to do */ - return 0; +int loop_undispatch(loop_t* loop) { + /* Nothing to do */ + return 0; } -void -loop_break(loop_t * loop) -{ - exit(0); -} +void loop_break(loop_t* loop) { exit(0); } -int -loop_callback(loop_t * loop, facemgr_cb_type_t type, void * data) -{ - INFO("loop_callback not (yet) implemented"); - return 0; +int loop_callback(loop_t* loop, facemgr_cb_type_t type, void* data) { + INFO("loop_callback not (yet) implemented"); + return 0; } diff --git a/ctrl/facemgr/src/loop_libevent.c b/ctrl/facemgr/src/loop_libevent.c index 674eee905..b619e02e6 100644 --- a/ctrl/facemgr/src/loop_libevent.c +++ b/ctrl/facemgr/src/loop_libevent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -25,13 +25,13 @@ #include <assert.h> #include <event2/event.h> #include <event2/thread.h> -#include <fcntl.h> // fcntl +#include <fcntl.h> // fcntl #ifdef WITH_THREAD #include <pthread.h> #endif /* WITH_THREAD */ #include <stdlib.h> #include <sys/timerfd.h> -#include <unistd.h> // fcntl +#include <unistd.h> // fcntl #include <hicn/facemgr/api.h> #include <hicn/util/log.h> @@ -43,160 +43,150 @@ * \brief Holds all callback parameters */ typedef struct { - void * owner; - fd_callback_t callback; - void * data; + void *owner; + fd_callback_t callback; + void *data; } cb_wrapper_args_t; TYPEDEF_MAP_H(event_map, int, struct event *); -TYPEDEF_MAP(event_map, int, struct event *, int_cmp, int_snprintf, generic_snprintf); +TYPEDEF_MAP(event_map, int, struct event *, int_cmp, int_snprintf, + generic_snprintf); /* Map that associates timer fds with their associated cb_wrapper_args_t */ TYPEDEF_MAP_H(timer_fd_map, int, cb_wrapper_args_t *); -TYPEDEF_MAP(timer_fd_map, int, cb_wrapper_args_t *, int_cmp, int_snprintf, generic_snprintf); +TYPEDEF_MAP(timer_fd_map, int, cb_wrapper_args_t *, int_cmp, int_snprintf, + generic_snprintf); struct loop_s { - struct event_base * event_base; - event_map_t * event_map; - timer_fd_map_t * timer_fd_map; + struct event_base *event_base; + event_map_t *event_map; + timer_fd_map_t *timer_fd_map; #ifdef WITH_THREAD - pthread_t thread; + pthread_t thread; #endif /* WITH_THREAD */ }; /* Forward declarations */ -int _loop_unregister_fd(loop_t * loop, int fd); -int _loop_unregister_timer(loop_t * loop, int fd); - -loop_t * -loop_create() -{ - loop_t * loop = malloc(sizeof(loop_t)); - if (!loop) { - ERROR("[loop_create] Failed to allocate memory"); - goto ERR_MALLOC; - } +int _loop_unregister_fd(loop_t *loop, int fd); +int _loop_unregister_timer(loop_t *loop, int fd); + +loop_t *loop_create() { + loop_t *loop = malloc(sizeof(loop_t)); + if (!loop) { + ERROR("[loop_create] Failed to allocate memory"); + goto ERR_MALLOC; + } #ifdef WITH_THREAD - evthread_use_pthreads(); + evthread_use_pthreads(); #endif /* WITH_THREAD */ - loop->event_base = event_base_new(); - if (!loop) - goto ERR_EVENT; + loop->event_base = event_base_new(); + if (!loop) goto ERR_EVENT; - loop->event_map = event_map_create(); - if (!loop->event_map) { - ERROR("[loop_create] Failed to create event_map"); - goto ERR_EVENT_MAP; - } + loop->event_map = event_map_create(); + if (!loop->event_map) { + ERROR("[loop_create] Failed to create event_map"); + goto ERR_EVENT_MAP; + } - loop->timer_fd_map = timer_fd_map_create(); - if (!loop->timer_fd_map) { - ERROR("[loop_create] Failed to create timer_fd_map"); - goto ERR_TIMER_FD_MAP; - } + loop->timer_fd_map = timer_fd_map_create(); + if (!loop->timer_fd_map) { + ERROR("[loop_create] Failed to create timer_fd_map"); + goto ERR_TIMER_FD_MAP; + } - event_set_log_callback(NULL); + event_set_log_callback(NULL); - return loop; + return loop; - timer_fd_map_free(loop->timer_fd_map); ERR_TIMER_FD_MAP: - event_map_free(loop->event_map); + event_map_free(loop->event_map); ERR_EVENT_MAP: - event_base_free(loop->event_base); + event_base_free(loop->event_base); ERR_EVENT: - free(loop); + free(loop); ERR_MALLOC: - return NULL; + return NULL; } -void -loop_free(loop_t * loop) -{ - /* - * Release all timer cb_wrapper_args_t - * - * We need to stop all timers, this should release associated fd events at - * the same time... for that reason, this code has to be called before - * releasing events - */ - - int * timer_fd_map_array; - int n = timer_fd_map_get_key_array(loop->timer_fd_map, &timer_fd_map_array); - if (n < 0) { - ERROR("[loop_free] Could not get event map array"); - } else { - for (unsigned i = 0; i < n; i++) { - int fd = timer_fd_map_array[i]; - if (_loop_unregister_timer(loop, fd) < 0) { - ERROR("[loop_free] Could not unregister timer"); - } - } - free(timer_fd_map_array); +void loop_free(loop_t *loop) { + /* + * Release all timer cb_wrapper_args_t + * + * We need to stop all timers, this should release associated fd events at + * the same time... for that reason, this code has to be called before + * releasing events + */ + + int *timer_fd_map_array; + int n = timer_fd_map_get_key_array(loop->timer_fd_map, &timer_fd_map_array); + if (n < 0) { + ERROR("[loop_free] Could not get event map array"); + } else { + for (unsigned i = 0; i < n; i++) { + int fd = timer_fd_map_array[i]; + if (_loop_unregister_timer(loop, fd) < 0) { + ERROR("[loop_free] Could not unregister timer"); + } } - timer_fd_map_free(loop->timer_fd_map); - - /* Release all events */ - - int * event_map_array; - n = event_map_get_key_array(loop->event_map, &event_map_array); - if (n < 0) { - ERROR("[loop_free] Could not get event map array"); - } else { - for (unsigned i = 0; i < n; i++) { - int fd = event_map_array[i]; - if (_loop_unregister_fd(loop, fd) < 0) { - ERROR("[loop_free] Could not unregister fd"); - } - } - free(event_map_array); + free(timer_fd_map_array); + } + timer_fd_map_free(loop->timer_fd_map); + + /* Release all events */ + + int *event_map_array; + n = event_map_get_key_array(loop->event_map, &event_map_array); + if (n < 0) { + ERROR("[loop_free] Could not get event map array"); + } else { + for (unsigned i = 0; i < n; i++) { + int fd = event_map_array[i]; + if (_loop_unregister_fd(loop, fd) < 0) { + ERROR("[loop_free] Could not unregister fd"); + } } - event_map_free(loop->event_map); + free(event_map_array); + } + event_map_free(loop->event_map); - event_base_free(loop->event_base); + event_base_free(loop->event_base); - free(loop); + free(loop); } -int -loop_dispatch(loop_t * loop) -{ +int loop_dispatch(loop_t *loop) { #ifdef WITH_THREAD - if (pthread_create(&loop->thread, NULL, (void * (*)(void *))event_base_dispatch, loop->event_base)) { - fprintf(stderr, "Error creating thread\n"); - return -1; - } + if (pthread_create(&loop->thread, NULL, + (void *(*)(void *))event_base_dispatch, + loop->event_base)) { + fprintf(stderr, "Error creating thread\n"); + return -1; + } #else - event_base_dispatch(loop->event_base); + event_base_dispatch(loop->event_base); #endif /* WITH_THREAD */ - return 0; + return 0; } -int -loop_undispatch(loop_t * loop) -{ +int loop_undispatch(loop_t *loop) { #ifdef WITH_THREAD - DEBUG("Waiting for loop to terminate..."); - if(pthread_join(loop->thread, NULL)) { - fprintf(stderr, "Error joining thread\n"); - return -1; - } - DEBUG("Loop terminated !"); + DEBUG("Waiting for loop to terminate..."); + if (pthread_join(loop->thread, NULL)) { + ERROR("Error joining thread\n"); + return -1; + } + DEBUG("Loop terminated !"); #endif /* WITH_THREAD */ - return 0; + return 0; } -void -loop_break(loop_t * loop) -{ - event_base_loopbreak(loop->event_base); -} +void loop_break(loop_t *loop) { event_base_loopbreak(loop->event_base); } -void cb_wrapper(evutil_socket_t fd, short what, void * arg) { - cb_wrapper_args_t * cb_wrapper_args = arg; - cb_wrapper_args->callback(cb_wrapper_args->owner, fd, cb_wrapper_args->data); +void cb_wrapper(evutil_socket_t fd, short what, void *arg) { + cb_wrapper_args_t *cb_wrapper_args = arg; + cb_wrapper_args->callback(cb_wrapper_args->owner, fd, cb_wrapper_args->data); } /** @@ -208,42 +198,41 @@ void cb_wrapper(evutil_socket_t fd, short what, void * arg) { * \param [in] callback_data - User data to pass alongside callback invocation * \return 0 in case of success, -1 otherwise */ -int -_loop_register_fd(loop_t * loop, int fd, void * callback_owner, - fd_callback_t callback, void * callback_data) -{ - /* This will be freed with the event */ - cb_wrapper_args_t * cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); - *cb_wrapper_args = (cb_wrapper_args_t) { - .owner = callback_owner, - .callback = callback, - .data = callback_data, - }; - - evutil_make_socket_nonblocking(fd); - struct event * event = event_new(loop->event_base, fd, EV_READ | EV_PERSIST, cb_wrapper, cb_wrapper_args); - if (!event) { - ERROR("[_loop_register_fd] event_new"); - goto ERR_EVENT_NEW; - } - - if (event_add(event, NULL) < 0) { - ERROR("[_loop_register_fd] event_add"); - goto ERR_EVENT_ADD; - } - - if (event_map_add(loop->event_map, fd, event) < 0) { - ERROR("[_loop_register_fd] event_map_add"); - goto ERR_EVENT_MAP; - } - - return 0; +int _loop_register_fd(loop_t *loop, int fd, void *callback_owner, + fd_callback_t callback, void *callback_data) { + /* This will be freed with the event */ + cb_wrapper_args_t *cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); + *cb_wrapper_args = (cb_wrapper_args_t){ + .owner = callback_owner, + .callback = callback, + .data = callback_data, + }; + + evutil_make_socket_nonblocking(fd); + struct event *event = event_new(loop->event_base, fd, EV_READ | EV_PERSIST, + cb_wrapper, cb_wrapper_args); + if (!event) { + ERROR("[_loop_register_fd] event_new"); + goto ERR_EVENT_NEW; + } + + if (event_add(event, NULL) < 0) { + ERROR("[_loop_register_fd] event_add"); + goto ERR_EVENT_ADD; + } + + if (event_map_add(loop->event_map, fd, event) < 0) { + ERROR("[_loop_register_fd] event_map_add"); + goto ERR_EVENT_MAP; + } + + return 0; ERR_EVENT_MAP: ERR_EVENT_ADD: - event_free(event); + event_free(event); ERR_EVENT_NEW: - return -1; + return -1; } /** @@ -251,183 +240,169 @@ ERR_EVENT_NEW: * \param [in] fd - File descriptor to unregister * \return 0 in case of success, -1 otherwise */ -int -_loop_unregister_fd(loop_t * loop, int fd) -{ - struct event * event = NULL; +int _loop_unregister_fd(loop_t *loop, int fd) { + struct event *event = NULL; - if (event_map_remove(loop->event_map, fd, &event) < 0) { - ERROR("[_loop_unregister_fd] Error removing event associated to fd"); - return -1; - } + if (event_map_remove(loop->event_map, fd, &event) < 0) { + ERROR("[_loop_unregister_fd] Error removing event associated to fd"); + return -1; + } - assert(event); + assert(event); - cb_wrapper_args_t * cb_wrapper_args = event_get_callback_arg(event); - free(cb_wrapper_args); + cb_wrapper_args_t *cb_wrapper_args = event_get_callback_arg(event); + free(cb_wrapper_args); - event_del(event); - event_free(event); + event_del(event); + event_free(event); - return 0; + return 0; } -int -loop_timer_callback(loop_t * loop, int fd, void * data) -{ - char buf[1024]; /* size is not important */ - cb_wrapper_args_t * cb_wrapper_args = data; - while (read(fd, &buf, sizeof(buf)) > 0) - ; +int loop_timer_callback(loop_t *loop, int fd, void *data) { + char buf[1024]; /* size is not important */ + cb_wrapper_args_t *cb_wrapper_args = data; + while (read(fd, &buf, sizeof(buf)) > 0) + ; - int rc = cb_wrapper_args->callback(cb_wrapper_args->owner, fd, - cb_wrapper_args->data); + int rc = cb_wrapper_args->callback(cb_wrapper_args->owner, fd, + cb_wrapper_args->data); - return rc; + return rc; } -int -_loop_register_timer(loop_t * loop, timer_callback_data_t * timer_callback_data) -{ - int fd = timerfd_create(CLOCK_MONOTONIC, 0); - if (fd == -1) { - perror("timerfd_create"); - return -1; - } +int _loop_register_timer(loop_t *loop, + timer_callback_data_t *timer_callback_data) { + int fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd == -1) { + perror("timerfd_create"); + return -1; + } - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { - perror("fcntl"); - return -1; - } + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + perror("fcntl"); + return -1; + } + + struct itimerspec ts = { + .it_interval = + { + .tv_sec = timer_callback_data->delay_ms / 1000, + .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, + }, + .it_value = { + .tv_sec = timer_callback_data->delay_ms / 1000, + .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, + }}; + + if (timerfd_settime(fd, 0, &ts, NULL) == -1) { + perror("timerfd_settime"); + return -1; + } + + /* This should be freed together with the timer release */ + cb_wrapper_args_t *cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); + *cb_wrapper_args = (cb_wrapper_args_t){ + .owner = timer_callback_data->owner, + .callback = timer_callback_data->callback, + .data = timer_callback_data->data, + }; + + if (timer_fd_map_add(loop->timer_fd_map, fd, cb_wrapper_args) < 0) { + ERROR("[_loop_register_timer] Could not add cb_wrapper to timer map"); + return -1; + } - struct itimerspec ts = { - .it_interval = { - .tv_sec = timer_callback_data->delay_ms / 1000, - .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, - }, - .it_value = { - .tv_sec = timer_callback_data->delay_ms / 1000, - .tv_nsec = (timer_callback_data->delay_ms % 1000) * 1000000, - } - }; - - if (timerfd_settime(fd, 0, &ts, NULL) == -1) { - perror("timerfd_settime"); - return -1; - } + if (_loop_register_fd(loop, fd, loop, (fd_callback_t)loop_timer_callback, + cb_wrapper_args) < 0) { + ERROR("[_loop_register_timer] Error registering fd to event loop"); + return -1; + } - /* This should be freed together with the timer release */ - cb_wrapper_args_t * cb_wrapper_args = malloc(sizeof(cb_wrapper_args_t)); - *cb_wrapper_args = (cb_wrapper_args_t) { - .owner = timer_callback_data->owner, - .callback = timer_callback_data->callback, - .data = timer_callback_data->data, - }; + return fd; +} - if (timer_fd_map_add(loop->timer_fd_map, fd, cb_wrapper_args) < 0) { - ERROR("[_loop_register_timer] Could not add cb_wrapper to timer map"); - return -1; - } +int _loop_unregister_timer(loop_t *loop, int fd) { + struct itimerspec ts = {.it_interval = + { + .tv_sec = 0, + .tv_nsec = 0, + }, + .it_value = { + /* This value disables the timer */ + .tv_sec = 0, + .tv_nsec = 0, + }}; + ts.it_value.tv_sec = 0; + + if (timerfd_settime(fd, 0, &ts, NULL) == -1) { + perror("timerfd_settime"); + return -1; + } - if (_loop_register_fd(loop, fd, loop, - (fd_callback_t) loop_timer_callback, cb_wrapper_args) < 0) { - ERROR("[_loop_register_timer] Error registering fd to event loop"); - return -1; - } + cb_wrapper_args_t *cb_wrapper_args; + if (timer_fd_map_remove(loop->timer_fd_map, fd, &cb_wrapper_args) < 0) { + ERROR( + "[_loop_unregister_timer] Could not remove cb_wrapper from timer map"); + return -1; + } + assert(cb_wrapper_args); + free(cb_wrapper_args); + + if (_loop_unregister_fd(loop, fd) < 0) { + ERROR("[_loop_unregister_timer] Error unregistering fd from event loop"); + return -1; + } - return fd; + close(fd); + + return 0; } -int -_loop_unregister_timer(loop_t * loop, int fd) -{ - struct itimerspec ts = { - .it_interval = { - .tv_sec = 0, - .tv_nsec = 0, - }, - .it_value = { /* This value disables the timer */ - .tv_sec = 0, - .tv_nsec = 0, - } - }; - ts.it_value.tv_sec = 0; - - if (timerfd_settime(fd, 0, &ts, NULL) == -1) { - perror("timerfd_settime"); +int loop_callback(loop_t *loop, facemgr_cb_type_t type, void *data) { + switch (type) { + case FACEMGR_CB_TYPE_REGISTER_FD: { + fd_callback_data_t *fd_callback_data = (fd_callback_data_t *)data; + if (_loop_register_fd(loop, fd_callback_data->fd, fd_callback_data->owner, + fd_callback_data->callback, + fd_callback_data->data) < 0) { + ERROR("[loop_callback] Error registering fd to event loop"); return -1; + } + break; } - cb_wrapper_args_t * cb_wrapper_args; - if (timer_fd_map_remove(loop->timer_fd_map, fd, &cb_wrapper_args) < 0) { - ERROR("[_loop_unregister_timer] Could not remove cb_wrapper from timer map"); + case FACEMGR_CB_TYPE_UNREGISTER_FD: { + fd_callback_data_t *fd_callback_data = (fd_callback_data_t *)data; + /* We need a map to associate fd and events */ + if (_loop_unregister_fd(loop, fd_callback_data->fd) < 0) { + ERROR("[loop_callback] Error unregistering fd from event loop"); return -1; + } + break; } - assert(cb_wrapper_args); - free(cb_wrapper_args); - if (_loop_unregister_fd(loop, fd) < 0) { - ERROR("[_loop_unregister_timer] Error unregistering fd from event loop"); + case FACEMGR_CB_TYPE_REGISTER_TIMER: { + timer_callback_data_t *timer_callback_data = + (timer_callback_data_t *)data; + + int fd = _loop_register_timer(loop, timer_callback_data); + if (fd < 0) { + ERROR("[loop_callback] Error registering timer to event loop"); return -1; + } + return fd; } - return 0; -} + case FACEMGR_CB_TYPE_UNREGISTER_TIMER: { + int fd = *(int *)data; -int -loop_callback(loop_t * loop, facemgr_cb_type_t type, void * data) -{ - switch(type) { - case FACEMGR_CB_TYPE_REGISTER_FD: - { - fd_callback_data_t * fd_callback_data = (fd_callback_data_t *)data; - if (_loop_register_fd(loop, fd_callback_data->fd, - fd_callback_data->owner, - fd_callback_data->callback, - fd_callback_data->data) < 0) { - - ERROR("[loop_callback] Error registering fd to event loop"); - return -1; - } - break; - } - - case FACEMGR_CB_TYPE_UNREGISTER_FD: - { - fd_callback_data_t * fd_callback_data = (fd_callback_data_t *)data; - /* We need a map to associate fd and events */ - if (_loop_unregister_fd(loop, fd_callback_data->fd) < 0) { - ERROR("[loop_callback] Error unregistering fd from event loop"); - return -1; - } - break; - } - - case FACEMGR_CB_TYPE_REGISTER_TIMER: - { - timer_callback_data_t * timer_callback_data = (timer_callback_data_t *)data; - - int fd = _loop_register_timer(loop, timer_callback_data); - if (fd < 0) { - ERROR("[loop_callback] Error registering timer to event loop"); - return -1; - } - return fd; - - } - - case FACEMGR_CB_TYPE_UNREGISTER_TIMER: - { - int fd = *(int*)data; - - if (_loop_unregister_timer(loop, fd) < 0) { - ERROR("[loop_callback] Error unregistering timer from event loop"); - return -1; - } - return 0; - - } + if (_loop_unregister_timer(loop, fd) < 0) { + ERROR("[loop_callback] Error unregistering timer from event loop"); + return -1; + } + return 0; } - return 0; + } + return 0; } - diff --git a/ctrl/facemgr/src/main.c b/ctrl/facemgr/src/main.c index 344b034ae..18d2f8f7c 100644 --- a/ctrl/facemgr/src/main.c +++ b/ctrl/facemgr/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -24,7 +24,7 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <unistd.h> // sleep +#include <unistd.h> // sleep #include <hicn/facemgr.h> #include <hicn/facemgr/cfg.h> @@ -41,7 +41,7 @@ #if 0 static struct event_base * loop; #endif -static loop_t * loop = NULL; +static loop_t* loop = NULL; #ifdef __linux__ #ifdef WITH_THREAD @@ -49,210 +49,193 @@ static bool stop = false; #endif /* WITH_THREAD */ #endif /* __linux__ */ -static struct option long_options[] = -{ - {"config", required_argument, 0, 'c'}, - {0, 0, 0, 0} -}; +static struct option long_options[] = {{"config", required_argument, 0, 'c'}, + {0, 0, 0, 0}}; typedef struct { - char * cfgfile; + char* cfgfile; } facemgr_options_t; -void usage(const char * progname) -{ - printf("%s: Face manager daemon\n", progname); - printf("\n"); - printf("Usage: %s [OPTIONS]\n", progname); - printf("\n"); - printf("OPTIONS:\n"); - printf(" -c --config [FILE|none] Sets the configuration file (unless none, default: /etc/facemgr.conf, ~/facemgr.conf)\n"); - printf("\n"); +void usage(const char* progname) { + printf("%s: Face manager daemon\n", progname); + printf("\n"); + printf("Usage: %s [OPTIONS]\n", progname); + printf("\n"); + printf("OPTIONS:\n"); + printf( + " -c --config [FILE|none] Sets the configuration file (unless none, " + "default: /etc/facemgr.conf, ~/facemgr.conf)\n"); + printf("\n"); } void facemgr_signal_handler(int signal) { - fprintf(stderr, "Received ^C... quitting !\n"); - if (loop) { - loop_break(loop); + fprintf(stderr, "Received ^C... quitting !\n"); + if (loop) { + loop_break(loop); #ifdef __linux__ #ifdef WITH_THREAD stop = true; #endif /* WITH_THREAD */ #endif /* __linux__ */ - } + } } -int parse_cmdline(int argc, char ** argv, facemgr_options_t * opts) -{ - int c; - while ((c = getopt_long(argc, argv, "c:", long_options, NULL)) != -1) { - switch(c) { - case 'c': - opts->cfgfile = optarg; - break; - case ':': - case '?': - default: - usage(argv[0]); - exit(EXIT_FAILURE); - } - +int parse_cmdline(int argc, char** argv, facemgr_options_t* opts) { + int c; + while ((c = getopt_long(argc, argv, "c:", long_options, NULL)) != -1) { + switch (c) { + case 'c': + opts->cfgfile = optarg; + break; + case ':': + case '?': + default: + usage(argv[0]); + exit(EXIT_FAILURE); } - return 0; + } + return 0; } -#ifdef __linux__ - -#endif /* __linux__ */ - -int -dump_facelet(const facemgr_t * facemgr, const facelet_t * facelet, - void * user_data) -{ - char facelet_s[MAXSZ_FACELET]; - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); - DEBUG("%s", facelet_s); - return 0; +int dump_facelet(const facemgr_t* facemgr, const facelet_t* facelet, + void* user_data) { + char facelet_s[MAXSZ_FACELET]; + facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); + DEBUG("%s", facelet_s); + return 0; } -int main(int argc, char ** argv) -{ - facemgr_cfg_t * cfg = NULL; - facemgr_t * facemgr; +int main(int argc, char** argv) { + facemgr_cfg_t* cfg = NULL; + facemgr_t* facemgr; - struct sigaction sigIntHandler; - sigIntHandler.sa_handler = facemgr_signal_handler; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, NULL); + struct sigaction sigIntHandler; + sigIntHandler.sa_handler = facemgr_signal_handler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + sigaction(SIGINT, &sigIntHandler, NULL); - char cfgfile[PATH_MAX]; + char cfgfile[PATH_MAX]; - // TODO: default < config < commandline on a per option basis + // TODO: default < config < commandline on a per option basis - /* Commandline */ - facemgr_options_t cmdline_opts = {0}; - if (parse_cmdline(argc, argv, &cmdline_opts) < 0) { - ERROR("Error parsing commandline"); - goto ERR_CMDLINE; - } + /* Commandline */ + facemgr_options_t cmdline_opts = {0}; + if (parse_cmdline(argc, argv, &cmdline_opts) < 0) { + ERROR("Error parsing commandline"); + goto ERR_CMDLINE; + } - /* Configuration file */ - //facemgr_options_t cfgfile_opts; + /* Configuration file */ + // facemgr_options_t cfgfile_opts; - if (cmdline_opts.cfgfile) { - if (strcasecmp(cmdline_opts.cfgfile, "none") == 0) - goto NO_CFGFILE; + if (cmdline_opts.cfgfile) { + if (strcasecmp(cmdline_opts.cfgfile, "none") == 0) goto NO_CFGFILE; - if (!realpath(cmdline_opts.cfgfile, (char*)&cfgfile)) - goto ERR_PATH; + if (!realpath(cmdline_opts.cfgfile, (char*)&cfgfile)) goto ERR_PATH; - goto PARSE_CFGFILE; - } + goto PARSE_CFGFILE; + } - /* No commandline path specifed, probe default locations... */ + /* No commandline path specifed, probe default locations... */ - if (probe_cfgfile(cfgfile) < 0) - goto NO_CFGFILE; + if (probe_cfgfile(cfgfile) < 0) goto NO_CFGFILE; PARSE_CFGFILE: - DEBUG("Using configuration file %s", cfgfile); - cfg = facemgr_cfg_create(); - if (!cfg) - goto ERR_FACEMGR_CFG; + DEBUG("Using configuration file %s", cfgfile); + cfg = facemgr_cfg_create(); + if (!cfg) goto ERR_FACEMGR_CFG; - if (parse_config_file(cfgfile, cfg) < 0) { - ERROR("Error parsing configuration file %s", cfgfile); - goto ERR_PARSE; - } + if (parse_config_file(cfgfile, cfg) < 0) { + ERROR("Error parsing configuration file %s", cfgfile); + goto ERR_PARSE; + } - facemgr = facemgr_create_with_config(cfg); - if (!facemgr) - goto ERR_FACEMGR_CONFIG; + facemgr = facemgr_create_with_config(cfg); + if (!facemgr) goto ERR_FACEMGR_CONFIG; - goto MAIN_LOOP; + goto MAIN_LOOP; NO_CFGFILE: - facemgr = facemgr_create(); - if (!facemgr) - goto ERR_FACEMGR; + facemgr = facemgr_create(); + if (!facemgr) goto ERR_FACEMGR; MAIN_LOOP: - /* Main loop */ - loop = loop_create(); - facemgr_set_callback(facemgr, loop, (void*)loop_callback); + /* Main loop */ + loop = loop_create(); + if (!loop) { + ERROR("Failed to create main loop"); + goto ERR_LOOP; + } + facemgr_set_callback(facemgr, loop, (void*)loop_callback); #ifdef __ANDROID__ - facemgr_set_jvm(facemgr, NULL); + facemgr_set_jvm(facemgr, NULL); #endif /* __ ANDROID__ */ - DEBUG("Bootstrap..."); + DEBUG("Bootstrap..."); - if (facemgr_bootstrap(facemgr) < 0 ) - goto ERR_BOOTSTRAP; + if (facemgr_bootstrap(facemgr) < 0) goto ERR_BOOTSTRAP; - if (loop_dispatch(loop) < 0) { - ERROR("Failed to run main loop"); - return EXIT_FAILURE; - } + if (loop_dispatch(loop) < 0) { + ERROR("Failed to run main loop"); + goto ERR_DISPATCH; + } #ifdef __linux__ #ifdef WITH_THREAD - unsigned cpt = 0; - while(!stop) { - if (cpt == 10) { - DEBUG("<facelets>"); + unsigned cpt = 0; + while (!stop) { + if (cpt == 10) { + DEBUG("<facelets>"); #if 1 - facemgr_list_facelets(facemgr, dump_facelet, NULL); + facemgr_list_facelets(facemgr, dump_facelet, NULL); #else - char * buffer; - int n = facemgr_list_facelets_json(facemgr, &buffer); - printf("%s\n", buffer); - free(buffer); + char* buffer; + int n = facemgr_list_facelets_json(facemgr, &buffer); + printf("%s\n", buffer); + free(buffer); #endif - DEBUG("</facelets>"); - cpt = 0; - } - usleep(500000); - cpt++; + DEBUG("</facelets>"); + cpt = 0; } + usleep(500000); + cpt++; + } #endif /* WITH_THREAD */ #endif /* __linux__ */ - facemgr_stop(facemgr); + facemgr_stop(facemgr); - if (loop_undispatch(loop) < 0) { - ERROR("Failed to terminate main loop"); - return EXIT_FAILURE; - } + if (loop_undispatch(loop) < 0) { + ERROR("Failed to terminate main loop"); + } - facemgr_free(facemgr); + facemgr_free(facemgr); - if (cfg) - facemgr_cfg_free(cfg); + if (cfg) facemgr_cfg_free(cfg); - loop_free(loop); + loop_free(loop); - return EXIT_SUCCESS; + return EXIT_SUCCESS; ERR_BOOTSTRAP: + facemgr_free(facemgr); +ERR_DISPATCH: + loop_free(loop); +ERR_LOOP: - facemgr_free(facemgr); - loop_free(loop); ERR_FACEMGR_CONFIG: ERR_FACEMGR: ERR_PARSE: - if (cfg) - facemgr_cfg_free(cfg); + if (cfg) facemgr_cfg_free(cfg); ERR_FACEMGR_CFG: ERR_PATH: ERR_CMDLINE: - return EXIT_FAILURE; - - + return EXIT_FAILURE; } |