Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add FindNS3 module to cmake.
[simgrid.git] / src / surf / surf_routing.c
index 7d0cba4..4ce3475 100644 (file)
@@ -4,13 +4,11 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-
-
 #include <float.h>
 #include "gras_config.h"
 
 #ifdef HAVE_PCRE_LIB
-#include <pcre.h>               /* regular expresion library */
+#include <pcre.h>               /* regular expression library */
 #endif
 #include "surf_private.h"
 #include "xbt/dynar.h"
@@ -36,7 +34,7 @@ static void *model_full_create(void);   /* create structures for full routing mo
 static void model_full_load(void);      /* load parse functions for full routing model */
 static void model_full_unload(void);    /* unload parse functions for full routing model */
 static void model_full_end(void);       /* finalize the creation of full routing model */
-static void model_full_set_route(              /* Set the route and ASroute between src and dst */
+static void model_full_set_route(      /* Set the route and ASroute between src and dst */
                routing_component_t rc, const char *src, const char *dst, name_route_extended_t route);
 
 static void *model_floyd_create(void);  /* create structures for floyd routing model */
@@ -56,22 +54,22 @@ static void model_dijkstra_both_set_route (routing_component_t rc, const char *s
                      const char *dst, name_route_extended_t route);
 
 static void *model_rulebased_create(void);      /* create structures for rulebased routing model */
-static void model_rulebased_load(void); /* load parse functions for rulebased routing model */
+static void model_rulebased_load(void);         /* load parse functions for rulebased routing model */
 static void model_rulebased_unload(void);       /* unload parse functions for rulebased routing model */
-static void model_rulebased_end(void);  /* finalize the creation of rulebased routing model */
+static void model_rulebased_end(void);          /* finalize the creation of rulebased routing model */
 
-static void *model_none_create(void);   /* none routing model */
-static void model_none_load(void);      /* none routing model */
-static void model_none_unload(void);    /* none routing model */
-static void model_none_end(void);       /* none routing model */
+static void *model_none_create(void);           /* none routing model */
+static void model_none_load(void);              /* none routing model */
+static void model_none_unload(void);            /* none routing model */
+static void model_none_end(void);               /* none routing model */
 
-static void routing_parse_Scluster(void);  /*cluster bypass */
-static void routing_parse_Speer(void);         /*peer bypass */
-static void routing_parse_Srandom(void);       /*random bypass */
-static void routing_parse_Erandom(void);       /*random bypass */
+static void routing_parse_Scluster(void);       /* cluster bypass */
+static void routing_parse_Speer(void);          /* peer bypass */
+static void routing_parse_Srandom(void);        /* random bypass */
+static void routing_parse_Erandom(void);        /* random bypass */
 
-static void routing_parse_Sconfig(void);        /*config Tag */
-static void routing_parse_Econfig(void);        /*config Tag */
+static void routing_parse_Sconfig(void);        /* config Tag */
+static void routing_parse_Econfig(void);        /* config Tag */
 
 static char* replace_random_parameter(char * chaine);
 static void clean_dict_random(void);
@@ -89,7 +87,7 @@ typedef enum {
 } e_routing_types;
 
 
-/* must be finish with null and carefull if change de order */
+/* must finish with NULL and be careful if the order is changed */
 struct s_model_type routing_models[] = { {"Full",
                                           "Full routing data (fast, large memory requirements, fully expressive)",
                                           model_full_create,
@@ -136,7 +134,8 @@ static int surf_pointer_resource_cmp(const void *a, const void *b);
 /* ************************************************************************** */
 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
 
-static double generic_get_link_latency(routing_component_t rc, const char *src, const char *dst);
+static double generic_get_link_latency(routing_component_t rc, const char *src, const char *dst,
+                                                                               route_extended_t e_route);
 static xbt_dynar_t generic_get_onelink_routes(routing_component_t rc);
 static route_extended_t generic_get_bypassroute(routing_component_t rc,
                                                 const char *src,
@@ -171,7 +170,7 @@ static char *gw_dst = NULL;     /* temporary store the gateway destination name
 static xbt_dynar_t link_list = NULL;    /* temporary store of current list link of a route */
 
 
-static double eculidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst)
+static double euclidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst)
 {
        double src_coord, dst_coord;
 
@@ -182,7 +181,7 @@ static double eculidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst)
 
 }
 
-static double vivaldi_get_link_latency (routing_component_t rc,const char *src, const char *dst)
+static double base_vivaldi_get_latency (const char *src, const char *dst)
 {
   double euclidean_dist;
   xbt_dynar_t src_ctn, dst_ctn;
@@ -194,25 +193,26 @@ static double vivaldi_get_link_latency (routing_component_t rc,const char *src,
   if(dst_ctn == NULL || src_ctn == NULL)
   xbt_die("Coord src '%s' :%p   dst '%s' :%p",src,src_ctn,dst,dst_ctn);
 
-  euclidean_dist = sqrt (eculidean_dist_comp(0,src_ctn,dst_ctn)+eculidean_dist_comp(1,src_ctn,dst_ctn))
-                                                               +fabs(atof(xbt_dynar_get_as(src_ctn, 2, char *)))+fabs(atof(xbt_dynar_get_as(dst_ctn, 2, char *)));
+  euclidean_dist = sqrt (euclidean_dist_comp(0,src_ctn,dst_ctn)+euclidean_dist_comp(1,src_ctn,dst_ctn))
+                                fabs(atof(xbt_dynar_get_as(src_ctn, 2, char *)))+fabs(atof(xbt_dynar_get_as(dst_ctn, 2, char *)));
 
   xbt_assert(euclidean_dist>=0, "Euclidean Dist is less than 0\"%s\" and \"%.2f\"", src, euclidean_dist);
 
   return euclidean_dist;
+}
 
-  /*
-  x = atof(xbt_dynar_get_as(src_ctn, 0, char *))-atof(xbt_dynar_get_as(dst_ctn, 0, char *));
-  y = atof(xbt_dynar_get_as(src_ctn, 1, char *));
-  h = atof(xbt_dynar_get_as(ctn, 2, char *));
-  sqrt((c1->x - c2->x) * (c1->x - c2->x) + (c1->y - c2->y) * (c1->y - c2->y)) + fabs(c1->h) + fabs(c2->h);
-
-         if (strcmp(coord,"")) {
-       xbt_dynar_t ctn = xbt_str_split_str(coord, " ");
-       xbt_dynar_shrink(ctn,0);
-       xbt_lib_set(host_lib, host_id, COORD_HOST_LEVEL, ctn);
+static double vivaldi_get_link_latency (routing_component_t rc,const char *src, const char *dst, route_extended_t e_route)
+{
+  if(get_network_element_type(src) == SURF_NETWORK_ELEMENT_AS) {
+         int need_to_clean = e_route?0:1;
+         double latency;
+         e_route = e_route?e_route:(*(rc->get_route)) (rc, src, dst);
+         latency = base_vivaldi_get_latency(e_route->src_gateway,e_route->dst_gateway);
+         if(need_to_clean) generic_free_extended_route(e_route);
+         return latency;
+  } else {
+         return base_vivaldi_get_latency(src,dst);
   }
-       */
 }
 
 /**
@@ -564,13 +564,6 @@ static void parse_S_AS(char *AS_id, char *AS_routing)
 static void parse_S_AS_XML(void)
 {
   parse_S_AS(A_surfxml_AS_id, A_surfxml_AS_routing);
-
-  if (strcmp(A_surfxml_AS_coordinates,"")) {
-       if(!COORD_ASR_LEVEL) xbt_die("To use coordinates, you must set configuration 'coordinates' to 'yes'");
-    xbt_dynar_t ctn = xbt_str_split_str(A_surfxml_AS_coordinates, " ");
-    xbt_dynar_shrink(ctn, 0);
-    xbt_lib_set(as_router_lib,A_surfxml_AS_id,COORD_ASR_LEVEL,(void *) ctn);
-  }
 }
 
 /*
@@ -741,8 +734,8 @@ static xbt_dynar_t elements_father(const char *src, const char *dst)
  * \param src the source host name 
  * \param dst the destination host name
  * 
- * This fuction is call by "get_route". It allow to walk through the 
- * routing components tree.
+ * This function is called by "get_route". It allows to walk recursively
+ * through the routing components tree.
  */
 static route_extended_t _get_route(const char *src, const char *dst)
 {
@@ -774,16 +767,15 @@ static route_extended_t _get_route(const char *src, const char *dst)
 
   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
 
-    if (strcmp(src, dst)) {
-      e_route_cnt =
-          (*(common_father->get_route)) (common_father, src, dst);
-      xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"", src,
-                  dst);
-      xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
-        xbt_dynar_push(e_route->generic_route.link_list, &link);
-      }
-      generic_free_extended_route(e_route_cnt);
-    }
+       e_route_cnt =
+         (*(common_father->get_route)) (common_father, src, dst);
+       xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"", src,
+                         dst);
+         // FIXME (optim): faire une copie et pas une série de push
+       xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
+       xbt_dynar_push(e_route->generic_route.link_list, &link);
+       }
+       generic_free_extended_route(e_route_cnt);
 
   } else {                      /* SURF_ROUTING_RECURSIVE */
 
@@ -863,12 +855,11 @@ static double _get_latency(const char *src, const char *dst)
 
   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
 
-    if (strcmp(src, dst)) {
       latency =
-          (*(common_father->get_latency)) (common_father, src, dst);
+          (*(common_father->get_latency)) (common_father, src, dst, NULL);
       xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"", src,
                   dst);
-     } else latency = 0;
+
   } else {                      /* SURF_ROUTING_RECURSIVE */
      route_extended_t e_route_bypass = NULL;
     if (common_father->get_bypass_route)
@@ -887,16 +878,14 @@ static double _get_latency(const char *src, const char *dst)
     xbt_assert((e_route_cnt->src_gateway == NULL) ==
                 (e_route_cnt->dst_gateway == NULL),
                 "bad gateway for route between \"%s\" and \"%s\"", src,
-                dst);            
-    latency =
-          (*(common_father->get_latency)) (common_father, elements_As_name(src),
-                         elements_As_name(dst));
+                dst);
+
+    latency = (*(common_father->get_latency)) (common_father, src_father->name, dst_father->name, e_route_cnt);
 
     xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"",
                 src_father->name, dst_father->name);
