diff options
Diffstat (limited to 'hicn-light/src/hicn/config')
21 files changed, 1243 insertions, 45 deletions
diff --git a/hicn-light/src/hicn/config/CMakeLists.txt b/hicn-light/src/hicn/config/CMakeLists.txt index 5ce680bfc..b1e475aee 100644 --- a/hicn-light/src/hicn/config/CMakeLists.txt +++ b/hicn-light/src/hicn/config/CMakeLists.txt @@ -26,15 +26,18 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/configurationFile.h ${CMAKE_CURRENT_SOURCE_DIR}/configurationListeners.h ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPolicy.h ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.h ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.h ${CMAKE_CURRENT_SOURCE_DIR}/controlList.h ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.h ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlListPolicies.h ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePolicy.h ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.h ${CMAKE_CURRENT_SOURCE_DIR}/controlUnset.h ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.h @@ -51,6 +54,8 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.h ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.h ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlUpdate.h + ${CMAKE_CURRENT_SOURCE_DIR}/controlUpdateConnection.h ) list(APPEND SOURCE_FILES @@ -64,15 +69,18 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/controlAdd.c ${CMAKE_CURRENT_SOURCE_DIR}/controlAddConnection.c ${CMAKE_CURRENT_SOURCE_DIR}/controlAddRoute.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPolicy.c ${CMAKE_CURRENT_SOURCE_DIR}/controlAddListener.c ${CMAKE_CURRENT_SOURCE_DIR}/controlList.c ${CMAKE_CURRENT_SOURCE_DIR}/controlListConnections.c ${CMAKE_CURRENT_SOURCE_DIR}/controlListListeners.c ${CMAKE_CURRENT_SOURCE_DIR}/controlListRoutes.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlListPolicies.c ${CMAKE_CURRENT_SOURCE_DIR}/controlQuit.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemove.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveConnection.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemoveRoute.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePolicy.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRoot.c ${CMAKE_CURRENT_SOURCE_DIR}/controlSet.c ${CMAKE_CURRENT_SOURCE_DIR}/controlSetDebug.c @@ -91,7 +99,9 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/controlSetWldr.c ${CMAKE_CURRENT_SOURCE_DIR}/controlAddPunting.c ${CMAKE_CURRENT_SOURCE_DIR}/controlRemovePunting.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlUpdate.c + ${CMAKE_CURRENT_SOURCE_DIR}/controlUpdateConnection.c ) set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE) -set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE)
\ No newline at end of file +set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index 07120f95b..182c2fdc1 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -356,8 +356,8 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, add_connection_command *control = request[1].iov_base; bool success = false; - bool exists = true; + Connection *conn; const char *symbolicName = control->symbolic; Address *source = NULL; @@ -379,18 +379,15 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, } AddressPair *pair = addressPair_Create(source, destination); - const Connection *conn = connectionTable_FindByAddressPair( + conn = (Connection *)connectionTable_FindByAddressPair( forwarder_GetConnectionTable(config->forwarder), pair); addressPair_Release(&pair); - - if (conn == NULL) { - // the connection does not exists (even without a name) - exists = false; - } + } else { + conn = NULL; } - if (!exists) { + if (!conn) { IoOperations *ops = NULL; switch (control->connectionType) { case TCP_CONN: @@ -420,6 +417,9 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, if (ops != NULL) { Connection *conn = connection_Create(ops); +#ifdef WITH_POLICY + connection_SetTags(conn, control->tags); +#endif /* WITH_POLICY */ connection_SetAdminState(conn, control->admin_state); @@ -428,6 +428,11 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, symbolicNameTable_Add(config->symbolicNameTable, symbolicName, connection_GetConnectionId(conn)); +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, conn, CONNECTION_EVENT_CREATE); +#endif /* WITH_MAPME */ + success = true; } else { @@ -435,23 +440,31 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, } } else { - printf("failed, symbolic name or connextion already exist\n"); - } +#ifdef WITH_POLICY + connection_SetTags(conn, control->tags); + connection_SetAdminState(conn, control->admin_state); - addressDestroy(&source); - addressDestroy(&destination); +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, conn, CONNECTION_EVENT_UPDATE); +#endif /* WITH_MAPME */ - // generate ACK/NACK - struct iovec *response; + success = true; +#else + printf("failed, symbolic name or connection already exist\n"); +#endif /* WITH_POLICY */ + } + + if (source) + addressDestroy(&source); + if (destination) + addressDestroy(&destination); if (success) { // ACK - response = utils_CreateAck(header, control, sizeof(add_connection_command)); + return utils_CreateAck(header, control, sizeof(add_connection_command)); } else { // NACK - response = - utils_CreateNack(header, control, sizeof(add_connection_command)); + return utils_CreateNack(header, control, sizeof(add_connection_command)); } - - return response; } /** @@ -479,6 +492,12 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, if (strcmp(symbolicOrConnid, "SELF") == 0) { forwarder_RemoveConnectionIdFromRoutes(config->forwarder, ingressId); connectionTable_RemoveById(table, ingressId); + +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, NULL, CONNECTION_EVENT_DELETE); +#endif /* WITH_MAPME */ + success = true; } else if (utils_IsNumber(symbolicOrConnid)) { // case for connid as input @@ -492,6 +511,11 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, // remove connection connectionTable_RemoveById(table, connid); +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, NULL, CONNECTION_EVENT_DELETE); +#endif /* WITH_MAPME */ + success = true; } else { logger_Log(forwarder_GetLogger(config->forwarder), LoggerFacility_IO, @@ -520,6 +544,12 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, connectionTable_RemoveById(table, connid); // remove connection from symbolicNameTable since we have symbolic input symbolicNameTable_Remove(config->symbolicNameTable, symbolicOrConnid); + +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, NULL, CONNECTION_EVENT_DELETE); +#endif /* WITH_MAPME */ + success = true; // to write } else { if (logger_IsLoggable(config->logger, LoggerFacility_Config, @@ -580,6 +610,10 @@ struct iovec *configuration_ProcessConnectionList(Configuration *config, listConnectionsCommand->connectionData.admin_state = connection_GetAdminState(original); +#ifdef WITH_POLICY + listConnectionsCommand->connectionData.tags = connection_GetTags(original); +#endif /* WITH_POLICY */ + if (addressGetType(localAddress) == ADDR_INET && addressGetType(remoteAddress) == ADDR_INET) { listConnectionsCommand->connectionData.ipType = ADDR_INET; @@ -1017,15 +1051,119 @@ struct iovec *configuration_ConnectionSetAdminState(Configuration *config, header_control_message *header = request[0].iov_base; connection_set_admin_state_command *control = request[1].iov_base; + if ((control->admin_state != CONNECTION_STATE_UP) && (control->admin_state != CONNECTION_STATE_DOWN)) + return utils_CreateNack(header, control, sizeof(connection_set_admin_state_command)); + Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid); if (!conn) return utils_CreateNack(header, control, sizeof(connection_set_admin_state_command)); connection_SetAdminState(conn, control->admin_state); +#ifdef WITH_MAPME + /* Hook: new connection created through the control protocol */ + forwarder_onConnectionEvent(config->forwarder, conn, + control->admin_state == CONNECTION_STATE_UP + ? CONNECTION_EVENT_SET_UP + : CONNECTION_EVENT_SET_DOWN); +#endif /* WITH_MAPME */ + return utils_CreateAck(header, control, sizeof(connection_set_admin_state_command)); } +#ifdef WITH_POLICY +struct iovec *configuration_ProcessPolicyAdd(Configuration *config, + struct iovec *request) { + header_control_message *header = request[0].iov_base; + add_policy_command *control = request[1].iov_base; + + if (forwarder_AddOrUpdatePolicy(config->forwarder, control)) { + return utils_CreateAck(header, control, sizeof(add_policy_command)); + } else { + return utils_CreateNack(header, control, sizeof(add_policy_command)); + } +} + +struct iovec *configuration_ProcessPolicyList(Configuration *config, + struct iovec *request) { + FibEntryList *fibList = forwarder_GetFibEntries(config->forwarder); + + size_t payloadSize = fibEntryList_Length(fibList); + struct sockaddr_in tmpAddr; + struct sockaddr_in6 tmpAddr6; + + // allocate payload, cast from void* to uint8_t* = bytes granularity + uint8_t *payloadResponse = + parcMemory_AllocateAndClear(sizeof(list_policies_command) * payloadSize); + + for (size_t i = 0; i < fibEntryList_Length(fibList); i++) { + FibEntry *entry = (FibEntry *)fibEntryList_Get(fibList, i); + NameBitvector *prefix = name_GetContentName(fibEntry_GetPrefix(entry)); + + list_policies_command *listPoliciesCommand = + (list_policies_command *)(payloadResponse + + (i * sizeof(list_policies_command))); + + Address *addressEntry = nameBitvector_ToAddress(prefix); + if (addressGetType(addressEntry) == ADDR_INET) { + addressGetInet(addressEntry, &tmpAddr); + listPoliciesCommand->addressType = ADDR_INET; + listPoliciesCommand->address.ipv4 = tmpAddr.sin_addr.s_addr; + } else if (addressGetType(addressEntry) == ADDR_INET6) { + addressGetInet6(addressEntry, &tmpAddr6); + listPoliciesCommand->addressType = ADDR_INET6; + listPoliciesCommand->address.ipv6 = tmpAddr6.sin6_addr; + } + listPoliciesCommand->len = nameBitvector_GetLength(prefix); + listPoliciesCommand->policy = fibEntry_GetPolicy(entry); + + addressDestroy(&addressEntry); + } + + // send response + header_control_message *header = request[0].iov_base; + header->messageType = RESPONSE_LIGHT; + header->length = (unsigned)payloadSize; + + struct iovec *response = + parcMemory_AllocateAndClear(sizeof(struct iovec) * 2); + + response[0].iov_base = header; + response[0].iov_len = sizeof(header_control_message); + response[1].iov_base = payloadResponse; + response[1].iov_len = sizeof(list_policies_command) * payloadSize; + + fibEntryList_Destroy(&fibList); + return response; +} + +struct iovec *configuration_ProcessPolicyRemove(Configuration *config, + struct iovec *request) { + header_control_message *header = request[0].iov_base; + remove_policy_command *control = request[1].iov_base; + + if (forwarder_RemovePolicy(config->forwarder, control)) + return utils_CreateAck(header, control, sizeof(remove_policy_command)); + else + return utils_CreateNack(header, control, sizeof(remove_policy_command)); +} + +struct iovec *configuration_UpdateConnection(Configuration *config, + struct iovec *request) { + header_control_message *header = request[0].iov_base; + update_connection_command *control = request[1].iov_base; + + Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid); + if (!conn) + return utils_CreateNack(header, control, sizeof(connection_set_admin_state_command)); + + connection_SetTags(conn, control->tags); + connection_SetAdminState(conn, control->admin_state); + + return utils_CreateAck(header, control, sizeof(remove_policy_command)); +} +#endif /* WITH_POLICY */ + // =========================== // Main functions that deal with receiving commands, executing them, and sending // ACK/NACK @@ -1114,6 +1252,24 @@ struct iovec *configuration_DispatchCommand(Configuration *config, response = configuration_ConnectionSetAdminState(config, control); break; +#ifdef WITH_POLICY + case ADD_POLICY: + response = configuration_ProcessPolicyAdd(config, control); + break; + + case LIST_POLICIES: + response = configuration_ProcessPolicyList(config, control); + break; + + case REMOVE_POLICY: + response = configuration_ProcessPolicyRemove(config, control); + break; + + case UPDATE_CONNECTION: + response = configuration_UpdateConnection(config, control); + break; +#endif /* WITH_POLICY */ + default: break; } diff --git a/hicn-light/src/hicn/config/controlAdd.c b/hicn-light/src/hicn/config/controlAdd.c index 7667f467e..519e11e40 100644 --- a/hicn-light/src/hicn/config/controlAdd.c +++ b/hicn-light/src/hicn/config/controlAdd.c @@ -28,6 +28,9 @@ #include <hicn/config/controlAddListener.h> #include <hicn/config/controlAddPunting.h> #include <hicn/config/controlAddRoute.h> +#ifdef WITH_POLICY +#include <hicn/config/controlAddPolicy.h> +#endif /* WITH_POLICY */ // =================================================== @@ -60,18 +63,27 @@ static CommandReturn _controlAdd_HelpExecute(CommandParser *parser, CommandOps *ops_add_route = controlAddRoute_Create(NULL); CommandOps *ops_add_punting = controlAddPunting_Create(NULL); CommandOps *ops_add_listener = controlAddListener_Create(NULL); +#ifdef WITH_POLICY + CommandOps *ops_add_policy = controlAddPolicy_Create(NULL); +#endif /* WITH_POLICY */ printf("Available commands:\n"); printf(" %s\n", ops_add_connection->command); printf(" %s\n", ops_add_route->command); printf(" %s\n", ops_add_punting->command); printf(" %s\n", ops_add_listener->command); +#ifdef WITH_POLICIES + printf(" %s\n", ops_add_policy->command); +#endif /* WITH_POLICIES */ printf("\n"); commandOps_Destroy(&ops_add_connection); commandOps_Destroy(&ops_add_route); commandOps_Destroy(&ops_add_punting); commandOps_Destroy(&ops_add_listener); +#ifdef WITH_POLICY + commandOps_Destroy(&ops_add_policy); +#endif /* WITH_POLICY */ return CommandReturn_Success; } @@ -85,6 +97,10 @@ static void _controlAdd_Init(CommandParser *parser, CommandOps *ops) { controlState_RegisterCommand(state, controlAddRoute_Create(state)); controlState_RegisterCommand(state, controlAddPunting_Create(state)); controlState_RegisterCommand(state, controlAddPunting_HelpCreate(state)); +#ifdef WITH_POLICY + controlState_RegisterCommand(state, controlAddPolicy_HelpCreate(state)); + controlState_RegisterCommand(state, controlAddPolicy_Create(state)); +#endif /* WITH_POLICY */ } static CommandReturn _controlAdd_Execute(CommandParser *parser, CommandOps *ops, diff --git a/hicn-light/src/hicn/config/controlAddPolicy.c b/hicn-light/src/hicn/config/controlAddPolicy.c new file mode 100644 index 000000000..9bca3355e --- /dev/null +++ b/hicn-light/src/hicn/config/controlAddPolicy.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_POLICY + +#include <hicn/hicn-light/config.h> + +#include <ctype.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <parc/assert/parc_Assert.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_Network.h> + +#include <hicn/config/controlAddPolicy.h> + +#include <hicn/utils/commands.h> +#include <hicn/utils/utils.h> +#include <hicn/utils/token.h> + +static CommandReturn _controlAddPolicy_Execute(CommandParser *parser, + CommandOps *ops, PARCList *args); +static CommandReturn _controlAddPolicy_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args); + +static const char *_commandAddPolicy = "add policy"; +static const char *_commandAddPolicyHelp = "help add policy"; + +CommandOps *controlAddPolicy_Create(ControlState *state) { + return commandOps_Create(state, _commandAddPolicy, NULL, + _controlAddPolicy_Execute, commandOps_Destroy); +} + +CommandOps *controlAddPolicy_HelpCreate(ControlState *state) { + return commandOps_Create(state, _commandAddPolicyHelp, NULL, + _controlAddPolicy_HelpExecute, commandOps_Destroy); +} + +// ==================================================== + +static CommandReturn _controlAddPolicy_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + printf("commands:\n"); + printf(" add policy <prefix> <app_name>" + #define _(x, y) " FLAG:%s" + foreach_policy_tag + #undef _ + "%s", + #define _(x, y) policy_tag_str[POLICY_TAG_ ## x], + foreach_policy_tag + #undef _ + "\n"); + printf("\n"); + printf( + " prefix: The hicn name as IPv4 or IPv6 address (e.g 1234::0/64)\n"); + printf(" app_name: The application name associated to this policy\n"); + printf(" FLAG:*: A value among [neutral|require|prefer|avoid|prohibit] with an optional '!' character prefix for disabling changes\n"); + printf("\n"); + return CommandReturn_Success; +} + +static CommandReturn _controlAddPolicy_Execute(CommandParser *parser, + CommandOps *ops, PARCList *args) { + ControlState *state = ops->closure; + + if (parcList_Size(args) != 11) { + _controlAddPolicy_HelpExecute(parser, ops, args); + return CommandReturn_Failure; + } + + const char *prefixStr = parcList_GetAtIndex(args, 2); + char *addr = (char *)malloc((strlen(prefixStr) + 1) * sizeof(char)); + + // separate address and len + char *slash; + uint32_t len = 0; + strcpy(addr, prefixStr); + slash = strrchr(addr, '/'); + if (slash != NULL) { + len = atoi(slash + 1); + *slash = '\0'; + } + + // allocate command payload + add_policy_command *addPolicyCommand = + parcMemory_AllocateAndClear(sizeof(add_policy_command)); + + // check and set IP address + if (inet_pton(AF_INET, addr, &addPolicyCommand->address.ipv4) == 1) { + if (len > 32) { + printf("ERROR: exceeded INET mask length, max=32\n"); + parcMemory_Deallocate(&addPolicyCommand); + free(addr); + return CommandReturn_Failure; + } + addPolicyCommand->addressType = ADDR_INET; + } else if (inet_pton(AF_INET6, addr, &addPolicyCommand->address.ipv6) == 1) { + if (len > 128) { + printf("ERROR: exceeded INET6 mask length, max=128\n"); + parcMemory_Deallocate(&addPolicyCommand); + free(addr); + return CommandReturn_Failure; + } + addPolicyCommand->addressType = ADDR_INET6; + } else { + printf("Error: %s is not a valid network address \n", addr); + parcMemory_Deallocate(&addPolicyCommand); + free(addr); + return CommandReturn_Failure; + } + + free(addr); + + addPolicyCommand->len = len; + + policy_t policy; + snprintf((char*)policy.app_name, APP_NAME_LEN, "%s", (char*)parcList_GetAtIndex(args, 3)); + for (int i=4; i < 11; i++) { + const char *tag = parcList_GetAtIndex(args, i); + policy_tag_state_t tag_state; + tag_state.disabled = (tag[0] == '!') ? 1 : 0; + if (strcmp(&tag[tag_state.disabled], "neutral") == 0) { + tag_state.state = POLICY_STATE_NEUTRAL; + } else if (strcmp(&tag[tag_state.disabled], "require") == 0) { + tag_state.state = POLICY_STATE_REQUIRE; + } else if (strcmp(&tag[tag_state.disabled], "prefer") == 0) { + tag_state.state = POLICY_STATE_PREFER; + } else if (strcmp(&tag[tag_state.disabled], "avoid") == 0) { + tag_state.state = POLICY_STATE_AVOID; + } else if (strcmp(&tag[tag_state.disabled], "prohibit") == 0) { + tag_state.state = POLICY_STATE_PROHIBIT; + } else { + printf("ERROR: invalid tag value '%s'\n", tag); + parcMemory_Deallocate(&addPolicyCommand); + free(addr); + return CommandReturn_Failure; + } + + policy.tags[i-4] = tag_state; + + } + + addPolicyCommand->policy = policy; + + // send message and receive response + struct iovec *response = utils_SendRequest(state, ADD_POLICY, addPolicyCommand, + sizeof(add_policy_command)); + + if (!response) { // get NULL pointer + return CommandReturn_Failure; + } + + parcMemory_Deallocate(&response); // free iovec pointer + return CommandReturn_Success; +} + +#endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/config/controlAddPolicy.h b/hicn-light/src/hicn/config/controlAddPolicy.h new file mode 100644 index 000000000..273e3a476 --- /dev/null +++ b/hicn-light/src/hicn/config/controlAddPolicy.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_AddPolicy.h + * @brief Add a static policy + * + * Implements the "add policy" node of the CLI tree + * + */ + +#ifndef Control_AddPolicy_h +#define Control_AddPolicy_h + +#ifdef WITH_POLICY + +#include <hicn/config/controlState.h> +CommandOps *controlAddPolicy_Create(ControlState *state); +CommandOps *controlAddPolicy_HelpCreate(ControlState *state); + +#endif /* WITH_POLICY */ + +#endif // Control_AddPolicy_h diff --git a/hicn-light/src/hicn/config/controlAddPunting.c b/hicn-light/src/hicn/config/controlAddPunting.c index 61308b33b..ff441f7f0 100644 --- a/hicn-light/src/hicn/config/controlAddPunting.c +++ b/hicn-light/src/hicn/config/controlAddPunting.c @@ -104,12 +104,6 @@ static CommandReturn _controlAddPunting_Execute(CommandParser *parser, *slash = '\0'; } - if (len == 0) { - printf("ERROR: a prefix can not be of length 0\n"); - free(addr); - return CommandReturn_Failure; - } - // allocate command payload add_punting_command *addPuntingCommand = parcMemory_AllocateAndClear(sizeof(add_punting_command)); diff --git a/hicn-light/src/hicn/config/controlAddRoute.c b/hicn-light/src/hicn/config/controlAddRoute.c index d7847f837..086cf3a2b 100644 --- a/hicn-light/src/hicn/config/controlAddRoute.c +++ b/hicn-light/src/hicn/config/controlAddRoute.c @@ -108,12 +108,6 @@ static CommandReturn _controlAddRoute_Execute(CommandParser *parser, *slash = '\0'; } - if (len == 0) { - printf("ERROR: a prefix can not be of length 0\n"); - free(addr); - return CommandReturn_Failure; - } - // allocate command payload add_route_command *addRouteCommand = parcMemory_AllocateAndClear(sizeof(add_route_command)); diff --git a/hicn-light/src/hicn/config/controlList.c b/hicn-light/src/hicn/config/controlList.c index 8ec47ad23..c45f05428 100644 --- a/hicn-light/src/hicn/config/controlList.c +++ b/hicn-light/src/hicn/config/controlList.c @@ -31,6 +31,9 @@ //#include <hicn/config/controlListInterfaces.h> #include <hicn/config/controlListListeners.h> #include <hicn/config/controlListRoutes.h> +#ifdef WITH_POLICY +#include <hicn/config/controlListPolicies.h> +#endif /* WITH_POLICY */ static void _controlList_Init(CommandParser *parser, CommandOps *ops); static CommandReturn _controlList_Execute(CommandParser *parser, @@ -59,18 +62,27 @@ static CommandReturn _controlList_HelpExecute(CommandParser *parser, // CommandOps *ops_list_interfaces = controlListInterfaces_HelpCreate(NULL); CommandOps *ops_list_routes = controlListRoutes_HelpCreate(NULL); CommandOps *ops_list_listeners = controlListListeners_HelpCreate(NULL); +#ifdef WITH_POLICY + CommandOps *ops_list_policies = controlListPolicies_HelpCreate(NULL); +#endif /* WITH_POLICY */ printf("Available commands:\n"); printf(" %s\n", ops_list_connections->command); // printf(" %s\n", ops_list_interfaces->command); printf(" %s\n", ops_list_routes->command); printf(" %s\n", ops_list_listeners->command); +#ifdef WITH_POLICY + printf(" %s\n", ops_list_policies->command); +#endif /* WITH_POLICY */ printf("\n"); commandOps_Destroy(&ops_list_connections); // commandOps_Destroy(&ops_list_interfaces); commandOps_Destroy(&ops_list_routes); commandOps_Destroy(&ops_list_listeners); +#ifdef WITH_POLICY + commandOps_Destroy(&ops_list_policies); +#endif /* WITH_POLICY */ return CommandReturn_Success; } @@ -86,6 +98,10 @@ static void _controlList_Init(CommandParser *parser, CommandOps *ops) { // controlState_RegisterCommand(state, controlListInterfaces_Create(state)); controlState_RegisterCommand(state, controlListRoutes_Create(state)); controlState_RegisterCommand(state, controlListListeners_Create(state)); +#ifdef WITH_POLICY + controlState_RegisterCommand(state, controlListPolicies_HelpCreate(state)); + controlState_RegisterCommand(state, controlListPolicies_Create(state)); +#endif /* WITH_POLICY */ } static CommandReturn _controlList_Execute(CommandParser *parser, diff --git a/hicn-light/src/hicn/config/controlListConnections.c b/hicn-light/src/hicn/config/controlListConnections.c index f94a1e7ca..0eb6392ea 100644 --- a/hicn-light/src/hicn/config/controlListConnections.c +++ b/hicn-light/src/hicn/config/controlListConnections.c @@ -82,6 +82,10 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser, _controlListConnections_HelpExecute(parser, ops, args); return CommandReturn_Failure; } +#ifdef WITH_POLICY + char flags_str[POLICY_TAG_N]; + char *s; +#endif /* WITH_POLICY */ ControlState *state = ops->closure; @@ -127,11 +131,28 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser, PARCBufferComposer *composer = parcBufferComposer_Create(); +#ifdef WITH_POLICY + + s = flags_str; +#define _(x, y) *s++ = policy_tags_has(listConnectionsCommand->connectionData.tags, POLICY_TAG_ ## x) ? y : '.'; +foreach_policy_tag +#undef _ + *s = '\0'; + + parcBufferComposer_Format( + composer, "%5d %4s %s %s %s [%s]", listConnectionsCommand->connid, + stateString[listConnectionsCommand->state], sourceString, + destinationString, + connTypeString[listConnectionsCommand->connectionData.connectionType], + flags_str); + +#else parcBufferComposer_Format( composer, "%5d %4s %s %s %s", listConnectionsCommand->connid, stateString[listConnectionsCommand->state], sourceString, destinationString, connTypeString[listConnectionsCommand->connectionData.connectionType]); +#endif /* WITH_POLICY */ PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer); char *result = parcBuffer_ToString(tempBuffer); diff --git a/hicn-light/src/hicn/config/controlListPolicies.c b/hicn-light/src/hicn/config/controlListPolicies.c new file mode 100644 index 000000000..c70d8baea --- /dev/null +++ b/hicn-light/src/hicn/config/controlListPolicies.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_POLICY + +#include <hicn/hicn-light/config.h> + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <parc/assert/parc_Assert.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_Time.h> + +#include <hicn/config/controlListPolicies.h> + +#include <hicn/utils/commands.h> +#include <hicn/utils/utils.h> + +static CommandReturn _controlListPolicies_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args); +static CommandReturn _controlListPolicies_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args); + +static const char *_commandListPolicies = "list policies"; +static const char *_commandListPoliciesHelp = "help list policies"; + +// ==================================================== + +CommandOps *controlListPolicies_Create(ControlState *state) { + return commandOps_Create(state, _commandListPolicies, NULL, + _controlListPolicies_Execute, commandOps_Destroy); +} + +CommandOps *controlListPolicies_HelpCreate(ControlState *state) { + return commandOps_Create(state, _commandListPoliciesHelp, NULL, + _controlListPolicies_HelpExecute, commandOps_Destroy); +} + +// ==================================================== + +static CommandReturn _controlListPolicies_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + printf("command: list policies\n"); + printf("\n"); + return CommandReturn_Success; +} + +#define MAX(x,y) (x > y ? x : y) +#define MAXSZ_COLUMN MAX(MAXSZ_POLICY_TAG, MAXSZ_POLICY_TAG_STATE) + +#define MAXSZ_STR_STAT 10 +#define MAXSZ_APP_NAME 25 +#define MAXSZ_PREFIX 25 + +typedef struct { + #define _(x, y) char x[MAXSZ_POLICY_TAG_STATE]; + foreach_policy_tag + #undef _ +} tag_state_str_t; + +static CommandReturn _controlListPolicies_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + if (parcList_Size(args) != 2) { + _controlListPolicies_HelpExecute(parser, ops, args); + return CommandReturn_Failure; + } + + ControlState *state = ops->closure; + + // send message and receive response + struct iovec *response = utils_SendRequest(state, LIST_POLICIES, NULL, 0); + if (!response) { // get NULL pointer = FAILURE + return CommandReturn_Failure; + } + + // Process/Print message + header_control_message *receivedHeader = + (header_control_message *)response[0].iov_base; + uint8_t *receivedPayload = (uint8_t *)response[1].iov_base; + if (!receivedPayload) { + printf("No payload!\n"); + return CommandReturn_Failure; + } + + // Allocate output to pass to the main function if the call is not interactive + char **commandOutputMain = NULL; + if (!controlState_IsInteractive(state) && receivedHeader->length > 0) { + commandOutputMain = + parcMemory_Allocate(sizeof(char *) * receivedHeader->length); + for (size_t j = 0; j < receivedHeader->length; j++) { + commandOutputMain[j] = parcMemory_Allocate(sizeof(char) * 128); + } + } + + char *addrString = NULL; + in_port_t port = htons(1234); // this is a random port number that is ignored + + if (receivedHeader->length > 0) { + printf("%*s %*s" + #define _(x, y) " %*s" + foreach_policy_tag + #undef _ + "%s", + MAXSZ_PREFIX, "prefix", MAXSZ_APP_NAME /*APP_NAME_LEN*/, "app_name", + #define _(x, y) MAXSZ_COLUMN, policy_tag_str[POLICY_TAG_ ## x], + foreach_policy_tag + #undef _ + "\n"); + } else { + printf(" --- No entry in the list \n"); + } + + tag_state_str_t str; + + for (int i = 0; i < receivedHeader->length; i++) { + list_policies_command *listPoliciesCommand = + (list_policies_command *)(receivedPayload + + (i * sizeof(list_policies_command))); + +#if 0 + char tag_s[MAXSZ_POLICY_TAG_STATE * POLICY_TAG_N]; + + policy_tag_state_snprintf((char*)&tag_s[MAXSZ_POLICY_TAG_STATE * POLICY_TAG_ ## x], \ + MAXSZ_POLICY_TAG_STATE, \ + &listPoliciesCommand->policy.tags[POLICY_TAG_ ## x]); +#endif + + #define _(x, y) policy_tag_state_snprintf(str.x, MAXSZ_POLICY_TAG_STATE, &listPoliciesCommand->policy.tags[POLICY_TAG_ ## x]); + foreach_policy_tag + #undef _ + + addrString = utils_CommandAddressToString( + listPoliciesCommand->addressType, &listPoliciesCommand->address, &port); + +#if 0 + PARCBufferComposer *composer = parcBufferComposer_Create(); + + parcBufferComposer_Format( + composer, "%*s %*s" + #define _(x, y) " %*s" + foreach_policy_tag + #undef _ + "%s", + MAXSZ_PREFIX, addrString, APP_NAME_LEN, listPoliciesCommand->policy.app_name, + #define _(x, y) MAXSZ_COLUMN, str.x, + foreach_policy_tag + #undef _ + ""); + + PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer); + char *result = parcBuffer_ToString(tempBuffer); + parcBuffer_Release(&tempBuffer); + + if (!controlState_IsInteractive(state)) { + strcpy(commandOutputMain[i], result); + } + + puts(result); + parcMemory_Deallocate((void **)&result); + parcBufferComposer_Release(&composer); +#else + printf("%*s %*s" + #define _(x, y) " %*s" + foreach_policy_tag + #undef _ + "%s\n", + MAXSZ_PREFIX, addrString, MAXSZ_APP_NAME /*APP_NAME_LEN*/, listPoliciesCommand->policy.app_name, + #define _(x, y) MAXSZ_COLUMN, str.x, + foreach_policy_tag + #undef _ + ""); + +#endif + } + + printf("\nSTATISTICS\n\n"); + // STATISTICS + printf("%*s %*s %*s | %*s | %*s | %*s\n", + MAXSZ_PREFIX, "", MAXSZ_APP_NAME /*APP_NAME_LEN*/, "", + 3*MAXSZ_STR_STAT+2, "WIRED", 3*MAXSZ_STR_STAT+2, "WIFI", 3*MAXSZ_STR_STAT+2, "CELLULAR", 3*MAXSZ_STR_STAT+2, "ALL"); + printf("%*s %*s %*s %*s %*s | %*s %*s %*s | %*s %*s %*s | %*s %*s %*s\n", + MAXSZ_PREFIX, "prefix", MAXSZ_APP_NAME /*APP_NAME_LEN*/, "app_name", + MAXSZ_STR_STAT, "throughput", MAXSZ_STR_STAT, "latency", MAXSZ_STR_STAT, "loss_rate", + MAXSZ_STR_STAT, "throughput", MAXSZ_STR_STAT, "latency", MAXSZ_STR_STAT, "loss_rate", + MAXSZ_STR_STAT, "throughput", MAXSZ_STR_STAT, "latency", MAXSZ_STR_STAT, "loss_rate", + MAXSZ_STR_STAT, "throughput", MAXSZ_STR_STAT, "latency", MAXSZ_STR_STAT, "loss_rate"); + for (int i = 0; i < receivedHeader->length; i++) { + list_policies_command *listPoliciesCommand = + (list_policies_command *)(receivedPayload + + (i * sizeof(list_policies_command))); + addrString = utils_CommandAddressToString( + listPoliciesCommand->addressType, &listPoliciesCommand->address, &port); + printf("%*s %*s %*.2f %*.2f %*.2f | %*.2f %*.2f %*.2f | %*.2f %*.2f %*.2f | %*.2f %*.2f %*.2f\n", + MAXSZ_PREFIX, addrString, MAXSZ_APP_NAME, listPoliciesCommand->policy.app_name, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wired.throughput, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wired.latency, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wired.loss_rate, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wifi.throughput, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wifi.latency, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.wifi.loss_rate, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.cellular.throughput, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.cellular.latency, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.cellular.loss_rate, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.all.throughput, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.all.latency, + MAXSZ_STR_STAT, listPoliciesCommand->policy.stats.all.loss_rate); + } + + controlState_SetCommandOutput(state, commandOutputMain); + + // DEALLOCATE + parcMemory_Deallocate((void **)&addrString); + parcMemory_Deallocate(&receivedHeader); // free response[0].iov_base + parcMemory_Deallocate(&receivedPayload); // free response[1].iov_base + parcMemory_Deallocate(&response); // free iovec pointer + + return CommandReturn_Success; +} + +#endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/config/controlListPolicies.h b/hicn-light/src/hicn/config/controlListPolicies.h new file mode 100644 index 000000000..7aa0bdd26 --- /dev/null +++ b/hicn-light/src/hicn/config/controlListPolicies.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_ListPolicies.h + * @brief List the icn-light policies + * + * Implements the "list policies" and "help list policies" nodes of the command tree + * + */ +#ifndef Control_ListPolicies_h +#define Control_ListPolicies_h + +#ifdef WITH_POLICY + +#include <hicn/config/controlState.h> +CommandOps *controlListPolicies_Create(ControlState *state); +CommandOps *controlListPolicies_HelpCreate(ControlState *state); + +#endif /* WITH_POLICY */ + +#endif // Control_ListPolicies_h diff --git a/hicn-light/src/hicn/config/controlRemove.c b/hicn-light/src/hicn/config/controlRemove.c index d33d57206..af833dc8b 100644 --- a/hicn-light/src/hicn/config/controlRemove.c +++ b/hicn-light/src/hicn/config/controlRemove.c @@ -30,6 +30,9 @@ #include <hicn/config/controlRemoveConnection.h> #include <hicn/config/controlRemovePunting.h> #include <hicn/config/controlRemoveRoute.h> +#ifdef WITH_POLICY +#include <hicn/config/controlRemovePolicy.h> +#endif /* WITH_POLICY */ static void _controlRemove_Init(CommandParser *parser, CommandOps *ops); static CommandReturn _controlRemove_Execute(CommandParser *parser, @@ -61,16 +64,25 @@ static CommandReturn _controlRemove_HelpExecute(CommandParser *parser, CommandOps *ops_remove_connection = controlRemoveConnection_Create(NULL); CommandOps *ops_remove_route = controlRemoveRoute_Create(NULL); CommandOps *ops_remove_punting = controlRemovePunting_Create(NULL); +#ifdef WITH_POLICY + CommandOps *ops_remove_policy = controlRemovePolicy_Create(NULL); +#endif /* WITH_POLICY */ printf("Available commands:\n"); printf(" %s\n", ops_remove_connection->command); printf(" %s\n", ops_remove_route->command); printf(" %s\n", ops_remove_punting->command); +#ifdef WITH_POLICY + printf(" %s\n", ops_remove_policy->command); +#endif /* WITH_POLICY */ printf("\n"); commandOps_Destroy(&ops_remove_connection); commandOps_Destroy(&ops_remove_route); commandOps_Destroy(&ops_remove_punting); +#ifdef WITH_POLICY + commandOps_Destroy(&ops_remove_policy); +#endif /* WITH_POLICY */ return CommandReturn_Success; } @@ -83,6 +95,10 @@ static void _controlRemove_Init(CommandParser *parser, CommandOps *ops) { controlState_RegisterCommand(state, controlRemoveRoute_Create(state)); controlState_RegisterCommand(state, controlRemovePunting_Create(state)); controlState_RegisterCommand(state, controlRemovePunting_HelpCreate(state)); +#ifdef WITH_POLICY + controlState_RegisterCommand(state, controlRemovePolicy_HelpCreate(state)); + controlState_RegisterCommand(state, controlRemovePolicy_Create(state)); +#endif /* WITH_POLICY */ } static CommandReturn _controlRemove_Execute(CommandParser *parser, diff --git a/hicn-light/src/hicn/config/controlRemovePolicy.c b/hicn-light/src/hicn/config/controlRemovePolicy.c new file mode 100644 index 000000000..510203886 --- /dev/null +++ b/hicn-light/src/hicn/config/controlRemovePolicy.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_POLICY + +#include <hicn/hicn-light/config.h> + +#include <ctype.h> +#include <parc/algol/parc_List.h> +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_Network.h> +#include <parc/assert/parc_Assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <hicn/utils/address.h> + +#include <hicn/config/controlRemovePolicy.h> + +#include <hicn/utils/commands.h> +#include <hicn/utils/utils.h> + +static CommandReturn _controlRemovePolicy_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args); +static CommandReturn _controlRemovePolicy_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args); + +// =================================================== + +static const char *_commandRemovePolicy = "remove policy"; +static const char *_commandRemovePolicyHelp = "help remove policy"; + +// ==================================================== + +CommandOps *controlRemovePolicy_Create(ControlState *state) { + return commandOps_Create(state, _commandRemovePolicy, NULL, + _controlRemovePolicy_Execute, commandOps_Destroy); +} + +CommandOps *controlRemovePolicy_HelpCreate(ControlState *state) { + return commandOps_Create(state, _commandRemovePolicyHelp, NULL, + _controlRemovePolicy_HelpExecute, commandOps_Destroy); +} + +// ==================================================== + +static CommandReturn _controlRemovePolicy_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + printf("commands:\n"); + printf(" remove policy <prefix>\n"); + return CommandReturn_Success; +} + +static CommandReturn _controlRemovePolicy_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + ControlState *state = ops->closure; + + if (parcList_Size(args) != 3) { + _controlRemovePolicy_HelpExecute(parser, ops, args); + return CommandReturn_Failure; + } + + const char *prefixStr = parcList_GetAtIndex(args, 2); + char *addr = (char *)malloc(sizeof(char) * (strlen(prefixStr) + 1)); + + // separate address and len + char *slash; + uint32_t len = 0; + strcpy(addr, prefixStr); + slash = strrchr(addr, '/'); + if (slash != NULL) { + len = atoi(slash + 1); + *slash = '\0'; + } + + // allocate command payload + remove_policy_command *removePolicyCommand = + parcMemory_AllocateAndClear(sizeof(remove_policy_command)); + + // check and set IP address + if (inet_pton(AF_INET, addr, &removePolicyCommand->address.ipv4) == 1) { + if (len > 32) { + printf("ERROR: exceeded INET mask length, max=32\n"); + parcMemory_Deallocate(&removePolicyCommand); + free(addr); + return CommandReturn_Failure; + } + removePolicyCommand->addressType = ADDR_INET; + } else if (inet_pton(AF_INET6, addr, &removePolicyCommand->address.ipv6) == + 1) { + if (len > 128) { + printf("ERROR: exceeded INET6 mask length, max=128\n"); + parcMemory_Deallocate(&removePolicyCommand); + free(addr); + return CommandReturn_Failure; + } + removePolicyCommand->addressType = ADDR_INET6; + } else { + printf("Error: %s is not a valid network address \n", addr); + parcMemory_Deallocate(&removePolicyCommand); + free(addr); + return CommandReturn_Failure; + } + + free(addr); + // Fill remaining payload fields + removePolicyCommand->len = len; + + // send message and receive response + struct iovec *response = utils_SendRequest( + state, REMOVE_POLICY, removePolicyCommand, sizeof(remove_policy_command)); + + if (!response) { // get NULL pointer + return CommandReturn_Failure; + } + + parcMemory_Deallocate(&response); // free iovec pointer + return CommandReturn_Success; +} + +#endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/config/controlRemovePolicy.h b/hicn-light/src/hicn/config/controlRemovePolicy.h new file mode 100644 index 000000000..ebe098985 --- /dev/null +++ b/hicn-light/src/hicn/config/controlRemovePolicy.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_RemovePolicy.h + * @brief Remove a policy from the FIB + * + * Implements the "remove policy" and "help remove policy" nodes of the command + * tree + * + */ + +#ifndef Control_RemovePolicy_h +#define Control_RemovePolicy_h + +#ifdef WITH_POLICY + +#include <hicn/config/controlState.h> +CommandOps *controlRemovePolicy_Create(ControlState *state); +CommandOps *controlRemovePolicy_HelpCreate(ControlState *state); + +#endif /* WITH_POLICY */ + +#endif // Control_RemovePolicy_h diff --git a/hicn-light/src/hicn/config/controlRemoveRoute.c b/hicn-light/src/hicn/config/controlRemoveRoute.c index 8cb888f7c..0626886de 100644 --- a/hicn-light/src/hicn/config/controlRemoveRoute.c +++ b/hicn-light/src/hicn/config/controlRemoveRoute.c @@ -99,12 +99,6 @@ static CommandReturn _controlRemoveRoute_Execute(CommandParser *parser, *slash = '\0'; } - if (len == 0) { - printf("ERROR: a prefix can not be of length 0\n"); - free(addr); - return CommandReturn_Failure; - } - // allocate command payload remove_route_command *removeRouteCommand = parcMemory_AllocateAndClear(sizeof(remove_route_command)); diff --git a/hicn-light/src/hicn/config/controlRoot.c b/hicn-light/src/hicn/config/controlRoot.c index 675fe4c6e..e135dfc50 100644 --- a/hicn-light/src/hicn/config/controlRoot.c +++ b/hicn-light/src/hicn/config/controlRoot.c @@ -31,6 +31,9 @@ #include <hicn/config/controlRoot.h> #include <hicn/config/controlSet.h> #include <hicn/config/controlUnset.h> +#ifdef WITH_POLICY +#include <hicn/config/controlUpdate.h> +#endif /* WITH_POLICY */ static void _controlRoot_Init(CommandParser *parser, CommandOps *ops); static CommandReturn _controlRoot_Execute(CommandParser *parser, @@ -79,6 +82,9 @@ static CommandReturn _controlRoot_HelpExecute(CommandParser *parser, CommandOps *ops_help_unset = controlUnset_HelpCreate(NULL); CommandOps *ops_help_cache = controlCache_HelpCreate(NULL); CommandOps *ops_help_mapme = controlMapMe_HelpCreate(NULL); +#ifdef WITH_POLICY + CommandOps *ops_help_update = controlUpdate_HelpCreate(NULL); +#endif /* WITH_POLICY */ printf("Available commands:\n"); printf(" %s\n", ops_help_add->command); @@ -89,6 +95,9 @@ static CommandReturn _controlRoot_HelpExecute(CommandParser *parser, printf(" %s\n", ops_help_unset->command); printf(" %s\n", ops_help_cache->command); printf(" %s\n", ops_help_mapme->command); +#ifdef WITH_POLICY + printf(" %s\n", ops_help_update->command); +#endif /* WITH_POLICY */ printf("\n"); commandOps_Destroy(&ops_help_add); @@ -99,6 +108,9 @@ static CommandReturn _controlRoot_HelpExecute(CommandParser *parser, commandOps_Destroy(&ops_help_unset); commandOps_Destroy(&ops_help_cache); commandOps_Destroy(&ops_help_mapme); +#ifdef WITH_POLICY + commandOps_Destroy(&ops_help_update); +#endif /* WITH_POLICY */ return CommandReturn_Success; } @@ -114,6 +126,9 @@ static void _controlRoot_Init(CommandParser *parser, CommandOps *ops) { controlState_RegisterCommand(state, controlUnset_HelpCreate(state)); controlState_RegisterCommand(state, controlCache_HelpCreate(state)); controlState_RegisterCommand(state, controlMapMe_HelpCreate(state)); +#ifdef WITH_POLICY + controlState_RegisterCommand(state, controlUpdate_HelpCreate(state)); +#endif /* WITH_POLICY */ controlState_RegisterCommand(state, webControlAdd_Create(state)); controlState_RegisterCommand(state, controlList_Create(state)); @@ -123,6 +138,9 @@ static void _controlRoot_Init(CommandParser *parser, CommandOps *ops) { controlState_RegisterCommand(state, controlUnset_Create(state)); controlState_RegisterCommand(state, controlCache_Create(state)); controlState_RegisterCommand(state, controlMapMe_Create(state)); +#ifdef WITH_POLICY + controlState_RegisterCommand(state, controlUpdate_Create(state)); +#endif /* WITH_POLICY */ } static CommandReturn _controlRoot_Execute(CommandParser *parser, diff --git a/hicn-light/src/hicn/config/controlSetStrategy.c b/hicn-light/src/hicn/config/controlSetStrategy.c index 1b1396342..b2968712f 100644 --- a/hicn-light/src/hicn/config/controlSetStrategy.c +++ b/hicn-light/src/hicn/config/controlSetStrategy.c @@ -47,8 +47,7 @@ static const char *_commandSetStrategyOptions[LAST_STRATEGY_VALUE] = { "random", "random_per_dash_segment", "loadbalancer_with_delay", - "loadbalancer_by_rate", - "loadbalancer_best_route"}; +}; // ==================================================== @@ -118,11 +117,6 @@ static CommandReturn _controlSetStrategy_Execute(CommandParser *parser, len = atoi(slash + 1); *slash = '\0'; } - if (len == 0) { - printf("ERROR: a prefix can not be of length 0\n"); - free(addr); - return CommandReturn_Failure; - } // allocate command payload set_strategy_command *setStrategyCommand = diff --git a/hicn-light/src/hicn/config/controlUpdate.c b/hicn-light/src/hicn/config/controlUpdate.c new file mode 100644 index 000000000..4c74660c2 --- /dev/null +++ b/hicn-light/src/hicn/config/controlUpdate.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_POLICY + +#include <hicn/hicn-light/config.h> + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <parc/assert/parc_Assert.h> + +#include <parc/security/parc_Security.h> + +#include <parc/algol/parc_Memory.h> + +#include <hicn/config/controlUpdate.h> +#include <hicn/config/controlUpdateConnection.h> + +static void _controlUpdate_Init(CommandParser *parser, CommandOps *ops); +static CommandReturn _controlUpdate_Execute(CommandParser *parser, + CommandOps *ops, PARCList *args); +static CommandReturn _controlUpdate_HelpExecute(CommandParser *parser, + CommandOps *ops, PARCList *args); + +static const char *_commandUpdate = "update"; +static const char *_commandUpdateHelp = "help update"; + +CommandOps *controlUpdate_Create(ControlState *state) { + return commandOps_Create(state, _commandUpdate, _controlUpdate_Init, + _controlUpdate_Execute, commandOps_Destroy); +} + +CommandOps *controlUpdate_HelpCreate(ControlState *state) { + return commandOps_Create(state, _commandUpdateHelp, NULL, + _controlUpdate_HelpExecute, commandOps_Destroy); +} + +// ===================================================== + +static CommandReturn _controlUpdate_HelpExecute(CommandParser *parser, + CommandOps *ops, PARCList *args) { + //CommandOps *ops_update_connections = controlUpdateConnections_HelpCreate(NULL); + // CommandOps *ops_update_interfaces = controlUpdateInterfaces_HelpCreate(NULL); + //CommandOps *ops_update_routes = controlUpdateRoutes_HelpCreate(NULL); + CommandOps *ops_update_listeners = controlUpdateConnection_HelpCreate(NULL); + + printf("Available commands:\n"); + //printf(" %s\n", ops_update_connections->command); + // printf(" %s\n", ops_update_interfaces->command); + //printf(" %s\n", ops_update_routes->command); + printf(" %s\n", ops_update_listeners->command); + printf("\n"); + + // commandOps_Destroy(&ops_update_connections); + // commandOps_Destroy(&ops_update_interfaces); + //commandOps_Destroy(&ops_update_routes); + commandOps_Destroy(&ops_update_listeners); + + return CommandReturn_Success; +} + +static void _controlUpdate_Init(CommandParser *parser, CommandOps *ops) { + ControlState *state = ops->closure; + //controlState_RegisterCommand(state, controlUpdateConnections_HelpCreate(state)); + // controlState_RegisterCommand(state, + // controlUpdateInterfaces_HelpCreate(state)); + controlState_RegisterCommand(state, controlUpdateConnection_HelpCreate(state)); + //controlState_RegisterCommand(state, controlUpdateRoutes_HelpCreate(state)); + //controlState_RegisterCommand(state, controlUpdateConnections_Create(state)); + // controlState_RegisterCommand(state, controlUpdateInterfaces_Create(state)); + //controlState_RegisterCommand(state, controlUpdateRoutes_Create(state)); + controlState_RegisterCommand(state, controlUpdateConnection_Create(state)); +} + +static CommandReturn _controlUpdate_Execute(CommandParser *parser, + CommandOps *ops, PARCList *args) { + return _controlUpdate_HelpExecute(parser, ops, args); +} + +#endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/config/controlUpdate.h b/hicn-light/src/hicn/config/controlUpdate.h new file mode 100644 index 000000000..0007ab653 --- /dev/null +++ b/hicn-light/src/hicn/config/controlUpdate.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_Update.h + * @brief Root node for the "update" commands + * + * Implements the "update" node of the CLI tree. + * + */ + +#ifndef controlUpdate_h +#define controlUpdate_h + +#ifdef WITH_POLICY + +#include <hicn/config/controlState.h> +CommandOps *controlUpdate_Create(ControlState *state); +CommandOps *controlUpdate_HelpCreate(ControlState *state); + +#endif /* WITH_POLICY */ + +#endif // controlUpdate_h diff --git a/hicn-light/src/hicn/config/controlUpdateConnection.c b/hicn-light/src/hicn/config/controlUpdateConnection.c new file mode 100644 index 000000000..3e573d41d --- /dev/null +++ b/hicn-light/src/hicn/config/controlUpdateConnection.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WITH_POLICY + +#include <hicn/hicn-light/config.h> + +#include <ctype.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <parc/assert/parc_Assert.h> + +#include <parc/algol/parc_Memory.h> +#include <parc/algol/parc_Network.h> + +#include <hicn/config/controlUpdateConnection.h> + +#include <hicn/utils/commands.h> +#include <hicn/utils/utils.h> +#include <hicn/utils/policy.h> + +static CommandReturn _controlUpdateConnection_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args); +static CommandReturn _controlUpdateConnection_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args); + +static const char *command_update_connection = "update connection"; +static const char *command_help_update_connection = "help update connection"; + +CommandOps *controlUpdateConnection_Create(ControlState *state) { + return commandOps_Create(state, command_update_connection, NULL, + _controlUpdateConnection_Execute, commandOps_Destroy); +} + +CommandOps *controlUpdateConnection_HelpCreate(ControlState *state) { + return commandOps_Create(state, command_help_update_connection, NULL, + _controlUpdateConnection_HelpExecute, commandOps_Destroy); +} + +// ==================================================== + +static const int _indexSymbolic = 2; +static const int _indexTags = 3; + +static CommandReturn _controlUpdateConnection_HelpExecute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + printf("commands:\n"); + printf(" update connection <symbolic | id> <tags> \n"); + printf("\n"); + printf( + " symbolic: User defined name for connection, must start with " + "alpha and be alphanum\n"); + printf(" id: Identifier for the connection\n"); + printf(" tags: A string representing tags\n"); + return CommandReturn_Success; +} + + +static CommandReturn _controlUpdateConnection_Execute(CommandParser *parser, + CommandOps *ops, + PARCList *args) { + if ((parcList_Size(args) != 3) && (parcList_Size(args) != 4)) { + _controlUpdateConnection_HelpExecute(parser, ops, args); + return CommandReturn_Failure; + } + + const char *symbolicOrConnid = parcList_GetAtIndex(args, _indexSymbolic); + + if (!utils_ValidateSymbolicName(symbolicOrConnid) && + !utils_IsNumber(symbolicOrConnid)) { + printf( + "ERROR: Invalid symbolic or connid:\nsymbolic name must begin with an " + "alpha followed by alphanum;\nconnid must be an integer\n"); + return CommandReturn_Failure; + } + + policy_tags_t tags = POLICY_TAGS_EMPTY; + if (parcList_Size(args) == 4) { + const char *str_tags = parcList_GetAtIndex(args, _indexTags); + + for (unsigned i = 0; str_tags[i] != 0; i++) { + switch(tolower(str_tags[i])) { + case 'e': + policy_tags_add(&tags, POLICY_TAG_WIRED); + break; + case 'w': + policy_tags_add(&tags, POLICY_TAG_WIFI); + break; + case 'c': + policy_tags_add(&tags, POLICY_TAG_CELLULAR); + break; + case 'b': + policy_tags_add(&tags, POLICY_TAG_BEST_EFFORT); + break; + case 'r': + policy_tags_add(&tags, POLICY_TAG_REALTIME); + break; + case 'm': + policy_tags_add(&tags, POLICY_TAG_MULTIPATH); + break; + case 't': + policy_tags_add(&tags, POLICY_TAG_TRUSTED); + break; + } + } + } + ControlState *state = ops->closure; + + // allocate command payload + update_connection_command *updateConnectionCommand = + parcMemory_AllocateAndClear(sizeof(update_connection_command)); + updateConnectionCommand->tags = tags; + strcpy(updateConnectionCommand->symbolicOrConnid, symbolicOrConnid); + + // send message and receive response + struct iovec *response = utils_SendRequest( + state, UPDATE_CONNECTION, updateConnectionCommand, sizeof(update_connection_command)); + + if (!response) // get NULL pointer + return CommandReturn_Failure; + + parcMemory_Deallocate(&response); // free iovec pointer + return CommandReturn_Success; +} + +#endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/config/controlUpdateConnection.h b/hicn-light/src/hicn/config/controlUpdateConnection.h new file mode 100644 index 000000000..eea303202 --- /dev/null +++ b/hicn-light/src/hicn/config/controlUpdateConnection.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file control_UpdateConnection.h + * @brief Update a connection to an interface + * + * <#Detailed Description#> + * + */ + +#ifndef Control_UpdateConnection_h +#define Control_UpdateConnection_h + +#ifdef WITH_POLICY + +#include <hicn/config/controlState.h> +CommandOps *controlUpdateConnection_Create(ControlState *state); +CommandOps *controlUpdateConnection_HelpCreate(ControlState *state); + +#endif /* WITH_POLICY */ + +#endif // Control_UpdateConnection_h |