diff options
Diffstat (limited to 'ctrl/libhicnctrl/includes')
28 files changed, 2103 insertions, 1476 deletions
diff --git a/ctrl/libhicnctrl/includes/CMakeLists.txt b/ctrl/libhicnctrl/includes/CMakeLists.txt index 1a90690a4..554021c48 100644 --- a/ctrl/libhicnctrl/includes/CMakeLists.txt +++ b/ctrl/libhicnctrl/includes/CMakeLists.txt @@ -27,8 +27,29 @@ set(Libhicnctrl_INCLUDE_DIRS set(TO_INSTALL_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ctrl.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/api.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/action.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/callback.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/command.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/data.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/fw_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/hicn-light.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/hicn-light-ng.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/object.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/object_type.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/active_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/base.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/cache.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/connection.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/face.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/listener.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/mapme.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/policy.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/punting.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/route.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/strategy.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/objects/subscription.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/parse.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/route.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/socket.h PARENT_SCOPE ) diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl.h b/ctrl/libhicnctrl/includes/hicn/ctrl.h index 477afd152..4decdf10f 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl.h @@ -21,5 +21,6 @@ #define HICNCTRL_H #include <hicn/ctrl/api.h> +#include <hicn/ctrl/socket.h> #endif /* HICNCTRL_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/action.h b/ctrl/libhicnctrl/includes/hicn/ctrl/action.h new file mode 100644 index 000000000..55c4ebf77 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/action.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file action.h + * \brief Actions. + */ + +#ifndef HICNCTRL_ACTION_H +#define HICNCTRL_ACTION_H + +#define foreach_action \ + _(UNDEFINED) \ + _(CREATE) \ + _(UPDATE) \ + _(DELETE) \ + _(LIST) \ + _(GET) \ + _(SET) \ + _(SERVE) \ + _(STORE) \ + _(CLEAR) \ + _(SUBSCRIBE) \ + _(N) + +typedef enum { +#define _(x) ACTION_##x, + foreach_action +#undef _ +} hc_action_t; + +extern const char *action_str[]; + +#define action_str(x) action_str[x] + +hc_action_t action_from_str(const char *action_str); + +#endif /* HICNCTRL_ACTION_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h index c259fc10c..21a5e548f 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -58,8 +58,6 @@ * provide a set of defines to preserve backwards compatibility. At the * moment, those defines are : * - * WITH_POLICY: - * */ #ifndef HICNTRL_API @@ -69,9 +67,17 @@ #include <stdint.h> #include <stddef.h> // object_offset_t +#include <hicn/ctrl/action.h> +#include <hicn/ctrl/callback.h> +#include <hicn/ctrl/data.h> +#include <hicn/ctrl/object.h> +#include <hicn/ctrl/object_type.h> +#include <hicn/ctrl/objects.h> +#include <hicn/ctrl/socket.h> #include <hicn/util/ip_address.h> #include <hicn/face.h> #include <hicn/strategy.h> + #include <hicn/base.h> /* * This has to be common between hicn-light and hicn-plugin. We now we keep the @@ -79,13 +85,12 @@ */ #define SYMBOLIC_NAME_LEN 16 +#include <hicn/ctrl/objects.h> + #define HICN_DEFAULT_PORT 9695 #define HOTFIXMARGIN 0 -#define INVALID_FACE_ID ~0 -#define INVALID_NETDEVICE_ID ~0 - /** * \brief Defines the default size for the allocated data arrays holding the * results of API calls. @@ -105,336 +110,21 @@ })x) \ .b) #endif + +#define MAX2(x1, x2) (x1 > x2 ? x1 : x2) +#define MAX4(x1, x2, x3, x4) (MAX2(MAX2(x1, x2), MAX2(x3, x4))) +#define MAX8(x1, x2, x3, x4, x5, x6, x7, x8) \ + (MAX2(MAX4(x1, x2, x3, x4), MAX4(x5, x6, x7, x8))) + /****************************************************************************** * Message helper types and aliases ******************************************************************************/ -/* Action */ - -#define foreach_action \ - _(UNDEFINED) \ - _(CREATE) \ - _(UPDATE) \ - _(DELETE) \ - _(LIST) \ - _(SET) \ - _(SERVE) \ - _(STORE) \ - _(CLEAR) \ - _(GET) \ - _(N) - -typedef enum { -#define _(x) ACTION_##x, - foreach_action -#undef _ -} hc_action_t; - -extern const char *action_str[]; - -#define action_str(x) action_str[x] - -hc_action_t action_from_str(const char *action_str); - -/* Object type */ - -#define foreach_object \ - _(UNDEFINED) \ - _(CONNECTION) \ - _(LISTENER) \ - _(ROUTE) \ - _(FACE) \ - _(STRATEGY) \ - _(PUNTING) \ - _(POLICY) \ - _(CACHE) \ - _(MAPME) \ - _(LOCAL_PREFIX) \ - _(PROBE) \ - _(SUBSCRIPTION) \ - _(STATS) \ - _(N) - -typedef enum { -#define _(x) OBJECT_##x, - foreach_object -#undef _ -} hc_object_type_t; - -extern const char *object_str[]; - -#define object_str(x) object_str[x] - -hc_object_type_t object_from_str(const char *object_str); - -#define IS_VALID_OBJECT_TYPE(x) IS_VALID_ENUM_TYPE(OBJECT, x) -#define IS_VALID_ACTION(x) IS_VALID_ENUM_TYPE(ACTION, x) - /** * \brief hICN control message header */ typedef struct hc_msg_s hc_msg_t; typedef struct hc_result_s hc_result_t; -/****************************************************************************** - * Control Data - ******************************************************************************/ - -struct hc_data_s; -typedef int (*data_callback_t)(struct hc_data_s *, void *); - -/** - * \brief Holds the results of an hICN control request - */ -typedef struct hc_data_s { - size_t size; - size_t current; - size_t max_size_log; - size_t in_element_size; - size_t out_element_size; - u8 command_id; /**< Expected message type (should give element size) */ - u8 *buffer; - bool complete; - - /* Callbacks */ - data_callback_t - complete_cb; // XXX int (*complete_cb)(struct hc_data_s * data); - void *complete_cb_data; - int ret; -} hc_data_t; - -/** - * Create a structure holding the results of an hICN control request. - * \result The newly create data structure. - */ -hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size, - data_callback_t complete_cb); - -/** - * Free a structure holding the results of an hICN control request. - * \param [in] data - The data structure to free. - */ -void hc_data_free(hc_data_t *data); - -/** - * \brief Adds many new results at the end of the data structure, eventually - * allocating buffer space for it. - * \param [in] data - The data structure to which to add elements. - * \param [in] elements - The array of elements to add. - * \param [in] count - The number of elements to add. - * \return Error code - * - * NOTE: The size of the element should match the one declared at structure - * initialization. - */ -int hc_data_push_many(hc_data_t *data, const void *elements, size_t count); - -/** - * \brief Adds a new result at the end of the data structure, eventually - * allocating buffer space for it. - * \param [in] data - The data structure to which to add an element. - * \param [in] element - The element to add - * \return Error code - * - * NOTE: The size of the element should match the one declared at structure - * initialization. - */ -int hc_data_push(hc_data_t *data, const void *element); - -/** - * \brief Configure a callback (along with private data) to be called upon - * completion of a request - * \param [in] data - hICN control data - * \param [in] cb - Callback function - * \param [in] cb_data - Callback private data - */ -int hc_data_set_callback(hc_data_t *data, data_callback_t cb, void *cb_data); - -/** - * \brief Mark the data structure as complete. - * \param [in] data - The data structure to which to add an element. - * \return The error code resulting from callback execution if any. 0 is - * returned if the callback executed successfully, or if no callback were - * defined. - */ -int hc_data_set_complete(hc_data_t *data); - -/** - * \brief Reset the data structure holding control data - * \param [in] data - hICN control data - * \return Error code - */ -int hc_data_reset(hc_data_t *data); - -/** - * \brief Find en element in the data structure - * \param [in] data - The data structure in which to find - * \param [in] element - The element to find - * \param [out] found - A pointer to the element, or NULL if not found. - * \return Error code - */ -#define GENERATE_FIND_HEADER(TYPE) \ - int hc_##TYPE##_find(hc_data_t *data, const hc_##TYPE##_t *element, \ - hc_##TYPE##_t **found) - -#define GENERATE_FIND(TYPE) \ - int hc_##TYPE##_find(hc_data_t *data, const hc_##TYPE##_t *element, \ - hc_##TYPE##_t **found) { \ - foreach_type(hc_##TYPE##_t, x, data) { \ - if (hc_##TYPE##_cmp(x, element) == 0) { \ - *found = x; \ - return 0; \ - } \ - }; \ - *found = NULL; /* this is optional */ \ - return 0; \ - } - -/****************************************************************************** - * Control socket - ******************************************************************************/ - -/* With UDP, the buffer should be able to receieve a full packet, and thus MTU - * (max 9000) is sufficient. Messages will be received fully one by one. - * With TCP, the buffer should be at least able to receive a message header and - * the maximum size of a data element, so any reasonable size will be correct, - * it might just optimize performance. Messages might arrive in chunks that the - * library is able to parse. - */ -#define JUMBO_MTU 9000 -#define RECV_BUFLEN 65535 - -#define foreach_forwarder_type \ - _(UNDEFINED) \ - _(HICNLIGHT) \ - _(HICNLIGHT_NG) \ - _(VPP) \ - _(N) - -typedef enum { -#define _(x) x, - foreach_forwarder_type -#undef _ -} forwarder_type_t; - -/** - * \brief Holds the state of an hICN control socket - */ -typedef struct hc_sock_s hc_sock_t; - -/** - * \brief Create an hICN control socket using the specified URL. - * \param [in] url - The URL to connect to. - * \return an hICN control socket - */ -hc_sock_t *hc_sock_create_url(const char *url); - -/** - * \brief Create an hICN control socket using the provided forwarder. - * \return an hICN control socket - */ -hc_sock_t *hc_sock_create_forwarder(forwarder_type_t forwarder); - -/** - * \brief Create an hICN control socket using the provided forwarder and a URL. - * \return an hICN control socket - */ -hc_sock_t *hc_sock_create_forwarder_url(forwarder_type_t forwarder, - const char *url); - -/** - * \brief Create an hICN control socket using the default connection type. - * \return an hICN control socket - */ -hc_sock_t *hc_sock_create(void); - -/** - * \brief Frees an hICN control socket - * \param [in] s - hICN control socket - */ -void hc_sock_free(hc_sock_t *s); - -/** - * \brief Returns the next available sequence number to use for requests to the - * API. - * \param [in] s - hICN control socket - */ -int hc_sock_get_next_seq(hc_sock_t *s); - -/** - * \brief Sets the socket as non-blocking - * \param [in] s - hICN control socket - * \return Error code - */ -int hc_sock_set_nonblocking(hc_sock_t *s); - -/** - * \brief Return the file descriptor associated to the hICN contorl sock - * \param [in] s - hICN control socket - * \return The file descriptor (positive value), or a negative integer in case - * of error - */ -int hc_sock_get_fd(hc_sock_t *s); - -/** - * \brief Connect the socket - * \return Error code - */ -int hc_sock_connect(hc_sock_t *s); - -/** - * \brief Return the offset and size of available buffer space - * \param [in] s - hICN control socket - * \param [out] buffer - Offset in buffer - * \param [out] size - Remaining size - * \return Error code - */ -int hc_sock_get_available(hc_sock_t *s, u8 **buffer, size_t *size); - -/** - * \brief Write/read iexchance on the control socket (internal helper function) - * \param [in] s - hICN control socket - * \param [in] msg - Message to send - * \param [in] msglen - Length of the message to send - * \return Error code - */ -int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen, uint32_t seq); - -/** - * \brief Helper for reading socket contents - * \param [in] s - hICN control socket - * \return Error code - */ -int hc_sock_recv(hc_sock_t *s); - -/** - * \brief Processing data received by socket - * \param [in] s - hICN control socket - * \param [in] parse - Parse function to convert remote types into lib native - * types, or NULL not to perform any translation. - * \return Error code - */ -int hc_sock_process(hc_sock_t *s, hc_data_t **data); - -/** - * \brief Callback used in async mode when data is available on the socket - * \param [in] s - hICN control socket - * \return Error code - */ -int hc_sock_callback(hc_sock_t *s, hc_data_t **data); - -/** - * \brief Reset the state of the sock (eg. to handle a reconnecton) - * \param [in] s - hICN control socket - * \return Error code - */ -int hc_sock_reset(hc_sock_t *s); - -void hc_sock_increment_woff(hc_sock_t *s, size_t bytes); - -int hc_sock_prepare_send(hc_sock_t *s, hc_result_t *result, - data_callback_t complete_cb, void *complete_cb_data); - -int hc_sock_set_recv_timeout_ms(hc_sock_t *s, long timeout_ms); /****************************************************************************** * Command-specific structures and functions @@ -448,7 +138,8 @@ int hc_sock_set_recv_timeout_ms(hc_sock_t *s, long timeout_ms); * * We redefine command struct: * - for uniformization - * - to use enum instead of type specifiers more appropriate for packet format + * - to use enum instead of type specifiers more appropriate for packet + * format * - to use more flexible types such as for manipulating IP addresses * - host endianness * - more intuitive field name, ordering, consistency, and hierarchy removal @@ -460,9 +151,9 @@ int hc_sock_set_recv_timeout_ms(hc_sock_t *s, long timeout_ms); * * RETURN DATA FIXME * - * \param [out] pdata - Pointer to the structure storing the results of the call - * (NULL if no data has been received). If the pointer is NULL, no result will - * be stored and only the error code will be exposed to the caller. It is + * \param [out] pdata - Pointer to the structure storing the results of the + * call (NULL if no data has been received). If the pointer is NULL, no result + * will be stored and only the error code will be exposed to the caller. It is * expected that the caller frees this structure using hc_data_free() after * usage. * \see hc_data_free. @@ -487,147 +178,134 @@ int hc_sock_set_recv_timeout_ms(hc_sock_t *s, long timeout_ms); #define NULLTERM 1 #endif -#define INTERFACE_LEN 16 - #define MAXSZ_HC_NAME_ SYMBOLIC_NAME_LEN #define MAXSZ_HC_NAME MAXSZ_HC_NAME_ + NULLTERM #define MAXSZ_HC_ID_ 10 /* Number of digits for MAX_INT */ #define MAXSZ_HC_ID MAXSZ_HC_ID_ + NULLTERM -#define foreach_type(TYPE, VAR, data) \ - for (TYPE *VAR = (TYPE *)data->buffer; \ - VAR < (TYPE *)(data->buffer + data->size * data->out_element_size); \ - VAR++) - -typedef int (*HC_PARSE)(const u8 *, u8 *); +#if 0 +#define foreach_type(TYPE, VAR, data) \ + for (TYPE *VAR = (TYPE *)data->buffer; \ + VAR < (TYPE *)((data)->buffer + (data)->size * sizeof(TYPE)); VAR++) +#endif #define INPUT_ERROR -2 #define UNSUPPORTED_CMD_ERROR -3 /*----------------------------------------------------------------------------* - * Listeners + * Strategy *----------------------------------------------------------------------------*/ -// FIXME the listener should not require any port for hICN... -typedef struct { - char name[SYMBOLIC_NAME_LEN]; /* K.w */ // XXX clarify what used for - char interface_name[INTERFACE_LEN]; /* Kr. */ - u32 id; - face_type_t type; /* .rw */ - int family; /* .rw */ - ip_address_t local_addr; /* .rw */ - u16 local_port; /* .rw */ -} hc_listener_t; +/*----------------------------------------------------------------------------* + * WLDR + *----------------------------------------------------------------------------*/ -int hc_listener_create(hc_sock_t *s, hc_listener_t *listener); -/* listener_found might eventually be allocated, and needs to be freed */ -hc_result_t *hc_listener_create_conf(hc_sock_t *s, hc_listener_t *listener); -int hc_listener_get(hc_sock_t *s, hc_listener_t *listener, - hc_listener_t **listener_found); -int hc_listener_delete(hc_sock_t *s, hc_listener_t *listener); -int hc_listener_list(hc_sock_t *s, hc_data_t **pdata); -hc_result_t *hc_listener_list_conf(hc_sock_t *s); +// per connection +int hc_wldr_set(hc_sock_t *s /* XXX */); -int hc_listener_validate(const hc_listener_t *listener); -int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2); +/*----------------------------------------------------------------------------* + * MAP-Me + *----------------------------------------------------------------------------*/ -#define foreach_listener(VAR, data) foreach_type(hc_listener_t, VAR, data) +/*----------------------------------------------------------------------------* + * Policies + *----------------------------------------------------------------------------*/ -#define MAXSZ_HC_LISTENER_ \ - INTERFACE_LEN + SPACE + MAXSZ_URL_ + SPACE + MAXSZ_FACE_TYPE_ -#define MAXSZ_HC_LISTENER MAXSZ_HC_LISTENER_ + NULLTERM +/*----------------------------------------------------------------------------* + * Subscription + *----------------------------------------------------------------------------*/ +// Topics -GENERATE_FIND_HEADER(listener); +#if 0 +/* Result */ -int hc_listener_snprintf(char *s, size_t size, hc_listener_t *listener); +hc_msg_t *hc_result_get_msg(hc_sock_t *s, hc_result_t *result); +int hc_result_get_cmd_id(hc_sock_t *s, hc_result_t *result); +bool hc_result_get_success(hc_sock_t *s, hc_result_t *result); +void hc_result_free(hc_result_t *result); +#endif -/*----------------------------------------------------------------------------* - * Connections - *----------------------------------------------------------------------------*/ +/* Object */ + +// FIXME +#define MAXSZ_HC_SUBSCRIPTION 1 + +#define MAXSZ_HC_OBJECT \ + MAX8(MAXSZ_HC_CONNECTION, MAXSZ_HC_LISTENER, MAXSZ_HC_ROUTE, MAXSZ_HC_FACE, \ + MAXSZ_HC_PUNTING, MAXSZ_HC_STRATEGY, MAXSZ_HC_POLICY, \ + MAXSZ_HC_SUBSCRIPTION) -/* - * NOTE : - * - interface_name is mainly used to derive listeners from connections, - * but is not itself used to create connections. - */ typedef struct { - u32 id; /* Kr. */ - char name[SYMBOLIC_NAME_LEN]; /* K.w */ - char interface_name[INTERFACE_LEN]; /* Kr. */ - face_type_t type; /* .rw */ - int family; /* .rw */ - ip_address_t local_addr; /* .rw */ - u16 local_port; /* .rw */ - ip_address_t remote_addr; /* .rw */ - u16 remote_port; /* .rw */ - face_state_t admin_state; /* .rw */ -#ifdef WITH_POLICY - uint32_t priority; /* .rw */ - policy_tags_t tags; /* .rw */ -#endif /* WITH_POLICY */ - face_state_t state; /* .r. */ -} hc_connection_t; + hc_action_t action; + hc_object_type_t object_type; + hc_object_t object; +} hc_command_t; + +// NEW API CALLS + +// XXX private ? +int _hc_execute(hc_sock_t *s, hc_action_t action, hc_object_type_t object_type, + hc_object_t *object, hc_result_callback_t callback, + void *callback_data, hc_data_t **pdata); +int hc_execute(hc_sock_t *s, hc_action_t action, hc_object_type_t object_type, + hc_object_t *object, hc_data_t **pdata); +int hc_execute_async(hc_sock_t *s, hc_action_t action, + hc_object_type_t object_type, hc_object_t *object, + hc_result_callback_t callback, void *callback_data); + +int hc_object_create(hc_sock_t *s, hc_object_type_t object_type, + hc_object_t *object); +int hc_object_get(hc_sock_t *s, hc_object_type_t object_type, + hc_object_t *object, hc_object_t **found); +int hc_object_delete(hc_sock_t *s, hc_object_type_t object_type, + hc_object_t *object); +int hc_object_list(hc_sock_t *s, hc_object_type_t object_type, + hc_data_t **pdata); + +/* Former API */ + +int hc_listener_create(hc_sock_t *s, hc_listener_t *listener); +/* listener_found might eventually be allocated, and needs to be freed */ +int hc_listener_get(hc_sock_t *s, hc_listener_t *listener, hc_data_t **pdata); +int hc_listener_delete(hc_sock_t *s, hc_listener_t *listener); +int hc_listener_list(hc_sock_t *s, hc_data_t **pdata); int hc_connection_create(hc_sock_t *s, hc_connection_t *connection); -hc_result_t *hc_connection_create_conf(hc_sock_t *s, - hc_connection_t *connection); -/* connection_found will be allocated, and must be freed */ +/* connection_found might eventually be allocated, and needs to be freed */ int hc_connection_get(hc_sock_t *s, hc_connection_t *connection, - hc_connection_t **connection_found); + hc_data_t **pdata); +int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection); int hc_connection_update_by_id(hc_sock_t *s, int hc_connection_id, hc_connection_t *connection); int hc_connection_update(hc_sock_t *s, hc_connection_t *connection_current, hc_connection_t *connection_updated); -int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection); -hc_result_t *hc_connection_delete_conf(hc_sock_t *s, - hc_connection_t *connection); +int hc_connection_list(hc_sock_t *s, hc_data_t **pdata); + +int hc_connection_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, + face_state_t state); +int hc_connection_set_priority(hc_sock_t *s, const char *conn_id_or_name, + uint32_t priority); +int hc_connection_set_tags(hc_sock_t *s, const char *conn_id_or_name, + policy_tags_t tags); + /* int hc_connection_remove_by_id(hc_sock_t * s, char * name); int hc_connection_remove_by_name(hc_sock_t * s, char * name); */ -int hc_connection_list(hc_sock_t *s, hc_data_t **pdata); - -int hc_connection_validate(const hc_connection_t *connection); -int hc_connection_cmp(const hc_connection_t *c1, const hc_connection_t *c2); int hc_connection_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, face_state_t state); -#ifdef WITH_POLICY int hc_connection_set_priority(hc_sock_t *s, const char *conn_id_or_name, uint32_t priority); int hc_connection_set_tags(hc_sock_t *s, const char *conn_id_or_name, policy_tags_t tags); -#endif /* WITH_POLICY */ - -#define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) - -#define MAXSZ_HC_CONNECTION_ \ - MAXSZ_FACE_STATE_ + INTERFACE_LEN + SPACE + 2 * MAXSZ_URL_ + \ - MAXSZ_FACE_TYPE_ + SPACES(3) -#define MAXSZ_HC_CONNECTION MAXSZ_HC_CONNECTION_ + NULLTERM - -GENERATE_FIND_HEADER(connection); -int hc_connection_snprintf(char *s, size_t size, - const hc_connection_t *connection); - -/*----------------------------------------------------------------------------* - * Faces - * - * A face is an abstraction introduced by the control library to abstract the - * forwarder implementation details. It encompasses connections and listeners - * and ensures the right dependencies are enforced, eg that we always have a - * listener when a connection is created. - * - *----------------------------------------------------------------------------*/ - -typedef struct { - face_id_t id; - char name[SYMBOLIC_NAME_LEN]; - face_t face; // or embed ? - // face_id_t parent; /* Pointer from connection to listener */ -} hc_face_t; +int hc_route_create(hc_sock_t *s, hc_route_t *route); +// hc_result_t *hc_route_create_conf(hc_sock_t *s, hc_route_t *route); +int hc_route_delete(hc_sock_t *s, hc_route_t *route); +int hc_route_list(hc_sock_t *s, hc_data_t **pdata); +int hc_route_list_async(hc_sock_t *s); /** * \brief Create a face @@ -638,194 +316,27 @@ typedef struct { * The face parameters will be updated with the face ID. */ int hc_face_create(hc_sock_t *s, hc_face_t *face); -int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_face_t **face_found); -int hc_face_delete(hc_sock_t *s, hc_face_t *face, uint8_t delete_listener); +int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_data_t **pdata); +int hc_face_delete(hc_sock_t *s, + hc_face_t *face); //, uint8_t delete_listener); int hc_face_list(hc_sock_t *s, hc_data_t **pdata); -int hc_face_list_async(hc_sock_t *s); //, hc_data_t ** pdata); +int hc_face_list_async(hc_sock_t *s); int hc_face_set_admin_state(hc_sock_t *s, const char *conn_id_or_name, face_state_t state); -#ifdef WITH_POLICY int hc_face_set_priority(hc_sock_t *s, const char *conn_id_or_name, uint32_t priority); int hc_face_set_tags(hc_sock_t *s, const char *conn_id_or_name, policy_tags_t tags); -#endif /* WITH_POLICY */ - -#define foreach_face(VAR, data) foreach_type(hc_face_t, VAR, data) - -#define MAX_FACE_ID 255 -#define MAXSZ_FACE_ID_ 3 -#define MAXSZ_FACE_ID MAXSZ_FACE_ID_ + NULLTERM -#define MAXSZ_FACE_NAME_ SYMBOLIC_NAME_LEN -#define MAXSZ_FACE_NAME MAXSZ_FACE_NAME_ + NULLTERM - -#define MAXSZ_HC_FACE_ \ - MAXSZ_FACE_ID_ + MAXSZ_FACE_NAME_ + MAXSZ_FACE_ + 5 + HOTFIXMARGIN -#define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM - -int hc_face_snprintf(char *s, size_t size, hc_face_t *face); -/*----------------------------------------------------------------------------* - * Routes - *----------------------------------------------------------------------------*/ - -typedef struct { - face_id_t face_id; /* Kr. use when name == NULL */ - char name[SYMBOLIC_NAME_LEN]; /* Kr. use by default vs face_id */ - int family; /* Krw */ - ip_address_t remote_addr; /* krw */ - u8 len; /* krw */ - u16 cost; /* .rw */ - hc_face_t face; /* TODO remove, used by hicn_plugin_api */ -} hc_route_t; - -int hc_route_create(hc_sock_t *s, hc_route_t *route); -hc_result_t *hc_route_create_conf(hc_sock_t *s, hc_route_t *route); -int hc_route_delete(hc_sock_t *s, hc_route_t *route); -int hc_route_list(hc_sock_t *s, hc_data_t **pdata); -int hc_route_list_async(hc_sock_t *s); - -#define foreach_route(VAR, data) foreach_type(hc_route_t, VAR, data) - -#define MAX_COST 65535 -#define MAXSZ_COST 5 -#define MAX_LEN 255 -#define MAXSZ_LEN 3 - -#define MAXSZ_HC_ROUTE_ \ - MAXSZ_FACE_ID + 1 + MAXSZ_COST + 1 + MAXSZ_IP_ADDRESS + 1 + MAXSZ_LEN -#define MAXSZ_HC_ROUTE MAXSZ_HC_ROUTE_ + NULLTERM - -int hc_route_snprintf(char *s, size_t size, hc_route_t *route); -int hc_route_validate(const hc_route_t *route); - -/*----------------------------------------------------------------------------* - * Punting - *----------------------------------------------------------------------------*/ - -typedef struct { - face_id_t face_id; /* Kr. */ // XXX listener id, could be NULL for all ? - int family; /* Krw */ - ip_address_t prefix; /* krw */ - u8 prefix_len; /* krw */ -} hc_punting_t; - -int hc_punting_create(hc_sock_t *s, hc_punting_t *punting); -int hc_punting_get(hc_sock_t *s, hc_punting_t *punting, - hc_punting_t **punting_found); -int hc_punting_delete(hc_sock_t *s, hc_punting_t *punting); -int hc_punting_list(hc_sock_t *s, hc_data_t **pdata); - -int hc_punting_validate(const hc_punting_t *punting); -int hc_punting_cmp(const hc_punting_t *c1, const hc_punting_t *c2); - -#define foreach_punting(VAR, data) foreach_type(hc_punting_t, VAR, data) - -#define MAXSZ_HC_PUNTING_ 0 -#define MAXSZ_HC_PUNTING MAXSZ_HC_PUNTING_ + NULLTERM - -GENERATE_FIND_HEADER(punting); - -int hc_punting_snprintf(char *s, size_t size, hc_punting_t *punting); - -/*----------------------------------------------------------------------------* - * Cache - *----------------------------------------------------------------------------*/ - -typedef struct { - uint8_t serve; // 1 = on, 0 = off - uint8_t store; // 1 = on, 0 = off -} hc_cache_t; - -typedef struct { - bool store; - bool serve; - size_t cs_size; - size_t num_stale_entries; -} hc_cache_info_t; +int hc_strategy_list(hc_sock_t *s, hc_data_t **data); +int hc_strategy_set(hc_sock_t *s, hc_strategy_t *strategy); +int hc_strategy_add_local_prefix(hc_sock_t *s, hc_strategy_t *strategy); int hc_cache_set_store(hc_sock_t *s, hc_cache_t *cache); int hc_cache_set_serve(hc_sock_t *s, hc_cache_t *cache); int hc_cache_clear(hc_sock_t *s, hc_cache_t *cache); int hc_cache_list(hc_sock_t *s, hc_data_t **pdata); -int hc_cache_snprintf(char *s, size_t size, const hc_cache_info_t *cache_info); - -/*----------------------------------------------------------------------------* - * Strategy - *----------------------------------------------------------------------------*/ - -#define MAXSZ_STRATEGY_NAME 255 - -typedef struct { - // The name is not set by the controller - // but populated by the daemon - char name[MAXSZ_STRATEGY_NAME]; - strategy_type_t type; - ip_address_t address, local_address; - int family, local_family; - u8 len, local_len; -} hc_strategy_t; - -int hc_strategy_list(hc_sock_t *s, hc_data_t **data); - -#define foreach_strategy(VAR, data) foreach_type(hc_strategy_t, VAR, data) - -#define MAXSZ_HC_STRATEGY_ MAXSZ_STRATEGY_NAME -#define MAXSZ_HC_STRATEGY MAXSZ_HC_STRATEGY_ + NULLTERM - -int hc_strategy_snprintf(char *s, size_t size, hc_strategy_t *strategy); - -// per prefix -int hc_strategy_set(hc_sock_t *s, hc_strategy_t *strategy); -hc_result_t *hc_strategy_set_conf(hc_sock_t *s, hc_strategy_t *strategy); -int hc_strategy_add_local_prefix(hc_sock_t *s, hc_strategy_t *strategy); -hc_result_t *hc_strategy_add_local_prefix_conf(hc_sock_t *s, - hc_strategy_t *strategy); -/*----------------------------------------------------------------------------* - * WLDR - *----------------------------------------------------------------------------*/ - -// per connection -int hc_wldr_set(hc_sock_t *s /* XXX */); - -/*----------------------------------------------------------------------------* - * MAP-Me - *----------------------------------------------------------------------------*/ - -typedef enum { - MAPME_TARGET_ENABLE, - MAPME_TARGET_DISCOVERY, - MAPME_TARGET_TIMESCALE, - MAPME_TARGET_RETX, -} mapme_target_t; - -static inline mapme_target_t mapme_target_from_str(char *mapme_target_str) { - if (strcasecmp(mapme_target_str, "enable") == 0) - return MAPME_TARGET_ENABLE; - else if (strcasecmp(mapme_target_str, "discovery") == 0) - return MAPME_TARGET_DISCOVERY; - else if (strcasecmp(mapme_target_str, "timescale") == 0) - return MAPME_TARGET_TIMESCALE; - else - return MAPME_TARGET_RETX; -} - -#define MAX_MAPME_ARG_LEN 30 - -typedef struct { - mapme_target_t target; - // Command argument stored as a string - // before being parsed into 'enabled' or 'timescale' - char unparsed_arg[MAX_MAPME_ARG_LEN]; - - uint8_t enabled; // 1 = on, 0 = off - uint32_t timescale; // Milliseconds - - ip_address_t address; - int family; - u8 len; -} hc_mapme_t; int hc_mapme_set(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_set_discovery(hc_sock_t *s, hc_mapme_t *mapme); @@ -833,145 +344,21 @@ int hc_mapme_set_timescale(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_set_retx(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_send_update(hc_sock_t *s, hc_mapme_t *mapme); -/*----------------------------------------------------------------------------* - * Policies - *----------------------------------------------------------------------------*/ - -#ifdef WITH_POLICY - -typedef struct { - int family; /* Krw */ - ip_address_t remote_addr; /* krw */ - u8 len; /* krw */ - hicn_policy_t policy; /* .rw */ -} hc_policy_t; - int hc_policy_create(hc_sock_t *s, hc_policy_t *policy); int hc_policy_delete(hc_sock_t *s, hc_policy_t *policy); int hc_policy_list(hc_sock_t *s, hc_data_t **pdata); -#define foreach_policy(VAR, data) foreach_type(hc_policy_t, VAR, data) - -/* TODO */ -#define MAXSZ_HC_POLICY_ 0 -#define MAXSZ_HC_POLICY MAXSZ_HC_POLICY_ + NULLTERM - -int hc_policy_snprintf(char *s, size_t size, hc_policy_t *policy); -int hc_policy_validate(const hc_policy_t *policy); - -#endif /* WITH_POLICY */ - -/*----------------------------------------------------------------------------* - * Subscription - *----------------------------------------------------------------------------*/ -// Topics - -#undef PUNTING // TODO(eloparco): Undefined to avoid collisions - // Fix the collision - -// Used only to create 'hc_topic_t' -typedef struct { -#define _(x) char x; - foreach_object -#undef _ -} object_offset_t; - -// Flags for topic subscriptions -typedef enum { -#define _(x) TOPIC_##x = (1 << offsetof(object_offset_t, x)), - foreach_object -#undef _ -} hc_topic_t; - -static inline hc_object_type_t object_from_topic(hc_topic_t topic) { -#define _(x) \ - if (topic == TOPIC_##x) return OBJECT_##x; - foreach_object -#undef _ - return OBJECT_UNDEFINED; -} - -#define NUM_TOPICS OBJECT_N // Because a topic is created for each object -#define ALL_TOPICS ~0 - -// Subscriptions -typedef uint32_t hc_topics_t; -typedef struct { - hc_topics_t topics; -} hc_subscription_t; +int hc_punting_create(hc_sock_t *s, hc_punting_t *punting); +int hc_punting_get(hc_sock_t *s, hc_punting_t *punting, + hc_punting_t **punting_found); +int hc_punting_delete(hc_sock_t *s, hc_punting_t *punting); +int hc_punting_list(hc_sock_t *s, hc_data_t **pdata); int hc_subscription_create(hc_sock_t *s, hc_subscription_t *subscription); int hc_subscription_delete(hc_sock_t *s, hc_subscription_t *subscription); -hc_result_t *hc_subscription_create_conf(hc_sock_t *s, - hc_subscription_t *subscription); -hc_result_t *hc_subscription_delete_conf(hc_sock_t *s, - hc_subscription_t *subscription); - -/*----------------------------------------------------------------------------* - * Events - *----------------------------------------------------------------------------*/ -#define foreach_event_type \ - _(UNDEFINED) \ - _(INTERFACE_UPDATE) \ - _(N) -typedef enum { -#define _(x) EVENT_##x, - foreach_event_type -#undef _ -} event_type_t; - -extern const char *event_str[]; -#define event_str(x) event_str[x] - -typedef enum { - FLAG_INTERFACE_TYPE_WIRED = 0x1, - FLAG_INTERFACE_TYPE_WIFI = 0x2, - FLAG_INTERFACE_TYPE_CELLULAR = 0x4, -} flag_interface_type_t; - -typedef struct { - flag_interface_type_t interface_type; -} hc_event_interface_update_t; -/*----------------------------------------------------------------------------* - * Statistics - *----------------------------------------------------------------------------*/ int hc_stats_get(hc_sock_t *s, hc_data_t **pdata); // General stats int hc_stats_list(hc_sock_t *s, hc_data_t **pdata); // Per-face stats int hc_stats_snprintf(char *s, size_t size, const hicn_light_stats_t *stats); -/* Result */ - -hc_msg_t *hc_result_get_msg(hc_sock_t *s, hc_result_t *result); -int hc_result_get_cmd_id(hc_sock_t *s, hc_result_t *result); -bool hc_result_get_success(hc_sock_t *s, hc_result_t *result); -void hc_result_free(hc_result_t *result); - -/* Object */ - -typedef struct { - hc_object_type_t type; - union { - hc_connection_t connection; - hc_listener_t listener; - hc_route_t route; - hc_face_t face; - // hc_data_t *data; - hc_punting_t punting; - hc_strategy_t strategy; -#ifdef WITH_POLICY - hc_policy_t policy; -#endif /* WITH_POLICY */ - hc_subscription_t subscription; - hc_cache_t cache; - hc_mapme_t mapme; - uint8_t as_uint8; - }; -} hc_object_t; - -typedef struct { - hc_action_t action; - hc_object_t object; -} hc_command_t; - #endif /* HICNTRL_API */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/callback.h b/ctrl/libhicnctrl/includes/hicn/ctrl/callback.h new file mode 100644 index 000000000..5b7f424d6 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/callback.h @@ -0,0 +1,13 @@ +#ifndef HICNCTRL_CALLBACK_H +#define HICNCTRL_CALLBACK_H + +#include <stdbool.h> + +#include <hicn/ctrl/data.h> + +typedef int (*hc_enable_callback_t)(bool enable); +typedef void (*hc_state_callback_t)(bool enable, void *user_data); +typedef void (*hc_result_callback_t)(hc_data_t *data, void *user_data); +typedef void (*hc_notification_callback_t)(hc_data_t *data, void *user_data); + +#endif /* HICNCTRL_CALLBACK_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/command.h b/ctrl/libhicnctrl/includes/hicn/ctrl/command.h new file mode 100644 index 000000000..1824d14c2 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/command.h @@ -0,0 +1,191 @@ +#ifndef HICNLIGHT_CONFIG_COMMAND +#define HICNLIGHT_CONFIG_COMMAND + +/** + * @file command.h + * @brief Commands. + */ + +#include <stddef.h> // offsetof +#include <hicn/util/ip_address.h> + +#include <hicn/ctrl/api.h> + +/* Update sscanf accordingly in parse_cmd.c */ +#define MAX_PARAMETERS 10 +#define MAX_SCANF_PARAM_LEN 100 + +typedef int (*parser_hook_t)(void *arg); + +typedef enum { + TYPENAME_UNDEFINED, + TYPENAME_INT, + TYPENAME_UINT, + TYPENAME_INT16, + TYPENAME_UINT16, + TYPENAME_STR, + TYPENAME_SYMBOLIC_OR_ID, + TYPENAME_INTERFACE_NAME, + TYPENAME_IP_ADDRESS, + TYPENAME_IP_PREFIX, + TYPENAME_ON_OFF, + TYPENAME_ENUM, + TYPENAME_POLICY_STATE, +} parser_typename_t; + +typedef struct { + parser_typename_t name; + union { + struct { + size_t max_size; + } str; + struct { + int min; + int max; + } integer; + struct { + int (*from_str)(const char *str); + } enum_; + struct { + policy_tag_t tag; + } policy_state; + }; +} parser_type_t; + +typedef struct { + const char *name; + const char *help; + parser_type_t type; + size_t offset; + /* + * quick hack to let the functions update two or more parameters, like for + * IP_ADDRESS or IP_PREFIX types + */ + size_t offset2; + size_t offset3; +} command_parameter_t; + +typedef struct { + hc_action_t action; + hc_object_type_t object_type; + unsigned nparams; + command_parameter_t parameters[MAX_PARAMETERS]; + parser_hook_t post_hook; +} command_parser_t; + +/* + * NOTE: we now use strings everywhere to parse in the same way parameters + * coming from the commandline through getopt (strings), and those coming from + * sscanf (used to be variables, now all strings also. + */ + +#define TYPE_STRN(N) \ + (parser_type_t) { \ + .name = TYPENAME_STR, \ + .str = { \ + .max_size = N, \ + }, \ + } + +#define TYPE_INT(MIN, MAX) \ + (parser_type_t) { \ + .name = TYPENAME_INT, \ + .integer = { \ + .min = (MIN), \ + .max = (MAX), \ + }, \ + } + +#define TYPE_UINT(MIN, MAX) \ + (parser_type_t) { \ + .name = TYPENAME_UINT, \ + .integer = { \ + .min = (MIN), \ + .max = (MAX), \ + }, \ + } + +#define TYPE_INT16(MIN, MAX) \ + (parser_type_t) { \ + .name = TYPENAME_INT16, \ + .integer = { \ + .min = (MIN), \ + .max = (MAX), \ + }, \ + } + +#define TYPE_UINT16(MIN, MAX) \ + (parser_type_t) { \ + .name = TYPENAME_UINT16, \ + .integer = { \ + .min = (MIN), \ + .max = (MAX), \ + }, \ + } + +#define TYPE_SYMBOLIC_OR_ID TYPE_STRN(SYMBOLIC_NAME_LEN) + +#define TYPE_INTERFACE_NAME TYPE_STRN(INTERFACE_LEN) + +#define TYPE_IP_ADDRESS \ + (parser_type_t) { .name = TYPENAME_IP_ADDRESS, } + +#define TYPE_IP_PREFIX \ + (parser_type_t) { .name = TYPENAME_IP_PREFIX, } + +#define TYPE_ON_OFF \ + (parser_type_t) { .name = TYPENAME_ON_OFF, } + +#define TYPE_ENUM(x) \ + (parser_type_t) { \ + .name = TYPENAME_ENUM, \ + .enum_ = { \ + .from_str = (int (*)(const char *))x##_from_str, \ + }, \ + } +/* We need to allocate room for the intermediate string */ + +#define TYPE_POLICY_STATE(TAG) \ + (parser_type_t) { \ + .name = TYPENAME_POLICY_STATE, \ + .policy_state = { \ + .tag = TAG, \ + }, \ + } +/* We need to allocate room for the intermediate string */ + +/** + * \brief Register a protocol + * \param protocol Pointer to a protocol_t structure describing the protocol to + * register \return None + */ + +void command_register(const command_parser_t *command); + +/** + * \brief Search a registered protocol in the library according to its name + * \param[in] action The action of the command. + * \param[in] object The object of the command. + * \param[in] nparams The number of parameters expected in the command. + * \return A pointer to the corresponding command if any, NULL othewise + */ +const command_parser_t *command_search(hc_action_t action, + hc_object_type_t object, + unsigned nparams); + +/** + * @brief List the commands associated with the specified object and/or action. + * Use OBJECT_UNDEFINED and ACTION_UNDEFINED to list all the available objects. + * Use ACTION_UNDEFINED to list all the actions associated to the specified + * object. + * + * @param object The action of the command + * @param action The object of the command + */ +void command_list(hc_object_type_t object, hc_action_t action); + +#define COMMAND_REGISTER(MOD) \ + static void __init_##MOD(void) __attribute__((constructor)); \ + static void __init_##MOD(void) { command_register(&MOD); } + +#endif /* HICNLIGHT_CONFIG_COMMAND */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/data.h b/ctrl/libhicnctrl/includes/hicn/ctrl/data.h new file mode 100644 index 000000000..d2696db1c --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/data.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file data.h + * \brief Request result data. + */ + +#ifndef HICNCTRL_DATA_H +#define HICNCTRL_DATA_H + +#include <stdbool.h> +#include <stddef.h> // size_t +#include <stdint.h> // uint*_t +#include <sys/types.h> +#include <unistd.h> + +#include <hicn/ctrl/object_type.h> +#include <hicn/ctrl/object.h> + +/** + * \brief Holds the results of an hICN control request + */ +typedef struct hc_data_s hc_data_t; + +/** + * Create a structure holding the results of an hICN control request. + * \result The newly create data structure. + */ +hc_data_t *hc_data_create(hc_object_type_t object_type); + +/** + * Free a structure holding the results of an hICN control request. + * \param [in] data - The data structure to free. + */ +void hc_data_free(hc_data_t *data); + +/* + * This function can fail if the current data size is bigger than the requested + * maximum size + */ +int hc_data_set_max_size(hc_data_t *data, size_t max_size); + +const uint8_t *hc_data_get_buffer(hc_data_t *data); +const uint8_t *hc_data_get_free(hc_data_t *data); +void hc_data_inc_size(hc_data_t *data); + +hc_object_type_t hc_data_get_object_type(const hc_data_t *data); + +void hc_data_set_object_type(hc_data_t *data, hc_object_type_t object_type); + +ssize_t hc_data_get_size(const hc_data_t *data); + +/* + * This is used to perform manual allocation once after initialization is the + * size of the data to store is known in advance. This does not prevent future + * reallocations (in the limit though of the value in max_size, if applicable). + */ +int hc_data_allocate(hc_data_t *data, size_t size); + +int hc_data_clear(hc_data_t *data); + +#if 0 +int hc_data_ensure_available(hc_data_t *data, size_t count); +#endif + +/** + * \brief Adds many new results at the end of the data structure, eventually + * allocating buffer space for it. + * \param [in] data - The data structure to which to add elements. + * \param [in] elements - The array of elements to add. + * \param [in] count - The number of elements to add. + * \return Error code + * + * NOTE: The size of the element should match the one declared at structure + * initialization. + */ +int hc_data_push_many(hc_data_t *data, const void *elements, size_t count); + +/** + * \brief Adds a new result at the end of the data structure, eventually + * allocating buffer space for it. + * \param [in] data - The data structure to which to add an element. + * \param [in] element - The element to add + * \return Error code + * + * NOTE: The size of the element should match the one declared at structure + * initialization. + */ +int hc_data_push(hc_data_t *data, const void *element); + +#if 0 +uint8_t *hc_data_get_next(hc_data_t *data); + +/** + * \brief Configure a callback (along with private data) to be called upon + * completion of a request + * \param [in] data - hICN control data + * \param [in] cb - Callback function + * \param [in] cb_data - Callback private data + */ +int hc_data_set_callback(hc_data_t *data, data_callback_t cb, void *cb_data); + +void hc_data_set_size(hc_data_t *data, int size); +#endif + +void hc_data_set_complete(hc_data_t *data); +bool hc_data_is_complete(const hc_data_t *data); + +void hc_data_set_error(hc_data_t *data); + +bool hc_data_get_result(hc_data_t *data); + +#if 0 +/** + * \brief Reset the data structure holding control data + * \param [in] data - hICN control data + * \return Error code + */ +int hc_data_reset(hc_data_t *data); +#endif + +#define VAR(x) __##x +#define hc_data_foreach(DATA, OBJECT, BODY) \ + do { \ + hc_object_t *OBJECT; \ + size_t VAR(size) = hc_object_size(hc_data_get_object_type(DATA)); \ + for (unsigned VAR(i) = 0; VAR(i) < hc_data_get_size(DATA); VAR(i)++) { \ + OBJECT = (hc_object_t *)(hc_data_get_buffer(DATA) + VAR(i) * VAR(size)); \ + BODY \ + } \ + } while (0) + +hc_object_t *hc_data_find(hc_data_t *data, hc_object_t *object); + +const hc_object_t *hc_data_get_object(const hc_data_t *data, off_t pos); + +#endif /* HICNCTRL_DATA_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/fw_interface.h b/ctrl/libhicnctrl/includes/hicn/ctrl/fw_interface.h new file mode 100644 index 000000000..0656de080 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/fw_interface.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HICNCTRL_FW_INTERFACE_H +#define HICNCTRL_FW_INTERFACE_H + +#include <hicn/ctrl/api.h> +#include <hicn/ctrl/callback.h> + +/** + * \file fw_interface.h + * \brief Forwarder interface + * + * Forwarder interface is designed to be a reusable module (that might be + * wrapped in a C++ class), providing a fw-agnostic interface with the + * following goals: + * - maintaining a permanent connection to the fw (and keep track of the + * fw state, eventually caching some aspects) + * - allowing the tracking of multiplexed requests + * - supporting a stream of concurrent notifications that might be needed to + * synchronize states. + * + * It is design to be easily integrated with the different event loops used + * across the projects (libevent for C, asio for C++). + */ + +#define foreach_fw_state \ + _(UNDEFINED) \ + _(DISABLED) /* stack is stopped */ \ + _(REQUESTED) /* stack is starting */ \ + _(AVAILABLE) /* forwarder is running */ \ + _(CONNECTING) /* XXX NEW */ \ + _(CONNECTED) /* control socket connected */ \ + _(READY) /* listener is present */ \ + _(N) + +typedef enum { +#define _(x) FW_STATE_##x, + foreach_fw_state +#undef _ +} fw_state_t; + +extern const char *fw_state_str[]; + +#define fw_state_str(x) fw_state_str[x] + +typedef struct fw_interface_s fw_interface_t; + +fw_interface_t *fw_interface_create_url(forwarder_type_t type, const char *url); +fw_interface_t *fw_interface_create(forwarder_type_t type); + +void fw_interface_free(fw_interface_t *fi); + +int fw_interface_get_fd(const fw_interface_t *fi); + +/* + * Enable the stack + */ +int fw_interface_enable(fw_interface_t *fi); + +/* + * Disable the stack + */ +int fw_interface_disable(fw_interface_t *fi); + +/* + * Request a permanent connection to the forwarder, starting it if needed. + */ +int fw_interface_connect(fw_interface_t *fi); + +/* + * Disconnect from the forwarder + */ +int fw_interface_disconnect(fw_interface_t *fi); + +fw_state_t fw_interface_get_state(const fw_interface_t *fi); + +int fw_interface_subscribe_all(fw_interface_t *fi); + +int fw_interface_unsubscribe_all(fw_interface_t *fi); + +int fw_interface_execute(fw_interface_t *fi, hc_action_t action, + hc_object_type_t object_type, hc_object_t *object, + hc_data_t **pdata); + +int fw_interface_execute_async(fw_interface_t *fi, hc_action_t action, + hc_object_type_t object_type, + hc_object_t *object, + hc_result_callback_t callback, + void *callback_data); + +int fw_interface_set_enable_callback(fw_interface_t *fi, + hc_enable_callback_t callback); + +int fw_interface_set_state_callback(fw_interface_t *fi, + hc_state_callback_t callback, + void *callback_data); + +int fw_interface_set_result_callback(fw_interface_t *fi, + hc_result_callback_t callback, + void *callback_data); + +int fw_interface_set_notification_callback(fw_interface_t *fi, + hc_notification_callback_t callback, + void *callback_data); + +// manage stack [android] +// - not needed for face mgr +// operations +// - create face/route : facemgr, hproxy +// - set fw strategy +// - get listeners, hicn listener port +// subscribe all +// callbacks: +// - forwarder available/unavailable +// timers & reattempts : clarify +// XXX remove_self on sock disconnect... should be in libhicnctrl + +int fw_interface_on_receive(fw_interface_t *fi, size_t count); +int fw_interface_get_recv_buffer(fw_interface_t *fi, uint8_t **buffer, + size_t *size); + +#endif /* HICNCTRL_FW_INTERFACE_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light-ng.h b/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light-ng.h deleted file mode 100644 index 783eab086..000000000 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light-ng.h +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (c) 2021 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file commands.h - * @brief All hicn-light commands: 14 in total. - * - * Header and payload in binary format. - */ - -#ifndef HICN_CTRL_HICNLIGHTNG_H -#define HICN_CTRL_HICNLIGHTNG_H - -#ifndef _WIN32 -#include <netinet/in.h> -#include <sys/socket.h> -#endif - -#include <stdint.h> -#include <stdlib.h> - -#include <hicn/policy.h> -#include <hicn/strategy.h> -#include <hicn/util/ip_address.h> - -#define SYMBOLIC_NAME_LEN 16 - -typedef struct in6_addr ipv6_addr_t; -typedef uint32_t ipv4_addr_t; - -typedef enum { - MESSAGE_COMMAND_SUBTYPE_UNDEFINED, - REQUEST_LIGHT = 0xc0, // this is a command - RESPONSE_LIGHT, - ACK_LIGHT, - NACK_LIGHT, - NOTIFICATION_LIGHT, - MESSAGE_COMMAND_SUBTYPE_N -} message_command_subtype_t; - -#define message_type_is_valid(message_type) \ - ((message_type != MESSAGE_TYPE_UNDEFINED) && \ - (message_type != MESSAGE_COMMAND_SUBTYPE_N)) - -#define message_type_from_uchar(x) \ - (((x) < REQUEST_LIGHT) || (((x) >= MESSAGE_COMMAND_SUBTYPE_N)) \ - ? MESSAGE_COMMAND_SUBTYPE_N \ - : (message_command_subtype_t)(x)) - -#define foreach_command_type \ - _(listener_add, LISTENER_ADD) \ - _(listener_remove, LISTENER_REMOVE) \ - _(listener_list, LISTENER_LIST) \ - _(connection_add, CONNECTION_ADD) \ - _(connection_remove, CONNECTION_REMOVE) \ - _(connection_list, CONNECTION_LIST) \ - _(connection_set_admin_state, CONNECTION_SET_ADMIN_STATE) \ - _(connection_update, CONNECTION_UPDATE) \ - _(connection_set_priority, CONNECTION_SET_PRIORITY) \ - _(connection_set_tags, CONNECTION_SET_TAGS) \ - _(route_add, ROUTE_ADD) \ - _(route_remove, ROUTE_REMOVE) \ - _(route_list, ROUTE_LIST) \ - _(cache_set_store, CACHE_SET_STORE) \ - _(cache_set_serve, CACHE_SET_SERVE) \ - _(cache_clear, CACHE_CLEAR) \ - _(cache_list, CACHE_LIST) \ - _(strategy_set, STRATEGY_SET) \ - _(strategy_add_local_prefix, STRATEGY_ADD_LOCAL_PREFIX) \ - _(wldr_set, WLDR_SET) \ - _(punting_add, PUNTING_ADD) \ - _(mapme_enable, MAPME_ENABLE) \ - _(mapme_set_discovery, MAPME_SET_DISCOVERY) \ - _(mapme_set_timescale, MAPME_SET_TIMESCALE) \ - _(mapme_set_retx, MAPME_SET_RETX) \ - _(mapme_send_update, MAPME_SEND_UPDATE) \ - _(policy_add, POLICY_ADD) \ - _(policy_remove, POLICY_REMOVE) \ - _(policy_list, POLICY_LIST) \ - _(subscription_add, SUBSCRIPTION_ADD) \ - _(subscription_remove, SUBSCRIPTION_REMOVE) \ - _(stats_get, STATS_GET) \ - _(stats_list, STATS_LIST) - -typedef enum { - COMMAND_TYPE_UNDEFINED, -#define _(l, u) COMMAND_TYPE_##u, - foreach_command_type -#undef _ - COMMAND_TYPE_N, -} command_type_t; - -extern const char *command_type_str[]; - -#define command_type_str(x) command_type_str[x] - -#define command_type_is_valid(command_type) \ - ((command_type != COMMAND_TYPE_UNDEFINED) && (command_type != COMMAND_TYPE_N)) - -#define command_type_from_uchar(x) \ - (((x) >= COMMAND_TYPE_N) ? COMMAND_TYPE_N : (command_type_t)(x)) - -/* Should be at least 8 bytes */ -typedef struct { - uint8_t message_type; - uint8_t command_id; - uint16_t length; /* Number of structures in the payload */ - uint32_t seq_num; -} cmd_header_t; - -typedef struct { - cmd_header_t header; -} msg_header_t; - -/* Listener */ - -typedef struct { - char symbolic[SYMBOLIC_NAME_LEN]; - char interface_name[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint16_t port; - uint8_t family; - uint8_t type; -} cmd_listener_add_t; - -typedef struct { - char symbolicOrListenerid[SYMBOLIC_NAME_LEN]; -} cmd_listener_remove_t; - -typedef struct { - void *_; // Otherwise empty structs result in clang build error -} cmd_listener_list_t; - -// Sync this struct with `hc_listener_t` in `api.h` -typedef struct { - char name[SYMBOLIC_NAME_LEN]; - char interface_name[SYMBOLIC_NAME_LEN]; - uint32_t id; - uint8_t type; - uint8_t family; - ip_address_t address; - uint16_t port; -} cmd_listener_list_item_t; - -/* Connection */ - -typedef struct { - char symbolic[SYMBOLIC_NAME_LEN]; - // char interface_name[SYMBOLIC_NAME_LEN]; - ip_address_t remote_ip; - ip_address_t local_ip; - uint16_t remote_port; - uint16_t local_port; - uint8_t family; - uint8_t type; - uint8_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; - policy_tags_t tags; -#endif /* WITH_POLICY */ -} cmd_connection_add_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; -} cmd_connection_remove_t; - -typedef struct { - void *_; -} cmd_connection_list_t; - -// Sync this struct with `hc_connection_t` in `api.h` -typedef struct { - uint32_t id; - char name[SYMBOLIC_NAME_LEN]; - char interface_name[SYMBOLIC_NAME_LEN]; - uint8_t type; - uint8_t family; - ip_address_t local_addr; - uint16_t local_port; - ip_address_t remote_addr; - uint16_t remote_port; - uint8_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; - policy_tags_t tags; -#endif /* WITH_POLICY */ - uint8_t state; -} cmd_connection_list_item_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - uint8_t admin_state; - uint8_t pad8[3]; -} cmd_connection_set_admin_state_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - uint8_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; - policy_tags_t tags; -#endif /* WITH_POLICY */ -} cmd_connection_update_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - uint32_t priority; -} cmd_connection_set_priority_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - policy_tags_t tags; -} cmd_connection_set_tags_t; - -/* Route */ - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint16_t cost; - uint8_t family; - uint8_t len; -} cmd_route_add_t; - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_route_remove_t; - -typedef struct { - void *_; -} cmd_route_list_t; - -// Sync this struct with `hc_route_t` in `api.h` -typedef struct { - ip_address_t address; - uint32_t connection_id; - uint16_t cost; - uint8_t family; - uint8_t len; -} cmd_route_list_item_t; - -/* Cache */ - -typedef struct { - uint8_t activate; -} cmd_cache_set_store_t; - -typedef struct { - uint8_t activate; -} cmd_cache_set_serve_t; - -typedef struct { - void *_; -} cmd_cache_clear_t; - -typedef struct { - void *_; -} cmd_cache_list_t; - -typedef struct { - uint8_t store_in_cs; - uint8_t serve_from_cs; - uint32_t cs_size; - uint32_t num_stale_entries; -} cmd_cache_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_cache_list_reply_t payload; -} msg_cache_list_reply_t; - -/* Statistics */ - -// General stats -typedef struct { - void *_; -} cmd_stats_get_t; - -typedef struct { - cmd_header_t header; - hicn_light_stats_t payload; -} msg_stats_get_reply_t; - -// Per-face stats -typedef struct { - void *_; -} cmd_stats_list_t; - -typedef struct { - uint32_t id; - connection_stats_t stats; -} cmd_stats_list_item_t; - -typedef struct { - cmd_header_t header; - cmd_stats_list_item_t payload; -} msg_stats_list_reply_t; - -/* WLDR */ - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - uint8_t activate; -} cmd_wldr_set_t; - -/* Strategy */ - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; - uint8_t type; - uint8_t related_prefixes; - union { - struct { - ip_address_t addresses[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t lens[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t families[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - } low_latency; - }; -} cmd_strategy_set_t; - -typedef struct { - uint8_t type; - ip_address_t address; - uint8_t family; - uint8_t len; - ip_address_t local_address; - uint8_t local_family; - uint8_t local_len; -} cmd_strategy_add_local_prefix_t; - -/* Punting */ - -typedef struct { - char symbolic_or_connid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_punting_add_t; - -/* MAP-Me */ - -typedef struct { - uint8_t activate; -} cmd_mapme_activator_t; - -typedef cmd_mapme_activator_t cmd_mapme_enable_t; -typedef cmd_mapme_activator_t cmd_mapme_set_discovery_t; - -typedef struct { - uint32_t timePeriod; -} cmd_mapme_timing_t; - -typedef cmd_mapme_timing_t cmd_mapme_set_timescale_t; -typedef cmd_mapme_timing_t cmd_mapme_set_retx_t; - -typedef struct { - void *_; -} cmd_mapme_send_update_t; - -/* Policy */ - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; - hicn_policy_t policy; -} cmd_policy_add_t; - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_policy_remove_t; - -typedef struct { - void *_; -} cmd_policy_list_t; - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; - hicn_policy_t policy; -} cmd_policy_list_item_t; - -/* Subscription */ - -typedef struct { - uint32_t topics; -} cmd_subscription_add_t; - -typedef struct { - uint32_t topics; -} cmd_subscription_remove_t; - -/* Full messages */ - -#define _(l, u) \ - typedef struct { \ - cmd_header_t header; \ - cmd_##l##_t payload; \ - } msg_##l##_t; -foreach_command_type; -#undef _ - -typedef struct { - cmd_header_t header; - cmd_listener_list_item_t payload; -} msg_listener_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_connection_list_item_t payload; -} msg_connection_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_route_list_item_t payload; -} msg_route_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_policy_list_item_t payload; -} msg_policy_list_reply_t; - -//===== size of commands ====== -// REMINDER: when a new_command is added, the following switch has to be -// updated. -static inline int command_get_payload_len(command_type_t command_type) { - switch (command_type) { -#define _(l, u) \ - case COMMAND_TYPE_##u: \ - return sizeof(cmd_##l##_t); - foreach_command_type -#undef _ - case COMMAND_TYPE_UNDEFINED : case COMMAND_TYPE_N : return 0; - } -} -#endif /* HICN_CTRL_HICNLIGHTNG_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h b/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h index 69ede1985..34667cc1b 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,8 +20,8 @@ * Header and payload in binary format. */ -#ifndef HICN_CTRL_HICNLIGHT_H -#define HICN_CTRL_HICNLIGHT_H +#ifndef HICN_CTRL_HICNLIGHTNG_H +#define HICN_CTRL_HICNLIGHTNG_H #ifndef _WIN32 #include <netinet/in.h> @@ -31,404 +31,506 @@ #include <stdint.h> #include <stdlib.h> -#include <hicn/util/ip_address.h> -#ifdef WITH_POLICY #include <hicn/policy.h> -#endif /* WITH_POLICY */ +#include <hicn/strategy.h> +#include <hicn/util/ip_address.h> + +#include "api.h" #define SYMBOLIC_NAME_LEN 16 -#define MAX_FWD_STRATEGY_RELATED_PREFIXES 10 typedef struct in6_addr ipv6_addr_t; typedef uint32_t ipv4_addr_t; typedef enum { + MESSAGE_COMMAND_SUBTYPE_UNDEFINED, REQUEST_LIGHT = 0xc0, // this is a command RESPONSE_LIGHT, ACK_LIGHT, NACK_LIGHT, - LAST_MSG_TYPE_VALUE -} message_type; + NOTIFICATION_LIGHT, + MESSAGE_COMMAND_SUBTYPE_N +} message_command_subtype_t; + +#define message_type_is_valid(message_type) \ + ((message_type != MESSAGE_TYPE_UNDEFINED) && \ + (message_type != MESSAGE_COMMAND_SUBTYPE_N)) + +#define message_type_from_uchar(x) \ + (((x) < REQUEST_LIGHT) || (((x) >= MESSAGE_COMMAND_SUBTYPE_N)) \ + ? MESSAGE_COMMAND_SUBTYPE_N \ + : (message_command_subtype_t)(x)) + +#define foreach_command_type \ + _(listener_add, LISTENER_ADD) \ + _(listener_remove, LISTENER_REMOVE) \ + _(listener_list, LISTENER_LIST) \ + _(connection_add, CONNECTION_ADD) \ + _(connection_remove, CONNECTION_REMOVE) \ + _(connection_list, CONNECTION_LIST) \ + _(connection_update, CONNECTION_UPDATE) \ + _(route_add, ROUTE_ADD) \ + _(route_remove, ROUTE_REMOVE) \ + _(route_list, ROUTE_LIST) \ + _(cache_set_store, CACHE_SET_STORE) \ + _(cache_set_serve, CACHE_SET_SERVE) \ + _(cache_clear, CACHE_CLEAR) \ + _(cache_list, CACHE_LIST) \ + _(strategy_set, STRATEGY_SET) \ + _(strategy_add_local_prefix, STRATEGY_ADD_LOCAL_PREFIX) \ + _(wldr_set, WLDR_SET) \ + _(punting_add, PUNTING_ADD) \ + _(mapme_enable, MAPME_ENABLE) \ + _(mapme_set_discovery, MAPME_SET_DISCOVERY) \ + _(mapme_set_timescale, MAPME_SET_TIMESCALE) \ + _(mapme_set_retx, MAPME_SET_RETX) \ + _(mapme_send_update, MAPME_SEND_UPDATE) \ + _(policy_add, POLICY_ADD) \ + _(policy_remove, POLICY_REMOVE) \ + _(policy_list, POLICY_LIST) \ + _(active_interface_update, ACTIVE_INTERFACE_UPDATE) \ + _(subscription_add, SUBSCRIPTION_ADD) \ + _(subscription_remove, SUBSCRIPTION_REMOVE) \ + _(stats_get, STATS_GET) \ + _(stats_list, STATS_LIST) typedef enum { - ADD_LISTENER = 0, - ADD_CONNECTION, - LIST_CONNECTIONS, - ADD_ROUTE, - LIST_ROUTES, - REMOVE_CONNECTION, - REMOVE_LISTENER, - REMOVE_ROUTE, - CACHE_STORE, - CACHE_SERVE, - CACHE_CLEAR, - SET_STRATEGY, - SET_WLDR, - ADD_PUNTING, - LIST_LISTENERS, - MAPME_ENABLE, - MAPME_DISCOVERY, - MAPME_TIMESCALE, - MAPME_RETX, - MAPME_SEND_UPDATE, - CONNECTION_SET_ADMIN_STATE, -#ifdef WITH_POLICY - ADD_POLICY, - LIST_POLICIES, - REMOVE_POLICY, - UPDATE_CONNECTION, - CONNECTION_SET_PRIORITY, - CONNECTION_SET_TAGS, -#endif /* WITH_POLICY */ - LAST_COMMAND_VALUE -} command_id; + COMMAND_TYPE_UNDEFINED, +#define _(l, u) COMMAND_TYPE_##u, + foreach_command_type +#undef _ + COMMAND_TYPE_N, +} command_type_t; -typedef enum { - ADDR_INET = 1, - ADDR_INET6, - ADDR_LINK, - ADDR_IFACE, - ADDR_UNIX /* PF_UNIX */ -} address_type; +extern const char *command_type_str[]; -typedef enum { - UDP_CONN, - TCP_CONN, - GRE_CONN, // not implemented - HICN_CONN -} connection_type; +#define command_type_str(x) command_type_str[x] -typedef enum { ACTIVATE_ON, ACTIVATE_OFF } activate_type; +#define command_type_is_valid(command_type) \ + ((command_type != COMMAND_TYPE_UNDEFINED) && (command_type != COMMAND_TYPE_N)) -//========== HEADER ========== +#define command_type_from_uchar(x) \ + (((x) >= COMMAND_TYPE_N) ? COMMAND_TYPE_N : (command_type_t)(x)) +/* Should be at least 8 bytes */ typedef struct { - uint8_t messageType; - uint8_t commandID; - uint16_t length; // tells the number of structures in the payload - uint32_t seqNum; -} header_control_message; -// for the moment has to be at least 8 bytes - -// SIZE=8 + uint8_t message_type; + uint8_t command_id; + uint16_t length; /* Number of structures in the payload */ + uint32_t seq_num; +} cmd_header_t; -//========== [00] ADD LISTENER ========== +typedef struct { + cmd_header_t header; +} msg_header_t; -typedef enum { ETHER_MODE, IP_MODE, HICN_MODE } listener_mode; +/* Listener */ typedef struct { char symbolic[SYMBOLIC_NAME_LEN]; - char interfaceName[SYMBOLIC_NAME_LEN]; - ip_address_t address; + char interface_name[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t address; uint16_t port; - // uint16_t etherType; - uint8_t addressType; - uint8_t listenerMode; - uint8_t connectionType; -} add_listener_command; + uint8_t family; + uint8_t type; +} cmd_listener_add_t; -// SIZE=56 +typedef struct { + char symbolicOrListenerid[SYMBOLIC_NAME_LEN]; +} cmd_listener_remove_t; + +typedef struct { + void *_; // Otherwise empty structs result in clang build error +} cmd_listener_list_t; -//========== [01] ADD CONNECTION ========== +/* Connection */ typedef struct { char symbolic[SYMBOLIC_NAME_LEN]; - // char interfaceName[SYMBOLIC_NAME_LEN]; - ip_address_t remoteIp; - ip_address_t localIp; - uint16_t remotePort; - uint16_t localPort; - uint8_t ipType; - uint8_t connectionType; + // char interface_name[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t remote_ip; + hicn_ip_address_t local_ip; + uint16_t remote_port; + uint16_t local_port; + uint8_t family; + uint8_t type; uint8_t admin_state; -#ifdef WITH_POLICY + uint8_t __pad; uint32_t priority; policy_tags_t tags; -#endif /* WITH_POLICY */ -} add_connection_command; +} cmd_connection_add_t; -// SIZE=56 +typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; +} cmd_connection_remove_t; -//========== [02] LIST CONNECTIONS ========== +typedef struct { + void *_; +} cmd_connection_list_t; -typedef enum { - CONN_GRE, - CONN_TCP, - CONN_UDP, - CONN_MULTICAST, - CONN_L2, - CONN_HICN -} list_connections_type; +typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + uint8_t admin_state; + uint8_t pad8[3]; +} cmd_connection_set_admin_state_t; -typedef enum { - IFACE_UP = 0, - IFACE_DOWN = 1, - IFACE_UNKNOWN = 2 // not used actually -} connection_state; +typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + uint8_t admin_state; + uint32_t priority; + policy_tags_t tags; +} cmd_connection_update_t; typedef struct { - add_connection_command connectionData; - uint32_t connid; - uint8_t state; - char interfaceName[SYMBOLIC_NAME_LEN]; - char connectionName[SYMBOLIC_NAME_LEN]; -} list_connections_command; + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + uint32_t priority; +} cmd_connection_set_priority_t; -// SIZE=80 +typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + policy_tags_t tags; +} cmd_connection_set_tags_t; -//========== [03] ADD ROUTE ========== +/* Route */ typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t address; uint16_t cost; - uint8_t addressType; + uint8_t family; uint8_t len; -} add_route_command; - -// SIZE=36 - -//========== [04] LIST ROUTE ========== +} cmd_route_add_t; typedef struct { - ip_address_t address; - uint32_t connid; - uint16_t cost; - uint8_t addressType; + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t address; + uint8_t family; uint8_t len; -} list_routes_command; +} cmd_route_remove_t; -// SIZE=24 +typedef struct { + void *_; +} cmd_route_list_t; + +/* Cache */ -//========== [05] REMOVE CONNECTION ========== typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; -} remove_connection_command; + uint8_t activate; +} cmd_cache_set_store_t; -//========== [06] REMOVE LISTENER ========== typedef struct { - char symbolicOrListenerid[SYMBOLIC_NAME_LEN]; -} remove_listener_command; + uint8_t activate; +} cmd_cache_set_serve_t; -// SIZE=16 +typedef struct { + void *_; +} cmd_cache_clear_t; -//========== [07] REMOVE ROUTE ========== +typedef struct { + void *_; +} cmd_cache_list_t; typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t addressType; - uint8_t len; -} remove_route_command; + uint8_t store_in_cs; + uint8_t serve_from_cs; + uint32_t cs_size; + uint32_t num_stale_entries; +} cmd_cache_list_reply_t; -// SIZE=36 +typedef struct { + cmd_header_t header; + cmd_cache_list_reply_t payload; +} msg_cache_list_reply_t; -//========== [08] CACHE STORE ========== +/* WLDR */ typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; uint8_t activate; -} cache_store_command; +} cmd_wldr_set_t; -// SIZE=1 +/* Strategy */ -//========== [09] CACHE SERVE ========== +typedef struct { + hicn_ip_address_t address; + uint8_t family; + uint8_t len; + uint8_t type; + uint8_t related_prefixes; + union { + struct { + hicn_ip_address_t addresses[MAX_FWD_STRATEGY_RELATED_PREFIXES]; + uint8_t lens[MAX_FWD_STRATEGY_RELATED_PREFIXES]; + uint8_t families[MAX_FWD_STRATEGY_RELATED_PREFIXES]; + } low_latency; + }; +} cmd_strategy_set_t; typedef struct { - uint8_t activate; -} cache_serve_command; + uint8_t type; + hicn_ip_address_t address; + uint8_t family; + uint8_t len; + hicn_ip_address_t local_address; + uint8_t local_family; + uint8_t local_len; +} cmd_strategy_add_local_prefix_t; -// SIZE=1 +/* Punting */ -//========== [10] SET STRATEGY ========== +typedef struct { + char symbolic_or_connid[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t address; + uint8_t family; + uint8_t len; +} cmd_punting_add_t; -typedef enum { - SET_STRATEGY_LOADBALANCER, - SET_STRATEGY_RANDOM, - SET_STRATEGY_LOW_LATENCY, - LAST_STRATEGY_VALUE -} strategy_type; +/* MAP-Me */ typedef struct { - ip_address_t address; - uint8_t strategyType; - uint8_t addressType; - uint8_t len; - uint8_t related_prefixes; - ip_address_t addresses[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t lens[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t addresses_type[MAX_FWD_STRATEGY_RELATED_PREFIXES]; -} set_strategy_command; + uint8_t activate; +} cmd_mapme_activator_t; + +typedef cmd_mapme_activator_t cmd_mapme_enable_t; +typedef cmd_mapme_activator_t cmd_mapme_set_discovery_t; -// SIZE=208 +typedef struct { + uint32_t timePeriod; +} cmd_mapme_timing_t; -//========== [11] SET WLDR ========== +typedef cmd_mapme_timing_t cmd_mapme_set_timescale_t; +typedef cmd_mapme_timing_t cmd_mapme_set_retx_t; typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint8_t activate; -} set_wldr_command; + void *_; +} cmd_mapme_send_update_t; -// SIZE=17 +/* Policy */ -//========== [12] ADD PUNTING ========== +typedef struct { + hicn_ip_address_t address; + uint8_t family; + uint8_t len; + hicn_policy_t policy; +} cmd_policy_add_t; typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t addressType; + hicn_ip_address_t address; + uint8_t family; uint8_t len; -} add_punting_command; +} cmd_policy_remove_t; -// SIZE=36 +typedef struct { + void *_; +} cmd_policy_list_t; -//========== [13] LIST LISTENER ========== +/* Subscription */ typedef struct { - ip_address_t address; - char listenerName[SYMBOLIC_NAME_LEN]; - char interfaceName[SYMBOLIC_NAME_LEN]; - uint32_t connid; - uint16_t port; - uint8_t addressType; - uint8_t encapType; -} list_listeners_command; + uint32_t topics; +} cmd_subscription_add_t; -// SIZE=56 +typedef struct { + uint32_t topics; +} cmd_subscription_remove_t; -//========== [14] MAPME ========== +/* Statistics */ -// (enable/discovery/timescale/retx) +// General stats +typedef struct { + void *_; +} cmd_stats_get_t; +// Per-face stats typedef struct { - uint8_t activate; -} mapme_activator_command; + void *_; +} cmd_stats_list_t; + +typedef void *cmd_active_interface_update_t; + +/* Full messages */ + +#define _(l, u) \ + typedef struct { \ + cmd_header_t header; \ + cmd_##l##_t payload; \ + } msg_##l##_t; +foreach_command_type +#undef _ + + /* Serialized version of hc_listener_t */ + typedef struct { + char name[SYMBOLIC_NAME_LEN]; + char interface_name[INTERFACE_LEN]; + hicn_ip_address_t local_addr; + uint32_t id; + uint16_t local_port; + uint8_t type; + uint8_t family; +} cmd_listener_list_item_t; + +static_assert(sizeof(cmd_listener_list_item_t) == 56, ""); -// SIZE=1 +typedef struct { + cmd_header_t header; + cmd_listener_list_item_t payload; +} msg_listener_list_reply_t; +/* Serialized version of hc_connection_t */ typedef struct { - uint32_t timePeriod; -} mapme_timing_command; + char name[SYMBOLIC_NAME_LEN]; + char interface_name[INTERFACE_LEN]; + hicn_ip_address_t local_addr; + hicn_ip_address_t remote_addr; + uint32_t id; + uint32_t priority; + uint16_t local_port; + uint16_t remote_port; + uint8_t netdevice_type; + uint8_t type; + uint8_t family; + uint8_t admin_state; + uint8_t tags; + uint8_t state; + uint8_t __pad[6]; +} cmd_connection_list_item_t; + +static_assert(POLICY_TAG_N <= 8, ""); +static_assert(sizeof(cmd_connection_list_item_t) == 88, ""); typedef struct { - ip_address_t address; - uint8_t addressType; - uint8_t len; -} mapme_send_update_command; + cmd_header_t header; + cmd_connection_list_item_t payload; +} msg_connection_list_reply_t; -// SIZE=1 +typedef msg_connection_list_reply_t msg_connection_notify_t; typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; + char interface_name[INTERFACE_LEN]; + hicn_ip_address_t local_addr; + hicn_ip_address_t remote_addr; + uint32_t id; + uint32_t priority; + uint16_t local_port; + uint16_t remote_port; + uint8_t netdevice_type; + uint8_t type; + uint8_t family; uint8_t admin_state; - uint8_t pad8[3]; -} connection_set_admin_state_command; + uint8_t tags; + uint8_t state; + uint8_t __pad[6]; +} cmd_face_list_item_t; -#ifdef WITH_POLICY +static_assert(sizeof(cmd_face_list_item_t) == 72, ""); typedef struct { - ip_address_t address; - uint8_t addressType; + char face_name[SYMBOLIC_NAME_LEN]; + hicn_ip_address_t remote_addr; + uint32_t face_id; + uint16_t cost; + uint8_t family; uint8_t len; - hicn_policy_t policy; -} add_policy_command; + cmd_face_list_item_t face; +} cmd_route_list_item_t; + +static_assert(sizeof(cmd_route_list_item_t) == 112, ""); typedef struct { - ip_address_t address; - uint8_t addressType; - uint8_t len; - hicn_policy_t policy; -} list_policies_command; + cmd_header_t header; + cmd_route_list_item_t payload; +} msg_route_list_reply_t; + +typedef msg_route_list_reply_t msg_route_notify_t; typedef struct { - ip_address_t address; - uint8_t addressType; + uint8_t state; + uint8_t disabled; + uint16_t __pad; +} _policy_tag_state_t; + +typedef struct { + uint32_t throughput; + uint32_t latency; + uint32_t loss_rate; +} _interface_stats_t; + +typedef struct { + _interface_stats_t wired; + _interface_stats_t wifi; + _interface_stats_t cellular; + _interface_stats_t all; +} _policy_stats_t; + +typedef struct { + char app_name[APP_NAME_LEN]; + _policy_tag_state_t tags[POLICY_TAG_N]; + _policy_stats_t stats; + uint8_t __pad[4]; +} _hicn_policy_t; + +static_assert(sizeof(_hicn_policy_t) == 208, ""); + +typedef struct { + uint8_t policy[208]; + hicn_ip_address_t remote_addr; + uint8_t family; uint8_t len; -} remove_policy_command; + uint8_t __pad[6]; +} cmd_policy_list_item_t; + +static_assert(sizeof(cmd_policy_list_item_t) == 232, ""); typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint8_t admin_state; - uint32_t priority; - policy_tags_t tags; -} update_connection_command; + cmd_header_t header; + cmd_policy_list_item_t payload; +} msg_policy_list_reply_t; + +typedef msg_policy_list_reply_t msg_policy_notify_t; +/* Those are needed to build but not used */ typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint32_t priority; -} connection_set_priority_command; + uint8_t _; +} cmd_strategy_list_item_t; +typedef struct { + uint8_t _; +} cmd_subscription_list_item_t; + +/* Statistics */ typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - policy_tags_t tags; -} connection_set_tags_command; + cmd_header_t header; + hicn_light_stats_t payload; +} msg_stats_get_reply_t; -#endif /* WITH_POLICY */ +typedef struct { + uint32_t id; + connection_stats_t stats; +} cmd_stats_list_item_t; + +typedef struct { + cmd_header_t header; + cmd_stats_list_item_t payload; +} msg_stats_list_reply_t; //===== size of commands ====== // REMINDER: when a new_command is added, the following switch has to be // updated. -static inline int payloadLengthDaemon(command_id id) { - switch (id) { - case ADD_LISTENER: - return sizeof(add_listener_command); - case ADD_CONNECTION: - return sizeof(add_connection_command); - case LIST_CONNECTIONS: - return 0; // list connections: payload always 0 - case ADD_ROUTE: - return sizeof(add_route_command); - case LIST_ROUTES: - return 0; // list routes: payload always 0 - case REMOVE_CONNECTION: - return sizeof(remove_connection_command); - case REMOVE_LISTENER: - return sizeof(remove_listener_command); - case REMOVE_ROUTE: - return sizeof(remove_route_command); - case CACHE_STORE: - return sizeof(cache_store_command); - case CACHE_SERVE: - return sizeof(cache_serve_command); - case CACHE_CLEAR: - return 0; // cache clear - case SET_STRATEGY: - return sizeof(set_strategy_command); - case SET_WLDR: - return sizeof(set_wldr_command); - case ADD_PUNTING: - return sizeof(add_punting_command); - case LIST_LISTENERS: - return 0; // list listeners: payload always 0 - case MAPME_ENABLE: - return sizeof(mapme_activator_command); - case MAPME_DISCOVERY: - return sizeof(mapme_activator_command); - case MAPME_TIMESCALE: - return sizeof(mapme_timing_command); - case MAPME_RETX: - return sizeof(mapme_timing_command); - case MAPME_SEND_UPDATE: - return sizeof(mapme_send_update_command); - case CONNECTION_SET_ADMIN_STATE: - return sizeof(connection_set_admin_state_command); -#ifdef WITH_POLICY - case ADD_POLICY: - return sizeof(add_policy_command); - case LIST_POLICIES: - return 0; // list policies: payload always 0 - case REMOVE_POLICY: - return sizeof(remove_policy_command); - case UPDATE_CONNECTION: - return sizeof(update_connection_command); - case CONNECTION_SET_PRIORITY: - return sizeof(connection_set_priority_command); - case CONNECTION_SET_TAGS: - return sizeof(connection_set_tags_command); -#endif /* WITH_POLICY */ - case LAST_COMMAND_VALUE: - return 0; - default: - return 0; +static inline int command_get_payload_len(command_type_t command_type) { + switch (command_type) { +#define _(l, u) \ + case COMMAND_TYPE_##u: \ + return sizeof(cmd_##l##_t); + foreach_command_type +#undef _ + case COMMAND_TYPE_UNDEFINED : case COMMAND_TYPE_N : return 0; } } -#endif /* HICN_CTRL_HICNLIGHT_H */ + +ssize_t hc_light_command_serialize(hc_action_t action, + hc_object_type_t object_type, + hc_object_t *object, uint8_t *msg); + +int hc_sock_initialize_module(hc_sock_t *s); + +#endif /* HICN_CTRL_HICNLIGHTNG_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/object.h b/ctrl/libhicnctrl/includes/hicn/ctrl/object.h new file mode 100644 index 000000000..c659d1824 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/object.h @@ -0,0 +1,76 @@ +/* + * 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 object.h + * \brief API object representation. + */ + +#ifndef HICNCTRL_OBJECT_H +#define HICNCTRL_OBJECT_H + +#include <hicn/ctrl/object_type.h> + +#include <hicn/ctrl/objects/listener.h> +#include <hicn/ctrl/objects/connection.h> +#include <hicn/ctrl/objects/route.h> +#include <hicn/ctrl/objects/punting.h> +#include <hicn/ctrl/objects/strategy.h> +#include <hicn/ctrl/objects/policy.h> +#include <hicn/ctrl/objects/subscription.h> +#include <hicn/ctrl/objects/cache.h> +#include <hicn/ctrl/objects/mapme.h> +#include <hicn/ctrl/objects/active_interface.h> + +typedef union { + hc_connection_t connection; + hc_listener_t listener; + hc_route_t route; + hc_face_t face; + // hc_data_t *data; + hc_punting_t punting; + hc_strategy_t strategy; + hc_policy_t policy; + hc_subscription_t subscription; + hc_cache_t cache; + hc_mapme_t mapme; + hc_active_interface_t active_interface; + uint8_t as_uint8; +} hc_object_t; + +#define MAXSZ_OBJECT_T MAX + +#define IS_VALID_ACTION(x) IS_VALID_ENUM_TYPE(ACTION, x) + +bool hc_object_is_empty(const hc_object_t *object); + +size_t hc_object_size(hc_object_type_t object_type); + +int hc_object_validate(hc_object_type_t object_type, hc_object_t *object, + bool allow_partial); +int hc_object_cmp(hc_object_type_t object_type, hc_object_t *object1, + hc_object_t *object2); +int hc_object_snprintf(char *s, size_t size, hc_object_type_t object_type, + hc_object_t *object); + +#define foreach_object(VAR, data) foreach_type(hc_object_t, VAR, data) + +#define foreach_type(TYPE, VAR, DATA) \ + for (TYPE *VAR = (TYPE *)hc_data_get_buffer(DATA); \ + VAR < (TYPE *)(hc_data_get_buffer(DATA) + \ + hc_data_get_size(DATA) * sizeof(TYPE)); \ + VAR++) + +#endif /* HICNCTRL_OBJECT_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/object_type.h b/ctrl/libhicnctrl/includes/hicn/ctrl/object_type.h new file mode 100644 index 000000000..39a2d188e --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/object_type.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file object_type.h + * \brief Object type. + */ + +#ifndef HICNCTRL_OBJECT_TYPE_H +#define HICNCTRL_OBJECT_TYPE_H + +#define foreach_object_type \ + _(UNDEFINED) \ + _(CONNECTION) \ + _(LISTENER) \ + _(ROUTE) \ + _(FACE) \ + _(STRATEGY) \ + _(PUNTING) \ + _(POLICY) \ + _(CACHE) \ + _(MAPME) \ + _(WLDR) \ + _(LOCAL_PREFIX) \ + _(PROBE) \ + _(SUBSCRIPTION) \ + _(ACTIVE_INTERFACE) \ + _(STATS) \ + _(N) + +typedef enum { +#define _(x) OBJECT_TYPE_##x, + foreach_object_type +#undef _ +} hc_object_type_t; + +extern const char *object_type_str[]; + +#define object_type_str(x) object_type_str[x] + +hc_object_type_t object_type_from_str(const char *object_str); + +#define IS_VALID_OBJECT_TYPE(x) IS_VALID_ENUM_TYPE(OBJECT_TYPE, x) + +#endif /* HICNCTRL_OBJECT_TYPE_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects.h new file mode 100644 index 000000000..4f560a2f3 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects.h @@ -0,0 +1,11 @@ +#ifndef HICNCTRL_OBJECTS_H +#define HICNCTRL_OBJECTS_H + +#include <hicn/ctrl/objects/connection.h> +#include <hicn/ctrl/objects/face.h> +#include <hicn/ctrl/objects/listener.h> +#include <hicn/ctrl/objects/route.h> +#include <hicn/ctrl/objects/strategy.h> +#include <hicn/ctrl/objects/subscription.h> + +#endif /* HICNCTRL_OBJECTS_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/active_interface.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/active_interface.h new file mode 100644 index 000000000..56a1d8cd5 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/active_interface.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/active_interface.h + * \brief Route. + */ + +#ifndef HICNCTRL_OBJECTS_ACTIVE_INTERFACE_H +#define HICNCTRL_OBJECTS_ACTIVE_INTERFACE_H + +#include <hicn/ctrl/objects/face.h> + +typedef struct { + hicn_ip_prefix_t prefix; + netdevice_flags_t interface_types; +} hc_active_interface_t; + +#define foreach_active_interface(VAR, data) \ + foreach_type(hc_active_interface_t, VAR, data) + +// XXX WRONG +#define MAXSZ_HC_ACTIVE_INTERFACE_ \ + MAXSZ_FACE_ID + 1 + MAXSZ_COST + 1 + MAXSZ_IP_ADDRESS + 1 + MAXSZ_LEN +#define MAXSZ_HC_ACTIVE_INTERFACE MAXSZ_HC_ACTIVE_INTERFACE_ + NULLTERM + +int hc_active_interface_snprintf(char *s, size_t size, + const hc_active_interface_t *active_interface); +int hc_active_interface_validate(const hc_active_interface_t *active_interface, + bool allow_partial); + +#endif diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/base.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/base.h new file mode 100644 index 000000000..fc40f680e --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/base.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file base.h + * \brief Base definitions for objects. + */ +#ifndef HICNCTRL_OBJECTS_BASE +#define HICNCTRL_OBJECTS_BASE + +#define INTERFACE_LEN 16 + +#endif /* HICNCTRL_OBJECTS_BASE */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/cache.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/cache.h new file mode 100644 index 000000000..1f8691be6 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/cache.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/cache.h + * \brief Cache. + */ + +#ifndef HICNCTRL_OBJECTS_CACHE_H +#define HICNCTRL_OBJECTS_CACHE_H + +typedef struct { + uint8_t serve; // 1 = on, 0 = off + uint8_t store; // 1 = on, 0 = off +} hc_cache_t; + +typedef struct { + bool store; + bool serve; + size_t cs_size; + size_t num_stale_entries; +} hc_cache_info_t; + +int hc_cache_snprintf(char *s, size_t size, const hc_cache_info_t *cache_info); + +#endif /* HICNCTRL_OBJECTS_CACHE_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/connection.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/connection.h new file mode 100644 index 000000000..771b48c20 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/connection.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/connection.h + * \brief Connection. + */ + +#ifndef HICNCTRL_OBJECTS_CONNECTION_H +#define HICNCTRL_OBJECTS_CONNECTION_H + +#include <stdint.h> +#include <hicn/face.h> + +#include "base.h" + +/* + * NOTE : + * - interface_name is mainly used to derive listeners from connections, + * but is not itself used to create connections. + */ +typedef struct { + uint32_t id; /* Kr. */ + char name[SYMBOLIC_NAME_LEN]; /* K.w */ + char interface_name[INTERFACE_LEN]; /* Kr. */ + netdevice_type_t netdevice_type; /* .r. */ + face_type_t type; /* .rw */ + int family; /* .rw */ + hicn_ip_address_t local_addr; /* .rw */ + uint16_t local_port; /* .rw */ + hicn_ip_address_t remote_addr; /* .rw */ + uint16_t remote_port; /* .rw */ + face_state_t admin_state; /* .rw */ + uint32_t priority; /* .rw */ + policy_tags_t tags; /* .rw */ + face_state_t state; /* .r. */ +} hc_connection_t; + +#define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) + +#define MAXSZ_HC_CONNECTION_ \ + MAXSZ_FACE_STATE_ + INTERFACE_LEN + SPACE + 2 * MAXSZ_URL_ + \ + MAXSZ_FACE_TYPE_ + SPACES(3) +#define MAXSZ_HC_CONNECTION MAXSZ_HC_CONNECTION_ + NULLTERM + +int hc_connection_validate(const hc_connection_t *connection, + bool allow_partial); +int hc_connection_cmp(const hc_connection_t *c1, const hc_connection_t *c2); +int hc_connection_snprintf(char *s, size_t size, + const hc_connection_t *connection); + +#endif /* HICNCTRL_OBJECTS_CONNECTION_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/face.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/face.h new file mode 100644 index 000000000..1aa122f37 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/face.h @@ -0,0 +1,49 @@ +/* + * 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 objects/face.h + * \brief Face. + * + * A face is an abstraction introduced by the control library to abstract the + * forwarder implementation details. It encompasses connections and listeners + * and ensures the right dependencies are enforced, eg that we always have a + * listener when a connection is created. + */ + +#ifndef HICNCTRL_OBJECTS_FACE_H +#define HICNCTRL_OBJECTS_FACE_H + +#include <hicn/face.h> + +#include "base.h" + +typedef face_t hc_face_t; + +#define foreach_face(VAR, data) foreach_type(hc_face_t, VAR, data) + +#define MAX_FACE_ID 255 +#define MAXSZ_FACE_ID_ 3 +#define MAXSZ_FACE_ID MAXSZ_FACE_ID_ + NULLTERM +#define MAXSZ_FACE_NAME_ SYMBOLIC_NAME_LEN +#define MAXSZ_FACE_NAME MAXSZ_FACE_NAME_ + NULLTERM + +#define MAXSZ_HC_FACE_ \ + MAXSZ_FACE_ID_ + MAXSZ_FACE_NAME_ + MAXSZ_FACE_ + 5 + HOTFIXMARGIN +#define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM + +int hc_face_snprintf(char *s, size_t size, const hc_face_t *face); + +#endif /* HICNCTRL_OBJECTS_FACE_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/listener.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/listener.h new file mode 100644 index 000000000..0fb74f558 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/listener.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/listener.h + * \brief Listener. + */ + +#ifndef HICNCTRL_OBJECTS_LISTENER_H +#define HICNCTRL_OBJECTS_LISTENER_H + +#include <stddef.h> // offsetof +#include <stdint.h> +#include <hicn/face.h> + +#include "base.h" + +// FIXME the listener should not require any port for hICN... +typedef struct { + char name[SYMBOLIC_NAME_LEN]; /* K.w */ + char interface_name[INTERFACE_LEN]; /* Kr. */ + uint32_t id; /* Kr. */ + face_type_t type; /* .rw */ + int family; /* .rw */ + hicn_ip_address_t local_addr; /* .rw */ + uint16_t local_port; /* .rw */ +} hc_listener_t; + +int hc_listener_validate(const hc_listener_t *listener, bool allow_partial); +int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2); + +#define foreach_listener(VAR, data) foreach_type(hc_listener_t, VAR, data) + +#define MAXSZ_HC_LISTENER_ \ + INTERFACE_LEN + SPACE + MAXSZ_URL_ + SPACE + MAXSZ_FACE_TYPE_ +#define MAXSZ_HC_LISTENER MAXSZ_HC_LISTENER_ + NULLTERM + +int hc_listener_snprintf(char *s, size_t size, const hc_listener_t *listener); + +#endif /* HICNCTRL_OBJECTS_LISTENER_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h new file mode 100644 index 000000000..37623ebfe --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/mapme.h + * \brief MAP-Me. + */ + +#ifndef HICNCTRL_OBJECTS_MAPME_H +#define HICNCTRL_OBJECTS_MAPME_H + +typedef enum { + MAPME_TARGET_ENABLE, + MAPME_TARGET_DISCOVERY, + MAPME_TARGET_TIMESCALE, + MAPME_TARGET_RETX, +} mapme_target_t; + +static inline mapme_target_t mapme_target_from_str(char *mapme_target_str) { + if (strcasecmp(mapme_target_str, "enable") == 0) + return MAPME_TARGET_ENABLE; + else if (strcasecmp(mapme_target_str, "discovery") == 0) + return MAPME_TARGET_DISCOVERY; + else if (strcasecmp(mapme_target_str, "timescale") == 0) + return MAPME_TARGET_TIMESCALE; + else + return MAPME_TARGET_RETX; +} + +#define MAX_MAPME_ARG_LEN 30 + +typedef struct { + mapme_target_t target; + // Command argument stored as a string + // before being parsed into 'enabled' or 'timescale' + char unparsed_arg[MAX_MAPME_ARG_LEN]; + + uint8_t enabled; // 1 = on, 0 = off + uint32_t timescale; // Milliseconds + + hicn_ip_address_t address; + int family; + u8 len; +} hc_mapme_t; + +#endif /* HICNCTRL_OBJECTS_MAPME_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/policy.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/policy.h new file mode 100644 index 000000000..437387e4a --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/policy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/policy.h + * \brief Policy. + */ + +#ifndef HICNCTRL_OBJECTS_POLICY_H +#define HICNCTRL_OBJECTS_POLICY_H + +typedef struct { + int family; /* Krw */ + hicn_ip_address_t remote_addr; /* krw */ + uint8_t len; /* krw */ + hicn_policy_t policy; /* .rw */ +} hc_policy_t; + +#define foreach_policy(VAR, data) foreach_type(hc_policy_t, VAR, data) + +/* TODO */ +#define MAXSZ_HC_POLICY_ 0 +#define MAXSZ_HC_POLICY MAXSZ_HC_POLICY_ + NULLTERM + +int hc_policy_snprintf(char *s, size_t size, hc_policy_t *policy); +int hc_policy_validate(const hc_policy_t *policy); + +#endif /* HICNCTRL_OBJECTS_POLICY_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/punting.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/punting.h new file mode 100644 index 000000000..d18e596b1 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/punting.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/punting.h + * \brief Punting + */ + +#ifndef HICNCTRL_OBJECTS_PUNTING_H +#define HICNCTRL_OBJECTS_PUNTING_H + +typedef struct { + face_id_t face_id; /* Kr. */ // XXX listener id, could be NULL for all ? + int family; /* Krw */ + hicn_ip_address_t prefix; /* krw */ + u8 prefix_len; /* krw */ +} hc_punting_t; + +int hc_punting_validate(const hc_punting_t *punting); +int hc_punting_cmp(const hc_punting_t *c1, const hc_punting_t *c2); + +#define foreach_punting(VAR, data) foreach_type(hc_punting_t, VAR, data) + +#define MAXSZ_HC_PUNTING_ 0 +#define MAXSZ_HC_PUNTING MAXSZ_HC_PUNTING_ + NULLTERM + +int hc_punting_snprintf(char *s, size_t size, hc_punting_t *punting); + +#endif /* HICNCTRL_OBJECTS_PUNTING_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/route.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/route.h new file mode 100644 index 000000000..fb68e9430 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/route.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/route.h + * \brief Route. + */ + +#ifndef HICNCTRL_OBJECTS_ROUTE_H +#define HICNCTRL_OBJECTS_ROUTE_H + +#include <hicn/ctrl/objects/face.h> + +typedef struct { + face_id_t face_id; /* Kr. ID (used when face and face_name == NULL) */ + char face_name[SYMBOLIC_NAME_LEN]; /* Kr. a name or an ID (if integer), used + if face is NULL */ + int family; /* Krw */ + hicn_ip_address_t remote_addr; /* krw */ + uint8_t len; /* krw */ + uint16_t cost; /* .rw */ + hc_face_t face; /* use by default if not NULL, otherwise look at face_name, + then face_id */ +} hc_route_t; + +#define foreach_route(VAR, data) foreach_type(hc_route_t, VAR, data) + +#define MAX_COST 65535 +#define MAXSZ_COST 5 +#define MAX_LEN 255 +#define MAXSZ_LEN 3 + +#define MAXSZ_HC_ROUTE_ \ + MAXSZ_FACE_ID + 1 + MAXSZ_COST + 1 + MAXSZ_IP_ADDRESS + 1 + MAXSZ_LEN +#define MAXSZ_HC_ROUTE MAXSZ_HC_ROUTE_ + NULLTERM + +int hc_route_snprintf(char *s, size_t size, const hc_route_t *route); +int hc_route_validate(const hc_route_t *route, bool allow_partial); + +#endif /* HICNCTRL_OBJECTS_ROUTE_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/strategy.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/strategy.h new file mode 100644 index 000000000..208f4620b --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/strategy.h @@ -0,0 +1,46 @@ + +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/strategy.h + * \brief Strategy. + */ + +#ifndef HICNCTRL_OBJECTS_STRATEGY_H +#define HICNCTRL_OBJECTS_STRATEGY_H + +#include <hicn/strategy.h> + +#define MAXSZ_STRATEGY_NAME 255 + +typedef struct { + // The name is not set by the controller + // but populated by the daemon + char name[MAXSZ_STRATEGY_NAME]; + strategy_type_t type; + hicn_ip_address_t address, local_address; + int family, local_family; + u8 len, local_len; +} hc_strategy_t; + +#define foreach_strategy(VAR, data) foreach_type(hc_strategy_t, VAR, data) + +#define MAXSZ_HC_STRATEGY_ MAXSZ_STRATEGY_NAME +#define MAXSZ_HC_STRATEGY MAXSZ_HC_STRATEGY_ + NULLTERM + +int hc_strategy_snprintf(char *s, size_t size, const hc_strategy_t *strategy); + +#endif /* HICNCTRL_OBJECTS_STRATEGY_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/subscription.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/subscription.h new file mode 100644 index 000000000..861341160 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/subscription.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file objects/subscription.h + * \brief Subscription. + */ + +#ifndef HICNCTRL_OBJECTS_SUBSCRIPTION_H +#define HICNCTRL_OBJECTS_SUBSCRIPTION_H + +#include <limits.h> +#include <stddef.h> +#include <hicn/ctrl/object_type.h> + +#undef PUNTING // TODO(eloparco): Undefined to avoid collisions + // Fix the collision + +// Used only to create 'hc_topic_t' +typedef struct { +#define _(x) char x; + foreach_object_type +#undef _ +} object_offset_t; + +// Flags for topic subscriptions +typedef enum { +#define _(x) TOPIC_##x = (1 << offsetof(object_offset_t, x)), + foreach_object_type +#undef _ + TOPIC_ALL = INT_MAX, +} hc_topic_t; + +static inline hc_object_type_t object_from_topic(hc_topic_t topic) { +#define _(x) \ + if (topic == TOPIC_##x) return OBJECT_TYPE_##x; + foreach_object_type +#undef _ + return OBJECT_TYPE_UNDEFINED; +} + +static inline hc_topic_t topic_from_object_type(hc_object_type_t object_type) { + if (object_type == OBJECT_TYPE_UNDEFINED) return TOPIC_ALL; +#define _(x) \ + if (object_type == OBJECT_TYPE_##x) return TOPIC_##x; + foreach_object_type +#undef _ + return TOPIC_UNDEFINED; +} + +#define NUM_TOPICS OBJECT_TYPE_N // Because a topic is created for each object +#define ALL_TOPICS ~0 + +// Subscriptions +typedef uint32_t hc_topics_t; +typedef struct { + hc_topics_t topics; +} hc_subscription_t; + +#if 0 +typedef struct { + netdevice_type_t interface_type; +} hc_event_interface_update_t; + +typedef struct { + ip_prefix_t prefix; + netdevice_type_t interface_type; +} hc_event_active_interface_update_t; +#endif + +#endif /* HICNCTRL_OBJECTS_SUBSCRIPTION_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/parse.h b/ctrl/libhicnctrl/includes/hicn/ctrl/parse.h new file mode 100644 index 000000000..8921d25ed --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/parse.h @@ -0,0 +1,116 @@ +#ifndef HICNLIGHT_PARSE_CMD +#define HICNLIGHT_PARSE_CMD + +#include <hicn/ctrl/api.h> + +#include "command.h" + +/* Update sscanf accordingly in parse_cmd.c */ +#define MAX_PARAMETERS 10 +#define MAX_SCANF_PARAM_LEN 100 + +typedef int (*parser_hook_t)(void* arg); + +#if 0 +typedef struct { + const char* name; + const char* help; + parser_type_t type; + size_t offset; + /* + * quick hack to let the functions update two or more parameters, like for + * IP_ADDRESS or IP_PREFIX types + */ + size_t offset2; + size_t offset3; +} command_parameter_t; + +typedef struct { + hc_action_t action; + hc_object_type_t object; + unsigned nparams; + command_parameter_t parameters[MAX_PARAMETERS]; + parser_hook_t post_hook; +} command_parser_t; + +#define TYPE_STRN(N) \ + (parser_type_t) { \ + .name = TYPENAME_STR, \ + .str = { \ + .max_size = N, \ + }, \ + } +#define TYPE_FMT_STRN(N) "%s" + +#define TYPE_INT(MIN, MAX) \ + (parser_type_t) { \ + .name = TYPENAME_INT, \ + .sint = { \ + .min = (MIN), \ + .max = (MAX), \ + }, \ + } +#define TYPE_FMT_INT "%d" + +#define TYPE_UINT(min, max) \ + (parser_type_t) { \ + .name = TYPENAME_UINT, \ + .uint = { \ + .min = min, \ + .max = max, \ + }, \ + } +#define TYPE_FMT_UINT "%u" + +#define TYPE_SYMBOLIC_OR_ID TYPE_STRN(SYMBOLIC_NAME_LEN) +#define TYPE_FMT_SYMBOLIC_OR_ID "%s" + +#define TYPE_INTERFACE_NAME TYPE_STRN(INTERFACE_LEN) +#define TYPE_FMT_INTERFACE_NAME "%s" + +#define TYPE_IP_ADDRESS \ + (parser_type_t) { .name = TYPENAME_IP_ADDRESS, } +#define TYPE_FMT_IP_ADDRESS "%s" + +#define TYPE_IP_PREFIX \ + (parser_type_t) { .name = TYPENAME_IP_PREFIX, } +#define TYPE_FMT_IP_PREFIX "%s" + +#define TYPE_ON_OFF \ + (parser_type_t) { .name = TYPENAME_ON_OFF, } +#define TYPE_FMT_ON_OFF "%s" + +#define TYPE_ENUM(x) \ + (parser_type_t) { \ + .name = TYPENAME_ENUM, \ + .enum_ = { \ + .from_str = (int (*)(const char*))x##_from_str, \ + }, \ + } +/* We need to allocate room for the intermediate string */ +#define TYPE_FMT_ENUM "%s" + +#define TYPE_POLICY_STATE(TAG) \ + (parser_type_t) { \ + .name = TYPENAME_POLICY_STATE, \ + .policy_state = { \ + .tag = TAG, \ + }, \ + } +/* We need to allocate room for the intermediate string */ +#define TYPE_FMT_POLICY_STATE "%s" +#endif + +int parse_getopt_args(const command_parser_t* parser, int argc, char* argv[], + hc_command_t* command); + +int parse(const char* cmd, hc_command_t* command); +int help(const char* cmd); + +/** + * @brief Convert the action enum to the action name used in the commands (e.g. + * from ACTION_CREATE to "add"). + */ +const char* action_to_cmd_action(hc_action_t action); + +#endif /* HICNLIGHT_PARSE_CMD */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/route.h b/ctrl/libhicnctrl/includes/hicn/ctrl/route.h index 81f011d4d..f1801d772 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/route.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/route.h @@ -34,15 +34,15 @@ typedef struct hicn_route_s hicn_route_t; #define MAX_ROUTE_COST 255 #define IS_VALID_ROUTE_COST(x) ((x >= MIN_ROUTE_COST) && (x <= MAX_ROUTE_COST)) -hicn_route_t* hicn_route_create(ip_prefix_t* prefix, face_id_t face_id, +hicn_route_t* hicn_route_create(hicn_ip_prefix_t* prefix, face_id_t face_id, route_cost_t cost); hicn_route_t* hicn_route_dup(const hicn_route_t* route); void hicn_route_free(hicn_route_t* route); int hicn_route_cmp(const hicn_route_t* route1, const hicn_route_t* route2); -int hicn_route_get_prefix(const hicn_route_t* route, ip_prefix_t* prefix); -int hicn_route_set_prefix(hicn_route_t* route, const ip_prefix_t prefix); +int hicn_route_get_prefix(const hicn_route_t* route, hicn_ip_prefix_t* prefix); +int hicn_route_set_prefix(hicn_route_t* route, const hicn_ip_prefix_t prefix); int hicn_route_get_cost(const hicn_route_t* route, int* cost); int hicn_route_set_cost(hicn_route_t* route, const int cost); diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/socket.h b/ctrl/libhicnctrl/includes/hicn/ctrl/socket.h new file mode 100644 index 000000000..2503fadd0 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/socket.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file socket.h + * \brief Control socket + */ + +#ifndef HICNCTRL_SOCKET_H +#define HICNCTRL_SOCKET_H + +#include <hicn/ctrl/data.h> + +/* With UDP, the buffer should be able to receieve a full packet, and thus MTU + * (max 9000) is sufficient. Messages will be received fully one by one. + * With TCP, the buffer should be at least able to receive a message header and + * the maximum size of a data element, so any reasonable size will be correct, + * it might just optimize performance. Messages might arrive in chunks that the + * library is able to parse. + */ +#define JUMBO_MTU 9000 +#define RECV_BUFLEN 65535 + +#define foreach_forwarder_type \ + _(UNDEFINED) \ + _(HICNLIGHT) \ + _(VPP) \ + _(N) + +typedef enum { +#define _(x) FORWARDER_TYPE_##x, + foreach_forwarder_type +#undef _ +} forwarder_type_t; + +extern const char *forwarder_type_str[]; + +#define forwarder_type_str(x) forwarder_type_str[x] + +forwarder_type_t forwarder_type_from_str(const char *str); + +/** + * \brief Holds the state of an hICN control socket + */ +typedef struct hc_sock_s hc_sock_t; + +/** + * \brief Create an hICN control socket using the specified URL. + * \param [in] url - The URL to connect to. + * \return an hICN control socket + */ +hc_sock_t *hc_sock_create_url(const char *url); + +/** + * \brief Create an hICN control socket using the provided forwarder. + * \return an hICN control socket + */ +hc_sock_t *hc_sock_create_forwarder(forwarder_type_t forwarder); + +/** + * \brief Create an hICN control socket using the provided forwarder and a + * URL. \return an hICN control socket + */ +hc_sock_t *hc_sock_create_forwarder_url(forwarder_type_t forwarder, + const char *url); + +/** + * \brief Create an hICN control socket using the default connection type. + * XXX doc + * \return an hICN control socket + */ +hc_sock_t *hc_sock_create(forwarder_type_t forwarder, const char *url); + +/** + * \brief Frees an hICN control socket + * \param [in] s - hICN control socket + */ +void hc_sock_free(hc_sock_t *s); + +/** + * \brief Returns the next available sequence number to use for requests to + * the API. \param [in] s - hICN control socket + */ +int hc_sock_get_next_seq(hc_sock_t *s); + +/** + * \brief Sets the socket as non-blocking + * \param [in] s - hICN control socket + * \return Error code + */ +int hc_sock_set_nonblocking(hc_sock_t *s); + +/** + * \brief Return the file descriptor associated to the hICN contorl sock + * \param [in] s - hICN control socket + * \return The file descriptor (positive value), or a negative integer in case + * of error + */ +int hc_sock_get_fd(hc_sock_t *s); + +/** + * \brief Connect the socket + * \return Error code + */ +int hc_sock_connect(hc_sock_t *s); + +/** + * \brief Return the offset and size of available buffer space + * \param [in] s - hICN control socket + * \param [out] buffer - Offset in buffer + * \param [out] size - Remaining size + * \return Error code + */ +int hc_sock_get_recv_buffer(hc_sock_t *s, uint8_t **buffer, size_t *size); + +#if 0 +/** + * \brief Write/read iexchance on the control socket (internal helper + * function) \param [in] s - hICN control socket \param [in] msg - Message to + * send \param [in] msglen - Length of the message to send \return Error code + */ +int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen, uint32_t seq); +#endif + +/** + * \brief Processing data received by socket + * \param [in] s - hICN control socket + * \param [in] parse - Parse function to convert remote types into lib native + * types, or NULL not to perform any translation. + * \return Error code + */ +int hc_sock_process(hc_sock_t *s, hc_data_t **data); + +int hc_sock_receive(hc_sock_t *s, hc_data_t **data); +int hc_sock_receive_all(hc_sock_t *s, hc_data_t **data); + +#if 0 +/** + * \brief Callback used in async mode when data is available on the socket + * \param [in] s - hICN control socket + * \return Error code + */ +int hc_sock_callback(hc_sock_t *s, hc_data_t **data); +#endif + +/** + * \brief Reset the state of the sock (eg. to handle a reconnecton) + * \param [in] s - hICN control socket + * \return Error code + */ +int hc_sock_reset(hc_sock_t *s); + +void hc_sock_increment_woff(hc_sock_t *s, size_t bytes); + +#if 0 +int hc_sock_prepare_send(hc_sock_t *s, hc_result_t *result, + data_callback_t complete_cb, void *complete_cb_data); + +#endif + +int hc_sock_set_recv_timeout_ms(hc_sock_t *s, long timeout_ms); + +int hc_sock_set_async(hc_sock_t *s); + +int hc_sock_is_async(hc_sock_t *s); + +int hc_sock_on_receive(hc_sock_t *s, size_t count); + +#endif /* HICNCTRL_SOCKET_H */ |