Loading src/pathcomp/.gitignore +3 −0 Original line number Diff line number Diff line backend/wireshark backend/*.o backend/pathComp backend/pathComp-dbg src/pathcomp/backend/pathComp_RESTapi.c +10 −5 Original line number Diff line number Diff line Loading @@ -281,7 +281,6 @@ void add_comp_path_deviceId_endpointId_json(cJSON* pathObj, struct path_t* p, st return; } //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c Loading Loading @@ -812,10 +811,16 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { parse_service_constraints(constraintArray, service); } // Get the maximum number of paths to be computed (kPaths) cJSON* kPathsObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths"); if (cJSON_IsNumber(kPathsObj)){ service->kPaths = (guint)(kPathsObj->valuedouble); // Get the maximum number of paths to be computed (kPaths) inspected/explored cJSON* kPathsInspObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_inspection"); if (cJSON_IsNumber(kPathsInspObj)){ service->kPaths_inspected = (guint)(kPathsInspObj->valuedouble); } // Get the maximum number of paths to be computed (kPaths) returned cJSON* kPathsRetpObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_return"); if (cJSON_IsNumber(kPathsRetpObj)){ service->kPaths_returned = (guint)(kPathsRetpObj->valuedouble); } // Append the requested service to the serviceList Loading src/pathcomp/backend/pathComp_ksp.c +6 −6 Original line number Diff line number Diff line Loading @@ -64,14 +64,13 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { for (GList* listnode = g_list_first(serviceList); listnode; listnode = g_list_next(listnode), i++){ //struct service_t* service = &(serviceList->services[i]); struct service_t* service = (struct service_t*)(listnode->data); DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); struct compRouteOutput_t* pathService = &(outputList->compRouteConnection[i]); // check endpoints of the service are different (PE devices/nodes are different) if (same_src_dst_pe_nodeid(service) == 0) { DEBUG_PC("PEs are the same... no path computation"); DEBUG_PC("PEs are the same... NO PATH COMPUTATION"); comp_route_connection_issue_handler(pathService, service); outputList->numCompRouteConnList++; continue; Loading @@ -84,6 +83,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { outputList->numCompRouteConnList++; continue; } alg_comp(service, pathService, g, NO_OPTIMIZATION_ARGUMENT); // last parameter 0 is related to an optimization computation argument outputList->numCompRouteConnList++; Loading @@ -92,7 +92,8 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { continue; } struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); // Out of the comnputed paths for the pathservice, the first one is chosen to be locally allocated struct path_t* path = &(pathService->paths[0]); allocate_graph_resources(path, service, g); allocate_graph_reverse_resources(path, service, g); print_graph(g); Loading @@ -111,8 +112,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { g_assert(routeConnList); gint numSuccesPathComp = 0, numPathCompIntents = 0; Loading src/pathcomp/backend/pathComp_sp.c +32 −32 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay); print_path(p); gboolean feasibleRoute = check_computed_path_feasability(s, p); gboolean feasibleRoute = check_computed_path_feasibility(s, p); if (feasibleRoute == TRUE) { DEBUG_PC("SP Feasible"); print_path(p); Loading src/pathcomp/backend/pathComp_tools.c +63 −40 Original line number Diff line number Diff line Loading @@ -1459,8 +1459,7 @@ void modify_targeted_graph (struct graph_t *g, struct path_set_t *A, struct comp * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gint find_nodeId (gconstpointer data, gconstpointer userdata) { gint find_nodeId (gconstpointer data, gconstpointer userdata) { /** check values */ g_assert(data != NULL); g_assert(userdata != NULL); Loading @@ -1470,8 +1469,7 @@ gint find_nodeId (gconstpointer data, gconstpointer userdata) //DEBUG_PC ("SNodeId (%s) nodeId (%s)", SNodeId->node.nodeId, nodeId); if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) { if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) { return (0); } return -1; Loading Loading @@ -1500,13 +1498,13 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc g_assert(g); g_assert(s); g_assert(mapNodes); struct targetNodes_t *v = &(g->vertices[indexGraphU].targetedVertices[indexGraphV]); DEBUG_PC("Explored Link %s => %s)", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC("=======================CHECK Edge %s => %s =================================", u->node.nodeId, v->tVertice.nodeId); //DEBUG_PC("\t %s => %s", u->node.nodeId, v->tVertice.nodeId); // v already explored in S? then, discard it GList *found = g_list_find_custom (*S, v->tVertice.nodeId, find_nodeId); if (found != NULL) { DEBUG_PC ("v (%s) in S, Discard", v->tVertice.nodeId); DEBUG_PC ("%s in S, DISCARD", v->tVertice.nodeId); return 0; } Loading @@ -1523,10 +1521,11 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc DEBUG_PC("EDGE %s[%s] => %s[%s]", u->node.nodeId, e->aEndPointId, v->tVertice.nodeId, e->zEndPointId); //DEBUG_PC ("\t %s[%s] =>", u->node.nodeId, e->aEndPointId); //DEBUG_PC("\t => %s[%s]", v->tVertice.nodeId, e->zEndPointId); DEBUG_PC("\t AvailBw: %f, TotalBw: %f", edgeAvailBw, edgeTotalBw); DEBUG_PC("\t Edge Att: AvailBw: %f, TotalBw: %f", edgeAvailBw, edgeTotalBw); // Check Service Bw constraint if ((path_constraints->bw == TRUE) && (edgeAvailBw < path_constraints->bwConstraint)) if ((path_constraints->bw == TRUE) && (edgeAvailBw < path_constraints->bwConstraint)) { continue; } else { foundAvailBw = 1; break; Loading @@ -1534,7 +1533,7 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc } // BW constraint NOT MET, then DISCARD edge if ((path_constraints->bw == TRUE) && (foundAvailBw == 0)) { DEBUG_PC ("AvailBw: %f < path_constraint: %f -- Discard Edge", edgeAvailBw, path_constraints->bwConstraint); DEBUG_PC ("Edge AvailBw: %f < path_constraint: %f -- DISCARD Edge", edgeAvailBw, path_constraints->bwConstraint); g_free(path_constraints); return 0; } Loading Loading @@ -1580,13 +1579,14 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc if (arg & ENERGY_EFFICIENT_ARGUMENT) { if (distance_through_u == v_map->distance) { if (power_through_u > v_map->power) { DEBUG_PC("Energy (src -> u + u -> v: %f (Watts) >Energy (src, v): %f (Watts)--> DISCARD LINK", power_through_u, v_map->power); DEBUG_PC("Energy (src -> u + u -> v: %f (Watts) > Energy (src, v): %f (Watts) --> DISCARD EDGE", power_through_u, v_map->power); return 0; } // same energy consumption, consider latency if ((power_through_u == v_map->power) && (latency_through_u > v_map->latency)) { return 0; } // same energy, same latency, criteria: choose the one having the largest available bw if ((power_through_u == v_map->power) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) { return 0; } Loading @@ -1603,8 +1603,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc return 0; } } DEBUG_PC ("%s --> %s Relaxed", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC ("\t AvailBw: %f Mb/s, Cost: %f, Latency: %f ms, Energy: %f Watts", availBw_through_u, distance_through_u, latency_through_u, power_through_u); DEBUG_PC ("Edge %s --> %s [RELAXED]", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC ("\t path till %s: AvailBw: %f Mb/s | Cost: %f | Latency: %f ms | Energy: %f Watts", v->tVertice.nodeId, availBw_through_u, distance_through_u, latency_through_u, power_through_u); // Update Q list -- struct nodeItem_t *nodeItem = g_malloc0 (sizeof (struct nodeItem_t)); Loading @@ -1621,8 +1622,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc if (arg & ENERGY_EFFICIENT_ARGUMENT) { *Q = g_list_insert_sorted(*Q, nodeItem, sort_by_energy); } else else { *Q = g_list_insert_sorted (*Q, nodeItem, sort_by_distance); } // Update the mapNodes for the specific reached tv v_map->distance = distance_through_u; Loading @@ -1634,9 +1636,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc struct edges_t *e1 = &(v_map->predecessor); struct edges_t *e2 = &(v->edges[indexEdge]); duplicate_edge(e1, e2); DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); //DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); //DEBUG_PC("v-pred aTopology: %s", e2->aTopologyId); DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); //DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); // Check whether v is dstPEId //DEBUG_PC ("Targeted dstId: %s", s->service_endpoints_id[1].device_uuid); Loading @@ -1658,7 +1660,7 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gboolean check_computed_path_feasability (struct service_t *s, struct compRouteOutputItem_t* p) { gboolean check_computed_path_feasibility (struct service_t *s, struct compRouteOutputItem_t* p) { float epsilon = 0.0000001; struct path_constraints_t* pathCons = get_path_constraints(s); gboolean ret = TRUE; Loading Loading @@ -2345,7 +2347,7 @@ void build_contextSet_linklList(GList** set, gint activeFlag) { // for each link in linkList: // 1st- Retrieve endpoints A --> B feauture (context Id, device Id, endpoint Id) // 2st - In the graph associated to the contextId, check wheter A (deviceId) is in the vertices list // o No, this is weird ... exist // o No, this is weird ... exit // o Yes, get the other link endpoint (i.e., B) and check whether it exists. If NOT add it, considering // all the attributes; Otherwise, check whether the link is different from existing edges between A and B gdouble epsilon = 0.1; Loading Loading @@ -3064,7 +3066,7 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv // if ingress of the root link (aNodeId) is the spurNode, then stops if (compare_node_id(&re->aNodeId, SN) == 0) { DEBUG_PC("root Link: aNodeId: %s and spurNode: %s -- stop exploring the rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); DEBUG_PC("Ingress Node rootLink %s = spurNode %s; STOP exploring rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); break; } // Extract from Q Loading @@ -3072,7 +3074,6 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); Q = g_list_remove(Q, node); //DEBUG_RL_RA ("Exploring node %s", node->node.nodeId); indexVertice = graph_vertice_lookup(node->node.nodeId, g); g_assert(indexVertice >= 0); Loading @@ -3086,22 +3087,21 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv } // Check that the first node in Q set is SpurNode, otherwise something went wrong ... if (compare_node_id(&re->aNodeId, SN) != 0) { //DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); g_list_free_full(g_steal_pointer(&S), g_free); g_list_free_full(g_steal_pointer(&Q), g_free); return; } } while (g_list_length(Q) > 0) { //Extract from Q set GList* listnode = g_list_first(Q); struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); Q = g_list_remove(Q, node); DEBUG_PC("Q length: %d", g_list_length(Q)); DEBUG_PC("DeviceId: %s", node->node.nodeId); DEBUG_PC("Explored DeviceId: %s", node->node.nodeId); // visit all the links from u within the graph // scan all the links from u within the graph indexVertice = graph_vertice_lookup(node->node.nodeId, g); g_assert(indexVertice >= 0); Loading Loading @@ -3139,18 +3139,19 @@ gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, struct map_nodes_t* mapNodes, guint arg) { g_assert(pred); g_assert(g); g_assert(s); DEBUG_PC("Source: %s -- Destination: %s", s->service_endpoints_id[0].device_uuid, s->service_endpoints_id[1].device_uuid); DEBUG_PC("SOURCE: %s --> DESTINATION: %s", s->service_endpoints_id[0].device_uuid, s->service_endpoints_id[1].device_uuid); // Check the both ingress src and dst endpoints are in the graph 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); DEBUG_PC("ingress DeviceId: %s NOT in G", s->service_endpoints_id[0].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); DEBUG_PC("egress DeviceId: %s NOT in G", s->service_endpoints_id[1].device_uuid); return -1; } Loading @@ -3164,17 +3165,17 @@ gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); 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("DESTINATION: %s NOT reachable", s->service_endpoints_id[1].device_uuid); return -1; } DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth); // 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("DESTINATION %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid); return -1; } DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid); DEBUG_PC("DESTINATION %s REACHABLE", s->service_endpoints_id[1].device_uuid); // Handle predecessors build_predecessors(pred, s, mapNodes); return 1; Loading Loading @@ -3219,6 +3220,18 @@ void set_path_attributes(struct compRouteOutputItem_t* p, struct map_t* mapV) { void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g, guint arg) { g_assert(s); g_assert(path); g_assert(g); // Check if the service specifies a nuumber of K paths to be explored/computed for the // service. If not, compute that number; otherwise set the max number of explored // computed paths to MAX_KSP_VALUE guint maxK = 0; if(s->kPaths_inspected == 0) { maxK = MAX_KSP_VALUE; } else { maxK = s->kPaths_inspected; } DEBUG_PC("The KSP considers K: %d", maxK); // create map of devices/nodes to handle the path computation using the context struct map_nodes_t* mapNodes = create_map_node(); build_map_node(mapNodes, g); Loading @@ -3228,6 +3241,9 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]); struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); DEBUG_PC("======================================================================================="); DEBUG_PC("STARTING PATH COMP FOR %s[%s] --> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); // Compute the 1st KSP path gint done = ksp_comp(predecessors, g, s, NULL, NULL, mapNodes, arg); if (done == -1) { Loading Loading @@ -3260,14 +3276,14 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ } path->num_service_endpoints_id = s->num_service_endpoints_id; DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", MAX_KSP_VALUE); DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", maxK); // Create A and B sets of paths to handle the YEN algorithm struct path_set_t *A = create_path_set(), *B = create_path_set(); // Add 1st Computed path into A->paths[0] duplicate_path(p, &A->paths[0]); A->numPaths++; g_free(predecessors); g_free(p); for (gint k = 1; k < MAX_KSP_VALUE; k++) { for (gint k = 1; k < maxK; k++) { DEBUG_PC("*************************** kth (%d) ***********************************", k); struct compRouteOutputItem_t* p = create_path_item(); duplicate_path(&A->paths[k - 1], p); Loading Loading @@ -3359,9 +3375,10 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) for (gint m = 0; m < s->num_service_endpoints_id; m++) { struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[m]); struct service_endpoints_id_t* oEp = &(s->service_endpoints_id[m]); struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[m]); copy_service_endpoint_id(oEp, iEp); } path->num_service_endpoints_id = s->num_service_endpoints_id; // Print all the paths i A for (gint h = 0; h < A->numPaths; h++) { Loading @@ -3371,25 +3388,31 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ DEBUG_PC("Number of paths: %d", path->numPaths); // For all the computed paths in A, pick the one being feasible wrt the service constraints for (gint ksp = 0; ksp < A->numPaths; ksp++) { if (ksp >= MAX_KSP_VALUE) { DEBUG_PC("Number Requested paths (%d) REACHED - STOP", ksp); if (ksp >= s->kPaths_returned) { DEBUG_PC("Number Requested/returned paths (%d) REACHED - STOP", ksp); break; } gdouble feasibleRoute = check_computed_path_feasability(s, &A->paths[ksp]); gdouble feasibleRoute = check_computed_path_feasibility(s, &A->paths[ksp]); if (feasibleRoute == TRUE) { DEBUG_PC("A[%d] available: %f, pathCost: %f; latency: %f, Power: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay, A->paths[ksp].power); DEBUG_PC("A[%d] available: %f, pathCost: %f; latency: %f, Power: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay, A->paths[ksp].power); struct compRouteOutputItem_t* pathaux = &A->paths[ksp]; path->numPaths++; struct path_t* targetedPath = &path->paths[path->numPaths - 1]; duplicate_path_t(pathaux, targetedPath); print_path_t(targetedPath); remove_path_set(A); remove_path_set(B); return; //remove_path_set(A); //remove_path_set(B); //return; } } remove_path_set(A); remove_path_set(B); // At least 1 out (K) paths was found, then K-SP succeded if (path->numPaths > 0) { DEBUG_PC("K-SP succeeded"); return; } // No paths found --> Issue DEBUG_PC("K-SP failed!!!"); comp_route_connection_issue_handler(path, s); Loading Loading
src/pathcomp/.gitignore +3 −0 Original line number Diff line number Diff line backend/wireshark backend/*.o backend/pathComp backend/pathComp-dbg
src/pathcomp/backend/pathComp_RESTapi.c +10 −5 Original line number Diff line number Diff line Loading @@ -281,7 +281,6 @@ void add_comp_path_deviceId_endpointId_json(cJSON* pathObj, struct path_t* p, st return; } //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c Loading Loading @@ -812,10 +811,16 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { parse_service_constraints(constraintArray, service); } // Get the maximum number of paths to be computed (kPaths) cJSON* kPathsObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths"); if (cJSON_IsNumber(kPathsObj)){ service->kPaths = (guint)(kPathsObj->valuedouble); // Get the maximum number of paths to be computed (kPaths) inspected/explored cJSON* kPathsInspObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_inspection"); if (cJSON_IsNumber(kPathsInspObj)){ service->kPaths_inspected = (guint)(kPathsInspObj->valuedouble); } // Get the maximum number of paths to be computed (kPaths) returned cJSON* kPathsRetpObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_return"); if (cJSON_IsNumber(kPathsRetpObj)){ service->kPaths_returned = (guint)(kPathsRetpObj->valuedouble); } // Append the requested service to the serviceList Loading
src/pathcomp/backend/pathComp_ksp.c +6 −6 Original line number Diff line number Diff line Loading @@ -64,14 +64,13 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { for (GList* listnode = g_list_first(serviceList); listnode; listnode = g_list_next(listnode), i++){ //struct service_t* service = &(serviceList->services[i]); struct service_t* service = (struct service_t*)(listnode->data); DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); struct compRouteOutput_t* pathService = &(outputList->compRouteConnection[i]); // check endpoints of the service are different (PE devices/nodes are different) if (same_src_dst_pe_nodeid(service) == 0) { DEBUG_PC("PEs are the same... no path computation"); DEBUG_PC("PEs are the same... NO PATH COMPUTATION"); comp_route_connection_issue_handler(pathService, service); outputList->numCompRouteConnList++; continue; Loading @@ -84,6 +83,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { outputList->numCompRouteConnList++; continue; } alg_comp(service, pathService, g, NO_OPTIMIZATION_ARGUMENT); // last parameter 0 is related to an optimization computation argument outputList->numCompRouteConnList++; Loading @@ -92,7 +92,8 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { continue; } struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); // Out of the comnputed paths for the pathservice, the first one is chosen to be locally allocated struct path_t* path = &(pathService->paths[0]); allocate_graph_resources(path, service, g); allocate_graph_reverse_resources(path, service, g); print_graph(g); Loading @@ -111,8 +112,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { g_assert(routeConnList); gint numSuccesPathComp = 0, numPathCompIntents = 0; Loading
src/pathcomp/backend/pathComp_sp.c +32 −32 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ void computation_shortest_path(struct service_t* s, struct compRouteOutput_t* pa DEBUG_PC("Computed Path Avail Bw: %f, Path Cost: %f, latency: %f", p->availCap, p->cost, p->delay); print_path(p); gboolean feasibleRoute = check_computed_path_feasability(s, p); gboolean feasibleRoute = check_computed_path_feasibility(s, p); if (feasibleRoute == TRUE) { DEBUG_PC("SP Feasible"); print_path(p); Loading
src/pathcomp/backend/pathComp_tools.c +63 −40 Original line number Diff line number Diff line Loading @@ -1459,8 +1459,7 @@ void modify_targeted_graph (struct graph_t *g, struct path_set_t *A, struct comp * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gint find_nodeId (gconstpointer data, gconstpointer userdata) { gint find_nodeId (gconstpointer data, gconstpointer userdata) { /** check values */ g_assert(data != NULL); g_assert(userdata != NULL); Loading @@ -1470,8 +1469,7 @@ gint find_nodeId (gconstpointer data, gconstpointer userdata) //DEBUG_PC ("SNodeId (%s) nodeId (%s)", SNodeId->node.nodeId, nodeId); if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) { if (!memcmp(SNodeId->node.nodeId, nodeId, strlen (SNodeId->node.nodeId))) { return (0); } return -1; Loading Loading @@ -1500,13 +1498,13 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc g_assert(g); g_assert(s); g_assert(mapNodes); struct targetNodes_t *v = &(g->vertices[indexGraphU].targetedVertices[indexGraphV]); DEBUG_PC("Explored Link %s => %s)", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC("=======================CHECK Edge %s => %s =================================", u->node.nodeId, v->tVertice.nodeId); //DEBUG_PC("\t %s => %s", u->node.nodeId, v->tVertice.nodeId); // v already explored in S? then, discard it GList *found = g_list_find_custom (*S, v->tVertice.nodeId, find_nodeId); if (found != NULL) { DEBUG_PC ("v (%s) in S, Discard", v->tVertice.nodeId); DEBUG_PC ("%s in S, DISCARD", v->tVertice.nodeId); return 0; } Loading @@ -1523,10 +1521,11 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc DEBUG_PC("EDGE %s[%s] => %s[%s]", u->node.nodeId, e->aEndPointId, v->tVertice.nodeId, e->zEndPointId); //DEBUG_PC ("\t %s[%s] =>", u->node.nodeId, e->aEndPointId); //DEBUG_PC("\t => %s[%s]", v->tVertice.nodeId, e->zEndPointId); DEBUG_PC("\t AvailBw: %f, TotalBw: %f", edgeAvailBw, edgeTotalBw); DEBUG_PC("\t Edge Att: AvailBw: %f, TotalBw: %f", edgeAvailBw, edgeTotalBw); // Check Service Bw constraint if ((path_constraints->bw == TRUE) && (edgeAvailBw < path_constraints->bwConstraint)) if ((path_constraints->bw == TRUE) && (edgeAvailBw < path_constraints->bwConstraint)) { continue; } else { foundAvailBw = 1; break; Loading @@ -1534,7 +1533,7 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc } // BW constraint NOT MET, then DISCARD edge if ((path_constraints->bw == TRUE) && (foundAvailBw == 0)) { DEBUG_PC ("AvailBw: %f < path_constraint: %f -- Discard Edge", edgeAvailBw, path_constraints->bwConstraint); DEBUG_PC ("Edge AvailBw: %f < path_constraint: %f -- DISCARD Edge", edgeAvailBw, path_constraints->bwConstraint); g_free(path_constraints); return 0; } Loading Loading @@ -1580,13 +1579,14 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc if (arg & ENERGY_EFFICIENT_ARGUMENT) { if (distance_through_u == v_map->distance) { if (power_through_u > v_map->power) { DEBUG_PC("Energy (src -> u + u -> v: %f (Watts) >Energy (src, v): %f (Watts)--> DISCARD LINK", power_through_u, v_map->power); DEBUG_PC("Energy (src -> u + u -> v: %f (Watts) > Energy (src, v): %f (Watts) --> DISCARD EDGE", power_through_u, v_map->power); return 0; } // same energy consumption, consider latency if ((power_through_u == v_map->power) && (latency_through_u > v_map->latency)) { return 0; } // same energy, same latency, criteria: choose the one having the largest available bw if ((power_through_u == v_map->power) && (latency_through_u == v_map->latency) && (availBw_through_u < v_map->avaiBandwidth)) { return 0; } Loading @@ -1603,8 +1603,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc return 0; } } DEBUG_PC ("%s --> %s Relaxed", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC ("\t AvailBw: %f Mb/s, Cost: %f, Latency: %f ms, Energy: %f Watts", availBw_through_u, distance_through_u, latency_through_u, power_through_u); DEBUG_PC ("Edge %s --> %s [RELAXED]", u->node.nodeId, v->tVertice.nodeId); DEBUG_PC ("\t path till %s: AvailBw: %f Mb/s | Cost: %f | Latency: %f ms | Energy: %f Watts", v->tVertice.nodeId, availBw_through_u, distance_through_u, latency_through_u, power_through_u); // Update Q list -- struct nodeItem_t *nodeItem = g_malloc0 (sizeof (struct nodeItem_t)); Loading @@ -1621,8 +1622,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc if (arg & ENERGY_EFFICIENT_ARGUMENT) { *Q = g_list_insert_sorted(*Q, nodeItem, sort_by_energy); } else else { *Q = g_list_insert_sorted (*Q, nodeItem, sort_by_distance); } // Update the mapNodes for the specific reached tv v_map->distance = distance_through_u; Loading @@ -1634,9 +1636,9 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc struct edges_t *e1 = &(v_map->predecessor); struct edges_t *e2 = &(v->edges[indexEdge]); duplicate_edge(e1, e2); DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); //DEBUG_PC ("u->v Edge: %s(%s) --> %s(%s)", e2->aNodeId.nodeId, e2->aEndPointId, e2->zNodeId.nodeId, e2->zEndPointId); //DEBUG_PC("v-pred aTopology: %s", e2->aTopologyId); DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); //DEBUG_PC("v-pred zTopology: %s", e2->zTopologyId); // Check whether v is dstPEId //DEBUG_PC ("Targeted dstId: %s", s->service_endpoints_id[1].device_uuid); Loading @@ -1658,7 +1660,7 @@ gint check_link (struct nodeItem_t *u, gint indexGraphU, gint indexGraphV, struc * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// gboolean check_computed_path_feasability (struct service_t *s, struct compRouteOutputItem_t* p) { gboolean check_computed_path_feasibility (struct service_t *s, struct compRouteOutputItem_t* p) { float epsilon = 0.0000001; struct path_constraints_t* pathCons = get_path_constraints(s); gboolean ret = TRUE; Loading Loading @@ -2345,7 +2347,7 @@ void build_contextSet_linklList(GList** set, gint activeFlag) { // for each link in linkList: // 1st- Retrieve endpoints A --> B feauture (context Id, device Id, endpoint Id) // 2st - In the graph associated to the contextId, check wheter A (deviceId) is in the vertices list // o No, this is weird ... exist // o No, this is weird ... exit // o Yes, get the other link endpoint (i.e., B) and check whether it exists. If NOT add it, considering // all the attributes; Otherwise, check whether the link is different from existing edges between A and B gdouble epsilon = 0.1; Loading Loading @@ -3064,7 +3066,7 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv // if ingress of the root link (aNodeId) is the spurNode, then stops if (compare_node_id(&re->aNodeId, SN) == 0) { DEBUG_PC("root Link: aNodeId: %s and spurNode: %s -- stop exploring the rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); DEBUG_PC("Ingress Node rootLink %s = spurNode %s; STOP exploring rootPath (RP)", re->aNodeId.nodeId, SN->nodeId); break; } // Extract from Q Loading @@ -3072,7 +3074,6 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); Q = g_list_remove(Q, node); //DEBUG_RL_RA ("Exploring node %s", node->node.nodeId); indexVertice = graph_vertice_lookup(node->node.nodeId, g); g_assert(indexVertice >= 0); Loading @@ -3086,22 +3087,21 @@ void dijkstra(gint srcMapIndex, gint dstMapIndex, struct graph_t* g, struct serv } // Check that the first node in Q set is SpurNode, otherwise something went wrong ... if (compare_node_id(&re->aNodeId, SN) != 0) { //DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); DEBUG_PC ("root Link: aNodeId: %s is NOT the spurNode: %s -- something wrong", re->aNodeId.nodeId, SN->nodeId); g_list_free_full(g_steal_pointer(&S), g_free); g_list_free_full(g_steal_pointer(&Q), g_free); return; } } while (g_list_length(Q) > 0) { //Extract from Q set GList* listnode = g_list_first(Q); struct nodeItem_t* node = (struct nodeItem_t*)(listnode->data); Q = g_list_remove(Q, node); DEBUG_PC("Q length: %d", g_list_length(Q)); DEBUG_PC("DeviceId: %s", node->node.nodeId); DEBUG_PC("Explored DeviceId: %s", node->node.nodeId); // visit all the links from u within the graph // scan all the links from u within the graph indexVertice = graph_vertice_lookup(node->node.nodeId, g); g_assert(indexVertice >= 0); Loading Loading @@ -3139,18 +3139,19 @@ gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, struct map_nodes_t* mapNodes, guint arg) { g_assert(pred); g_assert(g); g_assert(s); DEBUG_PC("Source: %s -- Destination: %s", s->service_endpoints_id[0].device_uuid, s->service_endpoints_id[1].device_uuid); DEBUG_PC("SOURCE: %s --> DESTINATION: %s", s->service_endpoints_id[0].device_uuid, s->service_endpoints_id[1].device_uuid); // Check the both ingress src and dst endpoints are in the graph 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); DEBUG_PC("ingress DeviceId: %s NOT in G", s->service_endpoints_id[0].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); DEBUG_PC("egress DeviceId: %s NOT in G", s->service_endpoints_id[1].device_uuid); return -1; } Loading @@ -3164,17 +3165,17 @@ gint ksp_comp(struct pred_t* pred, struct graph_t* g, struct service_t* s, gint map_dstIndex = get_map_index_by_nodeId(s->service_endpoints_id[1].device_uuid, mapNodes); 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("DESTINATION: %s NOT reachable", s->service_endpoints_id[1].device_uuid); return -1; } DEBUG_PC("AvailBw @ %s is %f", dest_map->verticeId.nodeId, dest_map->avaiBandwidth); // 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("DESTINATION %s NOT REACHABLE", s->service_endpoints_id[1].device_uuid); return -1; } DEBUG_PC("dst: %s REACHABLE", s->service_endpoints_id[1].device_uuid); DEBUG_PC("DESTINATION %s REACHABLE", s->service_endpoints_id[1].device_uuid); // Handle predecessors build_predecessors(pred, s, mapNodes); return 1; Loading Loading @@ -3219,6 +3220,18 @@ void set_path_attributes(struct compRouteOutputItem_t* p, struct map_t* mapV) { void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g, guint arg) { g_assert(s); g_assert(path); g_assert(g); // Check if the service specifies a nuumber of K paths to be explored/computed for the // service. If not, compute that number; otherwise set the max number of explored // computed paths to MAX_KSP_VALUE guint maxK = 0; if(s->kPaths_inspected == 0) { maxK = MAX_KSP_VALUE; } else { maxK = s->kPaths_inspected; } DEBUG_PC("The KSP considers K: %d", maxK); // create map of devices/nodes to handle the path computation using the context struct map_nodes_t* mapNodes = create_map_node(); build_map_node(mapNodes, g); Loading @@ -3228,6 +3241,9 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[0]); struct service_endpoints_id_t* eEp = &(s->service_endpoints_id[1]); DEBUG_PC("======================================================================================="); DEBUG_PC("STARTING PATH COMP FOR %s[%s] --> %s[%s]", iEp->device_uuid, iEp->endpoint_uuid, eEp->device_uuid, eEp->endpoint_uuid); // Compute the 1st KSP path gint done = ksp_comp(predecessors, g, s, NULL, NULL, mapNodes, arg); if (done == -1) { Loading Loading @@ -3260,14 +3276,14 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ } path->num_service_endpoints_id = s->num_service_endpoints_id; DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", MAX_KSP_VALUE); DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", maxK); // Create A and B sets of paths to handle the YEN algorithm struct path_set_t *A = create_path_set(), *B = create_path_set(); // Add 1st Computed path into A->paths[0] duplicate_path(p, &A->paths[0]); A->numPaths++; g_free(predecessors); g_free(p); for (gint k = 1; k < MAX_KSP_VALUE; k++) { for (gint k = 1; k < maxK; k++) { DEBUG_PC("*************************** kth (%d) ***********************************", k); struct compRouteOutputItem_t* p = create_path_item(); duplicate_path(&A->paths[k - 1], p); Loading Loading @@ -3359,9 +3375,10 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ // copy the service endpoints, in general, there will be 2 (point-to-point network connectivity services) for (gint m = 0; m < s->num_service_endpoints_id; m++) { struct service_endpoints_id_t* iEp = &(s->service_endpoints_id[m]); struct service_endpoints_id_t* oEp = &(s->service_endpoints_id[m]); struct service_endpoints_id_t* oEp = &(path->service_endpoints_id[m]); copy_service_endpoint_id(oEp, iEp); } path->num_service_endpoints_id = s->num_service_endpoints_id; // Print all the paths i A for (gint h = 0; h < A->numPaths; h++) { Loading @@ -3371,25 +3388,31 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ DEBUG_PC("Number of paths: %d", path->numPaths); // For all the computed paths in A, pick the one being feasible wrt the service constraints for (gint ksp = 0; ksp < A->numPaths; ksp++) { if (ksp >= MAX_KSP_VALUE) { DEBUG_PC("Number Requested paths (%d) REACHED - STOP", ksp); if (ksp >= s->kPaths_returned) { DEBUG_PC("Number Requested/returned paths (%d) REACHED - STOP", ksp); break; } gdouble feasibleRoute = check_computed_path_feasability(s, &A->paths[ksp]); gdouble feasibleRoute = check_computed_path_feasibility(s, &A->paths[ksp]); if (feasibleRoute == TRUE) { DEBUG_PC("A[%d] available: %f, pathCost: %f; latency: %f, Power: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay, A->paths[ksp].power); DEBUG_PC("A[%d] available: %f, pathCost: %f; latency: %f, Power: %f", ksp, A->paths[ksp].availCap, A->paths[ksp].cost, A->paths[ksp].delay, A->paths[ksp].power); struct compRouteOutputItem_t* pathaux = &A->paths[ksp]; path->numPaths++; struct path_t* targetedPath = &path->paths[path->numPaths - 1]; duplicate_path_t(pathaux, targetedPath); print_path_t(targetedPath); remove_path_set(A); remove_path_set(B); return; //remove_path_set(A); //remove_path_set(B); //return; } } remove_path_set(A); remove_path_set(B); // At least 1 out (K) paths was found, then K-SP succeded if (path->numPaths > 0) { DEBUG_PC("K-SP succeeded"); return; } // No paths found --> Issue DEBUG_PC("K-SP failed!!!"); comp_route_connection_issue_handler(path, s); Loading