From 0a1c6b5565e20167d1f1f33a5a8b597f420b18b0 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Fri, 26 Jul 2019 23:20:30 +0200 Subject: [HICN-252] Add per-application policy framework to hicn-light forwarder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0531cd7a7de179581295ae34766c81cd9cf3e172 Signed-off-by: Jordan Augé Signed-off-by: Mauro Sardara Co-authored-by: Mauro Sardara --- ctrl/libhicnctrl/includes/CMakeLists.txt | 26 + ctrl/libhicnctrl/includes/ctrl.h | 1 + ctrl/libhicnctrl/includes/hicn/ctrl.h | 25 + ctrl/libhicnctrl/includes/hicn/ctrl/api.h | 758 +++++++++++++++++++++++++ ctrl/libhicnctrl/includes/hicn/ctrl/commands.h | 411 ++++++++++++++ ctrl/libhicnctrl/includes/hicn/ctrl/face.h | 179 ++++++ 6 files changed, 1400 insertions(+) create mode 100644 ctrl/libhicnctrl/includes/CMakeLists.txt create mode 120000 ctrl/libhicnctrl/includes/ctrl.h create mode 100644 ctrl/libhicnctrl/includes/hicn/ctrl.h create mode 100644 ctrl/libhicnctrl/includes/hicn/ctrl/api.h create mode 100755 ctrl/libhicnctrl/includes/hicn/ctrl/commands.h create mode 100644 ctrl/libhicnctrl/includes/hicn/ctrl/face.h (limited to 'ctrl/libhicnctrl/includes') diff --git a/ctrl/libhicnctrl/includes/CMakeLists.txt b/ctrl/libhicnctrl/includes/CMakeLists.txt new file mode 100644 index 000000000..a85489a0c --- /dev/null +++ b/ctrl/libhicnctrl/includes/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(LIBHICNCTRL_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} "" + CACHE INTERNAL + "" FORCE +) + +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/commands.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn/ctrl/face.h + PARENT_SCOPE +) \ No newline at end of file diff --git a/ctrl/libhicnctrl/includes/ctrl.h b/ctrl/libhicnctrl/includes/ctrl.h new file mode 120000 index 000000000..646630968 --- /dev/null +++ b/ctrl/libhicnctrl/includes/ctrl.h @@ -0,0 +1 @@ +hicn/ctrl.h \ No newline at end of file diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl.h b/ctrl/libhicnctrl/includes/hicn/ctrl.h new file mode 100644 index 000000000..e61b7a482 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file ctrl.h + * \brief Main interface for hICN control library + */ +#ifndef HICNCTRL_H +#define HICNCTRL_H + +#include + +#endif /* HICNCTRL_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h new file mode 100644 index 000000000..45efb39f9 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -0,0 +1,758 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file api.h + * \brief hICN control library API + * + * This API supports basic hICN objects (face, route, punting) plus + * implementation-specific ones (connection, listener). Currently, this library + * only supports the hicn-light forwarder. + * + * For each object, a set of methods is provided among: + * - CREATE, GET, UPDATE, DELETE, LIST + * - CMP, PARSE, SNPRINTF + * - additionally, attribute getters and/or setters are provided and denoted + * GET( attribute ) and SET( attribute ) + * + * A summary per-object is presented here: + * + * | CRE GET UPD DEL LST | VAL CMP PAR SNP | attributes [GET/SET] + * +------------+---------------------+-------------+--------------------------- + * | face | O O ! O O | ! ! O | state [-S] + * | route | O - ! O O | ! O - | + * | punting | ! - ! ! ! | ! ! ! | + * +------------+---------------------+-----------------+--------------------------- + * | cache | | | store [!!], serve [!!] + * | strategy | | | + * | FIB | | | + * | PIT | | | + * | WLDR | | | + * | MAP-Me | | | + * +------------+---------------------+-----------------+--------------------------- + * | connection | O O ! O O | O O O | state [-S] + * | listener | O O ! - O | O O O O | + * +------------+---------------------+-----------------+--------------------------- + * + * LEGEND: [O] implemented, [!] in progress / TODO, [-] not supported + * + * NOTES: + * + * - Different extensions of the forwarder functionalities bring both new API + * calls, and new object attributes. While it is expected that the former will + * only raised NACK answers because of unsupported API calls, the latter will + * certainly trigger incompatibilities. It is expected that the forwarder + * validates the message length and returns a NACK too. In that case, we + * provide a set of defines to preserve backwards compatibility. At the + * moment, those defines are : + * + * WITH_POLICY: + * + */ + +#ifndef HICNTRL_API +#define HICNTRL_API + +#include +#include + +#include "face.h" +#include "util/types.h" + +#define LIBHICNCTRL_SUCCESS 0 +#define LIBHICNCTRL_FAILURE -1 +#define LIBHICNCTRL_NOT_IMPLEMENTED -99 +#define LIBHICNCTRL_IS_ERROR(x) (x < 0) + + +/** + * This allows to selectively define convenience types to avoid any collision + * when using the library in conjunction with other frameworks including similar + * defines + */ +#ifdef _HICNTRL_NO_DEFS +#define _HICNTRL_NO_DEF_TYPES +#define _HICNTRL_NO_DEF_IPADDR +#define _HICNTRL_NO_DEF_UNIONCAST +#endif + +#ifndef _HICNTRL_NO_DEF_TYPES +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +#endif /* _HICNTRL_NO_DEF_TYPES */ + +#ifndef _HICNTRL_NO_DEF_IPADDR +#include "util/ip_address.h" +#endif /* _HICNTRL_NO_DEF_IPADDR */ + +#ifndef _HICNTRL_NO_DEF_UNIONCAST +/* Helper for avoiding warnings about type-punning */ +#define UNION_CAST(x, destType) \ + (((union {__typeof__(x) a; destType b;})x).b) +#endif /* _HICNTRL_NO_DEF_UNIONCAST */ + +/****************************************************************************** + * Message helper types and aliases + ******************************************************************************/ + +#define foreach_command \ + _(UNDEFINED) \ + _(CREATE) \ + _(UPDATE) \ + _(DELETE) \ + _(LIST) \ + _(SET) \ + _(N) + +typedef enum { +#define _(x) ACTION_ ## x, +foreach_command +#undef _ +} hc_action_t; + +/** + * \brief hICN control message header + */ +typedef struct hc_msg_s hc_msg_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 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; +} 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); + +/** + * 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 LIBHICNCTRL_SUCCESS; \ + } \ + }; \ + *found = NULL; /* this is optional */ \ + return LIBHICNCTRL_SUCCESS; \ +} + +/****************************************************************************** + * Control socket + ******************************************************************************/ + +/* This should be at least equal to the maximum packet size */ +#define RECV_BUFLEN 8192 + +/** + * \brief Holds the state of an hICN control socket + */ +typedef struct { + char * url; + int fd; + u32 seq; + + /* Partial receive buffer */ + u8 buf[RECV_BUFLEN]; + size_t roff; /**< Read offset */ + size_t woff; /**< Write offset */ + + /* + * Because received messages are potentially unbounded in size, we might not + * guarantee that we can store a full packet before processing it. We must + * implement a very simple state machine remembering the current parsing + * status in order to partially process the packet. + */ + size_t remaining; + u32 send_id; + u32 send_seq; + u32 recv_seq; +} 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 default connection type. + * \return an hICN control socket + */ +hc_sock_t * +hc_sock_create(void); + +/** + * \brief Frees an hICN control socket + */ +void +hc_sock_free(hc_sock_t *s); + +/** + * \brief Sets the socket as non-blocking + * \return Error code + */ +int +hc_sock_set_nonblocking(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] sock - 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] sock - 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); + +/** + * \brief Helper for reading socket contents + * \param [in] sock - hICN control socket + * \param [in] data - Result data buffer + * \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_recv(hc_sock_t * s, hc_data_t * data); + +/** + * \brief Processing data received by socket + * \param [in] sock - hICN control socket + * \param [in] data - Result data buffer + * \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 (*parse)(const u8 * src, u8 * dst)); + +/** + * \brief Reset the state of the sock (eg. to handle a reconnecton) + * \param [in] sock - hICN control socket + * \return Error code + */ +int +hc_sock_reset(hc_sock_t * s); + +/****************************************************************************** + * Command-specific structures and functions + ******************************************************************************/ + +/* + * The following definitions are organized by sections each dealing with a + * specific object being manipulated. All follow a similar structure. + * + * TYPE DEFINITIONS AND ALIASES + * + * We redefine command struct: + * - for uniformization + * - 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 + * - to have command types in between add/list/... commands + * + * COMMAND IMPLEMENTATION + * + * All commands return information in a common format + * + * 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 + * expected that the caller frees this structure using hc_data_free() after + * usage. + * \see hc_data_free. + * + * PARSING + * + * While this is not made mandatory by the library, the returned data can be + * converted to the library's own data structures as described before. + * + * ITERATORS + * + * Macros are defined to facilitate iteration on the returned data structures. + */ + +#ifndef SPACES +#define SPACES(x) x +#endif +#ifndef SPACE +#define SPACE SPACES(1) +#endif +#ifndef NULLTERM +#define NULLTERM 1 +#endif + +#define NAME_LEN 16 /* NULL-terminated right ? */ +#ifdef __linux__ +#define INTERFACE_LEN 16 +#endif +#define MAXSZ_HC_NAME_ 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 MAXSZ_HC_PROTO_ 8 /* inetX:// */ +#define MAXSZ_HC_PROTO MAXSZ_HC_PROTO_ + NULLTERM + +#define MAXSZ_HC_URL4_ MAXSZ_HC_PROTO_ + MAXSZ_IP4_ADDRESS_ + MAXSZ_PORT_ +#define MAXSZ_HC_URL6_ MAXSZ_HC_PROTO_ + MAXSZ_IP6_ADDRESS_ + MAXSZ_PORT_ +#define MAXSZ_HC_URL_ MAXSZ_HC_URL6_ +#define MAXSZ_HC_URL4 MAXSZ_HC_URL4_ + NULLTERM +#define MAXSZ_HC_URL6 MAXSZ_HC_URL6_ + NULLTERM +#define MAXSZ_HC_URL MAXSZ_HC_URL_ + NULLTERM + +int hc_url_snprintf(char * s, size_t size, int family, + const ip_address_t * ip_address, u16 port); + +#define foreach_type(TYPE, VAR, data) \ + for (TYPE * VAR = (TYPE*)data->buffer; \ + VAR < (TYPE*)(data->buffer + data->size * data->out_element_size); \ + VAR++) + +/** + * New type is defined to reconciliate different enum for add and list. + * Also, values not implemented have been removed for clarity. + */ +#define foreach_connection_type \ + _(UNDEFINED) \ + _(TCP) \ + _(UDP) \ + _(HICN) \ + _(N) + +typedef enum { +#define _(x) CONNECTION_TYPE_ ## x, +foreach_connection_type +#undef _ +} hc_connection_type_t; + +#define MAXSZ_HC_CONNECTION_TYPE_ 9 +#define MAXSZ_HC_CONNECTION_TYPE MAXSZ_HC_CONNECTION_TYPE_ + NULLTERM + +extern const char * connection_type_str[]; + +hc_connection_type_t +connection_type_from_str(const char * str); + +/* Same order as connection_state_t in hicn/core/connectionState.h */ +#define foreach_connection_state \ + _(UNDEFINED) \ + _(DOWN) \ + _(UP) \ + _(N) + +typedef enum { +#define _(x) HC_CONNECTION_STATE_ ## x, +foreach_connection_state +#undef _ +} hc_connection_state_t; + +#define MAXSZ_HC_CONNECTION_STATE_ 9 +#define MAXSZ_HC_CONNECTION_STATE MAXSZ_HC_CONNECTION_STATE_ + NULLTERM + +extern const char * connection_state_str[]; + +typedef int (*HC_PARSE)(const u8 *, u8 *); + +/*----------------------------------------------------------------------------* + * Listeners + *----------------------------------------------------------------------------*/ + +// FIXME the listener should not require any port for hICN... +typedef struct { + char name[NAME_LEN]; /* K.w */ // XXX clarify what used for +#ifdef __linux__ + char interface_name[INTERFACE_LEN]; /* Kr. */ +#endif + u32 id; + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ +} hc_listener_t; + +int hc_listener_create(hc_sock_t * s, hc_listener_t * listener); +int hc_listener_get(hc_sock_t *s, hc_listener_t * listener, + hc_listener_t ** listener_found); +int hc_listener_delete(hc_sock_t * s, hc_listener_t * listener); +int hc_listener_list(hc_sock_t * s, hc_data_t ** pdata); + +int hc_listener_validate(const hc_listener_t * listener); +int hc_listener_cmp(const hc_listener_t * l1, const hc_listener_t * l2); +int hc_listener_parse(void * in, hc_listener_t * listener); + +#define foreach_listener(VAR, data) foreach_type(hc_listener_t, VAR, data) + +#define MAXSZ_HC_LISTENER_ MAXSZ_HC_URL_ + SPACE + MAXSZ_HC_CONNECTION_TYPE_ +#define MAXSZ_HC_LISTENER MAXSZ_HC_LISTENER_ + NULLTERM + +GENERATE_FIND_HEADER(listener); + +int hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener); + +/*----------------------------------------------------------------------------* + * Connections + *----------------------------------------------------------------------------*/ + +typedef struct { + u32 id; /* Kr. */ + char name[NAME_LEN]; /* K.w */ + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ + ip_address_t remote_addr; /* .rw */ + u16 remote_port; /* .rw */ + hc_connection_state_t admin_state; /* .rw */ +#ifdef WITH_POLICY + policy_tags_t tags; /* .rw */ +#endif /* WITH_POLICY */ + hc_connection_state_t state; /* .r. */ +} hc_connection_t; + + +int hc_connection_create(hc_sock_t * s, hc_connection_t * connection); +int hc_connection_get(hc_sock_t *s, hc_connection_t * connection, + hc_connection_t ** connection_found); +int hc_connection_update_by_id(hc_sock_t * s, int hc_connection_id, + hc_connection_t * connection); +int hc_connection_update(hc_sock_t * s, hc_connection_t * connection_current, + hc_connection_t * connection_updated); +int hc_connection_delete(hc_sock_t * s, hc_connection_t * connection); +/* +int hc_connection_remove_by_id(hc_sock_t * s, char * name); +int hc_connection_remove_by_name(hc_sock_t * s, char * name); +*/ +int hc_connection_list(hc_sock_t * s, hc_data_t ** pdata); + +int hc_connection_validate(const hc_connection_t * connection); +int hc_connection_cmp(const hc_connection_t * c1, const hc_connection_t * c2); +int hc_connection_parse(void * in, hc_connection_t * connection); + +#ifdef WITH_POLICY +int hc_connection_set_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state); +#endif /* WITH_POLICY */ + +#define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) + +#define MAXSZ_HC_CONNECTION_ MAXSZ_HC_CONNECTION_STATE_ + \ + 2 * MAXSZ_HC_URL_ + MAXSZ_HC_CONNECTION_TYPE_ + SPACES(3) +#define MAXSZ_HC_CONNECTION MAXSZ_HC_CONNECTION_ + NULLTERM + +GENERATE_FIND_HEADER(connection); + +int hc_connection_snprintf(char * s, size_t size, const hc_connection_t * connection); + +/*----------------------------------------------------------------------------* + * Routes + *----------------------------------------------------------------------------*/ + +typedef struct { + u8 face_id; /* Kr. */ + int family; /* Krw */ + ip_address_t remote_addr; /* krw */ + u8 len; /* krw */ + u16 cost; /* .rw */ +} hc_route_t; + +int hc_route_parse(void * in, hc_route_t * route); + +int hc_route_create(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); + +#define foreach_route(VAR, data) foreach_type(hc_route_t, VAR, data) + +#define MAX_FACE_ID 255 +#define MAXSZ_FACE_ID 3 +#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); + +/*----------------------------------------------------------------------------* + * 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 { + u32 id; + char name[NAME_LEN]; + face_t face; // or embed ? + //face_id_t parent; /* Pointer from connection to listener */ +} hc_face_t; + +/** + * \brief Create a face + * \param [in] s - hICN socket + * \param [in,out] face - Parameters of the face to create + * \return Error code + * + * The face parameters will be updated with the face ID. + */ +int hc_face_create(hc_sock_t * s, hc_face_t * face); +int hc_face_get(hc_sock_t * s, hc_face_t * face, hc_face_t ** face_found); +int hc_face_delete(hc_sock_t * s, hc_face_t * face); +int hc_face_list(hc_sock_t * s, hc_data_t ** pdata); + +#define foreach_face(VAR, data) foreach_type(hc_face_t, VAR, data) + +#define MAXSZ_HC_FACE_ 0 +#define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM + +int hc_face_snprintf(char * s, size_t size, hc_face_t * face); + +/////// XXX XXX XXX XXX missing face api functions, cf punting now... + +/*----------------------------------------------------------------------------* + * Punting + *----------------------------------------------------------------------------*/ + +typedef struct { + u8 face_id; /* Kr. */ // XXX listener id, could be NULL for all ? + int family; /* Krw */ + ip_address_t prefix; /* krw */ + u8 prefix_len; /* krw */ +} 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); +int hc_punting_parse(void * in, hc_punting_t * punting); + +#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 + *----------------------------------------------------------------------------*/ + +int hc_cache_set_store(hc_sock_t * s, int enabled); +int hc_cache_set_serve(hc_sock_t * s, int enabled); + +/*----------------------------------------------------------------------------* + * Strategy + *----------------------------------------------------------------------------*/ + +#define MAXSZ_STRATEGY_NAME 255 + +typedef struct { + char name[MAXSZ_STRATEGY_NAME]; +} 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 /* XXX */); + +/*----------------------------------------------------------------------------* + * WLDR + *----------------------------------------------------------------------------*/ + +// per connection +int hc_wldr_set(hc_sock_t * s /* XXX */); + +/*----------------------------------------------------------------------------* + * MAP-Me + *----------------------------------------------------------------------------*/ + +int hc_mapme_set(hc_sock_t * s, int enabled); +int hc_mapme_set_discovery(hc_sock_t * s, int enabled); +int hc_mapme_set_timescale(hc_sock_t * s, double timescale); +int hc_mapme_set_retx(hc_sock_t * s, double timescale); + +/*----------------------------------------------------------------------------* + * Policies + *----------------------------------------------------------------------------*/ + +#ifdef WITH_POLICY + +typedef struct { + int family; /* Krw */ + ip_address_t remote_addr; /* krw */ + u8 len; /* krw */ + policy_t policy; /* .rw */ +} hc_policy_t; + +int hc_policy_parse(void * in, hc_policy_t * policy); + +int hc_policy_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); + +#endif /* WITH_POLICY */ + +#endif /* HICNTRL_API */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h new file mode 100755 index 000000000..1d07c9b72 --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file commands.h + * @brief All hicn-light commands: 14 in total. + * + * Header and payload in binary format. + */ + +#ifndef commands_h +#define commands_h + +#ifndef _WIN32 +#include +#include +#endif + +#include +#include + +#ifdef WITH_POLICY +#include "util/policy.h" +#endif /* WITH_POLICY */ + +typedef struct in6_addr ipv6_addr_t; +typedef uint32_t ipv4_addr_t; + +union commandAddr { + ipv4_addr_t ipv4; + ipv6_addr_t ipv6; +}; + +typedef enum { + REQUEST_LIGHT = 0xc0, // this is a command + RESPONSE_LIGHT, + ACK_LIGHT, + NACK_LIGHT, + LAST_MSG_TYPE_VALUE +} message_type; + +typedef enum { + ADD_LISTENER = 0, + ADD_CONNECTION, + LIST_CONNECTIONS, + ADD_ROUTE, + LIST_ROUTES, + REMOVE_CONNECTION, + REMOVE_ROUTE, + CACHE_STORE, + CACHE_SERVE, + CACHE_CLEAR, + SET_STRATEGY, + SET_WLDR, + ADD_PUNTING, + LIST_LISTENERS, + MAPME_ENABLE, + MAPME_DISCOVERY, + MAPME_TIMESCALE, + MAPME_RETX, + CONNECTION_SET_ADMIN_STATE, +#ifdef WITH_POLICY + ADD_POLICY, + LIST_POLICIES, + REMOVE_POLICY, + UPDATE_CONNECTION, +#endif /* WITH_POLICY */ + REMOVE_LISTENER, + LAST_COMMAND_VALUE +} command_id; + +typedef enum { + ADDR_INET = 1, + ADDR_INET6, + ADDR_LINK, + ADDR_IFACE, + ADDR_UNIX /* PF_UNIX */ +} address_type; + +typedef enum { + UDP_CONN, + TCP_CONN, + GRE_CONN, // not implemented + HICN_CONN +} connection_type; + +typedef enum { ACTIVATE_ON, ACTIVATE_OFF } activate_type; + +//========== HEADER ========== + +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 + +//========== [00] ADD LISTENER ========== + +typedef enum { ETHER_MODE, IP_MODE, HICN_MODE } listener_mode; + +typedef struct { + char symbolic[16]; + char interfaceName[16]; + union commandAddr address; + uint16_t port; + // uint16_t etherType; + uint8_t addressType; + uint8_t listenerMode; + uint8_t connectionType; +} add_listener_command; + +// SIZE=40 + +//========== [01] ADD CONNECTION ========== + +typedef struct { + char symbolic[16]; + union commandAddr remoteIp; + union commandAddr localIp; + uint16_t remotePort; + uint16_t localPort; + uint8_t ipType; + uint8_t connectionType; + uint8_t admin_state; +#ifdef WITH_POLICY + policy_tags_t tags; +#endif /* WITH_POLICY */ +} add_connection_command; + +// SIZE=56 + +//========== [02] LIST CONNECTIONS ========== + +typedef enum { + CONN_GRE, + CONN_TCP, + CONN_UDP, + CONN_MULTICAST, + CONN_L2, + CONN_HICN +} list_connections_type; + +typedef enum { + IFACE_UP = 0, + IFACE_DOWN = 1, + IFACE_UNKNOWN = 2 // not used actually +} connection_state; + +typedef struct { + add_connection_command connectionData; + uint32_t connid; + uint8_t state; +#ifdef WITH_UPDATE + char connectionName[16]; +#endif /* WITH_UPDATE */ +} list_connections_command; + +// SIZE=64 + +//========== [03] ADD ROUTE ========== + +typedef struct { + char symbolicOrConnid[16]; + union commandAddr address; + uint16_t cost; + uint8_t addressType; + uint8_t len; +} add_route_command; + +// SIZE=36 + +//========== [04] LIST ROUTE ========== + +typedef struct { + union commandAddr address; + uint32_t connid; + uint16_t cost; + uint8_t addressType; + uint8_t len; +} list_routes_command; + +// SIZE=24 + +//========== [05] REMOVE CONNECTION ========== + +typedef struct { + char symbolicOrConnid[16]; +} remove_connection_command; + +//========== [06] REMOVE LISTENER ========== +typedef struct { + char symbolicOrListenerid[16]; +} remove_listener_command; + +// SIZE=16 + +//========== [06] REMOVE ROUTE ========== + +typedef struct { + char symbolicOrConnid[16]; + union commandAddr address; + uint8_t addressType; + uint8_t len; +} remove_route_command; + +// SIZE=36 + +//========== [07] CACHE STORE ========== + +typedef struct { + uint8_t activate; +} cache_store_command; + +// SIZE=1 + +//========== [08] CACHE SERVE ========== + +typedef struct { + uint8_t activate; +} cache_serve_command; + +// SIZE=1 + +//========== [09] SET STRATEGY ========== + +typedef enum { + SET_STRATEGY_LOADBALANCER, + SET_STRATEGY_RANDOM, + SET_STRATEGY_RANDOM_PER_DASH_SEGMENT, + SET_STRATEGY_LOADBALANCER_WITH_DELAY, + SET_STRATEGY_LOADBALANCER_BY_RATE, + SET_STRATEGY_LOADBALANCER_BEST_ROUTE, + LAST_STRATEGY_VALUE +} strategy_type; + +typedef struct { + union commandAddr address; + uint8_t strategyType; + uint8_t addressType; + uint8_t len; +} set_strategy_command; + +// SIZE=20 + +//========== [11] SET WLDR ========== + +typedef struct { + char symbolicOrConnid[16]; + uint8_t activate; +} set_wldr_command; + +// SIZE=17 + +//========== [12] ADD PUNTING ========== + +typedef struct { + char symbolicOrConnid[16]; + union commandAddr address; + uint8_t addressType; + uint8_t len; +} add_punting_command; + +// SIZE=36 + +//========== [13] LIST LISTENER ========== + +typedef struct { + union commandAddr address; +#ifdef WITH_UPDATE + char listenerName[16]; + char interfaceName[16]; +#endif /* WITH_UPDATE */ + uint32_t connid; + uint16_t port; + uint8_t addressType; + uint8_t encapType; +} list_listeners_command; + +// SIZE=56 + +//========== [14] MAPME ========== + +// (enable/discovery/timescale/retx) + +typedef struct { + uint8_t activate; +} mapme_activator_command; + +// SIZE=1 + +typedef struct { + uint32_t timePeriod; +} mapme_timing_command; + +// SIZE=1 + +//========== NEW COMMANDS ========== + +typedef struct { + char symbolicOrConnid[16]; + uint8_t admin_state; +} connection_set_admin_state_command; + +#ifdef WITH_POLICY + +typedef struct { + union commandAddr address; + uint8_t addressType; + uint8_t len; + policy_t policy; +} add_policy_command; + +typedef struct { + union commandAddr address; + uint8_t addressType; + uint8_t len; + policy_t policy; +} list_policies_command; + +typedef struct { + union commandAddr address; + uint8_t addressType; + uint8_t len; +} remove_policy_command; + +typedef struct { + char symbolicOrConnid[16]; + uint8_t admin_state; + policy_tags_t tags; +} update_connection_command; + +#endif /* WITH_POLICY */ + +//===== 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 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); +#endif /* WITH_POLICY */ + case LAST_COMMAND_VALUE: + return 0; + default: + return 0; + } +} +#endif diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/face.h b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h new file mode 100644 index 000000000..2856ce89b --- /dev/null +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file face.h + * \brief Face abstraction + */ +#ifndef HICN_FACE_H +#define HICN_FACE_H + +#ifndef SPACES +#define SPACES(x) x +#endif +#ifndef SPACE +#define SPACE 1 +#endif +#ifndef NULLTERM +#define NULLTERM 1 +#endif + +#ifndef _HICNTRL_NO_DEF_IPADDR +#include "util/ip_address.h" +#endif /* _HICNTRL_NO_DEF_IPADDR */ +#include "util/policy.h" +#include "util/types.h" + + +/* Netdevice type */ + +#include // IFNAMSIZ + +#define foreach_netdevice_type \ + _(UNDEFINED) \ + _(WIRED) \ + _(WIFI) \ + _(CELLULAR) \ + _(VPN) \ + _(N) + +#define MAXSZ_NETDEVICE_TYPE_ 9 +#define MAXSZ_NETDEVICE_TYPE MAXSZ_NETDEVICE_TYPE_ + NULLTERM + +typedef enum { +#define _(x) NETDEVICE_TYPE_ ## x, +foreach_netdevice_type +#undef _ +} netdevice_type_t; + +extern const char * netdevice_type_str[]; + + +/* Netdevice */ + +typedef struct { + u32 index; + char name[IFNAMSIZ]; +} netdevice_t; + +#define NETDEVICE_UNDEFINED_INDEX 0 + +/* Face state */ + +#define foreach_face_state \ + _(UNDEFINED) \ + _(PENDING_UP) \ + _(UP) \ + _(PENDING_DOWN) \ + _(DOWN) \ + _(ERROR) \ + _(N) + +#define MAXSZ_FACE_STATE_ 12 +#define MAXSZ_FACE_STATE MAXSZ_FACE_STATE_ + 1 + +typedef enum { +#define _(x) FACE_STATE_ ## x, +foreach_face_state +#undef _ +} face_state_t; + +extern const char * face_state_str[]; + + +/* Face type */ + +#define foreach_face_type \ + _(UNDEFINED) \ + _(HICN) \ + _(HICN_LISTENER) \ + _(TCP) \ + _(TCP_LISTENER) \ + _(UDP) \ + _(UDP_LISTENER) \ + _(N) + +#define MAXSZ_FACE_TYPE_ 13 +#define MAXSZ_FACE_TYPE MAXSZ_FACE_TYPE_ + 1 + +typedef enum { +#define _(x) FACE_TYPE_ ## x, +foreach_face_type +#undef _ +} face_type_t; + +extern const char * face_type_str[]; + +#define MAXSZ_FACE_ MAXSZ_FACE_TYPE_ + 2 * MAXSZ_IP_ADDRESS + 2 * MAXSZ_PORT + 9 +#define MAXSZ_FACE MAXSZ_FACE_ + 1 + +/* Face */ + +typedef union { + int family; /* To access family independently of face type */ + struct { + int family; + netdevice_t netdevice; + ip_address_t local_addr; + ip_address_t remote_addr; + } hicn; + struct { + int family; + ip_address_t local_addr; + u16 local_port; + ip_address_t remote_addr; + u16 remote_port; + } tunnel; +} face_params_t; + +typedef struct { + face_type_t type; + face_params_t params; + face_state_t admin_state; + face_state_t state; +#ifdef WITH_POLICY + policy_tags_t tags; /**< \see policy_tag_t */ +#endif /* WITH_POLICY */ +} face_t; + +int face_initialize(face_t * face); +int face_initialize_udp(face_t * face, const ip_address_t * local_addr, + u16 local_port, const ip_address_t * remote_addr, u16 remote_port, + int family); +int face_initialize_udp_sa(face_t * face, + const struct sockaddr * local_addr, const struct sockaddr * remote_addr); + +face_t * face_create(); +face_t * face_create_udp(const ip_address_t * local_addr, u16 local_port, + const ip_address_t * remote_addr, u16 remote_port, int family); +face_t * face_create_udp_sa(const struct sockaddr * local_addr, + const struct sockaddr * remote_addr); + +int face_finalize(face_t * face); + +void face_free(face_t * face); + +typedef int (*face_cmp_t)(const face_t * f1, const face_t * f2); + +int face_cmp(const face_t * f1, const face_t * f2); +hash_t face_hash(const face_t * face); + +size_t +face_snprintf(char * s, size_t size, const face_t * face); + +int face_set_tags(face_t * face, policy_tags_t tags); + +#endif /* HICN_FACE_H */ + -- cgit 1.2.3-korg