aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/libhicnctrl/includes/hicn/ctrl
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/libhicnctrl/includes/hicn/ctrl')
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/action.h50
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h853
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/callback.h13
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/command.h191
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/data.h150
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/fw_interface.h135
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light-ng.h456
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h668
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/object.h76
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/object_type.h57
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects.h11
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/active_interface.h44
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/base.h25
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/cache.h38
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/connection.h64
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/face.h49
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/listener.h52
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h58
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/policy.h40
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/punting.h41
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/route.h52
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/strategy.h46
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/objects/subscription.h83
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/parse.h116
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/route.h6
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/socket.h181
26 files changed, 2080 insertions, 1475 deletions
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 */