Skip to content
Snippets Groups Projects
Commit e4b47afe authored by martinezric's avatar martinezric
Browse files

PathComp Backend Adding Logs

parent bd873955
No related branches found
No related tags found
2 merge requests!142Release TeraFlowSDN 2.1,!100PathComp Backend - Adding Logs and kpaths_return
/* ////////////////////////////////////////////////////////////////////////////////////////
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) /**
* * # Copyright 2022 Centre Tecnolgic de Telecomunicacions de Catalunya (CTTC/CERCA) www.cttc.es
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. * Licensed under the Apache License, Version 2.0 (the "License");
* You may obtain a copy of the License at * 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 *
* * 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, * Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* limitations under the License. * See the License for the specific language governing permissions and
*/ * limitations under the License.
#include <stdio.h> * Author: CTTC/CERCA PONS RU Ricardo Martnez (ricardo.martinez@cttc.es)
#include <stdlib.h> */
#include <sys/types.h> ////////////////////////////////////////////////////////////////////////////////////////
#include <sys/socket.h> #include <stdio.h>
#include <netinet/in.h> #include <stdlib.h>
#include <arpa/inet.h> #include <sys/types.h>
#include <string.h> #include <sys/socket.h>
#include <unistd.h> #include <netinet/in.h>
#include <netdb.h> #include <arpa/inet.h>
#include <glib.h> #include <string.h>
#include <sys/time.h> #include <unistd.h>
#include <ctype.h> #include <netdb.h>
#include <strings.h> #include <glib.h>
#include <time.h> #include <sys/time.h>
#include <math.h> #include <ctype.h>
#include <fcntl.h> #include <strings.h>
#include <time.h>
#include "pathComp_log.h" #include <math.h>
#include "pathComp_tools.h" #include <fcntl.h>
#include "pathComp_sp.h"
#include "pathComp_log.h"
// Global Variables #include "pathComp_tools.h"
GList* contextSet; #include "pathComp_sp.h"
/////////////////////////////////////////////////////////////////////////////////// // Global Variables
/** GList* contextSet;
* @file pathComp_sp.c
* @brief handling the Dijkstra algorithm ///////////////////////////////////////////////////////////////////////////////////
* /**
* @param pred * @file pathComp_sp.c
* @param g * @brief handling the Dijkstra algorithm
* @param s *
* @param mapNodes * @param pred
* * @param g
* @author Ricardo Mart�nez <ricardo.martinez@cttc.es> * @param s
* @date 2022 * @param mapNodes
*/ *
///////////////////////////////////////////////////////////////////////////////////////// * @author Ricardo Martnez <ricardo.martinez@cttc.es>
gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s, struct map_nodes_t* mapNodes) { * @date 2022
g_assert(pred); */
g_assert(g); /////////////////////////////////////////////////////////////////////////////////////////
g_assert(s); gint computation(struct pred_t* pred, struct graph_t* g, struct service_t* s, struct map_nodes_t* mapNodes) {
g_assert(pred);
// Check the both ingress src and dst endpoints are in the graph g_assert(g);
gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes); g_assert(s);
if (srcMapIndex == -1) {
DEBUG_PC("ingress DeviceId: %s NOT in the graph", s->service_endpoints_id[0].device_uuid); // Check the both ingress src and dst endpoints are in the graph
return -1; gint srcMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[0].device_uuid, mapNodes);
} if (srcMapIndex == -1) {
DEBUG_PC("ingress DeviceId: %s NOT in the graph", s->service_endpoints_id[0].device_uuid);
gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); return -1;
if (dstMapIndex == -1) { }
DEBUG_PC("egress DeviceId: %s NOT in the graph", s->service_endpoints_id[1].device_uuid);
return -1; gint dstMapIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
} if (dstMapIndex == -1) {
DEBUG_PC("egress DeviceId: %s NOT in the graph", s->service_endpoints_id[1].device_uuid);
// Compute the shortest path return -1;
dijkstra(srcMapIndex, dstMapIndex, g, s, mapNodes, NULL, NULL, 0x00000000); }
// Check that a feasible solution in term of latency and bandwidth is found // Compute the shortest path
gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); dijkstra(srcMapIndex, dstMapIndex, g, s, mapNodes, NULL, NULL, 0x00000000);
struct map_t* dest_map = &mapNodes->map[map_dstIndex];
if (!(dest_map->distance < INFINITY_COST)) { // Check that a feasible solution in term of latency and bandwidth is found
DEBUG_PC("destination: %s NOT reachable", s->service_endpoints_id[1].device_uuid); gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes);
return -1; struct map_t* dest_map = &mapNodes->map[map_dstIndex];
} if (!(dest_map->distance < INFINITY_COST)) {
DEBUG_PC("destination: %s NOT reachable", s->service_endpoints_id[1].device_uuid);
DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth); return -1;
// Check that the computed available bandwidth is larger than 0.0 }
if (dest_map->avaiBandwidth <= (gfloat)0.0) {
DEBUG_PC("dst: %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid); DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth);
return -1; // Check that the computed available bandwidth is larger than 0.0
} if (dest_map->avaiBandwidth <= (gfloat)0.0) {
DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid); DEBUG_PC("dst: %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid);
// Handle predecessors return -1;
build_predecessors(pred, s, mapNodes); }
DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid);
return 1; // Handle predecessors
} build_predecessors(pred, s, mapNodes);
//////////////////////////////////////////////////////////////////////////////////////// return 1;
/** }
* @file pathComp_sp.c
* @brief CSPF algorithm execution ////////////////////////////////////////////////////////////////////////////////////////
* /**
* @param s * @file pathComp_sp.c
* @param path * @brief CSPF algorithm execution
* @param g *
* * @param s
* @author Ricardo Mart�nez <ricardo.martinez@cttc.es> * @param path
* @date 2022 * @param g
*/ *
///////////////////////////////////////////////////////////////////////////////////////// * @author Ricardo Martnez <ricardo.martinez@cttc.es>
void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g) { * @date 2022
g_assert(s); */
g_assert(path); /////////////////////////////////////////////////////////////////////////////////////////
g_assert(g); void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g) {
g_assert(s);
// create map of devices / nodes to handle the path computation using the context g_assert(path);
struct map_nodes_t *mapNodes = create_map_node(); g_assert(g);
build_map_node(mapNodes, g);
// create map of devices / nodes to handle the path computation using the context
// predecessors to store the computed path struct map_nodes_t *mapNodes = create_map_node();
struct pred_t* predecessors = create_predecessors(); build_map_node(mapNodes, g);
struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]); // predecessors to store the computed path
struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); struct pred_t* predecessors = create_predecessors();
// SP computation struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]);
gint done = computation(predecessors, g, s, mapNodes); struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]);
if (done == -1) {
DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); // SP computation
comp_route_connection_issue_handler(path, s); gint done = computation(predecessors, g, s, mapNodes);
g_free(mapNodes); g_free(predecessors); if (done == -1) {
return; DEBUG_PC("NO PATH FOUND %s[%s] ---> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid);
} comp_route_connection_issue_handler(path, s);
g_free(mapNodes); g_free(predecessors);
// Construct the path from the computed predecessors return;
struct compRouteOutputItem_t* p = create_path_item(); }
//print_predecessors(predecessors);
build_path(p, predecessors, s); // Construct the path from the computed predecessors
//DEBUG_PC ("Path is constructed"); struct compRouteOutputItem_t* p = create_path_item();
//print_predecessors(predecessors);
gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes); build_path(p, predecessors, s);
struct map_t* dst_map = &mapNodes->map[indexDest]; //DEBUG_PC ("Path is constructed");
set_path_attributes(p, dst_map);
DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay); gint indexDest = get_map_index_by_nodeId(eEp->device_uuid, mapNodes);
print_path(p); struct map_t* dst_map = &mapNodes->map[indexDest];
set_path_attributes(p, dst_map);
gboolean feasibleRoute = check_computed_path_feasability(s, p); DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay);
if (feasibleRoute == TRUE) { print_path(p);
DEBUG_PC("SP Feasible");
print_path(p); gboolean feasibleRoute = check_computed_path_feasability(s, p);
path->numPaths++; if (feasibleRoute == TRUE) {
DEBUG_PC("SP Feasible");
// Copy the serviceId print_path(p);
DEBUG_PC("contextId: %s", s->serviceId.contextId); path->numPaths++;
copy_service_id(&path->serviceId, &s->serviceId);
// Copy the serviceId
// copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) DEBUG_PC("contextId: %s", s->serviceId.contextId);
for (gint i = 0; i < s->num_service_endpoints_id; i++) { copy_service_id(&path->serviceId, &s->serviceId);
struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]);
struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]); // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services)
copy_service_endpoint_id(oEp, iEp); for (gint i = 0; i < s->num_service_endpoints_id; i++) {
} struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[i]);
path->num_service_endpoints_id = s->num_service_endpoints_id; struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[i]);
copy_service_endpoint_id(oEp, iEp);
// Copy the computed path }
struct path_t* targetedPath = &(path->paths[path->numPaths - 1]); path->num_service_endpoints_id = s->num_service_endpoints_id;
duplicate_path_t(p, targetedPath);
print_path_t(targetedPath); // Copy the computed path
g_free(predecessors); struct path_t* targetedPath = &(path->paths[path->numPaths - 1]);
g_free(p); duplicate_path_t(p, targetedPath);
g_free(mapNodes); print_path_t(targetedPath);
return; g_free(predecessors);
} g_free(p);
DEBUG_PC("SP FAILED!!!"); g_free(mapNodes);
comp_route_connection_issue_handler(path, s); return;
return; }
} DEBUG_PC("SP FAILED!!!");
comp_route_connection_issue_handler(path, s);
//////////////////////////////////////////////////////////////////////////////////////// return;
/** }
* @file pathComp_sp.c
* @brief Iterates over the list of network connectivity service requests ////////////////////////////////////////////////////////////////////////////////////////
* to compute their own paths fulfilling the constraints /**
* * @file pathComp_sp.c
* @param outputList * @brief Iterates over the list of network connectivity service requests
* * to compute their own paths fulfilling the constraints
* @author Ricardo Mart�nez <ricardo.martinez@cttc.es> *
* @date 2022 * @param outputList
*/ *
void sp_execution_services(struct compRouteOutputList_t* oPathList) { * @author Ricardo Martnez <ricardo.martinez@cttc.es>
g_assert(oPathList); * @date 2022
// Check at least there is a service to be processed */
if (g_list_length(serviceList) == 0) { void sp_execution_services(struct compRouteOutputList_t* oPathList) {
DEBUG_PC("Lengtg requested serviceList is Empty..."); g_assert(oPathList);
return; // Check at least there is a service to be processed
} if (g_list_length(serviceList) == 0) {
DEBUG_PC("Lengtg requested serviceList is Empty...");
DEBUG_PC("----- Starting the SP Computation ------"); return;
gint i = 0; }
for (GList* listnode = g_list_first(serviceList);
listnode; DEBUG_PC("----- Starting the SP Computation ------");
listnode = g_list_next(listnode), i++) { gint i = 0;
//struct service_t* service = &(serviceList->services[i]); for (GList* listnode = g_list_first(serviceList);
struct service_t* service = (struct service_t*)(listnode->data); listnode;
listnode = g_list_next(listnode), i++) {
DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); //struct service_t* service = &(serviceList->services[i]);
struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]); struct service_t* service = (struct service_t*)(listnode->data);
// check endpoints of the service are different (PE devices/nodes are different)
if (same_src_dst_pe_nodeid(service) == 0) { DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId);
DEBUG_PC("PEs are the same... no path computation"); struct compRouteOutput_t* pathService = &(oPathList->compRouteConnection[i]);
comp_route_connection_issue_handler(pathService, service); // check endpoints of the service are different (PE devices/nodes are different)
oPathList->numCompRouteConnList++; if (same_src_dst_pe_nodeid(service) == 0) {
continue; DEBUG_PC("PEs are the same... no path computation");
} comp_route_connection_issue_handler(pathService, service);
oPathList->numCompRouteConnList++;
// get the graph associated to the contextId in the contextSet, if no then error continue;
struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId); }
if (g == NULL) {
DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph"); // get the graph associated to the contextId in the contextSet, if no then error
comp_route_connection_issue_handler(pathService, service); struct graph_t* g = get_graph_by_contextId(contextSet, service->serviceId.contextId);
oPathList->numCompRouteConnList++; if (g == NULL) {
continue; DEBUG_PC("The targeted contextId is NOT in the ContextSet ... then NO graph");
} comp_route_connection_issue_handler(pathService, service);
oPathList->numCompRouteConnList++;
computation_shortest_path(service, pathService, g); continue;
oPathList->numCompRouteConnList++; }
// for each network connectivity service, a single computed path (out of the KCSP) is retuned computation_shortest_path(service, pathService, g);
// If path is found, then the selected resources must be pre-assigned into the context information oPathList->numCompRouteConnList++;
if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) {
continue; // for each network connectivity service, a single computed path (out of the KCSP) is retuned
} // If path is found, then the selected resources must be pre-assigned into the context information
struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) {
//allocate_graph_resources(path, service, g); // LGR: crashes in some cases with assymetric topos continue;
//allocate_graph_reverse_resources(path, service, g); // LGR: crashes in some cases with assymetric topos }
print_graph(g); struct path_t* path = &(pathService->paths[pathService->numPaths - 1]);
} allocate_graph_resources(path, service, g);
return; allocate_graph_reverse_resources(path, service, g);
} print_graph(g);
}
//////////////////////////////////////////////////////////////////////////////////////// return;
/** }
* @file pathComp_sp.c
* @brief handles the path computation for the constrained shortest path ////////////////////////////////////////////////////////////////////////////////////////
* /**
* @param compRouteOutput * @file pathComp_sp.c
* * @brief handles the path computation for the constrained shortest path
* @author Ricardo Mart�nez <ricardo.martinez@cttc.es> *
* @date 2022 * @param compRouteOutput
*/ *
///////////////////////////////////////////////////////////////////////////////////////// * @author Ricardo Martnez <ricardo.martinez@cttc.es>
gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) { * @date 2022
g_assert(routeConnList); */
gint numSuccesPathComp = 0, numPathCompIntents = 0; /////////////////////////////////////////////////////////////////////////////////////////
gint pathComp_sp_alg(struct compRouteOutputList_t* routeConnList) {
DEBUG_PC("================================================================"); g_assert(routeConnList);
DEBUG_PC("=========================== SP ========================="); gint numSuccesPathComp = 0, numPathCompIntents = 0;
DEBUG_PC("================================================================");
// increase the number of Path Comp. Intents DEBUG_PC("================================================================");
numPathCompIntents++; DEBUG_PC("=========================== SP =========================");
gint http_code = HTTP_CODE_OK; DEBUG_PC("================================================================");
// increase the number of Path Comp. Intents
// timestamp t0 numPathCompIntents++;
struct timeval t0; gint http_code = HTTP_CODE_OK;
gettimeofday(&t0, NULL);
// timestamp t0
// Allocate memory for the context struct timeval t0;
contextSet = NULL; gettimeofday(&t0, NULL);
// Build up the contextSet (>= 1)
build_contextSet(&contextSet); // Allocate memory for the context
print_contextSet(contextSet); contextSet = NULL;
#if 1 // Build up the contextSet (>= 1)
//Triggering the path computation for each specific network connectivity service build_contextSet(&contextSet);
sp_execution_services(routeConnList); print_contextSet(contextSet);
#if 1
// -- timestamp t1 //Triggering the path computation for each specific network connectivity service
struct timeval t1, delta; sp_execution_services(routeConnList);
gettimeofday(&t1, NULL);
delta.tv_sec = t1.tv_sec - t0.tv_sec; // -- timestamp t1
delta.tv_usec = t1.tv_usec - t0.tv_usec; struct timeval t1, delta;
delta = tv_adjust(delta); gettimeofday(&t1, NULL);
delta.tv_sec = t1.tv_sec - t0.tv_sec;
numSuccesPathComp++; delta.tv_usec = t1.tv_usec - t0.tv_usec;
update_stats_path_comp(routeConnList, delta, numSuccesPathComp, numPathCompIntents); delta = tv_adjust(delta);
print_path_connection_list(routeConnList);
#endif numSuccesPathComp++;
update_stats_path_comp(routeConnList, delta, numSuccesPathComp, numPathCompIntents);
g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context); print_path_connection_list(routeConnList);
return http_code; #endif
}
g_list_free_full(g_steal_pointer(&contextSet), (GDestroyNotify)destroy_context);
return http_code;
}
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment