aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/config
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-07-26 23:20:30 +0200
committerMauro Sardara <msardara@cisco.com>2019-07-29 17:13:35 +0200
commit0a1c6b5565e20167d1f1f33a5a8b597f420b18b0 (patch)
tree98c5da8f231fbd3dc2ce6502040e29c8333d9ffc /hicn-light/src/hicn/config
parent05ca0aa8f612ee48fb66d4dbebe596b7f1e03181 (diff)
[HICN-252] Add per-application policy framework to hicn-light forwarder
Change-Id: I0531cd7a7de179581295ae34766c81cd9cf3e172 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com> Signed-off-by: Mauro Sardara <msardara@cisco.com> Co-authored-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'hicn-light/src/hicn/config')
-rw-r--r--hicn-light/src/hicn/config/CMakeLists.txt12
-rw-r--r--hicn-light/src/hicn/config/configuration.c194
-rw-r--r--hicn-light/src/hicn/config/controlAdd.c16
-rw-r--r--hicn-light/src/hicn/config/controlAddPolicy.c175
-rw-r--r--hicn-light/src/hicn/config/controlAddPolicy.h35
-rw-r--r--hicn-light/src/hicn/config/controlAddPunting.c6
-rw-r--r--hicn-light/src/hicn/config/controlAddRoute.c6
-rw-r--r--hicn-light/src/hicn/config/controlList.c16
-rw-r--r--hicn-light/src/hicn/config/controlListConnections.c21
-rw-r--r--hicn-light/src/hicn/config/controlListPolicies.c240
-rw-r--r--hicn-light/src/hicn/config/controlListPolicies.h34
-rw-r--r--hicn-light/src/hicn/config/controlRemove.c16
-rw-r--r--hicn-light/src/hicn/config/controlRemovePolicy.c139
-rw-r--r--hicn-light/src/hicn/config/controlRemovePolicy.h36
-rw-r--r--hicn-light/src/hicn/config/controlRemoveRoute.c6
-rw-r--r--hicn-light/src/hicn/config/controlRoot.c18
-rw-r--r--hicn-light/src/hicn/config/controlSetStrategy.c8
-rw-r--r--hicn-light/src/hicn/config/controlUpdate.c95
-rw-r--r--hicn-light/src/hicn/config/controlUpdate.h35
-rw-r--r--hicn-light/src/hicn/config/controlUpdateConnection.c145
-rw-r--r--hicn-light/src/hicn/config/controlUpdateConnection.h35
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