-    
 
-    if (src != e_route_cnt->src_gateway) {
+    if (strcmp(src,e_route_cnt->src_gateway)) {
 
       latency_src = _get_latency(src, e_route_cnt->src_gateway);
       xbt_assert(latency_src>=0, "no route between \"%s\" and \"%s\"", src,
@@ -904,7 +893,7 @@ static double _get_latency(const char *src, const char *dst)
       latency += latency_src;
     }
 
-    if (e_route_cnt->dst_gateway != dst) {
+    if (strcmp(e_route_cnt->dst_gateway,dst)) {
     
       latency_dst = _get_latency(e_route_cnt->dst_gateway, dst);
       xbt_assert(latency_dst>=0, "no route between \"%s\" and \"%s\"",
@@ -933,20 +922,8 @@ static xbt_dynar_t get_route(const char *src, const char *dst)
 {
 
   route_extended_t e_route;
-  xbt_dynar_t elem_father_list = NULL;
-  routing_component_t common_father = NULL;
-
-  if (strcmp(src, dst))
-    e_route = _get_route(src, dst);
-  else {
-    elem_father_list = elements_father(src, dst);
-    common_father =
-        xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
-
-    e_route = (*(common_father->get_route)) (common_father, src, dst);
-    xbt_dynar_free(&elem_father_list);
-  }
 
+  e_route = _get_route(src, dst);
   xbt_assert(e_route, "no route between \"%s\" and \"%s\"", src, dst);
 
   if (global_routing->last_route)
@@ -960,12 +937,7 @@ static xbt_dynar_t get_route(const char *src, const char *dst)
 
   xbt_free(e_route);
 
-/*
-  if (xbt_dynar_length(global_routing->last_route) == 0)
-    return NULL;
-  else
-*/
-    return global_routing->last_route;
+  return global_routing->last_route;
 }
 
 /**
@@ -990,18 +962,8 @@ static double get_latency(const char *src, const char *dst)
 {
 
   double latency = -1.0;
-  xbt_dynar_t elem_father_list = elements_father(src, dst);
-  routing_component_t common_father =
-      xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
-
-  if (strcmp(src, dst))
-    latency = _get_latency(src, dst);
-  else
-    latency = (*(common_father->get_latency)) (common_father, src, dst);
-
+  latency = _get_latency(src, dst);
   xbt_assert(latency>=0.0, "no route between \"%s\" and \"%s\"", src, dst);
-  xbt_dynar_free(&elem_father_list);
-
   return latency;
 }
 
@@ -1239,7 +1201,6 @@ static route_extended_t full_get_route(routing_component_t rc,
   routing_component_full_t routing = (routing_component_full_t) rc;
   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
 
-  generic_src_dst_check(rc, src, dst);
   int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
   int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
   xbt_assert(src_id
@@ -2437,6 +2398,12 @@ static void model_rulebased_set_route(routing_component_t rc,
   rule_route_t ruleroute = xbt_new0(s_rule_route_t, 1);
   const char *error;
   int erroffset;
+
+  if(!strcmp(rc->routing->name,"Vivaldi")){
+         if(xbt_dynar_length(route->generic_route.link_list) != 0)
+                 xbt_die("You can't have link_ctn with Model Vivaldi.");
+  }
+
   ruleroute->re_src = pcre_compile(src, 0, &error, &erroffset, NULL);
   xbt_assert(ruleroute->re_src,
               "PCRE compilation failed at offset %d (\"%s\"): %s\n",
@@ -2459,6 +2426,12 @@ static void model_rulebased_set_ASroute(routing_component_t rc,
   rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t, 1);
   const char *error;
   int erroffset;
+
+  if(!strcmp(rc->routing->name,"Vivaldi")){
+         if(xbt_dynar_length(route->generic_route.link_list) != 0)
+                 xbt_die("You can't have link_ctn with Model Vivaldi.");
+  }
+
   ruleroute_e->generic_rule_route.re_src =
       pcre_compile(src, 0, &error, &erroffset, NULL);
   xbt_assert(ruleroute_e->generic_rule_route.re_src,
@@ -2960,17 +2933,20 @@ static void generic_set_bypassroute(routing_component_t rc,
 /* *********************** GENERIC BUSINESS METHODS ************************* */
 
 static double generic_get_link_latency(routing_component_t rc,
-                                       const char *src, const char *dst)
+                                       const char *src, const char *dst,
+                                       route_extended_t route)
 {
-       route_extended_t route = rc->get_route(rc,src,dst);
+       int need_to_clean = route?0:1;
        void * link;
        unsigned int i;
        double latency = 0.0;
 
+       route = route?route:rc->get_route(rc,src,dst);
+
        xbt_dynar_foreach(route->generic_route.link_list,i,link) {
                latency += get_link_latency(link);
        }
-       generic_free_extended_route(route);
+       if(need_to_clean) generic_free_extended_route(route);
   return latency;
 }
 
@@ -3307,8 +3283,8 @@ static void generic_src_dst_check(routing_component_t rc, const char *src,
          xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
               src, src_as->name, dst, dst_as->name);
   if(rc != dst_as)
-        xbt_die("The routing component of src and dst is not the same as the network elements belong (%s==%s)",
-     rc->name, dst_as->name);
+        xbt_die("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
+     src,dst,src_as->name, dst_as->name,rc->name);
 }
 
 static void routing_parse_Sconfig(void)
@@ -3353,7 +3329,7 @@ static void routing_parse_Scluster(void)
   char *cluster_availability_file = A_surfxml_cluster_availability_file;
   char *cluster_state_file = A_surfxml_cluster_state_file;
   char *host_id, *groups, *link_id = NULL;
-  char *router_id, *link_router, *link_backbone;
+  char *router_id, *link_backbone;
   char *availability_file = xbt_strdup(cluster_availability_file);
   char *state_file = xbt_strdup(cluster_state_file);
 
@@ -3390,11 +3366,9 @@ static void routing_parse_Scluster(void)
   SURFXML_BUFFER_SET(AS_id, cluster_id);
 #ifdef HAVE_PCRE_LIB
   SURFXML_BUFFER_SET(AS_routing, "RuleBased");
-  SURFXML_BUFFER_SET(AS_coordinates, "");
   XBT_DEBUG("<AS id=\"%s\"\trouting=\"RuleBased\">", cluster_id);
 #else
   SURFXML_BUFFER_SET(AS_routing, "Full");
-  SURFXML_BUFFER_SET(AS_coordinates, "");
   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", cluster_id);
 #endif
   SURFXML_START_TAG(AS);
@@ -3537,7 +3511,7 @@ static void routing_parse_Scluster(void)
   router_id =
       bprintf("%s%s_router%s", cluster_prefix, cluster_id,
               cluster_suffix);
-  link_router = bprintf("%s_link_%s_router", cluster_id, cluster_id);
+  //link_router = bprintf("%s_link_%s_router", cluster_id, cluster_id);
   link_backbone = bprintf("%s_backbone", cluster_id);
 
   XBT_DEBUG("<router id=\"%s\"/>", router_id);
@@ -3547,29 +3521,29 @@ static void routing_parse_Scluster(void)
   SURFXML_END_TAG(router);
 
   //TODO
-  xbt_dict_set(patterns, "radical", xbt_strdup("_router"), xbt_free);
-  temp_cluster_bw = xbt_strdup(cluster_bw);
-  temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
-  temp_cluster_lat = xbt_strdup(cluster_lat);
-  temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
-  XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_router,temp_cluster_bw, temp_cluster_lat);
-  A_surfxml_link_state = A_surfxml_link_state_ON;
-  A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
-  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
-  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
-  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
-  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
-  SURFXML_BUFFER_SET(link_id, link_router);
-  SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
-  SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
-  SURFXML_BUFFER_SET(link_bandwidth_file, "");
-  SURFXML_BUFFER_SET(link_latency_file, "");
-  SURFXML_BUFFER_SET(link_state_file, "");
-  SURFXML_START_TAG(link);
-  SURFXML_END_TAG(link);
-
-  xbt_free(temp_cluster_bw);
-  xbt_free(temp_cluster_lat);
+//  xbt_dict_set(patterns, "radical", xbt_strdup("_router"), xbt_free);
+//  temp_cluster_bw = xbt_strdup(cluster_bw);
+//  temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
+//  temp_cluster_lat = xbt_strdup(cluster_lat);
+//  temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
+//  XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_router,temp_cluster_bw, temp_cluster_lat);
+//  A_surfxml_link_state = A_surfxml_link_state_ON;
+//  A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
+//  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
+//  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
+//  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
+//  {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
+//  SURFXML_BUFFER_SET(link_id, link_router);
+//  SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
+//  SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
+//  SURFXML_BUFFER_SET(link_bandwidth_file, "");
+//  SURFXML_BUFFER_SET(link_latency_file, "");
+//  SURFXML_BUFFER_SET(link_state_file, "");
+//  SURFXML_START_TAG(link);
+//  SURFXML_END_TAG(link);
+
+//  xbt_free(temp_cluster_bw);
+//  xbt_free(temp_cluster_lat);
 
   XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_backbone,cluster_bb_bw, cluster_bb_lat);
   A_surfxml_link_state = A_surfxml_link_state_ON;
@@ -3606,6 +3580,74 @@ static void routing_parse_Scluster(void)
   char *pcre_link_backbone = bprintf("%s_backbone", cluster_id);
   char *pcre_link_dst = bprintf("%s_link_$1dst", cluster_id);
 
+  //from router to router
+  XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, router_id);
+  XBT_DEBUG("symmetrical=\"NO\">");
+  SURFXML_BUFFER_SET(route_src, router_id);
+  SURFXML_BUFFER_SET(route_dst, router_id);
+  A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
+  SURFXML_START_TAG(route);
+
+  XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
+  SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
+  A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+  SURFXML_START_TAG(link_ctn);
+  SURFXML_END_TAG(link_ctn);
+
+  XBT_DEBUG("</route>");
+  SURFXML_END_TAG(route);
+
+  //from host to router
+  XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, router_id);
+  XBT_DEBUG("symmetrical=\"NO\">");
+  SURFXML_BUFFER_SET(route_src, route_src_dst);
+  SURFXML_BUFFER_SET(route_dst, router_id);
+  A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
+  SURFXML_START_TAG(route);
+
+  XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_src);
+  SURFXML_BUFFER_SET(link_ctn_id, pcre_link_src);
+  A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
+  {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
+  SURFXML_START_TAG(link_ctn);
+  SURFXML_END_TAG(link_ctn);
+
+  XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
+  SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
+  A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+  SURFXML_START_TAG(link_ctn);
+  SURFXML_END_TAG(link_ctn);
+
+  XBT_DEBUG("</route>");
+  SURFXML_END_TAG(route);
+
+  //from router to host
+  XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, route_src_dst);
+  XBT_DEBUG("symmetrical=\"NO\">");
+  SURFXML_BUFFER_SET(route_src, router_id);
+  SURFXML_BUFFER_SET(route_dst, route_src_dst);
+  A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
+  SURFXML_START_TAG(route);
+
+  XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
+  SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
+  A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+  SURFXML_START_TAG(link_ctn);
+  SURFXML_END_TAG(link_ctn);
+
+  XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_dst);
+  SURFXML_BUFFER_SET(link_ctn_id, pcre_link_dst);
+  A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+  if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
+  {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
+  SURFXML_START_TAG(link_ctn);
+  SURFXML_END_TAG(link_ctn);
+
+  XBT_DEBUG("</route>");
+  SURFXML_END_TAG(route);
+
+  //from host to host
   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, route_src_dst);
   XBT_DEBUG("symmetrical=\"NO\">");
   SURFXML_BUFFER_SET(route_src, route_src_dst);
