aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/libhicnctrl
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-11-19 17:57:20 +0000
committerAlberto Compagno <acompagn+fdio@cisco.com>2019-11-26 10:46:53 +0000
commit3e949f72778dd076fffecd7da2fb83cbb1ccb428 (patch)
treeeb5e437c0bc4be54fc57ae46ae964be7567c43bc /ctrl/libhicnctrl
parentb3ee2ed8602c909f8d5096e9d8d44aa345093566 (diff)
[HICN-398] Added face create/delete/list and listener list on libctrl for hicn-plugin
Listener list returns the list of interfaces and their ip addresses Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com> Change-Id: I2582cf29d4f1f60964766d47ad8d6dc64504fd62
Diffstat (limited to 'ctrl/libhicnctrl')
-rw-r--r--ctrl/libhicnctrl/CMakeLists.txt1
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h8
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/face.h4
-rw-r--r--ctrl/libhicnctrl/src/CMakeLists.txt1
-rw-r--r--ctrl/libhicnctrl/src/api.c10
-rw-r--r--ctrl/libhicnctrl/src/cli.c6
-rw-r--r--ctrl/libhicnctrl/src/face.c2
-rw-r--r--ctrl/libhicnctrl/src/hicn_plugin_api.c565
-rw-r--r--ctrl/libhicnctrl/src/util/hash.h3
9 files changed, 529 insertions, 71 deletions
diff --git a/ctrl/libhicnctrl/CMakeLists.txt b/ctrl/libhicnctrl/CMakeLists.txt
index 43d120473..59620088e 100644
--- a/ctrl/libhicnctrl/CMakeLists.txt
+++ b/ctrl/libhicnctrl/CMakeLists.txt
@@ -58,6 +58,7 @@ else()
${HICNPLUGIN_INCLUDE_DIRS})
set(HICN_LIBRARIES ${HICNPLUGIN_LIBRARIES})
+ set(LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs")
list(APPEND DEPENDENCIES
hicn_plugin
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
index eba80bdb3..068b3eb08 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
@@ -139,7 +139,7 @@ typedef struct hc_data_s {
* Create a structure holding the results of an hICN control request.
* \result The newly create data structure.
*/
-hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size);
+hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size, data_callback_t complete_cb);
/**
* Free a structure holding the results of an hICN control request.
@@ -382,7 +382,11 @@ int hc_sock_reset(hc_sock_t *s);
#define NULLTERM 1
#endif
-#define INTERFACE_LEN IFNAMSIZ
+#ifdef HICN_VPP_PLUGIN
+ #define INTERFACE_LEN 64
+#else
+ #define INTERFACE_LEN IFNAMSIZ
+#endif
#define MAXSZ_HC_NAME_ SYMBOLIC_NAME_LEN
#define MAXSZ_HC_NAME MAXSZ_HC_NAME_ + NULLTERM
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/face.h b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
index f0a8045de..12bf3afa6 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
@@ -34,7 +34,7 @@
#include <hicn/util/ip_address.h>
-typedef unsigned int hash_t;
+//typedef unsigned int hash_t; //incompatible with vpp
/* Netdevice type */
@@ -192,7 +192,7 @@ void face_free(face_t * face);
typedef int (*face_cmp_t)(const face_t * f1, const face_t * f2);
int face_cmp(const face_t * f1, const face_t * f2);
-hash_t face_hash(const face_t * face);
+unsigned int face_hash(const face_t * face);
size_t
face_snprintf(char * s, size_t size, const face_t * face);
diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt
index 14c204dda..42fe3d543 100644
--- a/ctrl/libhicnctrl/src/CMakeLists.txt
+++ b/ctrl/libhicnctrl/src/CMakeLists.txt
@@ -87,5 +87,6 @@ if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Android" AND NOT COMPILE_FOR_IOS)
COMPONENT ${LIBHICNCTRL_COMPONENT}
INCLUDE_DIRS ${INCLUDE_DIRS}
DEFINITIONS ${COMPILER_DEFINITIONS}
+ LINK_FLAGS ${LINK_FLAGS}
)
endif ()
diff --git a/ctrl/libhicnctrl/src/api.c b/ctrl/libhicnctrl/src/api.c
index ea4ed69c2..f7efd6b44 100644
--- a/ctrl/libhicnctrl/src/api.c
+++ b/ctrl/libhicnctrl/src/api.c
@@ -303,7 +303,7 @@ typedef struct hc_msg_s {
******************************************************************************/
hc_data_t *
-hc_data_create(size_t in_element_size, size_t out_element_size)
+hc_data_create(size_t in_element_size, size_t out_element_size, data_callback_t complete_cb)
{
hc_data_t * data = malloc(sizeof(hc_data_t));
if (!data)
@@ -317,7 +317,7 @@ hc_data_create(size_t in_element_size, size_t out_element_size)
data->complete = false;
data->command_id = 0; // TODO this could also be a busy mark in the socket
/* No callback needed in blocking code for instance */
- data->complete_cb = NULL;
+ data->complete_cb = complete_cb;
data->buffer = malloc((1 << data->max_size_log) * data->out_element_size);
if (!data->buffer)
@@ -851,7 +851,7 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len,
//hc_sock_reset(s);
/* XXX data will at least store the result (complete) */
- hc_data_t * data = hc_data_create(params->size_in, params->size_out);
+ hc_data_t * data = hc_data_create(params->size_in, params->size_out, NULL);
if (!data) {
ERROR("[hc_execute_command] Could not create data storage");
goto ERR_DATA;
@@ -2398,7 +2398,7 @@ hc_face_list(hc_sock_t * s, hc_data_t ** pdata)
return -1;
}
- hc_data_t * face_data = hc_data_create(sizeof(hc_connection_t), sizeof(hc_face_t));
+ hc_data_t * face_data = hc_data_create(sizeof(hc_connection_t), sizeof(hc_face_t), NULL);
foreach_connection(c, connection_data) {
if (hc_connection_to_face(c, &face) < 0) {
ERROR("[hc_face_list] Could not convert connection to face.");
@@ -2795,7 +2795,7 @@ hc_strategy_list(hc_sock_t * s, hc_data_t ** data)
{
int rc;
- *data = hc_data_create(0, sizeof(hc_strategy_t));
+ *data = hc_data_create(0, sizeof(hc_strategy_t), NULL);
for (unsigned i = 0; i < ARRAY_SIZE(strategies); i++) {
hc_strategy_t * strategy = (hc_strategy_t*)hc_data_get_next(*data);
diff --git a/ctrl/libhicnctrl/src/cli.c b/ctrl/libhicnctrl/src/cli.c
index 879454c3a..fc81139d6 100644
--- a/ctrl/libhicnctrl/src/cli.c
+++ b/ctrl/libhicnctrl/src/cli.c
@@ -401,7 +401,8 @@ parse_options(int argc, char *argv[], hc_command_t * command)
goto ERR_PARAM;
command->face.face.remote_port = atoi(argv[optind++]);
if (argc != optind) {
- netdevice_set_name(&command->face.face.netdevice, argv[optind++]);
+ //netdevice_set_name(&command->face.face.netdevice, argv[optind++]);
+ command->face.face.netdevice.index = atoi(argv[optind++]);
}
break;
@@ -439,7 +440,8 @@ parse_options(int argc, char *argv[], hc_command_t * command)
goto ERR_PARAM;
command->face.face.remote_port = atoi(argv[optind++]);
if (argc != optind) {
- netdevice_set_name(&command->face.face.netdevice, argv[optind++]);
+ command->face.face.netdevice.index = atoi(argv[optind++]);
+ //netdevice_set_name(&command->face.face.netdevice, argv[optind++]);
}
}
break;
diff --git a/ctrl/libhicnctrl/src/face.c b/ctrl/libhicnctrl/src/face.c
index 0e25890da..e617ff8a4 100644
--- a/ctrl/libhicnctrl/src/face.c
+++ b/ctrl/libhicnctrl/src/face.c
@@ -356,7 +356,7 @@ face_cmp(const face_t * f1, const face_t * f2)
return 0;
}
-hash_t
+unsigned int
face_hash(const face_t * face)
{
/* Assuming the unused part of the struct is set to zero */
diff --git a/ctrl/libhicnctrl/src/hicn_plugin_api.c b/ctrl/libhicnctrl/src/hicn_plugin_api.c
index 7dbd88771..7d2a4b4b4 100644
--- a/ctrl/libhicnctrl/src/hicn_plugin_api.c
+++ b/ctrl/libhicnctrl/src/hicn_plugin_api.c
@@ -32,19 +32,30 @@
#include <hicn/util/token.h>
#include <strings.h>
#include <vapi/hicn.api.vapi.h>
+#include <vapi/ip.api.vapi.h>
+#include <vapi/interface.api.vapi.h>
#include <hicn/util/log.h>
#include <hicn/util/map.h>
+#include <vnet/ip/ip6_packet.h>
+#include <vnet/ip/ip_types_api.h>
#define APP_NAME "hicn_plugin"
#define MAX_OUTSTANDING_REQUESTS 4
#define RESPONSE_QUEUE_SIZE 2
+// #define vl_typedefs
+// #include <vpp/api/vpe_all_api_h.h>
+// #undef vl_typedefs
+
DEFINE_VAPI_MSG_IDS_HICN_API_JSON
+DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON
+DEFINE_VAPI_MSG_IDS_IP_API_JSON
/*
* Internal state associated to a pending request
*/
typedef struct {
+ vapi_ctx_t g_vapi_ctx_instance;
int seq;
// Reusing the buffer of data to hold both the unparsed response from the
// forwarder and the result of the parsing
@@ -104,13 +115,14 @@ void hc_sock_request_free(hc_sock_request_t *request) { free(request); }
_(hicn_api_node_params_set_reply) \
_(hicn_api_node_params_get_reply) \
_(hicn_api_node_stats_get_reply) \
- _(hicn_api_face_ip_add) \
- _(hicn_api_face_ip_add_reply) \
- _(hicn_api_face_ip_del) \
- _(hicn_api_face_ip_del_reply) \
- _(hicn_api_face_ip_params_get) \
+ _(hicn_api_face_add) \
+ _(hicn_api_face_add_reply) \
+ _(hicn_api_face_del) \
+ _(hicn_api_face_del_reply) \
+ _(hicn_api_face_get) \
+ _(hicn_api_faces_details) \
_(hicn_api_face_stats_details) \
- _(hicn_api_face_ip_params_get_reply) \
+ _(hicn_api_face_get_reply) \
_(hicn_api_route_nhops_add) \
_(hicn_api_route_nhops_add_reply) \
_(hicn_api_route_del) \
@@ -136,7 +148,10 @@ typedef union {
#undef _
} hc_msg_payload_t;
-#define IS_DUMP_MSG(a) (a == vapi_msg_id_hicn_api_face_stats_dump || a == vapi_msg_id_hicn_api_routes_dump)
+#define IS_DUMP_MSG(a) (a == vapi_msg_id_hicn_api_face_stats_dump || \
+ a == vapi_msg_id_hicn_api_routes_dump || \
+ a == vapi_msg_id_hicn_api_faces_dump || \
+ a == vapi_msg_id_sw_interface_dump)
typedef struct __attribute__ ((__packed__)) {
hc_msg_header_t hdr;
@@ -161,7 +176,7 @@ typedef struct __attribute__((__packed__)) {
* Control Data
******************************************************************************/
-hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size) {
+hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size, data_callback_t complete_cb) {
hc_data_t *data = malloc(sizeof(hc_data_t));
if (!data) goto ERR_MALLOC;
@@ -173,7 +188,7 @@ hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size) {
data->complete = false;
data->command_id = 0; // TODO this could also be a busy mark in the socket
/* No callback needed in blocking code for instance */
- data->complete_cb = NULL;
+ data->complete_cb = complete_cb;
return data;
@@ -210,6 +225,9 @@ hc_sock_t *hc_sock_create_url(const char *url) {
hc_sock_t *hc_sock_create(void) {
hc_sock_t *s = malloc(sizeof(hc_sock_t));
+
+ if (!s) goto ERR_SOCK;
+
memset(s, 0, sizeof(hc_sock_t));
s->map = hc_sock_map_create();
@@ -222,6 +240,7 @@ hc_sock_t *hc_sock_create(void) {
ERR_MAP:
free(s);
+ERR_SOCK:
return NULL;
}
@@ -258,10 +277,12 @@ int hc_sock_get_fd(hc_sock_t *s) { return 1; }
vapi_error_e vapi_cb(vapi_ctx_t ctx, void *callback_ctx, vapi_error_e error, bool is_last, void *payload) {
callback_ctx_t *ctx_call = (callback_ctx_t *)callback_ctx;
hc_sock_t *s = ctx_call->s;
+ int ret = VAPI_OK;
if ((s->woff != s->roff) && (s->woff % RECV_BUFLEN == 0)) {
ERROR("[hc_sock_process] No more space on the buffer to store responces");
- return -1;
+ ret = VAPI_ENOMEM;
+ goto END;
}
if (is_last) {
@@ -269,14 +290,17 @@ vapi_error_e vapi_cb(vapi_ctx_t ctx, void *callback_ctx, vapi_error_e error, boo
s->woff++;
}
- if(!payload)
- return 0;
+ if(!payload) {
+ ret = VAPI_ENOMEM;
+ goto END;
+ }
hc_sock_request_t *request = NULL;
if (hc_sock_map_get(s->map, ctx_call->ctx_msg, &request) <
0) {
ERROR("[hc_sock_process] Error searching for matching request");
- return -1;
+ ret = VAPI_ENOMEM;
+ goto END;
}
if (request->data->current == request->data->size) {
@@ -284,20 +308,27 @@ vapi_error_e vapi_cb(vapi_ctx_t ctx, void *callback_ctx, vapi_error_e error, boo
request->data->size = 1;
request->data->buffer = malloc(request->data->in_element_size * request->data->size);
} else {
- void *tmp =
- malloc(request->data->in_element_size * request->data->size * 2);
- memcpy(tmp, request->data->buffer, request->data->current * request->data->in_element_size);
- free(request->data->buffer);
- request->data->size *= 2;
- request->data->buffer = tmp;
+ request->data->buffer = realloc(request->data->buffer, request->data->in_element_size * request->data->size * 2);
+ request->data->size *=2;
}
}
+
+ if (!request->data->buffer) {
+ request->data->size = 0;
+ ret = VAPI_ENOMEM;
+ goto END;
+ }
+
memcpy(request->data->buffer +
request->data->current * request->data->in_element_size,
payload, request->data->in_element_size);
request->data->current++;
- return 0;
+END:
+ if (is_last)
+ free(callback_ctx);
+
+ return ret;
}
int hc_sock_connect(hc_sock_t *s) {
@@ -349,7 +380,7 @@ int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen, int seq) {
vapi_store_request(s->g_vapi_ctx_instance, seq, false, (vapi_cb_t)callback, callback_ctx);
}
}
-
+
if (rv != VAPI_OK) {
if (VAPI_OK != vapi_producer_unlock (s->g_vapi_ctx_instance)) {
abort (); /* this really shouldn't happen */
@@ -396,8 +427,11 @@ int hc_sock_process(hc_sock_t *s, hc_data_t **pdata) {
return -1;
}
- err = request->parse((u8 *)request, NULL);
+ if(request->parse != NULL)
+ err = request->parse((u8 *)request, NULL);
request->data->complete = 1;
+ if (!err && request->data->complete_cb != NULL)
+ err = request->data->complete_cb(request->data, s);
s->roff++;
if (pdata) *pdata = request->data;
@@ -465,6 +499,7 @@ typedef struct {
size_t size_in;
size_t size_out;
HC_PARSE parse;
+ data_callback_t complete_cb;
} hc_command_params_t;
int hc_execute_command(hc_sock_t *s, hc_msg_t *msg, size_t msg_len,
@@ -476,7 +511,7 @@ int hc_execute_command(hc_sock_t *s, hc_msg_t *msg, size_t msg_len,
switch (params->cmd) {
case ACTION_CREATE:
assert(params->size_in != 0); /* payload repeated */
- assert(params->size_out == 0);
+ //assert(params->size_out == 0); //Face will return the face id
//assert(params->parse == NULL);
break;
case ACTION_DELETE:
@@ -499,7 +534,7 @@ int hc_execute_command(hc_sock_t *s, hc_msg_t *msg, size_t msg_len,
}
/* XXX data will at least store the result (complete) */
- hc_data_t *data = hc_data_create(params->size_in, params->size_out);
+ hc_data_t *data = hc_data_create(params->size_in, params->size_out, params->complete_cb);
if (!data) {
ERROR("[hc_execute_command] Could not create data storage");
goto ERR_DATA;
@@ -578,7 +613,6 @@ int hc_listener_create_async(hc_sock_t *s, hc_listener_t *listener) {
}
/* LISTENER GET */
-
int hc_listener_get(hc_sock_t *s, hc_listener_t *listener,
hc_listener_t **listener_found) {
// NOT IMPLEMENTED
@@ -597,10 +631,137 @@ int hc_listener_delete_async(hc_sock_t *s, hc_listener_t *listener) {
return -1;
}
+vapi_error_e process_ip_info(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_ip_address_details *reply) {
+
+ if (is_last)
+ return 0;
+ hc_data_t *data = (hc_data_t *)callback_ctx;
+
+ if (data->size == data->current) {
+ data->buffer = realloc(data->buffer, sizeof(hc_listener_t) * data->size * 2);
+
+ if (!data->buffer)
+ return VAPI_ENOMEM;
+
+ data->size *=2;
+ }
+
+ hc_listener_t * listener = (hc_listener_t *)(data->buffer + data->current * sizeof(hc_listener_t));
+
+ if(reply->prefix.address.af == ADDRESS_IP4) {
+ memcpy(listener->local_addr.v4.as_u8, reply->prefix.address.un.ip4, IPV4_ADDR_LEN);
+ listener->family = AF_INET;
+ }
+ else {
+ memcpy(listener->local_addr.v6.as_u8, reply->prefix.address.un.ip6, IPV6_ADDR_LEN);
+ listener->family = AF_INET6;
+ }
+
+ listener->id = reply->sw_if_index;
+ data->current++;
+ return rv;
+}
+
+/* A listener in vpp is an interface with classify enabled */
+int listener_list_complete_cb(struct hc_data_s * data, void *ctx) {
+ // No need to write anything on the dst, no data expected
+
+ hc_sock_t *s = (hc_sock_t *)ctx;
+
+ int n_interfaces = data->current;
+ u32 *swifs = malloc(sizeof(u32) * n_interfaces);
+ int retval = VAPI_OK;
+
+ if (!swifs) {
+ retval = VAPI_ENOMEM;
+ goto END;
+ }
+
+ for (int i = 0; i < n_interfaces; i++) {
+ vapi_payload_sw_interface_details *reply =
+ (vapi_payload_sw_interface_details *)(data->buffer + i * data->in_element_size);
+ swifs[i] = reply->sw_if_index;
+ }
+
+ vapi_payload_sw_interface_details * temp = (vapi_payload_sw_interface_details *)data->buffer;
+ data->buffer = malloc(sizeof(hc_listener_t));
+ data->size = 1;
+ data->current = 0;
+
+ if (!data->buffer) {
+ data->current = 0;
+ retval = VAPI_ENOMEM;
+ goto CLEAN;
+ }
+
+ /* Query the forwarder for each interface */
+ for(int i = 0; i < n_interfaces; i++) {
+ size_t index = data->current;
+ vapi_msg_ip_address_dump* msg = vapi_alloc_ip_address_dump(s->g_vapi_ctx_instance);
+ msg->payload.sw_if_index = swifs[i];
+ msg->payload.is_ipv6 = 0;
+ vapi_payload_sw_interface_details *reply =
+ &(temp[i]);
+ int retval = vapi_ip_address_dump(s->g_vapi_ctx_instance, msg, process_ip_info, data);
+ vapi_msg_ip_address_dump* msg2 = vapi_alloc_ip_address_dump(s->g_vapi_ctx_instance);
+
+ if (retval) goto CLEAN;
+
+ msg2->payload.sw_if_index = swifs[i];
+ msg2->payload.is_ipv6 = 1;
+ retval = vapi_ip_address_dump(s->g_vapi_ctx_instance, msg2, process_ip_info, data);
+ for (size_t j = index; j < data->current; j++) {
+ memcpy(((hc_listener_t *)(data->buffer))[j].interface_name, reply->interface_name, INTERFACE_LEN);
+ }
+
+ if (retval) goto CLEAN;
+ }
+
+CLEAN:
+ free(swifs);
+ free(temp);
+
+END:
+ data->size = data->current;
+ data->out_element_size = sizeof(hc_listener_t);
+ return retval;
+}
+
/* LISTENER LIST */
int hc_listener_list(hc_sock_t *s, hc_data_t **pdata) {
- // NOT IMPLEMENTED
- return -1;
+ hc_msg_s msg;
+ vapi_msg_sw_interface_dump *hicnp_msg;
+ hicnp_msg = vapi_alloc_sw_interface_dump(s->g_vapi_ctx_instance);
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_sw_interface_dump_hton;
+
+ if (!(msg.callback_ctx)) return VAPI_ENOMEM;
+
+ hicnp_msg->payload.sw_if_index = ~0;
+ hicnp_msg->payload.name_filter_valid = 0;
+
+ //hicnp_msg->payload.type = 1; //0 v4, 1 v6
+ hc_command_params_t params = {
+ .cmd = ACTION_LIST,
+ .cmd_id = LIST_LISTENERS,
+ .size_in = sizeof(vapi_msg_sw_interface_details),
+ .size_out = sizeof(hc_listener_t),
+ .parse = (HC_PARSE)NULL,
+ .complete_cb = listener_list_complete_cb,
+ };
+
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, pdata,
+ false);
}
int hc_listener_list_async(hc_sock_t *s, hc_data_t **pdata) {
@@ -634,9 +795,19 @@ GENERATE_FIND(listener)
/* LISTENER SNPRINTF */
/* /!\ Please update constants in header file upon changes */
-int hc_listener_snprintf(char *s, size_t size, hc_listener_t *listener) {
- // NOT IMPLEMENTED
- return -1;
+int
+hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener)
+{
+ char local[MAXSZ_URL];
+ int rc;
+ rc = url_snprintf(local, MAXSZ_URL,
+ listener->family, &listener->local_addr, listener->local_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_listener_snprintf] Unexpected truncation of URL string");
+ if (rc < 0)
+ return rc;
+
+ return snprintf(s, size, "%s %s", listener->interface_name, local);
}
/*----------------------------------------------------------------------------*
@@ -759,14 +930,20 @@ int parse_route_create(uint8_t *src, uint8_t *dst) {
int _hc_route_create(hc_sock_t *s, hc_route_t *route, bool async) {
if (!IS_VALID_FAMILY(route->family)) return -1;
- hc_msg_s *msg = malloc(sizeof(hc_msg_s));
+ hc_msg_s msg;
+
vapi_msg_hicn_api_route_nhops_add *hicnp_msg;
hicnp_msg = vapi_alloc_hicn_api_route_nhops_add(s->g_vapi_ctx_instance);
- msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg;
- msg->callback = &vapi_cb;
- msg->callback_ctx = malloc(sizeof(callback_ctx_t));
- msg->callback_ctx->s = s;
- msg->ntoh = (NTOH)&vapi_msg_hicn_api_route_nhops_add_hton;
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_route_nhops_add_hton;
+
+ if (!(msg.callback_ctx)) return VAPI_ENOMEM;
if (route->family == AF_INET) {
memcpy(&hicnp_msg->payload.prefix.address.un.ip4[0], &route->remote_addr.v4, 4);
@@ -789,7 +966,7 @@ int _hc_route_create(hc_sock_t *s, hc_route_t *route, bool async) {
.parse = (HC_PARSE)parse_route_create,
};
- return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), &params, NULL,
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, NULL,
async);
}
@@ -818,14 +995,20 @@ int parse_route_delete(uint8_t *src, uint8_t *dst) {
int _hc_route_delete(hc_sock_t *s, hc_route_t *route, bool async) {
if (!IS_VALID_FAMILY(route->family)) return -1;
- hc_msg_s *msg = malloc(sizeof(hc_msg_s));
+ hc_msg_s msg;
+
vapi_msg_hicn_api_route_nhop_del *hicnp_msg;
hicnp_msg = vapi_alloc_hicn_api_route_nhop_del(s->g_vapi_ctx_instance);
- msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg;
- msg->callback = &vapi_cb;
- msg->callback_ctx = malloc(sizeof(callback_ctx_t));
- msg->callback_ctx->s = s;
- msg->ntoh = (NTOH)&vapi_msg_hicn_api_route_nhop_del_hton;
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_route_nhop_del_hton;
+
+ if (!(msg.callback_ctx)) return VAPI_ENOMEM;
memcpy(&hicnp_msg->payload.prefix.address.un.ip6[0], &route->remote_addr, 16);
hicnp_msg->payload.prefix.address.af =
@@ -842,7 +1025,7 @@ int _hc_route_delete(hc_sock_t *s, hc_route_t *route, bool async) {
.parse = (HC_PARSE)parse_route_delete,
};
- return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), &params, NULL,
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, NULL,
async);
}
@@ -869,6 +1052,14 @@ int parse_route_list(uint8_t *src, uint8_t *dst) {
}
hc_route_t *output = malloc(sizeof(hc_route_t) * size);
+ int res = VAPI_OK;
+
+ if (!output) {
+ size = 0;
+ res = VAPI_ENOMEM;
+ goto END;
+ }
+
int cur = 0;
for (int j = 0; j < request->data->current; j++) {
vapi_payload_hicn_api_routes_details *reply =
@@ -891,22 +1082,29 @@ int parse_route_list(uint8_t *src, uint8_t *dst) {
}
}
+END:
free(request->data->buffer);
request->data->buffer = (void *)output;
request->data->size = size;
request->data->out_element_size = sizeof(hc_route_t);
- return 0;
+ return res;
}
int _hc_route_list(hc_sock_t *s, hc_data_t **pdata, bool async) {
- hc_msg_s *msg = malloc(sizeof(hc_msg_s));
+ hc_msg_s msg;
+
vapi_msg_hicn_api_routes_dump *hicnp_msg;
hicnp_msg = vapi_alloc_hicn_api_routes_dump(s->g_vapi_ctx_instance);
- msg->hicnp_msg = (hc_hicnp_t *)hicnp_msg;
- msg->callback = &vapi_cb;
- msg->callback_ctx = malloc(sizeof(callback_ctx_t));
- msg->callback_ctx->s = s;
- msg->ntoh = (NTOH)&vapi_msg_hicn_api_routes_dump_hton;
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_routes_dump_hton;
+
+ if (!(msg.callback_ctx)) return VAPI_ENOMEM;
hc_command_params_t params = {
.cmd = ACTION_LIST,
@@ -916,7 +1114,7 @@ int _hc_route_list(hc_sock_t *s, hc_data_t **pdata, bool async) {
.parse = (HC_PARSE)parse_route_list,
};
- return hc_execute_command(s, (hc_msg_t *)msg, sizeof(msg), &params, pdata,
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, pdata,
async);
}
@@ -1003,24 +1201,275 @@ int hc_connection_to_local_listener(const hc_connection_t *connection,
}
/* FACE CREATE */
+int parse_face_create(uint8_t *src, uint8_t *dst) {
+ // No need to write anything on the dst, no data expected
+
+ hc_sock_request_t *request = (hc_sock_request_t *)src;
+ vapi_payload_hicn_api_face_add_reply *reply =
+ (vapi_payload_hicn_api_face_add_reply *)request->data->buffer;
-int hc_face_create(hc_sock_t *s, hc_face_t *face) { return 0; }
+ hc_face_t *output = malloc(sizeof(hc_face_t));
-int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_face_t **face_found) {
- return 0;
+ int retval = VAPI_OK;
+ int size = 1;
+
+ if (!output) {
+ size = 0;
+ retval = VAPI_ENOMEM;
+ goto END;
+ }
+
+ output->id = reply->faceid;
+ retval = reply->retval;
+
+END:
+ free(request->data->buffer);
+ request->data->buffer = (void *)output;
+ request->data->size = size;
+ request->data->out_element_size = sizeof(hc_face_t);
+ return retval;
+}
+
+int hc_face_create(hc_sock_t *s, hc_face_t *face) {
+ hc_msg_s msg;
+
+ vapi_msg_hicn_api_face_add *hicnp_msg;
+ hicnp_msg = vapi_alloc_hicn_api_face_add(s->g_vapi_ctx_instance);
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_face_add_hton;
+
+ if (!msg.callback_ctx) return VAPI_ENOMEM;
+
+ switch(face->face.type) {
+ case FACE_TYPE_HICN:
+ {
+ u8 check = ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)) == ip46_address_is_ip4((ip46_address_t *)&(face->face.remote_addr));
+ if (!check)
+ return -1;
+
+ hicnp_msg->payload.type = IP_FACE;
+ if (ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)))
+ {
+ memcpy(hicnp_msg->payload.face.ip.local_addr.un.ip4, face->face.local_addr.v4.as_u8, 4);
+ memcpy(hicnp_msg->payload.face.ip.remote_addr.un.ip4, face->face.remote_addr.v4.as_u8, 4);
+ hicnp_msg->payload.face.ip.local_addr.af = ADDRESS_IP4;
+ hicnp_msg->payload.face.ip.remote_addr.af = ADDRESS_IP4;
+ }
+ else
+ {
+ memcpy(hicnp_msg->payload.face.ip.local_addr.un.ip6, face->face.local_addr.v6.as_u8, 16);
+ memcpy(hicnp_msg->payload.face.ip.remote_addr.un.ip6, face->face.remote_addr.v6.as_u8, 16);
+ hicnp_msg->payload.face.ip.local_addr.af = ADDRESS_IP6;
+ hicnp_msg->payload.face.ip.remote_addr.af = ADDRESS_IP6;
+ }
+ hicnp_msg->payload.face.ip.swif = face->face.netdevice.index;
+ memcpy(hicnp_msg->payload.face.ip.if_name, face->face.netdevice.name, IFNAMSIZ);
+ break;
+ }
+ case FACE_TYPE_UDP:
+ {
+ u8 check = ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)) == ip46_address_is_ip4((ip46_address_t *)&(face->face.remote_addr));
+ if (!check)
+ return -1;
+
+ hicnp_msg->payload.type = UDP_FACE;
+ if (ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)))
+ {
+ memcpy(hicnp_msg->payload.face.udp.local_addr.un.ip4, face->face.local_addr.v4.as_u8, 4);
+ memcpy(hicnp_msg->payload.face.udp.remote_addr.un.ip4, face->face.remote_addr.v4.as_u8, 4);
+ hicnp_msg->payload.face.udp.local_addr.af = ADDRESS_IP4;
+ hicnp_msg->payload.face.udp.remote_addr.af = ADDRESS_IP4;
+ }
+ else
+ {
+ memcpy(hicnp_msg->payload.face.udp.local_addr.un.ip6, face->face.local_addr.v6.as_u8, 16);
+ memcpy(hicnp_msg->payload.face.udp.remote_addr.un.ip6, face->face.remote_addr.v6.as_u8, 16);
+ hicnp_msg->payload.face.udp.local_addr.af = ADDRESS_IP6;
+ hicnp_msg->payload.face.udp.remote_addr.af = ADDRESS_IP6;
+ }
+ hicnp_msg->payload.face.udp.lport = face->face.local_port;
+ hicnp_msg->payload.face.udp.rport = face->face.remote_port;
+ hicnp_msg->payload.face.udp.swif = face->face.netdevice.index;
+ memcpy(hicnp_msg->payload.face.udp.if_name, face->face.netdevice.name, IFNAMSIZ);
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ hc_command_params_t params = {
+ .cmd = ACTION_CREATE,
+ .cmd_id = ADD_CONNECTION,
+ .size_in =
+ sizeof(vapi_msg_hicn_api_face_add),
+ .size_out = sizeof(hc_face_t),
+ .parse = (HC_PARSE)parse_face_create,
+ };
+
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, NULL,
+ false);
}
/* FACE DELETE */
+int parse_face_delete(uint8_t *src, uint8_t *dst) {
+ // No need to write anything on the dst, no data expected
+
+ hc_sock_request_t *request = (hc_sock_request_t *)src;
+ vapi_payload_hicn_api_face_del_reply *reply =
+ (vapi_payload_hicn_api_face_del_reply *)request->data->buffer;
+
+ int retval = reply->retval;
+ free(reply);
+ return retval;
+}
+
+int hc_face_delete(hc_sock_t *s, hc_face_t *face) {
+
+ hc_msg_s msg;
+
+ vapi_msg_hicn_api_face_del *hicnp_msg;
+ hicnp_msg = vapi_alloc_hicn_api_face_del(s->g_vapi_ctx_instance);
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
-int hc_face_delete(hc_sock_t *s, hc_face_t *face) { return 0; }
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_face_del_hton;
+
+ if (!msg.callback_ctx) return VAPI_ENOMEM;
+
+ hicnp_msg->payload.faceid = face->id;
+
+ hc_command_params_t params = {
+ .cmd = ACTION_DELETE,
+ .cmd_id = REMOVE_ROUTE,
+ .size_in =
+ sizeof(vapi_msg_hicn_api_face_del),
+ .size_out = 0,
+ .parse = (HC_PARSE)parse_route_delete,
+ };
+
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, NULL,
+ false);
+}
/* FACE LIST */
-int hc_face_list(hc_sock_t *s, hc_data_t **pdata) { return 0; }
+int parse_face_list(uint8_t *src, uint8_t *dst) {
+ // No need to write anything on the dst, no data expected
+
+ hc_sock_request_t *request = (hc_sock_request_t *)src;
+ hc_face_t *output = malloc(sizeof(hc_face_t)*request->data->current);
+
+ int retval = VAPI_OK;
+ int cur = 0;
+
+ if (!output) {
+ retval = VAPI_ENOMEM;
+ request->data->current = 0;
+ goto END;
+ }
+
+ for (int j = 0; j < request->data->current; j++) {
+ vapi_payload_hicn_api_faces_details *reply =
+ (vapi_payload_hicn_api_faces_details
+ *)(request->data->buffer + j * request->data->in_element_size);
+ retval = reply->retval;
+ switch(reply->type)
+ {
+ case IP_FACE:
+ {
+ if (reply->face.ip.local_addr.af == ADDRESS_IP4)
+ {
+ memcpy(output[j].face.local_addr.v4.as_u8, reply->face.ip.local_addr.un.ip4, IPV4_ADDR_LEN);
+ memcpy(output[j].face.remote_addr.v4.as_u8, reply->face.ip.remote_addr.un.ip4, IPV4_ADDR_LEN);
+ }
+ else
+ {
+ memcpy(output[j].face.local_addr.v6.as_u8, reply->face.ip.local_addr.un.ip6, IPV6_ADDR_LEN);
+ memcpy(output[j].face.remote_addr.v6.as_u8, reply->face.ip.remote_addr.un.ip6, IPV6_ADDR_LEN);
+ }
+ output[j].face.type = FACE_TYPE_HICN;
+ output[j].id = reply->faceid;
+ output[j].face.netdevice.index = reply->face.ip.swif;
+ memcpy(output[j].face.netdevice.name, reply->face.ip.if_name, IFNAMSIZ);
+ break;
+ }
+ case UDP_FACE:
+ {
+ if (reply->face.ip.local_addr.af == ADDRESS_IP4)
+ {
+ memcpy(output[j].face.local_addr.v4.as_u8, reply->face.udp.local_addr.un.ip4, IPV4_ADDR_LEN);
+ memcpy(output[j].face.remote_addr.v4.as_u8, reply->face.udp.remote_addr.un.ip4, IPV4_ADDR_LEN);
+ }
+ else
+ {
+ memcpy(output[j].face.local_addr.v6.as_u8, reply->face.udp.local_addr.un.ip6, IPV6_ADDR_LEN);
+ memcpy(output[j].face.remote_addr.v6.as_u8, reply->face.udp.remote_addr.un.ip6, IPV6_ADDR_LEN);
+ }
+ output[j].face.local_port = reply->face.udp.lport;
+ output[j].face.remote_port = reply->face.udp.rport;
+ output[j].face.type = FACE_TYPE_UDP;
+ output[j].id = reply->faceid;
+ output[j].face.netdevice.index = reply->face.udp.swif;
+ memcpy(output[j].face.netdevice.name, reply->face.udp.if_name, IFNAMSIZ);
+ break;
+ }
+ default:
+ retval = -1;
+ }
+ if (!retval)
+ cur++;
+ }
+
+END:
+ free(request->data->buffer);
+ request->data->buffer = (void *)output;
+ request->data->size = request->data->current;
+ request->data->out_element_size = sizeof(hc_face_t);
+ return retval;
+}
+
+int hc_face_list(hc_sock_t *s, hc_data_t **pdata) {
+ hc_msg_s msg;
+
+ vapi_msg_hicn_api_faces_dump *hicnp_msg;
+ hicnp_msg = vapi_alloc_hicn_api_faces_dump(s->g_vapi_ctx_instance);
+
+ if (!hicnp_msg) return VAPI_ENOMEM;
+
+ msg.hicnp_msg = (hc_hicnp_t *)hicnp_msg;
+ msg.callback = &vapi_cb;
+ msg.callback_ctx = malloc(sizeof(callback_ctx_t));
+ msg.callback_ctx->s = s;
+ msg.ntoh = (NTOH)&vapi_msg_hicn_api_faces_dump_hton;
+
+ if (!msg.callback_ctx) return VAPI_ENOMEM;
+
+
+ hc_command_params_t params = {
+ .cmd = ACTION_LIST,
+ .cmd_id = LIST_CONNECTIONS,
+ .size_in = sizeof(vapi_msg_hicn_api_faces_details),
+ .size_out = sizeof(hc_face_t),
+ .parse = (HC_PARSE)parse_face_list,
+ };
+
+ return hc_execute_command(s, (hc_msg_t *)&msg, sizeof(msg), &params, (hc_data_t**)pdata,
+ false);
+ }
int hc_connection_parse_to_face(void *in, hc_face_t *face) { return 0; }
-int hc_face_list_async(hc_sock_t *s) //, hc_data_t ** pdata)
+int hc_face_list_async(hc_sock_t *s)
{
return 0;
}
diff --git a/ctrl/libhicnctrl/src/util/hash.h b/ctrl/libhicnctrl/src/util/hash.h
index 0bc48896b..7c7bb1e3a 100644
--- a/ctrl/libhicnctrl/src/util/hash.h
+++ b/ctrl/libhicnctrl/src/util/hash.h
@@ -240,7 +240,8 @@ uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
/* Helpers */
#define HASH_INITVAL 1
-#define hash(buf, len) (hash_t)hashlittle(buf, len, HASH_INITVAL)
+//#define hash(buf, len) (hash_t)hashlittle(buf, len, HASH_INITVAL)
+#define hash(buf, len) hashlittle(buf, len, HASH_INITVAL)
#define hash_struct(buf) hash(buf, sizeof(buf))
#endif /* UTIL_JENKINS_HASH_H */