From 356530fa42140a9f0ad43269125fd96ad1ced594 Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Wed, 21 Sep 2022 19:36:30 +0200 Subject: feat(libhicnctrl): implement face delete command Ticket: HICN-793 Signed-off-by: Mauro Sardara Change-Id: I87f2cd5a9e077ba81cc0d92fc2ec9fb5c9ec2ff0 --- ctrl/libhicnctrl/src/commands/command_face.c | 18 ++++ ctrl/libhicnctrl/src/modules/hicn_light.c | 154 +++++++++++++++++++++++++++ ctrl/libhicnctrl/src/objects/connection.c | 5 +- ctrl/libhicnctrl/src/objects/connection.h | 1 + ctrl/libhicnctrl/src/request.h | 4 + 5 files changed, 181 insertions(+), 1 deletion(-) (limited to 'ctrl') diff --git a/ctrl/libhicnctrl/src/commands/command_face.c b/ctrl/libhicnctrl/src/commands/command_face.c index 68a6abefe..68a71f9ec 100644 --- a/ctrl/libhicnctrl/src/commands/command_face.c +++ b/ctrl/libhicnctrl/src/commands/command_face.c @@ -60,6 +60,7 @@ int on_face_create(hc_face_t* face) { face->admin_state = FACE_STATE_UP; + face->id = INVALID_FACE_ID; return 0; } @@ -110,3 +111,20 @@ static const command_parser_t command_face_list = { .nparams = 0, }; COMMAND_REGISTER(command_face_list); + +static const command_parser_t command_face_remove6 = { + .action = ACTION_DELETE, + .object_type = OBJECT_TYPE_FACE, + .nparams = 6, + .parameters = {type_tcp_udp, local_address, local_port, remote_address, + remote_port, interface}, +}; +COMMAND_REGISTER(command_face_remove6); + +static const command_parser_t command_face_remove1 = { + .action = ACTION_DELETE, + .object_type = OBJECT_TYPE_FACE, + .nparams = 1, + .parameters = {symbolic_or_id}, +}; +COMMAND_REGISTER(command_face_remove1); \ No newline at end of file diff --git a/ctrl/libhicnctrl/src/modules/hicn_light.c b/ctrl/libhicnctrl/src/modules/hicn_light.c index 658043b7f..2716eefd5 100644 --- a/ctrl/libhicnctrl/src/modules/hicn_light.c +++ b/ctrl/libhicnctrl/src/modules/hicn_light.c @@ -593,6 +593,63 @@ NEXT: return 0; } +static ssize_t hicnlight_prepare_face_delete(hc_sock_t *sock, + hc_request_t *request, + uint8_t **buffer) { + hc_request_t *current_request = hc_request_get_current(request); + hc_object_t *object = hc_request_get_object(current_request); + hc_data_t *data = hc_request_get_data(current_request); + hc_face_t *face = &object->face; + + // XXX those objects are created on stack and expected to be valid across + // several calls. A quick fix is to make them static + static hc_object_t connection; + + hc_request_state_t state; + +NEXT: + state = hc_request_get_state(current_request); + DEBUG("hicnlight_prepare_face_delete > %s", hc_request_state_str(state)); + + switch (state) { + case REQUEST_STATE_INIT: + _ASSERT(!data); + + switch (face->type) { + case FACE_TYPE_HICN: + case FACE_TYPE_TCP: + case FACE_TYPE_UDP: + hc_request_set_state(current_request, + REQUEST_STATE_FACE_DELETE_CONNECTION_DELETE); + goto NEXT; + case FACE_TYPE_HICN_LISTENER: + case FACE_TYPE_TCP_LISTENER: + case FACE_TYPE_UDP_LISTENER: + case FACE_TYPE_UNDEFINED: + case FACE_TYPE_N: + return -99; // Not implemented + } + + case REQUEST_STATE_FACE_DELETE_CONNECTION_DELETE: + if (hc_face_to_connection(face, &connection.connection, true) < 0) { + ERROR("[hc_face_create] Could not convert face to connection."); + return -1; + } + hc_request_set_state(current_request, REQUEST_STATE_COMPLETE); + + return hicnlight_prepare_subrequest(sock, request, ACTION_DELETE, + OBJECT_TYPE_CONNECTION, &connection, + buffer); + case REQUEST_STATE_COMPLETE: + break; + + default: + return -1; + } + + return 0; +} + static ssize_t hicnlight_prepare_face_list(hc_sock_t *sock, hc_request_t *request, uint8_t **buffer) { @@ -698,6 +755,8 @@ static ssize_t hicnlight_prepare_face(hc_sock_t *sock, hc_request_t *request, switch (action) { case ACTION_CREATE: return hicnlight_prepare_face_create(sock, request, buffer); + case ACTION_DELETE: + return hicnlight_prepare_face_delete(sock, request, buffer); case ACTION_LIST: return hicnlight_prepare_face_list(sock, request, buffer); default: @@ -1006,6 +1065,91 @@ NEXT: return 0; } +static ssize_t hicnlight_prepare_connection_delete(hc_sock_t *sock, + hc_request_t *request, + uint8_t **buffer) { + hc_request_t *current_request = hc_request_get_current(request); + + hc_action_t action = hc_request_get_action(current_request); + hc_object_type_t object_type = hc_request_get_object_type(current_request); + hc_object_t *object = hc_request_get_object(current_request); + + _ASSERT(action == ACTION_DELETE); + _ASSERT(object_type == OBJECT_TYPE_CONNECTION); + + hc_data_t *data = hc_request_get_data(current_request); + hc_request_state_t state; + +NEXT: + state = hc_request_get_state(current_request); + DEBUG("hicnlight_prepare_connection_delete > %s", + hc_request_state_str(state)); + + switch (state) { + case REQUEST_STATE_INIT: + /* Two behaviours depending on the content of the connection id: + * - Valid Id : delete connection with provided ID + * - Invalid Id: Retrieve ID and then delete connection + * + * We assume connection has been already validated. + */ + if (hc_connection_has_valid_id(&object->connection)) { + // Id is valid. Proceed with deleting the connection. + hc_request_set_state(current_request, + REQUEST_STATE_CONNECTION_DELETE_WITH_ID); + } else { + // Id is not valid. Try to retrieve it using the info in the connection. + hc_request_set_state(current_request, REQUEST_STATE_CONNECTION_GET); + } + goto NEXT; + + case REQUEST_STATE_CONNECTION_DELETE_WITH_ID: + // We have a valid id. Let's delete the connection. + hc_request_reset_data(current_request); + hc_request_set_state(current_request, REQUEST_STATE_COMPLETE); + return hicnlight_prepare_generic(sock, request, buffer); + + case REQUEST_STATE_CONNECTION_GET: + // Get the connection info from the forwarder. + hc_request_set_state(current_request, + REQUEST_STATE_CONNECTION_DELETE_AFTER_GET); + return hicnlight_prepare_subrequest( + sock, request, ACTION_GET, OBJECT_TYPE_CONNECTION, object, buffer); + + case REQUEST_STATE_CONNECTION_DELETE_AFTER_GET: + // We got the response from the forwarder. If valid, let's take the ID and + // delete the connection by ID. + if (!data) return -1; + + int rc = hc_data_get_result(data); + if (rc < 0) { + return -1; + } + + if (hc_data_get_size(data) != 1) { + return -1; + } + + _ASSERT(hc_data_get_object_type(data) == OBJECT_TYPE_CONNECTION); + + object->connection.id = hc_data_get_object(data, 0)->connection.id; + + hc_request_set_state(current_request, + REQUEST_STATE_CONNECTION_DELETE_WITH_ID); + goto NEXT; + + case REQUEST_STATE_COMPLETE: + // Connection delete complete. + hc_data_set_complete(data); + break; + + default: + return -1; + } + + return 0; +} + static int hicnlight_recv(hc_sock_t *sock) { hc_sock_light_data_t *s = (hc_sock_light_data_t *)sock->data; int rc; @@ -1120,6 +1264,16 @@ static ssize_t hicnlight_prepare(hc_sock_t *sock, hc_request_t *request, hc_request_set(request, ACTION_CREATE, OBJECT_TYPE_SUBSCRIPTION, object); break; + case ACTION_DELETE: + switch (object_type) { + case OBJECT_TYPE_CONNECTION: + return hicnlight_prepare_connection_delete(sock, request, buffer); + break; + + default: + break; + } + default: break; } diff --git a/ctrl/libhicnctrl/src/objects/connection.c b/ctrl/libhicnctrl/src/objects/connection.c index 14e763396..019e5dc22 100644 --- a/ctrl/libhicnctrl/src/objects/connection.c +++ b/ctrl/libhicnctrl/src/objects/connection.c @@ -191,6 +191,10 @@ int _hc_connection_cmp(const hc_object_t *object1, const hc_object_t *object2) { return hc_connection_cmp(&object1->connection, &object2->connection); } +int hc_connection_has_valid_id(const hc_connection_t *connection) { + return connection->id != INVALID_FACE_ID; +} + /* CONNECTION SNPRINTF */ /* /!\ Please update constants in header file upon changes */ @@ -273,7 +277,6 @@ int hc_connection_set_priority(hc_sock_t *s, const char *conn_id_or_name, } int hc_connection_set_tags(hc_sock_t *s, const char *conn_id_or_name, - policy_tags_t tags) { hc_object_t object; memset(&object, 0, sizeof(hc_object_t)); diff --git a/ctrl/libhicnctrl/src/objects/connection.h b/ctrl/libhicnctrl/src/objects/connection.h index 4a4c78f09..1e9bf0376 100644 --- a/ctrl/libhicnctrl/src/objects/connection.h +++ b/ctrl/libhicnctrl/src/objects/connection.h @@ -25,6 +25,7 @@ bool hc_connection_is_local(const hc_connection_t *connection); bool hc_connection_has_local(const hc_connection_t *connection); +bool hc_connection_has_valid_id(const hc_connection_t *connection); DECLARE_OBJECT_OPS_H(OBJECT_TYPE_CONNECTION, connection); diff --git a/ctrl/libhicnctrl/src/request.h b/ctrl/libhicnctrl/src/request.h index 32f9f72b9..aa07cad00 100644 --- a/ctrl/libhicnctrl/src/request.h +++ b/ctrl/libhicnctrl/src/request.h @@ -43,7 +43,11 @@ typedef int (*HC_PARSE)(const uint8_t *, uint8_t *); _(CONNECTION_CREATE_LISTENER_CHECK) \ _(CONNECTION_CREATE) \ _(CONNECTION_CREATE_N) \ + _(CONNECTION_GET) \ + _(CONNECTION_DELETE_WITH_ID) \ + _(CONNECTION_DELETE_AFTER_GET) \ _(FACE_CREATE_CONNECTION_CREATE) \ + _(FACE_DELETE_CONNECTION_DELETE) \ _(FACE_CREATE_CONNECTION_CHECK) \ _(FACE_CREATE_CONNECTION_GET) \ _(FACE_CREATE_CONNECTION_VERIFY) \ -- cgit 1.2.3-korg