@@ -3670,43 +3712,39 @@ static void routing_parse_Scluster(void)
       A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
       SURFXML_START_TAG(route);
 
-      if (i == xbt_dynar_length(tab_elements_num)) {
-        route_src = link_router;
-      } else {
-        route_src =
-            bprintf("%s_link_%d", cluster_id,
-                    xbt_dynar_get_as(tab_elements_num, i, int));
-      }
-
-      if (j == xbt_dynar_length(tab_elements_num)) {
-        route_dst = link_router;
-      } else {
-        route_dst =
-            bprintf("%s_link_%d", cluster_id,
-                    xbt_dynar_get_as(tab_elements_num, j, int));
+      if (i != xbt_dynar_length(tab_elements_num)){
+          route_src =
+                bprintf("%s_link_%d", cluster_id,
+                        xbt_dynar_get_as(tab_elements_num, i, int));
+                 XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_src);
+                 SURFXML_BUFFER_SET(link_ctn_id, route_src);
+                 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+                 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
+                 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
+                 SURFXML_START_TAG(link_ctn);
+                 SURFXML_END_TAG(link_ctn);
+                 free(route_src);
       }
 
-      XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_src);
-      SURFXML_BUFFER_SET(link_ctn_id, route_src);
-      A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
-      if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
-      {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
-      SURFXML_START_TAG(link_ctn);
-      SURFXML_END_TAG(link_ctn);
-
       XBT_DEBUG("<link_ctn\tid=\"%s_backbone\"/>", cluster_id);
       SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone", cluster_id));
       A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
       SURFXML_START_TAG(link_ctn);
       SURFXML_END_TAG(link_ctn);
 
-      XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_dst);
-      SURFXML_BUFFER_SET(link_ctn_id, route_dst);
-      A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
-      if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
-      {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
-      SURFXML_START_TAG(link_ctn);
-      SURFXML_END_TAG(link_ctn);
+      if (j != xbt_dynar_length(tab_elements_num)) {
+          route_dst =
+                bprintf("%s_link_%d", cluster_id,
+                        xbt_dynar_get_as(tab_elements_num, j, int));
+                 XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_dst);
+                 SURFXML_BUFFER_SET(link_ctn_id, route_dst);
+                 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
+                 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
+                 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
+                 SURFXML_START_TAG(link_ctn);
+                 SURFXML_END_TAG(link_ctn);
+                 free(route_dst);
+      }
 
       XBT_DEBUG("</route>");
       SURFXML_END_TAG(route);
@@ -3718,7 +3756,7 @@ static void routing_parse_Scluster(void)
 
   free(router_id);
   free(link_backbone);
-  free(link_router);
+  //free(link_router);
   xbt_dict_free(&patterns);
   free(availability_file);
   free(state_file);
@@ -3783,7 +3821,6 @@ static void routing_parse_Speer(void)
   surfxml_bufferstack_push(1);
 
   SURFXML_BUFFER_SET(AS_id, peer_id);
-  SURFXML_BUFFER_SET(AS_coordinates, peer_coord);
 
   SURFXML_BUFFER_SET(AS_routing, "Full");
   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", peer_id);