From c580a00aac271a524e5a75b35f4b91c174ed227b Mon Sep 17 00:00:00 2001 From: michele papalini Date: Thu, 23 Feb 2017 17:01:34 +0100 Subject: Initial commit: sb-forwarder, metis. Change-Id: I65ee3c851a6901929ef4417ad80d34bca0dce445 Signed-off-by: michele papalini --- .../forwarder/metis/config/metisControl_AddRoute.c | 189 +++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 metis/ccnx/forwarder/metis/config/metisControl_AddRoute.c (limited to 'metis/ccnx/forwarder/metis/config/metisControl_AddRoute.c') diff --git a/metis/ccnx/forwarder/metis/config/metisControl_AddRoute.c b/metis/ccnx/forwarder/metis/config/metisControl_AddRoute.c new file mode 100644 index 00000000..215bcee1 --- /dev/null +++ b/metis/ccnx/forwarder/metis/config/metisControl_AddRoute.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2017 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +static MetisCommandReturn _metisControlAddRoute_Execute(MetisCommandParser *parser, MetisCommandOps *ops, PARCList *args); +static MetisCommandReturn _metisControlAddRoute_HelpExecute(MetisCommandParser *parser, MetisCommandOps *ops, PARCList *args); + +static const char *_commandAddRoute = "add route"; +static const char *_commandAddRouteHelp = "help add route"; + +MetisCommandOps * +metisControlAddRoute_Create(MetisControlState *state) +{ + return metisCommandOps_Create(state, _commandAddRoute, NULL, _metisControlAddRoute_Execute, metisCommandOps_Destroy); +} + +MetisCommandOps * +metisControlAddRoute_HelpCreate(MetisControlState *state) +{ + return metisCommandOps_Create(state, _commandAddRouteHelp, NULL, _metisControlAddRoute_HelpExecute, metisCommandOps_Destroy); +} + +/** + * Return true if string is purely an integer + */ +static bool +_isNumber(const char *string) +{ + size_t len = strlen(string); + for (size_t i = 0; i < len; i++) { + if (!isdigit(string[i])) { + return false; + } + } + return true; +} + +/** + * A symbolic name must be at least 1 character and must begin with an alpha. + * The remainder must be an alphanum. + */ +static bool +_validateSymbolicName(const char *symbolic) +{ + bool success = false; + size_t len = strlen(symbolic); + if (len > 0) { + if (isalpha(symbolic[0])) { + success = true; + for (size_t i = 1; i < len; i++) { + if (!isalnum(symbolic[i])) { + success = false; + break; + } + } + } + } + return success; +} + +// ==================================================== + +static MetisCommandReturn +_metisControlAddRoute_HelpExecute(MetisCommandParser *parser, MetisCommandOps *ops, PARCList *args) +{ + printf("commands:\n"); + printf(" add route \n"); + printf("\n"); + printf(" symbolic: The symbolic name for an exgress\n"); + printf(" connid: The egress connection id (see 'help list connections')\n"); + printf(" prefix: The CCNx name as a URI (e.g. lci:/foo/bar)\n"); + printf(" cost: positive integer representing cost\n"); + printf(" nexthop: Optional network endpoint on the connection\n"); + printf(" seconds: Create a route that will expire if not refresed within the lifetime\n"); + printf("\n"); + printf("Examples:\n"); + printf(" add route 7 lci:/foo/bar 1\n"); + printf(" adds route to prefix '/foo/bar' on egress connection 7 with cost 1\n"); + printf(" add route tun3 lci:/foo/bar 1\n"); + printf(" adds route to prefix '/foo/bar' on egress connection 'tun3' with cost 1\n"); + printf("\n"); + return MetisCommandReturn_Success; +} + +static MetisCommandReturn +_metisControlAddRoute_Execute(MetisCommandParser *parser, MetisCommandOps *ops, PARCList *args) +{ + MetisControlState *state = ops->closure; + + if (parcList_Size(args) != 5) { + _metisControlAddRoute_HelpExecute(parser, ops, args); + return MetisCommandReturn_Failure; + } + + const char *symbolicOrConnid = parcList_GetAtIndex(args, 2); + + if (_validateSymbolicName(symbolicOrConnid) || _isNumber(symbolicOrConnid)) { + const char *prefixString = parcList_GetAtIndex(args, 3); + unsigned cost = atoi(parcList_GetAtIndex(args, 4)); + + if (cost == 0) { + printf("ERROR: cost must be positive integer, got %u from '%s'\n", cost, (char *) parcList_GetAtIndex(args, 4)); + return MetisCommandReturn_Failure; + } + + CCNxName *prefix = ccnxName_CreateFromCString(prefixString); + if (prefix == NULL) { + printf("ERROR: could not parse prefix '%s'\n", prefixString); + return MetisCommandReturn_Failure; + } + + char *protocolTypeAsString = "static"; + + CPINameRouteProtocolType protocolType = cpiNameRouteProtocolType_FromString(protocolTypeAsString); + CPINameRouteType routeType = cpiNameRouteType_LONGEST_MATCH; + CPIAddress *nexthop = NULL; + + struct timeval *lifetime = NULL; + + CPIRouteEntry *route = NULL; + + if (_isNumber(symbolicOrConnid)) { + unsigned connid = (unsigned) strtold(symbolicOrConnid, NULL); + route = cpiRouteEntry_Create(prefix, connid, nexthop, protocolType, routeType, lifetime, cost); + } else { + route = cpiRouteEntry_CreateSymbolic(prefix, symbolicOrConnid, protocolType, routeType, lifetime, cost); + } + + CCNxControl *addRouteRequest = ccnxControl_CreateAddRouteRequest(route); + + cpiRouteEntry_Destroy(&route); + + if (metisControlState_GetDebug(state)) { + char *str = parcJSON_ToString(ccnxControl_GetJson(addRouteRequest)); + printf("request: %s\n", str); + parcMemory_Deallocate((void **) &str); + } + + CCNxMetaMessage *message = ccnxMetaMessage_CreateFromControl(addRouteRequest); + CCNxMetaMessage *rawResponse = metisControlState_WriteRead(state, message); + ccnxMetaMessage_Release(&message); + + ccnxControl_Release(&addRouteRequest); + + CCNxControl *response = ccnxMetaMessage_GetControl(rawResponse); + + if (metisControlState_GetDebug(state)) { + char *str = parcJSON_ToString(ccnxControl_GetJson(response)); + printf("response: %s\n", str); + parcMemory_Deallocate((void **) &str); + } + + ccnxMetaMessage_Release(&rawResponse); + + return MetisCommandReturn_Success; + } else { + printf("ERROR: Invalid symbolic or connid. Symbolic name must begin with an alpha followed by alphanum. connid must be an integer\n"); + return MetisCommandReturn_Failure; + } +} -- cgit 1.2.3-korg