Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
87631c065ba93fb5e2021709c472a088f9be1fa5
[simgrid.git] / src / surf / surf_routing.c
1 /* Copyright (c) 2009, 2010. The SimGrid Team. 
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <float.h>
8 #include "gras_config.h"
9
10 #ifdef HAVE_PCRE_LIB
11 #include <pcre.h>               /* regular expression library */
12 #endif
13 #include "surf_private.h"
14 #include "xbt/dynar.h"
15 #include "xbt/str.h"
16 #include "xbt/config.h"
17 #include "xbt/graph.h"
18 #include "xbt/set.h"
19 #include "surf/surfxml_parse.h"
20
21 xbt_dict_t patterns = NULL;
22 xbt_dict_t random_value = NULL;
23
24 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
25
26 /* Global vars */
27 routing_global_t global_routing = NULL;
28 routing_component_t current_routing = NULL;
29 model_type_t current_routing_model = NULL;
30 static double_f_cpvoid_t get_link_latency = NULL;
31
32 /* Prototypes of each model */
33 static void *model_full_create(void);   /* create structures for full routing model */
34 static void model_full_load(void);      /* load parse functions for full routing model */
35 static void model_full_unload(void);    /* unload parse functions for full routing model */
36 static void model_full_end(void);       /* finalize the creation of full routing model */
37 static void model_full_set_route(       /* Set the route and ASroute between src and dst */
38                 routing_component_t rc, const char *src, const char *dst, name_route_extended_t route);
39
40 static void *model_floyd_create(void);  /* create structures for floyd routing model */
41 static void model_floyd_load(void);     /* load parse functions for floyd routing model */
42 static void model_floyd_unload(void);   /* unload parse functions for floyd routing model */
43 static void model_floyd_end(void);      /* finalize the creation of floyd routing model */
44 static void model_floyd_set_route(routing_component_t rc, const char *src,
45         const char *dst, name_route_extended_t route);
46
47 static void *model_dijkstra_both_create(int cached);    /* create by calling dijkstra or dijkstracache */
48 static void *model_dijkstra_create(void);       /* create structures for dijkstra routing model */
49 static void *model_dijkstracache_create(void);  /* create structures for dijkstracache routing model */
50 static void model_dijkstra_both_load(void);     /* load parse functions for dijkstra routing model */
51 static void model_dijkstra_both_unload(void);   /* unload parse functions for dijkstra routing model */
52 static void model_dijkstra_both_end(void);      /* finalize the creation of dijkstra routing model */
53 static void model_dijkstra_both_set_route (routing_component_t rc, const char *src,
54                      const char *dst, name_route_extended_t route);
55
56 static void *model_rulebased_create(void);      /* create structures for rulebased routing model */
57 static void model_rulebased_load(void);         /* load parse functions for rulebased routing model */
58 static void model_rulebased_unload(void);       /* unload parse functions for rulebased routing model */
59 static void model_rulebased_end(void);          /* finalize the creation of rulebased routing model */
60
61 static void *model_none_create(void);           /* none routing model */
62 static void model_none_load(void);              /* none routing model */
63 static void model_none_unload(void);            /* none routing model */
64 static void model_none_end(void);               /* none routing model */
65
66 static void routing_parse_Scluster(void);       /* cluster bypass */
67 static void routing_parse_Speer(void);          /* peer bypass */
68 static void routing_parse_Srandom(void);        /* random bypass */
69 static void routing_parse_Erandom(void);        /* random bypass */
70
71 static void routing_parse_Sconfig(void);        /* config Tag */
72 static void routing_parse_Econfig(void);        /* config Tag */
73
74 static char* replace_random_parameter(char * chaine);
75 static void clean_dict_random(void);
76
77 /* this lines are only for replace use like index in the model table */
78 typedef enum {
79   SURF_MODEL_FULL = 0,
80   SURF_MODEL_FLOYD,
81   SURF_MODEL_DIJKSTRA,
82   SURF_MODEL_DIJKSTRACACHE,
83   SURF_MODEL_NONE,
84 #ifdef HAVE_PCRE_LIB
85   SURF_MODEL_RULEBASED
86 #endif
87 } e_routing_types;
88
89
90 /* must finish with NULL and be careful if the order is changed */
91 struct s_model_type routing_models[] = { {"Full",
92                                           "Full routing data (fast, large memory requirements, fully expressive)",
93                                           model_full_create,
94                                           model_full_load,
95                                           model_full_unload,
96                                           model_full_end},
97 {"Floyd",
98  "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
99  model_floyd_create, model_floyd_load, model_floyd_unload,
100  model_floyd_end},
101 {"Dijkstra",
102  "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
103  model_dijkstra_create, model_dijkstra_both_load,
104  model_dijkstra_both_unload, model_dijkstra_both_end},
105 {"DijkstraCache",
106  "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
107  model_dijkstracache_create, model_dijkstra_both_load,
108  model_dijkstra_both_unload, model_dijkstra_both_end},
109 {"none", "No routing (usable with Constant network only)",
110  model_none_create, model_none_load, model_none_unload, model_none_end},
111 #ifdef HAVE_PCRE_LIB
112 {"RuleBased", "Rule-Based routing data (...)", model_rulebased_create,
113  model_rulebased_load, model_rulebased_unload, model_rulebased_end},
114 {"Vivaldi", "Vivaldi routing", model_rulebased_create,
115   model_rulebased_load, model_rulebased_unload, model_rulebased_end},
116 #endif
117 {NULL, NULL, NULL, NULL, NULL, NULL}
118 };
119
120 /* ************************************************************************** */
121 /* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
122
123 static void generic_set_processing_unit(routing_component_t rc,
124                                         const char *name);
125 static void generic_set_autonomous_system(routing_component_t rc,
126                                           const char *name);
127 static void generic_set_bypassroute(routing_component_t rc,
128                                     const char *src, const char *dst,
129                                     route_extended_t e_route);
130
131 static int surf_link_resource_cmp(const void *a, const void *b);
132 static int surf_pointer_resource_cmp(const void *a, const void *b);
133
134 /* ************************************************************************** */
135 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
136
137 static double generic_get_link_latency(routing_component_t rc, const char *src, const char *dst,
138                                                                                 route_extended_t e_route);
139 static xbt_dynar_t generic_get_onelink_routes(routing_component_t rc);
140 static route_extended_t generic_get_bypassroute(routing_component_t rc,
141                                                 const char *src,
142                                                 const char *dst);
143
144 /* ************************************************************************** */
145 /* ****************** GENERIC AUX FUNCTIONS (declarations) ****************** */
146
147 static route_extended_t
148 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
149                            void *data, int order);
150 static route_t
151 generic_new_route(e_surf_routing_hierarchy_t hierarchy,
152                            void *data, int order);
153 static void generic_free_route(route_t route);
154 static void generic_free_extended_route(route_extended_t e_route);
155 static routing_component_t
156 generic_autonomous_system_exist(routing_component_t rc, char *element);
157 static routing_component_t
158 generic_processing_units_exist(routing_component_t rc, char *element);
159 static void generic_src_dst_check(routing_component_t rc, const char *src,
160                                   const char *dst);
161
162 /* ************************************************************************** */
163 /* **************************** GLOBAL FUNCTIONS **************************** */
164
165 /* global parse functions */
166 static const char *src = NULL;        /* temporary store the source name of a route */
167 static const char *dst = NULL;        /* temporary store the destination name of a route */
168 static char *gw_src = NULL;     /* temporary store the gateway source name of a route */
169 static char *gw_dst = NULL;     /* temporary store the gateway destination name of a route */
170 static xbt_dynar_t link_list = NULL;    /* temporary store of current list link of a route */
171
172
173 static double euclidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst)
174 {
175         double src_coord, dst_coord;
176
177         src_coord = atof(xbt_dynar_get_as(src, index, char *));
178         dst_coord = atof(xbt_dynar_get_as(dst, index, char *));
179
180         return (src_coord-dst_coord)*(src_coord-dst_coord);
181
182 }
183
184 static double base_vivaldi_get_latency (const char *src, const char *dst)
185 {
186   double euclidean_dist;
187   xbt_dynar_t src_ctn, dst_ctn;
188   src_ctn = xbt_lib_get_or_null(host_lib, src, COORD_HOST_LEVEL);
189   if(!src_ctn) src_ctn = xbt_lib_get_or_null(as_router_lib, src, COORD_ASR_LEVEL);
190   dst_ctn = xbt_lib_get_or_null(host_lib, dst, COORD_HOST_LEVEL);
191   if(!dst_ctn) dst_ctn = xbt_lib_get_or_null(as_router_lib, dst, COORD_ASR_LEVEL);
192
193   if(dst_ctn == NULL || src_ctn == NULL)
194   xbt_die("Coord src '%s' :%p   dst '%s' :%p",src,src_ctn,dst,dst_ctn);
195
196   euclidean_dist = sqrt (euclidean_dist_comp(0,src_ctn,dst_ctn)+euclidean_dist_comp(1,src_ctn,dst_ctn))
197                                  + fabs(atof(xbt_dynar_get_as(src_ctn, 2, char *)))+fabs(atof(xbt_dynar_get_as(dst_ctn, 2, char *)));
198
199   xbt_assert(euclidean_dist>=0, "Euclidean Dist is less than 0\"%s\" and \"%.2f\"", src, euclidean_dist);
200
201   return euclidean_dist;
202 }
203
204 static double vivaldi_get_link_latency (routing_component_t rc,const char *src, const char *dst, route_extended_t e_route)
205 {
206   if(get_network_element_type(src) == SURF_NETWORK_ELEMENT_AS) {
207           int need_to_clean = e_route?0:1;
208           double latency;
209           e_route = e_route?e_route:(*(rc->get_route)) (rc, src, dst);
210           latency = base_vivaldi_get_latency(e_route->src_gateway,e_route->dst_gateway);
211           if(need_to_clean) generic_free_extended_route(e_route);
212           return latency;
213   } else {
214           return base_vivaldi_get_latency(src,dst);
215   }
216 }
217
218 /**
219  * \brief Add a "host" to the network element list
220  */
221 static void parse_S_host(const char *host_id, const char* coord)
222 {
223   network_element_info_t info = NULL;
224   if (current_routing->hierarchy == SURF_ROUTING_NULL)
225     current_routing->hierarchy = SURF_ROUTING_BASE;
226   xbt_assert(!xbt_lib_get_or_null(host_lib, host_id,ROUTING_HOST_LEVEL),
227               "Reading a host, processing unit \"%s\" already exists",
228               host_id);
229   xbt_assert(current_routing->set_processing_unit,
230               "no defined method \"set_processing_unit\" in \"%s\"",
231               current_routing->name);
232   (*(current_routing->set_processing_unit)) (current_routing, host_id);
233   info = xbt_new0(s_network_element_info_t, 1);
234   info->rc_component = current_routing;
235   info->rc_type = SURF_NETWORK_ELEMENT_HOST;
236   xbt_lib_set(host_lib,host_id,ROUTING_HOST_LEVEL,(void *) info);
237   if (strcmp(coord,"")) {
238         if(!COORD_HOST_LEVEL) xbt_die("To use coordinates, you must set configuration 'coordinates' to 'yes'");
239     xbt_dynar_t ctn = xbt_str_split_str(coord, " ");
240     xbt_dynar_shrink(ctn, 0);
241     xbt_lib_set(host_lib,host_id,COORD_HOST_LEVEL,(void *) ctn);
242   }
243 }
244
245 static void parse_E_host(void)
246 {
247          xbt_dict_cursor_t cursor = NULL;
248           char *key;
249           char *elem;
250
251           xbt_dict_foreach(current_property_set, cursor, key, elem) {
252                   XBT_DEBUG("property : %s = %s",key,elem);
253                 }
254 }
255
256 /*
257  * \brief Add a host to the network element list from XML
258  */
259 static void parse_S_host_XML(void)
260 {
261         parse_S_host(A_surfxml_host_id, A_surfxml_host_coordinates);
262 }
263 static void parse_E_host_XML(void)
264 {
265         parse_E_host();
266 }
267
268 /*
269  * \brief Add a host to the network element list from lua script
270  */
271 static void parse_S_host_lua(const char *host_id, const char *coord)
272 {
273   parse_S_host(host_id, coord);
274 }
275
276
277 /**
278  * \brief Add a "router" to the network element list
279  */
280 static void parse_S_router(const char *router_id)
281 {
282   network_element_info_t info = NULL;
283
284   if (current_routing->hierarchy == SURF_ROUTING_NULL)
285     current_routing->hierarchy = SURF_ROUTING_BASE;
286   xbt_assert(!xbt_lib_get_or_null(as_router_lib,A_surfxml_router_id, ROUTING_ASR_LEVEL),
287               "Reading a router, processing unit \"%s\" already exists",
288               router_id);
289   xbt_assert(current_routing->set_processing_unit,
290               "no defined method \"set_processing_unit\" in \"%s\"",
291               current_routing->name);
292   (*(current_routing->set_processing_unit)) (current_routing,
293                                              router_id);
294   info = xbt_new0(s_network_element_info_t, 1);
295   info->rc_component = current_routing;
296   info->rc_type = SURF_NETWORK_ELEMENT_ROUTER;
297
298   xbt_lib_set(as_router_lib,router_id,ROUTING_ASR_LEVEL,(void *) info);
299   if (strcmp(A_surfxml_router_coordinates,"")) {
300         if(!COORD_ASR_LEVEL) xbt_die("To use coordinates, you must set configuration 'coordinates' to 'yes'");
301     xbt_dynar_t ctn = xbt_str_split_str(A_surfxml_router_coordinates, " ");
302     xbt_dynar_shrink(ctn, 0);
303     xbt_lib_set(as_router_lib,router_id,COORD_ASR_LEVEL,(void *) ctn);
304   }
305 }
306
307 /**
308  * brief Add a "router" to the network element list from XML description
309  */
310 static void parse_S_router_XML(void)
311 {
312         return parse_S_router(A_surfxml_router_id);
313 }
314
315 /**
316  * brief Add a "router" to the network element list from XML description
317  */
318 static void parse_S_router_lua(const char* router_id)
319 {
320         return parse_S_router(router_id);
321 }
322
323 /**
324  * \brief Set the endponints for a route
325  */
326 static void parse_S_route_new_and_endpoints(const char *src_id, const char *dst_id)
327 {
328   if (src != NULL && dst != NULL && link_list != NULL)
329     THROWF(arg_error, 0, "Route between %s to %s can not be defined",
330            src_id, dst_id);
331   src = src_id;
332   dst = dst_id;
333   xbt_assert(strlen(src) > 0 || strlen(dst) > 0,
334               "Some limits are null in the route between \"%s\" and \"%s\"",
335               src, dst);
336   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
337 }
338
339 /**
340  * \brief Set the endpoints for a route from XML
341  */
342 static void parse_S_route_new_and_endpoints_XML(void)
343 {
344   parse_S_route_new_and_endpoints(A_surfxml_route_src,
345                                   A_surfxml_route_dst);
346 }
347
348 /**
349  * \brief Set the endpoints for a route from lua
350  */
351 static void parse_S_route_new_and_endpoints_lua(const char *id_src, const char *id_dst)
352 {
353   parse_S_route_new_and_endpoints(id_src, id_dst);
354 }
355
356 /**
357  * \brief Set the endponints and gateways for a ASroute
358  */
359 static void parse_S_ASroute_new_and_endpoints(void)
360 {
361   if (src != NULL && dst != NULL && link_list != NULL)
362     THROWF(arg_error, 0, "Route between %s to %s can not be defined",
363            A_surfxml_ASroute_src, A_surfxml_ASroute_dst);
364   src = A_surfxml_ASroute_src;
365   dst = A_surfxml_ASroute_dst;
366   gw_src = A_surfxml_ASroute_gw_src;
367   gw_dst = A_surfxml_ASroute_gw_dst;
368   xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
369               || strlen(gw_dst) > 0,
370               "Some limits are null in the route between \"%s\" and \"%s\"",
371               src, dst);
372   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
373 }
374
375 /**
376  * \brief Set the endponints for a bypassRoute
377  */
378 static void parse_S_bypassRoute_new_and_endpoints(void)
379 {
380   if (src != NULL && dst != NULL && link_list != NULL)
381     THROWF(arg_error, 0,
382            "Bypass Route between %s to %s can not be defined",
383            A_surfxml_bypassRoute_src, A_surfxml_bypassRoute_dst);
384   src = A_surfxml_bypassRoute_src;
385   dst = A_surfxml_bypassRoute_dst;
386   gw_src = A_surfxml_bypassRoute_gw_src;
387   gw_dst = A_surfxml_bypassRoute_gw_dst;
388   xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
389               || strlen(gw_dst) > 0,
390               "Some limits are null in the route between \"%s\" and \"%s\"",
391               src, dst);
392   link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
393 }
394
395 /**
396  * \brief Set a new link on the actual list of link for a route or ASroute
397  */
398 static void parse_E_link_ctn_new_elem(const char *link_id)
399 {
400   char *val;
401   val = xbt_strdup(link_id);
402   xbt_dynar_push(link_list, &val);
403 }
404
405 /**
406  * \brief Set a new link on the actual list of link for a route or ASroute from XML
407  */
408
409 static void parse_E_link_ctn_new_elem_XML(void)
410 {
411   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_NONE)
412     parse_E_link_ctn_new_elem(A_surfxml_link_ctn_id);
413   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_UP) {
414     char *link_id = bprintf("%s_UP", A_surfxml_link_ctn_id);
415     parse_E_link_ctn_new_elem(link_id);
416     free(link_id);
417   }
418   if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_DOWN) {
419     char *link_id = bprintf("%s_DOWN", A_surfxml_link_ctn_id);
420     parse_E_link_ctn_new_elem(link_id);
421     free(link_id);
422   }
423 }
424
425 /**
426  * \brief Set a new link on the actual list of link for a route or ASroute from lua
427  */
428 static void parse_E_link_c_ctn_new_elem_lua(const char *link_id)
429 {
430   parse_E_link_ctn_new_elem(link_id);
431 }
432
433 /**
434  * \brief Store the route by calling the set_route function of the current routing component
435  */
436 static void parse_E_route_store_route(void)
437 {
438   name_route_extended_t route = xbt_new0(s_name_route_extended_t, 1);
439   route->generic_route.link_list = link_list;
440   xbt_assert(current_routing->set_route,
441               "no defined method \"set_route\" in \"%s\"",
442               current_routing->name);
443   (*(current_routing->set_route)) (current_routing, src, dst, route);
444   link_list = NULL;
445   src = NULL;
446   dst = NULL;
447 }
448
449 /**
450  * \brief Store the ASroute by calling the set_ASroute function of the current routing component
451  */
452 static void parse_E_ASroute_store_route(void)
453 {
454   name_route_extended_t e_route = xbt_new0(s_name_route_extended_t, 1);
455   e_route->generic_route.link_list = link_list;
456   e_route->src_gateway = xbt_strdup(gw_src);
457   e_route->dst_gateway = xbt_strdup(gw_dst);
458   xbt_assert(current_routing->set_ASroute,
459               "no defined method \"set_ASroute\" in \"%s\"",
460               current_routing->name);
461   (*(current_routing->set_ASroute)) (current_routing, src, dst, e_route);
462   link_list = NULL;
463   src = NULL;
464   dst = NULL;
465   gw_src = NULL;
466   gw_dst = NULL;
467 }
468
469 /**
470  * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
471  */
472 static void parse_E_bypassRoute_store_route(void)
473 {
474   route_extended_t e_route = xbt_new0(s_route_extended_t, 1);
475   e_route->generic_route.link_list = link_list;
476   e_route->src_gateway = xbt_strdup(gw_src);
477   e_route->dst_gateway = xbt_strdup(gw_dst);
478   xbt_assert(current_routing->set_bypassroute,
479               "no defined method \"set_bypassroute\" in \"%s\"",
480               current_routing->name);
481   (*(current_routing->set_bypassroute)) (current_routing, src, dst,
482                                          e_route);
483   link_list = NULL;
484   src = NULL;
485   dst = NULL;
486   gw_src = NULL;
487   gw_dst = NULL;
488 }
489
490 /**
491  * \brief Make a new routing component
492  *
493  * make the new structure and
494  * set the parsing functions to allows parsing the part of the routing tree
495  */
496 static void parse_S_AS(char *AS_id, char *AS_routing)
497 {
498   routing_component_t new_routing;
499   model_type_t model = NULL;
500   char *wanted = AS_routing;
501   int cpt;
502   /* seach the routing model */
503   for (cpt = 0; routing_models[cpt].name; cpt++)
504     if (!strcmp(wanted, routing_models[cpt].name))
505       model = &routing_models[cpt];
506   /* if its not exist, error */
507   if (model == NULL) {
508     fprintf(stderr, "Routing model %s not found. Existing models:\n",
509             wanted);
510     for (cpt = 0; routing_models[cpt].name; cpt++)
511       if (!strcmp(wanted, routing_models[cpt].name))
512         fprintf(stderr, "   %s: %s\n", routing_models[cpt].name,
513                 routing_models[cpt].desc);
514     xbt_die(NULL);
515   }
516
517   /* make a new routing component */
518   new_routing = (routing_component_t) (*(model->create)) ();
519   new_routing->routing = model;
520   new_routing->hierarchy = SURF_ROUTING_NULL;
521   new_routing->name = xbt_strdup(AS_id);
522   new_routing->routing_sons = xbt_dict_new();
523
524   /* Hack for Vivaldi */
525   if(!strcmp(model->name,"Vivaldi"))
526         new_routing->get_latency = vivaldi_get_link_latency;
527
528   if (current_routing == NULL && global_routing->root == NULL) {
529
530     /* it is the first one */
531     new_routing->routing_father = NULL;
532     global_routing->root = new_routing;
533
534   } else if (current_routing != NULL && global_routing->root != NULL) {
535
536     xbt_assert(!xbt_dict_get_or_null
537                 (current_routing->routing_sons, AS_id),
538                 "The AS \"%s\" already exists", AS_id);
539     /* it is a part of the tree */
540     new_routing->routing_father = current_routing;
541     /* set the father behavior */
542     if (current_routing->hierarchy == SURF_ROUTING_NULL)
543       current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
544     /* add to the sons dictionary */
545     xbt_dict_set(current_routing->routing_sons, AS_id,
546                  (void *) new_routing, NULL);
547     /* add to the father element list */
548     (*(current_routing->set_autonomous_system)) (current_routing, AS_id);
549     /* unload the prev parse rules */
550     (*(current_routing->routing->unload)) ();
551
552   } else {
553     THROWF(arg_error, 0, "All defined components must be belong to a AS");
554   }
555   /* set the new parse rules */
556   (*(new_routing->routing->load)) ();
557   /* set the new current component of the tree */
558   current_routing = new_routing;
559 }
560
561 /*
562  * Detect the routing model type of the routing component from XML platforms
563  */
564 static void parse_S_AS_XML(void)
565 {
566   parse_S_AS(A_surfxml_AS_id, A_surfxml_AS_routing);
567 }
568
569 /*
570  * define the routing model type of routing component from lua script
571  */
572 static void parse_S_AS_lua(char *id, char *mode)
573 {
574   parse_S_AS(id, mode);
575 }
576
577
578 /**
579  * \brief Finish the creation of a new routing component
580  *
581  * When you finish to read the routing component, other structures must be created. 
582  * the "end" method allow to do that for any routing model type
583  */
584 static void parse_E_AS(const char *AS_id)
585 {
586
587   if (current_routing == NULL) {
588     THROWF(arg_error, 0, "Close AS(%s), that never open", AS_id);
589   } else {
590     network_element_info_t info = NULL;
591     xbt_assert(!xbt_lib_get_or_null(as_router_lib,current_routing->name, ROUTING_ASR_LEVEL),
592                 "The AS \"%s\" already exists",current_routing->name);
593     info = xbt_new0(s_network_element_info_t, 1);
594     info->rc_component = current_routing->routing_father;
595     info->rc_type = SURF_NETWORK_ELEMENT_AS;
596     xbt_lib_set(as_router_lib,current_routing->name,ROUTING_ASR_LEVEL,(void *) info);
597
598     (*(current_routing->routing->unload)) ();
599     (*(current_routing->routing->end)) ();
600     current_routing = current_routing->routing_father;
601     if (current_routing != NULL)
602       (*(current_routing->routing->load)) ();
603   }
604 }
605
606 /*
607  * \brief Finish the creation of a new routing component from XML
608  */
609 static void parse_E_AS_XML(void)
610 {
611   parse_E_AS(A_surfxml_AS_id);
612 }
613
614 /*
615  * \brief Finish the creation of a new routing component from lua
616  */
617 static void parse_E_AS_lua(const char *id)
618 {
619   parse_E_AS(id);
620 }
621
622 /* Aux Business methods */
623
624 /**
625  * \brief Get the AS name of the element
626  *
627  * \param name the host name
628  *
629  */
630 static char* elements_As_name(const char *name)
631 {
632   routing_component_t as_comp;
633
634   /* (1) find the as where the host is located */
635   as_comp = ((network_element_info_t)
636             xbt_lib_get_or_null(host_lib,name, ROUTING_HOST_LEVEL))->rc_component;
637   return as_comp->name;
638 }
639
640
641 /**
642  * \brief Get the AS father and the first elements of the chain
643  *
644  * \param src the source host name 
645  * \param dst the destination host name
646  * 
647  * Get the common father of the to processing units, and the first different 
648  * father in the chain
649  */
650 static xbt_dynar_t elements_father(const char *src, const char *dst)
651 {
652
653   xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
654
655   xbt_dynar_t result = xbt_dynar_new(sizeof(char *), NULL);
656
657   routing_component_t src_as, dst_as;
658   int index_src, index_dst, index_father_src, index_father_dst;
659   xbt_dynar_t path_src = NULL;
660   xbt_dynar_t path_dst = NULL;
661   routing_component_t current = NULL;
662   routing_component_t *current_src = NULL;
663   routing_component_t *current_dst = NULL;
664   routing_component_t *father = NULL;
665
666   /* (1) find the as where the src and dst are located */
667   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
668   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
669   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
670   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
671   src_as = ((network_element_info_t)src_data)->rc_component;
672   dst_as = ((network_element_info_t)dst_data)->rc_component;
673
674   xbt_assert(src_as
675               && dst_as,
676               "Ask for route \"from\"(%s) or \"to\"(%s) no found", src,
677               dst);
678
679   /* (2) find the path to the root routing component */
680   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
681   current = src_as;
682   while (current != NULL) {
683     xbt_dynar_push(path_src, &current);
684     current = current->routing_father;
685   }
686   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
687   current = dst_as;
688   while (current != NULL) {
689     xbt_dynar_push(path_dst, &current);
690     current = current->routing_father;
691   }
692
693   /* (3) find the common father */
694   index_src = path_src->used - 1;
695   index_dst = path_dst->used - 1;
696   current_src = xbt_dynar_get_ptr(path_src, index_src);
697   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
698   while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
699     current_src = xbt_dynar_get_ptr(path_src, index_src);
700     current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
701     index_src--;
702     index_dst--;
703   }
704   index_src++;
705   index_dst++;
706   current_src = xbt_dynar_get_ptr(path_src, index_src);
707   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
708
709   /* (4) they are not in the same routing component, make the path */
710   index_father_src = index_src + 1;
711   index_father_dst = index_dst + 1;
712
713   if (*current_src == *current_dst)
714     father = current_src;
715   else
716     father = xbt_dynar_get_ptr(path_src, index_father_src);
717
718   /* (5) result generation */
719   xbt_dynar_push(result, father);       /* first same the father of src and dst */
720   xbt_dynar_push(result, current_src);  /* second the first different father of src */
721   xbt_dynar_push(result, current_dst);  /* three  the first different father of dst */
722
723   xbt_dynar_free(&path_src);
724   xbt_dynar_free(&path_dst);
725
726   return result;
727 }
728
729 /* Global Business methods */
730
731 /**
732  * \brief Recursive function for get_route
733  *
734  * \param src the source host name 
735  * \param dst the destination host name
736  * 
737  * This function is called by "get_route". It allows to walk recursively
738  * through the routing components tree.
739  */
740 static route_extended_t _get_route(const char *src, const char *dst)
741 {
742
743   void *link;
744   unsigned int cpt = 0;
745
746   XBT_DEBUG("Solve route  \"%s\" to \"%s\"", src, dst);
747
748   xbt_assert(src && dst, "bad parameters for \"_get_route\" method");
749
750   route_extended_t e_route, e_route_cnt, e_route_src = NULL, e_route_dst =
751       NULL;
752
753   xbt_dynar_t elem_father_list = elements_father(src, dst);
754
755   routing_component_t common_father =
756       xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
757   routing_component_t src_father =
758       xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
759   routing_component_t dst_father =
760       xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
761
762   e_route = xbt_new0(s_route_extended_t, 1);
763   e_route->src_gateway = NULL;
764   e_route->dst_gateway = NULL;
765   e_route->generic_route.link_list =
766       xbt_dynar_new(global_routing->size_of_link, NULL);
767
768   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
769
770         e_route_cnt =
771           (*(common_father->get_route)) (common_father, src, dst);
772         xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"", src,
773                           dst);
774           // FIXME (optim): faire une copie et pas une série de push
775         xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
776         xbt_dynar_push(e_route->generic_route.link_list, &link);
777         }
778         generic_free_extended_route(e_route_cnt);
779
780   } else {                      /* SURF_ROUTING_RECURSIVE */
781
782     route_extended_t e_route_bypass = NULL;
783
784     if (common_father->get_bypass_route)
785       e_route_bypass =
786           (*(common_father->get_bypass_route)) (common_father, src, dst);
787
788     if (e_route_bypass)
789       e_route_cnt = e_route_bypass;
790     else
791       e_route_cnt =
792           (*(common_father->get_route)) (common_father, src_father->name,
793                                          dst_father->name);
794
795     xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"",
796                 src_father->name, dst_father->name);
797
798     xbt_assert((e_route_cnt->src_gateway == NULL) ==
799                 (e_route_cnt->dst_gateway == NULL),
800                 "bad gateway for route between \"%s\" and \"%s\"", src,
801                 dst);
802
803     if (strcmp(src, e_route_cnt->src_gateway)) {
804       e_route_src = _get_route(src, e_route_cnt->src_gateway);
805       xbt_assert(e_route_src, "no route between \"%s\" and \"%s\"", src,
806                   e_route_cnt->src_gateway);
807       xbt_dynar_foreach(e_route_src->generic_route.link_list, cpt, link) {
808         xbt_dynar_push(e_route->generic_route.link_list, &link);
809       }
810     }
811
812     xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
813       xbt_dynar_push(e_route->generic_route.link_list, &link);
814     }
815
816     if (strcmp(e_route_cnt->dst_gateway, dst)) {
817       e_route_dst = _get_route(e_route_cnt->dst_gateway, dst);
818       xbt_assert(e_route_dst, "no route between \"%s\" and \"%s\"",
819                   e_route_cnt->dst_gateway, dst);
820       xbt_dynar_foreach(e_route_dst->generic_route.link_list, cpt, link) {
821         xbt_dynar_push(e_route->generic_route.link_list, &link);
822       }
823     }
824
825     e_route->src_gateway = xbt_strdup(e_route_cnt->src_gateway);
826     e_route->dst_gateway = xbt_strdup(e_route_cnt->dst_gateway);
827
828     generic_free_extended_route(e_route_src);
829     generic_free_extended_route(e_route_cnt);
830     generic_free_extended_route(e_route_dst);
831   }
832
833   xbt_dynar_free(&elem_father_list);
834
835   return e_route;
836 }
837
838 static double _get_latency(const char *src, const char *dst)
839 {
840   double latency, latency_src, latency_dst = 0.0;
841
842   XBT_DEBUG("Solve route  \"%s\" to \"%s\"", src, dst);
843   xbt_assert(src && dst, "bad parameters for \"_get_route\" method");
844
845   route_extended_t e_route_cnt;
846
847   xbt_dynar_t elem_father_list = elements_father(src, dst);
848
849   routing_component_t common_father =
850       xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
851   routing_component_t src_father =
852       xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
853   routing_component_t dst_father =
854       xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
855
856   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
857
858       latency =
859           (*(common_father->get_latency)) (common_father, src, dst, NULL);
860       xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"", src,
861                   dst);
862
863   } else {                      /* SURF_ROUTING_RECURSIVE */
864      route_extended_t e_route_bypass = NULL;
865     if (common_father->get_bypass_route)
866       e_route_bypass =
867           (*(common_father->get_bypass_route)) (common_father, src, dst);
868
869     xbt_assert(!e_route_bypass,"Bypass cannot work yet with get_latency");
870                                                  
871     e_route_cnt =
872           (*(common_father->get_route)) (common_father, src_father->name,
873                                          dst_father->name);
874
875     xbt_assert(e_route_cnt, "no route between \"%s\" and \"%s\"",
876                 src_father->name, dst_father->name);
877
878     xbt_assert((e_route_cnt->src_gateway == NULL) ==
879                 (e_route_cnt->dst_gateway == NULL),
880                 "bad gateway for route between \"%s\" and \"%s\"", src,
881                 dst);
882
883     latency = (*(common_father->get_latency)) (common_father, src_father->name, dst_father->name, e_route_cnt);
884
885     xbt_assert(latency>=0, "no route between \"%s\" and \"%s\"",
886                 src_father->name, dst_father->name);
887
888     if (strcmp(src,e_route_cnt->src_gateway)) {
889
890       latency_src = _get_latency(src, e_route_cnt->src_gateway);
891       xbt_assert(latency_src>=0, "no route between \"%s\" and \"%s\"", src,
892                   e_route_cnt->src_gateway);
893       latency += latency_src;
894     }
895
896     if (strcmp(e_route_cnt->dst_gateway,dst)) {
897     
898       latency_dst = _get_latency(e_route_cnt->dst_gateway, dst);
899       xbt_assert(latency_dst>=0, "no route between \"%s\" and \"%s\"",
900                   e_route_cnt->dst_gateway, dst);
901       latency += latency_dst;
902     }
903         
904   }
905
906   xbt_dynar_free(&elem_father_list);
907
908   return latency;
909 }
910
911 /**
912  * \brief Generic method: find a route between hosts
913  *
914  * \param src the source host name 
915  * \param dst the destination host name
916  * 
917  * walk through the routing components tree and find a route between hosts
918  * by calling the differents "get_route" functions in each routing component.
919  * No need to free the returned dynar. It will be freed at the next call.
920  */
921 static xbt_dynar_t get_route(const char *src, const char *dst)
922 {
923
924   route_extended_t e_route;
925
926   e_route = _get_route(src, dst);
927   xbt_assert(e_route, "no route between \"%s\" and \"%s\"", src, dst);
928
929   if (global_routing->last_route)
930     xbt_dynar_free(&(global_routing->last_route));
931   global_routing->last_route = e_route->generic_route.link_list;
932
933   if (e_route->src_gateway)
934     xbt_free(e_route->src_gateway);
935   if (e_route->dst_gateway)
936     xbt_free(e_route->dst_gateway);
937
938   xbt_free(e_route);
939
940   return global_routing->last_route;
941 }
942
943 /**
944  * \brief Generic method: find a route between hosts
945  *
946  * \param src the source host name
947  * \param dst the destination host name
948  *
949  * walk through the routing components tree and find a route between hosts
950  * by calling the differents "get_route" functions in each routing component.
951  * Leaves the caller the responsability to clean the returned dynar.
952  */
953 static xbt_dynar_t get_route_no_cleanup(const char *src, const char *dst)
954 {
955         xbt_dynar_t d = get_route(src,dst);
956         global_routing->last_route = NULL;
957         return d;
958 }
959
960 /*Get Latency*/
961 static double get_latency(const char *src, const char *dst)
962 {
963
964   double latency = -1.0;
965   latency = _get_latency(src, dst);
966   xbt_assert(latency>=0.0, "no route between \"%s\" and \"%s\"", src, dst);
967   return latency;
968 }
969
970 /**
971  * \brief Recursive function for finalize
972  *
973  * \param rc the source host name 
974  * 
975  * This fuction is call by "finalize". It allow to finalize the 
976  * AS or routing components. It delete all the structures.
977  */
978 static void _finalize(routing_component_t rc)
979 {
980   if (rc) {
981     xbt_dict_cursor_t cursor = NULL;
982     char *key;
983     routing_component_t elem;
984     xbt_dict_foreach(rc->routing_sons, cursor, key, elem) {
985       _finalize(elem);
986     }
987     xbt_dict_t tmp_sons = rc->routing_sons;
988     char *tmp_name = rc->name;
989     xbt_dict_free(&tmp_sons);
990     xbt_free(tmp_name);
991     xbt_assert(rc->finalize, "no defined method \"finalize\" in \"%s\"",
992                 current_routing->name);
993     (*(rc->finalize)) (rc);
994   }
995 }
996
997 /**
998  * \brief Generic method: delete all the routing structures
999  * 
1000  * walk through the routing components tree and delete the structures
1001  * by calling the differents "finalize" functions in each routing component
1002  */
1003 static void finalize(void)
1004 {
1005   /* delete recursibly all the tree */
1006   _finalize(global_routing->root);
1007   /* delete last_route */
1008   xbt_dynar_free(&(global_routing->last_route));
1009   /* delete global routing structure */
1010   xbt_free(global_routing);
1011 }
1012
1013 static xbt_dynar_t recursive_get_onelink_routes(routing_component_t rc)
1014 {
1015   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
1016
1017   //adding my one link routes
1018   unsigned int cpt;
1019   void *link;
1020   xbt_dynar_t onelink_mine = rc->get_onelink_routes(rc);
1021   if (onelink_mine) {
1022     xbt_dynar_foreach(onelink_mine, cpt, link) {
1023       xbt_dynar_push(ret, &link);
1024     }
1025   }
1026   //recursing
1027   char *key;
1028   xbt_dict_cursor_t cursor = NULL;
1029   routing_component_t rc_child;
1030   xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
1031     xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
1032     if (onelink_child) {
1033       xbt_dynar_foreach(onelink_child, cpt, link) {
1034         xbt_dynar_push(ret, &link);
1035       }
1036     }
1037   }
1038   return ret;
1039 }
1040
1041 static xbt_dynar_t get_onelink_routes(void)
1042 {
1043   return recursive_get_onelink_routes(global_routing->root);
1044 }
1045
1046 e_surf_network_element_type_t get_network_element_type(const char
1047                                                               *name)
1048 {
1049   network_element_info_t rc = NULL;
1050
1051   rc = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
1052   if(rc) return rc->rc_type;
1053
1054   rc = xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
1055   if(rc) return rc->rc_type;
1056
1057   return SURF_NETWORK_ELEMENT_NULL;
1058 }
1059
1060 /**
1061  * \brief Generic method: create the global routing schema
1062  * 
1063  * Make a global routing structure and set all the parsing functions.
1064  */
1065 void routing_model_create(size_t size_of_links, void *loopback, double_f_cpvoid_t get_link_latency_fun)
1066 {
1067   /* config the uniq global routing */
1068   global_routing = xbt_new0(s_routing_global_t, 1);
1069   global_routing->root = NULL;
1070   global_routing->get_route = get_route;
1071   global_routing->get_latency = get_latency;
1072   global_routing->get_route_no_cleanup = get_route_no_cleanup;
1073   global_routing->get_onelink_routes = get_onelink_routes;
1074   global_routing->get_network_element_type = get_network_element_type;
1075   global_routing->finalize = finalize;
1076   global_routing->loopback = loopback;
1077   global_routing->size_of_link = size_of_links;
1078   global_routing->last_route = NULL;
1079   get_link_latency = get_link_latency_fun;
1080   /* no current routing at moment */
1081   current_routing = NULL;
1082
1083   /* parse generic elements */
1084   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_S_host_XML);
1085   surfxml_add_callback(ETag_surfxml_host_cb_list, &parse_E_host_XML);
1086   surfxml_add_callback(STag_surfxml_router_cb_list, &parse_S_router_XML);
1087
1088   surfxml_add_callback(STag_surfxml_route_cb_list,
1089                        &parse_S_route_new_and_endpoints_XML);
1090   surfxml_add_callback(STag_surfxml_ASroute_cb_list,
1091                        &parse_S_ASroute_new_and_endpoints);
1092   surfxml_add_callback(STag_surfxml_bypassRoute_cb_list,
1093                        &parse_S_bypassRoute_new_and_endpoints);
1094
1095   surfxml_add_callback(ETag_surfxml_link_ctn_cb_list,
1096                        &parse_E_link_ctn_new_elem_XML);
1097
1098   surfxml_add_callback(ETag_surfxml_route_cb_list,
1099                        &parse_E_route_store_route);
1100   surfxml_add_callback(ETag_surfxml_ASroute_cb_list,
1101                        &parse_E_ASroute_store_route);
1102   surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list,
1103                        &parse_E_bypassRoute_store_route);
1104
1105   surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
1106   surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
1107
1108   surfxml_add_callback(STag_surfxml_cluster_cb_list,
1109                        &routing_parse_Scluster);
1110
1111   surfxml_add_callback(STag_surfxml_peer_cb_list,
1112                          &routing_parse_Speer);
1113
1114   surfxml_add_callback(ETag_surfxml_platform_cb_list,
1115                                                   &clean_dict_random);
1116
1117 #ifdef HAVE_TRACING
1118   instr_routing_define_callbacks();
1119 #endif
1120 }
1121
1122 void surf_parse_add_callback_config(void)
1123 {
1124         surfxml_add_callback(STag_surfxml_config_cb_list, &routing_parse_Sconfig);
1125         surfxml_add_callback(ETag_surfxml_config_cb_list, &routing_parse_Econfig);
1126         surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties_XML);
1127         surfxml_add_callback(STag_surfxml_AS_cb_list, &surf_parse_models_setup);
1128         surfxml_add_callback(STag_surfxml_random_cb_list, &routing_parse_Srandom);
1129 }
1130
1131 void surf_parse_models_setup()
1132 {
1133         routing_parse_Erandom();
1134         surfxml_del_callback(STag_surfxml_AS_cb_list, surf_parse_models_setup);
1135         surf_config_models_setup(platform_filename);
1136         free(platform_filename);
1137 }
1138
1139 /* ************************************************************************** */
1140 /* *************************** FULL ROUTING ********************************* */
1141
1142 #define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
1143
1144 /* Routing model structure */
1145
1146 typedef struct {
1147   s_routing_component_t generic_routing;
1148   route_extended_t *routing_table;
1149 } s_routing_component_full_t, *routing_component_full_t;
1150
1151 /* Business methods */
1152 static xbt_dynar_t full_get_onelink_routes(routing_component_t rc)
1153 {
1154   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
1155
1156   routing_component_full_t routing = (routing_component_full_t) rc;
1157   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1158   xbt_dict_cursor_t c1 = NULL, c2 = NULL;
1159   char *k1, *d1, *k2, *d2;
1160   xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
1161     xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
1162       int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k1);
1163       int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k2);
1164       xbt_assert(src_id
1165                   && dst_id,
1166                   "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",
1167                   src, dst);
1168       route_extended_t route = TO_ROUTE_FULL(*src_id, *dst_id);
1169       if (route) {
1170         if (xbt_dynar_length(route->generic_route.link_list) == 1) {
1171           void *link =
1172               *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
1173                                            0);
1174           onelink_t onelink = xbt_new0(s_onelink_t, 1);
1175           onelink->link_ptr = link;
1176           if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
1177             onelink->src = xbt_strdup(k1);
1178             onelink->dst = xbt_strdup(k2);
1179           } else if (routing->generic_routing.hierarchy ==
1180                      SURF_ROUTING_RECURSIVE) {
1181             onelink->src = xbt_strdup(route->src_gateway);
1182             onelink->dst = xbt_strdup(route->dst_gateway);
1183           }
1184           xbt_dynar_push(ret, &onelink);
1185         }
1186       }
1187     }
1188   }
1189   return ret;
1190 }
1191
1192 static route_extended_t full_get_route(routing_component_t rc,
1193                                        const char *src, const char *dst)
1194 {
1195   xbt_assert(rc && src
1196               && dst,
1197               "Invalid params for \"get_route\" function at AS \"%s\"",
1198               rc->name);
1199
1200   /* set utils vars */
1201   routing_component_full_t routing = (routing_component_full_t) rc;
1202   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1203
1204   int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1205   int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1206   xbt_assert(src_id
1207               && dst_id,
1208               "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",
1209               src, dst);
1210
1211   route_extended_t e_route = NULL;
1212   route_extended_t new_e_route = NULL;
1213   void *link;
1214   unsigned int cpt = 0;
1215
1216   e_route = TO_ROUTE_FULL(*src_id, *dst_id);
1217
1218   if (e_route) {
1219     new_e_route = xbt_new0(s_route_extended_t, 1);
1220     new_e_route->src_gateway = xbt_strdup(e_route->src_gateway);
1221     new_e_route->dst_gateway = xbt_strdup(e_route->dst_gateway);
1222     new_e_route->generic_route.link_list =
1223         xbt_dynar_new(global_routing->size_of_link, NULL);
1224     xbt_dynar_foreach(e_route->generic_route.link_list, cpt, link) {
1225       xbt_dynar_push(new_e_route->generic_route.link_list, &link);
1226     }
1227   }
1228   return new_e_route;
1229 }
1230
1231 static void full_finalize(routing_component_t rc)
1232 {
1233   routing_component_full_t routing = (routing_component_full_t) rc;
1234   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1235   int i, j;
1236   if (routing) {
1237     /* Delete routing table */
1238     for (i = 0; i < table_size; i++)
1239       for (j = 0; j < table_size; j++)
1240         generic_free_extended_route(TO_ROUTE_FULL(i, j));
1241     xbt_free(routing->routing_table);
1242     /* Delete bypass dict */
1243     xbt_dict_free(&rc->bypassRoutes);
1244     /* Delete index dict */
1245     xbt_dict_free(&rc->to_index);
1246     /* Delete structure */
1247     xbt_free(rc);
1248   }
1249 }
1250
1251 /* Creation routing model functions */
1252
1253 static void *model_full_create(void)
1254 {
1255   routing_component_full_t new_component =
1256       xbt_new0(s_routing_component_full_t, 1);
1257   new_component->generic_routing.set_processing_unit =
1258       generic_set_processing_unit;
1259   new_component->generic_routing.set_autonomous_system =
1260       generic_set_autonomous_system;
1261   new_component->generic_routing.set_route = model_full_set_route;
1262   new_component->generic_routing.set_ASroute = model_full_set_route;
1263   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1264   new_component->generic_routing.get_route = full_get_route;
1265   new_component->generic_routing.get_latency = generic_get_link_latency;
1266   new_component->generic_routing.get_onelink_routes =
1267       full_get_onelink_routes;
1268   new_component->generic_routing.get_bypass_route =
1269       generic_get_bypassroute;
1270   new_component->generic_routing.finalize = full_finalize;
1271   new_component->generic_routing.to_index = xbt_dict_new();
1272   new_component->generic_routing.bypassRoutes = xbt_dict_new();
1273   new_component->generic_routing.get_network_element_type = get_network_element_type;
1274   return new_component;
1275 }
1276
1277 static void model_full_load(void)
1278 {
1279   /* use "surfxml_add_callback" to add a parse function call */
1280 }
1281
1282 static void model_full_unload(void)
1283 {
1284   /* use "surfxml_del_callback" to remove a parse function call */
1285 }
1286
1287 static void model_full_end(void)
1288 {
1289   unsigned int i;
1290   route_extended_t e_route;
1291
1292   /* set utils vars */
1293   routing_component_full_t routing =
1294       ((routing_component_full_t) current_routing);
1295   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1296
1297   /* Create table if necessary */
1298   if(!routing->routing_table)
1299           routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
1300
1301   /* Add the loopback if needed */
1302   if (current_routing->hierarchy == SURF_ROUTING_BASE) {
1303     for (i = 0; i < table_size; i++) {
1304       e_route = TO_ROUTE_FULL(i, i);
1305       if (!e_route) {
1306         e_route = xbt_new0(s_route_extended_t, 1);
1307         e_route->src_gateway = NULL;
1308         e_route->dst_gateway = NULL;
1309         e_route->generic_route.link_list =
1310             xbt_dynar_new(global_routing->size_of_link, NULL);
1311         xbt_dynar_push(e_route->generic_route.link_list,
1312                        &global_routing->loopback);
1313         TO_ROUTE_FULL(i, i) = e_route;
1314       }
1315     }
1316   }
1317 }
1318
1319 static void model_full_set_route(routing_component_t rc, const char *src,
1320                 const char *dst, name_route_extended_t route)
1321 {
1322         int *src_id, *dst_id;
1323         src_id = xbt_dict_get_or_null(rc->to_index, src);
1324         dst_id = xbt_dict_get_or_null(rc->to_index, dst);
1325         routing_component_full_t routing = ((routing_component_full_t) rc);
1326         size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1327
1328         xbt_assert(src_id
1329                           && dst_id, "Network elements %s or %s not found", src, dst);
1330
1331         xbt_assert(xbt_dynar_length(route->generic_route.link_list) > 0,
1332                           "Invalid count of links, must be greater than zero (%s,%s)",
1333                           src, dst);
1334
1335         if(!routing->routing_table)
1336                 routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
1337
1338         if(TO_ROUTE_FULL(*src_id, *dst_id))
1339         {
1340                 char * link_name;
1341                 unsigned int i;
1342                 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1343                 xbt_dynar_foreach(route->generic_route.link_list,i,link_name)
1344                 {
1345                         void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1346                         xbt_assert(link,"Link : '%s' doesn't exists.",link_name);
1347                         xbt_dynar_push(link_route_to_test,&link);
1348                 }
1349                 xbt_assert(!xbt_dynar_compare(
1350                           (void*)TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list,
1351                           (void*)link_route_to_test,
1352                           (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1353                           "The route between \"%s\" and \"%s\" already exists. If you are trying to define a reverse route, you must set the symmetrical=no attribute to your routes tags.", src,dst);
1354         }
1355         else
1356         {
1357                   if(!route->dst_gateway && !route->src_gateway)
1358                           XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
1359                   else{
1360                           XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1361                                  route->src_gateway, dst, route->dst_gateway);
1362                           if(global_routing->get_network_element_type((const char*)route->dst_gateway) == SURF_NETWORK_ELEMENT_NULL)
1363                                   xbt_die("The dst_gateway '%s' does not exist!",route->dst_gateway);
1364                           if(global_routing->get_network_element_type((const char*)route->src_gateway) == SURF_NETWORK_ELEMENT_NULL)
1365                                   xbt_die("The src_gateway '%s' does not exist!",route->src_gateway);
1366                   }
1367               TO_ROUTE_FULL(*src_id, *dst_id) = generic_new_extended_route(rc->hierarchy,route,1);
1368               xbt_dynar_shrink(TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list, 0);
1369         }
1370
1371         if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
1372                 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
1373         {
1374                 if(route->dst_gateway && route->src_gateway)
1375                 {
1376                   char *gw_tmp ;
1377                   gw_tmp = route->src_gateway;
1378                   route->src_gateway = route->dst_gateway;
1379                   route->dst_gateway = gw_tmp;
1380                 }
1381                 if(TO_ROUTE_FULL(*dst_id, *src_id))
1382                 {
1383                         char * link_name;
1384                         unsigned int i;
1385                         xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1386                         for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
1387                         {
1388                                 link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
1389                                 void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1390                                 xbt_assert(link,"Link : '%s' doesn't exists.",link_name);
1391                                 xbt_dynar_push(link_route_to_test,&link);
1392                         }
1393                         xbt_assert(!xbt_dynar_compare(
1394                                   (void*)TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list,
1395                               (void*)link_route_to_test,
1396                                   (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1397                                   "The route between \"%s\" and \"%s\" already exists", src,dst);
1398                 }
1399                 else
1400                 {
1401                           if(!route->dst_gateway && !route->src_gateway)
1402                                   XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
1403                           else
1404                                   XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1405                                          route->src_gateway, src, route->dst_gateway);
1406                       TO_ROUTE_FULL(*dst_id, *src_id) = generic_new_extended_route(rc->hierarchy,route,0);
1407                       xbt_dynar_shrink(TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list, 0);
1408                 }
1409         }
1410
1411         if (rc->hierarchy == SURF_ROUTING_BASE) generic_free_route((route_t)route) ;
1412         else generic_free_extended_route((route_extended_t)route);
1413 }
1414
1415 /* ************************************************************************** */
1416 /* *************************** FLOYD ROUTING ******************************** */
1417
1418 #define TO_FLOYD_COST(i,j) (routing->cost_table)[(i)+(j)*table_size]
1419 #define TO_FLOYD_PRED(i,j) (routing->predecessor_table)[(i)+(j)*table_size]
1420 #define TO_FLOYD_LINK(i,j) (routing->link_table)[(i)+(j)*table_size]
1421
1422 /* Routing model structure */
1423
1424 typedef struct {
1425   s_routing_component_t generic_routing;
1426   /* vars for calculate the floyd algorith. */
1427   int *predecessor_table;
1428   double *cost_table;
1429   route_extended_t *link_table; /* char* -> int* */
1430 } s_routing_component_floyd_t, *routing_component_floyd_t;
1431
1432 static route_extended_t floyd_get_route(routing_component_t rc,
1433                                         const char *src, const char *dst);
1434
1435 /* Business methods */
1436 static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
1437 {
1438   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
1439
1440   routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1441   //size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1442   xbt_dict_cursor_t c1 = NULL, c2 = NULL;
1443   char *k1, *d1, *k2, *d2;
1444   xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
1445     xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
1446       route_extended_t route = floyd_get_route(rc, k1, k2);
1447       if (route) {
1448         if (xbt_dynar_length(route->generic_route.link_list) == 1) {
1449           void *link =
1450               *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
1451                                            0);
1452           onelink_t onelink = xbt_new0(s_onelink_t, 1);
1453           onelink->link_ptr = link;
1454           if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
1455             onelink->src = xbt_strdup(k1);
1456             onelink->dst = xbt_strdup(k2);
1457           } else if (routing->generic_routing.hierarchy ==
1458                      SURF_ROUTING_RECURSIVE) {
1459             onelink->src = xbt_strdup(route->src_gateway);
1460             onelink->dst = xbt_strdup(route->dst_gateway);
1461           }
1462           xbt_dynar_push(ret, &onelink);
1463         }
1464       }
1465     }
1466   }
1467   return ret;
1468 }
1469
1470 static route_extended_t floyd_get_route(routing_component_t rc,
1471                                         const char *src, const char *dst)
1472 {
1473   xbt_assert(rc && src
1474               && dst,
1475               "Invalid params for \"get_route\" function at AS \"%s\"",
1476               rc->name);
1477
1478   /* set utils vars */
1479   routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1480   size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1481
1482   generic_src_dst_check(rc, src, dst);
1483   int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1484   int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1485   xbt_assert(src_id
1486               && dst_id,
1487               "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",
1488               src, dst);
1489
1490   /* create a result route */
1491   route_extended_t new_e_route = xbt_new0(s_route_extended_t, 1);
1492   new_e_route->generic_route.link_list =
1493       xbt_dynar_new(global_routing->size_of_link, NULL);
1494   new_e_route->src_gateway = NULL;
1495   new_e_route->dst_gateway = NULL;
1496
1497   int first = 1;
1498   int pred = *dst_id;
1499   int prev_pred = 0;
1500   char *gw_src = NULL, *gw_dst =
1501       NULL, *prev_gw_src, *prev_gw_dst, *first_gw = NULL;
1502   unsigned int cpt;
1503   void *link;
1504   xbt_dynar_t links;
1505
1506   do {
1507     prev_pred = pred;
1508     pred = TO_FLOYD_PRED(*src_id, pred);
1509     if (pred == -1)             /* if no pred in route -> no route to host */
1510       break;
1511     xbt_assert(TO_FLOYD_LINK(pred, prev_pred),
1512                 "Invalid link for the route between \"%s\" or \"%s\"", src,
1513                 dst);
1514
1515     prev_gw_src = gw_src;
1516     prev_gw_dst = gw_dst;
1517
1518     route_extended_t e_route = TO_FLOYD_LINK(pred, prev_pred);
1519     gw_src = e_route->src_gateway;
1520     gw_dst = e_route->dst_gateway;
1521
1522     if (first)
1523       first_gw = gw_dst;
1524
1525     if (rc->hierarchy == SURF_ROUTING_RECURSIVE && !first
1526         && strcmp(gw_dst, prev_gw_src)) {
1527       xbt_dynar_t e_route_as_to_as =
1528           (*(global_routing->get_route)) (gw_dst, prev_gw_src);
1529       xbt_assert(e_route_as_to_as, "no route between \"%s\" and \"%s\"",
1530                   gw_dst, prev_gw_src);
1531       links = e_route_as_to_as;
1532       int pos = 0;
1533       xbt_dynar_foreach(links, cpt, link) {
1534         xbt_dynar_insert_at(new_e_route->generic_route.link_list, pos,
1535                             &link);
1536         pos++;
1537       }
1538     }
1539
1540     links = e_route->generic_route.link_list;
1541     xbt_dynar_foreach(links, cpt, link) {
1542       xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
1543     }
1544     first = 0;
1545
1546   } while (pred != *src_id);
1547   xbt_assert(pred != -1, "no route from host %d to %d (\"%s\" to \"%s\")",
1548               *src_id, *dst_id, src, dst);
1549
1550   if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1551     new_e_route->src_gateway = xbt_strdup(gw_src);
1552     new_e_route->dst_gateway = xbt_strdup(first_gw);
1553   }
1554
1555   return new_e_route;
1556 }
1557
1558 static void floyd_finalize(routing_component_t rc)
1559 {
1560   routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1561   int i, j;
1562   size_t table_size;
1563   if (routing) {
1564     table_size = xbt_dict_length(routing->generic_routing.to_index);
1565     /* Delete link_table */
1566     for (i = 0; i < table_size; i++)
1567       for (j = 0; j < table_size; j++)
1568         generic_free_extended_route(TO_FLOYD_LINK(i, j));
1569     xbt_free(routing->link_table);
1570     /* Delete bypass dict */
1571     xbt_dict_free(&routing->generic_routing.bypassRoutes);
1572     /* Delete index dict */
1573     xbt_dict_free(&(routing->generic_routing.to_index));
1574     /* Delete dictionary index dict, predecessor and links table */
1575     xbt_free(routing->predecessor_table);
1576     /* Delete structure */
1577     xbt_free(rc);
1578   }
1579 }
1580
1581 static void *model_floyd_create(void)
1582 {
1583   routing_component_floyd_t new_component =
1584       xbt_new0(s_routing_component_floyd_t, 1);
1585   new_component->generic_routing.set_processing_unit =
1586       generic_set_processing_unit;
1587   new_component->generic_routing.set_autonomous_system =
1588       generic_set_autonomous_system;
1589   new_component->generic_routing.set_route = model_floyd_set_route;
1590   new_component->generic_routing.set_ASroute = model_floyd_set_route;
1591   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1592   new_component->generic_routing.get_route = floyd_get_route;
1593   new_component->generic_routing.get_latency = generic_get_link_latency;
1594   new_component->generic_routing.get_onelink_routes =
1595       floyd_get_onelink_routes;
1596   new_component->generic_routing.get_bypass_route =
1597       generic_get_bypassroute;
1598   new_component->generic_routing.finalize = floyd_finalize;
1599   new_component->generic_routing.to_index = xbt_dict_new();
1600   new_component->generic_routing.bypassRoutes = xbt_dict_new();
1601   new_component->generic_routing.get_network_element_type = get_network_element_type;
1602   return new_component;
1603 }
1604
1605 static void model_floyd_load(void)
1606 {
1607   /* use "surfxml_add_callback" to add a parse function call */
1608 }
1609
1610 static void model_floyd_unload(void)
1611 {
1612   /* use "surfxml_del_callback" to remove a parse function call */
1613 }
1614
1615 static void model_floyd_end(void)
1616 {
1617
1618         routing_component_floyd_t routing =
1619           ((routing_component_floyd_t) current_routing);
1620
1621         unsigned int i, j, a, b, c;
1622
1623         /* set the size of table routing */
1624         size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1625
1626         if(!routing->link_table)
1627         {
1628                 /* Create Cost, Predecessor and Link tables */
1629                 routing->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
1630                 routing->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
1631                 routing->link_table = xbt_new0(route_extended_t, table_size * table_size);    /* actual link between src and dst */
1632
1633                 /* Initialize costs and predecessors */
1634                 for (i = 0; i < table_size; i++)
1635                 for (j = 0; j < table_size; j++) {
1636                   TO_FLOYD_COST(i, j) = DBL_MAX;
1637                   TO_FLOYD_PRED(i, j) = -1;
1638                   TO_FLOYD_LINK(i, j) = NULL;       /* fixed, missing in the previous version */
1639                 }
1640         }
1641
1642         /* Add the loopback if needed */
1643         if (current_routing->hierarchy == SURF_ROUTING_BASE) {
1644                 for (i = 0; i < table_size; i++) {
1645                   route_extended_t e_route = TO_FLOYD_LINK(i, i);
1646                   if (!e_route) {
1647                         e_route = xbt_new0(s_route_extended_t, 1);
1648                         e_route->src_gateway = NULL;
1649                         e_route->dst_gateway = NULL;
1650                         e_route->generic_route.link_list =
1651                                 xbt_dynar_new(global_routing->size_of_link, NULL);
1652                         xbt_dynar_push(e_route->generic_route.link_list,
1653                                                    &global_routing->loopback);
1654                         TO_FLOYD_LINK(i, i) = e_route;
1655                         TO_FLOYD_PRED(i, i) = i;
1656                         TO_FLOYD_COST(i, i) = 1;
1657                   }
1658                 }
1659         }
1660         /* Calculate path costs */
1661         for (c = 0; c < table_size; c++) {
1662                 for (a = 0; a < table_size; a++) {
1663                   for (b = 0; b < table_size; b++) {
1664                         if (TO_FLOYD_COST(a, c) < DBL_MAX && TO_FLOYD_COST(c, b) < DBL_MAX) {
1665                           if (TO_FLOYD_COST(a, b) == DBL_MAX ||
1666                                   (TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b) <
1667                                    TO_FLOYD_COST(a, b))) {
1668                                 TO_FLOYD_COST(a, b) =
1669                                         TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b);
1670                                 TO_FLOYD_PRED(a, b) = TO_FLOYD_PRED(c, b);
1671                           }
1672                         }
1673                   }
1674                 }
1675         }
1676 }
1677
1678 static void model_floyd_set_route(routing_component_t rc, const char *src,
1679         const char *dst, name_route_extended_t route)
1680 {
1681         routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1682
1683         /* set the size of table routing */
1684         size_t table_size = xbt_dict_length(rc->to_index);
1685         int *src_id, *dst_id;
1686         int i,j;
1687
1688         src_id = xbt_dict_get_or_null(rc->to_index, src);
1689         dst_id = xbt_dict_get_or_null(rc->to_index, dst);
1690
1691         if(!routing->link_table)
1692         {
1693                 /* Create Cost, Predecessor and Link tables */
1694                 routing->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
1695                 routing->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
1696                 routing->link_table = xbt_new0(route_extended_t, table_size * table_size);    /* actual link between src and dst */
1697
1698                 /* Initialize costs and predecessors */
1699                 for (i = 0; i < table_size; i++)
1700                 for (j = 0; j < table_size; j++) {
1701                   TO_FLOYD_COST(i, j) = DBL_MAX;
1702                   TO_FLOYD_PRED(i, j) = -1;
1703                   TO_FLOYD_LINK(i, j) = NULL;       /* fixed, missing in the previous version */
1704                 }
1705         }
1706
1707         if(TO_FLOYD_LINK(*src_id, *dst_id))
1708         {
1709                 if(!route->dst_gateway && !route->src_gateway)
1710                         XBT_DEBUG("See Route from \"%s\" to \"%s\"", src, dst);
1711                 else
1712                         XBT_DEBUG("See ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1713                                  route->src_gateway, dst, route->dst_gateway);
1714                 char * link_name;
1715                 unsigned int cpt;
1716                 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1717                 xbt_dynar_foreach(route->generic_route.link_list,cpt,link_name)
1718                 {
1719                         void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1720                         xbt_assert(link,"Link : '%s' doesn't exists.",link_name);
1721                         xbt_dynar_push(link_route_to_test,&link);
1722                 }
1723                 xbt_assert(!xbt_dynar_compare(
1724                           (void*)TO_FLOYD_LINK(*src_id, *dst_id)->generic_route.link_list,
1725                           (void*)link_route_to_test,
1726                           (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1727                           "The route between \"%s\" and \"%s\" already exists", src,dst);
1728         }
1729         else
1730         {
1731                 if(!route->dst_gateway && !route->src_gateway)
1732                   XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
1733                 else{
1734                         XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1735                                  route->src_gateway, dst, route->dst_gateway);
1736                         if(global_routing->get_network_element_type((const char*)route->dst_gateway) == SURF_NETWORK_ELEMENT_NULL)
1737                                 xbt_die("The dst_gateway '%s' does not exist!",route->dst_gateway);
1738                         if(global_routing->get_network_element_type((const char*)route->src_gateway) == SURF_NETWORK_ELEMENT_NULL)
1739                                 xbt_die("The src_gateway '%s' does not exist!",route->src_gateway);
1740                 }
1741             TO_FLOYD_LINK(*src_id, *dst_id) =
1742                         generic_new_extended_route(rc->hierarchy, route, 1);
1743             TO_FLOYD_PRED(*src_id, *dst_id) = *src_id;
1744             TO_FLOYD_COST(*src_id, *dst_id) =
1745                         ((TO_FLOYD_LINK(*src_id, *dst_id))->generic_route.link_list)->used;   /* count of links, old model assume 1 */
1746         }
1747
1748         if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
1749                 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
1750         {
1751                 if(TO_FLOYD_LINK(*dst_id, *src_id))
1752                 {
1753                         if(!route->dst_gateway && !route->src_gateway)
1754                           XBT_DEBUG("See Route from \"%s\" to \"%s\"", dst, src);
1755                         else
1756                           XBT_DEBUG("See ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1757                                          route->src_gateway, src, route->dst_gateway);
1758                         char * link_name;
1759                         unsigned int i;
1760                         xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1761                         for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
1762                         {
1763                                 link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
1764                                 void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
1765                                 xbt_assert(link,"Link : '%s' doesn't exists.",link_name);
1766                                 xbt_dynar_push(link_route_to_test,&link);
1767                         }
1768                         xbt_assert(!xbt_dynar_compare(
1769                                   (void*)TO_FLOYD_LINK(*dst_id, *src_id)->generic_route.link_list,
1770                               (void*)link_route_to_test,
1771                                   (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1772                                   "The route between \"%s\" and \"%s\" already exists", src,dst);
1773                 }
1774                 else
1775                 {
1776                         if(route->dst_gateway && route->src_gateway)
1777                         {
1778                           char *gw_src = xbt_strdup(route->src_gateway);
1779                           char *gw_dst = xbt_strdup(route->dst_gateway);
1780                           route->src_gateway = gw_dst;
1781                           route->dst_gateway = gw_src;
1782                         }
1783
1784                         if(!route->dst_gateway && !route->src_gateway)
1785                           XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
1786                         else
1787                           XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1788                                          route->src_gateway, src, route->dst_gateway);
1789
1790                     TO_FLOYD_LINK(*dst_id, *src_id) =
1791                                 generic_new_extended_route(rc->hierarchy, route, 0);
1792                     TO_FLOYD_PRED(*dst_id, *src_id) = *dst_id;
1793                     TO_FLOYD_COST(*dst_id, *src_id) =
1794                                 ((TO_FLOYD_LINK(*dst_id, *src_id))->generic_route.link_list)->used;   /* count of links, old model assume 1 */
1795                 }
1796         }
1797 }
1798
1799 /* ************************************************************************** */
1800 /* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
1801
1802 typedef struct {
1803   s_routing_component_t generic_routing;
1804   xbt_graph_t route_graph;      /* xbt_graph */
1805   xbt_dict_t graph_node_map;    /* map */
1806   xbt_dict_t route_cache;       /* use in cache mode */
1807   int cached;
1808 } s_routing_component_dijkstra_t, *routing_component_dijkstra_t;
1809
1810
1811 typedef struct graph_node_data {
1812   int id;
1813   int graph_id;                 /* used for caching internal graph id's */
1814 } s_graph_node_data_t, *graph_node_data_t;
1815
1816 typedef struct graph_node_map_element {
1817   xbt_node_t node;
1818 } s_graph_node_map_element_t, *graph_node_map_element_t;
1819
1820 typedef struct route_cache_element {
1821   int *pred_arr;
1822   int size;
1823 } s_route_cache_element_t, *route_cache_element_t;
1824
1825 /* Free functions */
1826
1827 static void route_cache_elem_free(void *e)
1828 {
1829   route_cache_element_t elm = (route_cache_element_t) e;
1830   if (elm) {
1831     xbt_free(elm->pred_arr);
1832     xbt_free(elm);
1833   }
1834 }
1835
1836 static void graph_node_map_elem_free(void *e)
1837 {
1838   graph_node_map_element_t elm = (graph_node_map_element_t) e;
1839   if (elm) {
1840     xbt_free(elm);
1841   }
1842 }
1843
1844 static void graph_edge_data_free(void *e)
1845 {
1846   route_extended_t e_route = (route_extended_t) e;
1847   if (e_route) {
1848     xbt_dynar_free(&(e_route->generic_route.link_list));
1849     if (e_route->src_gateway)
1850       xbt_free(e_route->src_gateway);
1851     if (e_route->dst_gateway)
1852       xbt_free(e_route->dst_gateway);
1853     xbt_free(e_route);
1854   }
1855 }
1856
1857 /* Utility functions */
1858
1859 static xbt_node_t route_graph_new_node(routing_component_dijkstra_t rc,
1860                                        int id, int graph_id)
1861 {
1862   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1863   xbt_node_t node = NULL;
1864   graph_node_data_t data = NULL;
1865   graph_node_map_element_t elm = NULL;
1866
1867   data = xbt_new0(struct graph_node_data, 1);
1868   data->id = id;
1869   data->graph_id = graph_id;
1870   node = xbt_graph_new_node(routing->route_graph, data);
1871
1872   elm = xbt_new0(struct graph_node_map_element, 1);
1873   elm->node = node;
1874   xbt_dict_set_ext(routing->graph_node_map, (char *) (&id), sizeof(int),
1875                    (xbt_set_elm_t) elm, &graph_node_map_elem_free);
1876
1877   return node;
1878 }
1879
1880 static graph_node_map_element_t
1881 graph_node_map_search(routing_component_dijkstra_t rc, int id)
1882 {
1883   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1884   graph_node_map_element_t elm = (graph_node_map_element_t)
1885       xbt_dict_get_or_null_ext(routing->graph_node_map,
1886                                (char *) (&id),
1887                                sizeof(int));
1888   return elm;
1889 }
1890
1891 /* Parsing */
1892
1893 static void route_new_dijkstra(routing_component_dijkstra_t rc, int src_id,
1894                                int dst_id, route_extended_t e_route)
1895 {
1896   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1897   XBT_DEBUG("Load Route from \"%d\" to \"%d\"", src_id, dst_id);
1898   xbt_node_t src = NULL;
1899   xbt_node_t dst = NULL;
1900
1901   graph_node_map_element_t src_elm = (graph_node_map_element_t)
1902       xbt_dict_get_or_null_ext(routing->graph_node_map,
1903                                (char *) (&src_id),
1904                                sizeof(int));
1905   graph_node_map_element_t dst_elm = (graph_node_map_element_t)
1906       xbt_dict_get_or_null_ext(routing->graph_node_map,
1907                                (char *) (&dst_id),
1908                                sizeof(int));
1909
1910
1911   if (src_elm)
1912     src = src_elm->node;
1913
1914   if (dst_elm)
1915     dst = dst_elm->node;
1916
1917   /* add nodes if they don't exist in the graph */
1918   if (src_id == dst_id && src == NULL && dst == NULL) {
1919     src = route_graph_new_node(rc, src_id, -1);
1920     dst = src;
1921   } else {
1922     if (src == NULL) {
1923       src = route_graph_new_node(rc, src_id, -1);
1924     }
1925     if (dst == NULL) {
1926       dst = route_graph_new_node(rc, dst_id, -1);
1927     }
1928   }
1929
1930   /* add link as edge to graph */
1931   xbt_graph_new_edge(routing->route_graph, src, dst, e_route);
1932 }
1933
1934 static void add_loopback_dijkstra(routing_component_dijkstra_t rc)
1935 {
1936   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1937
1938   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1939
1940   xbt_node_t node = NULL;
1941   unsigned int cursor2;
1942   xbt_dynar_foreach(nodes, cursor2, node) {
1943     xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node);
1944     xbt_edge_t edge = NULL;
1945     unsigned int cursor;
1946
1947     int found = 0;
1948     xbt_dynar_foreach(out_edges, cursor, edge) {
1949       xbt_node_t other_node = xbt_graph_edge_get_target(edge);
1950       if (other_node == node) {
1951         found = 1;
1952         break;
1953       }
1954     }
1955
1956     if (!found) {
1957       route_extended_t e_route = xbt_new0(s_route_extended_t, 1);
1958       e_route->src_gateway = NULL;
1959       e_route->dst_gateway = NULL;
1960       e_route->generic_route.link_list =
1961           xbt_dynar_new(global_routing->size_of_link, NULL);
1962       xbt_dynar_push(e_route->generic_route.link_list,
1963                      &global_routing->loopback);
1964       xbt_graph_new_edge(routing->route_graph, node, node, e_route);
1965     }
1966   }
1967 }
1968
1969 /* Business methods */
1970 static xbt_dynar_t dijkstra_get_onelink_routes(routing_component_t rc)
1971 {
1972   xbt_die("\"dijkstra_get_onelink_routes\" function not implemented yet");
1973 }
1974
1975 static route_extended_t dijkstra_get_route(routing_component_t rc,
1976                                            const char *src,
1977                                            const char *dst)
1978 {
1979   xbt_assert(rc && src
1980               && dst,
1981               "Invalid params for \"get_route\" function at AS \"%s\"",
1982               rc->name);
1983
1984   /* set utils vars */
1985   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1986
1987   generic_src_dst_check(rc, src, dst);
1988   int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1989   int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1990   xbt_assert(src_id
1991               && dst_id,
1992               "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",
1993               src, dst);
1994
1995   /* create a result route */
1996   route_extended_t new_e_route = xbt_new0(s_route_extended_t, 1);
1997   new_e_route->generic_route.link_list =
1998       xbt_dynar_new(global_routing->size_of_link, NULL);
1999   new_e_route->src_gateway = NULL;
2000   new_e_route->dst_gateway = NULL;
2001
2002   int *pred_arr = NULL;
2003   int src_node_id = 0;
2004   int dst_node_id = 0;
2005   int *nodeid = NULL;
2006   int v;
2007   route_extended_t e_route;
2008   int size = 0;
2009   unsigned int cpt;
2010   void *link;
2011   xbt_dynar_t links = NULL;
2012   route_cache_element_t elm = NULL;
2013   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
2014
2015   /* Use the graph_node id mapping set to quickly find the nodes */
2016   graph_node_map_element_t src_elm =
2017       graph_node_map_search(routing, *src_id);
2018   graph_node_map_element_t dst_elm =
2019       graph_node_map_search(routing, *dst_id);
2020   xbt_assert(src_elm != NULL
2021               && dst_elm != NULL, "src %d or dst %d does not exist",
2022               *src_id, *dst_id);
2023   src_node_id = ((graph_node_data_t)
2024                  xbt_graph_node_get_data(src_elm->node))->graph_id;
2025   dst_node_id = ((graph_node_data_t)
2026                  xbt_graph_node_get_data(dst_elm->node))->graph_id;
2027
2028   /* if the src and dst are the same *//* fixed, missing in the previous version */
2029   if (src_node_id == dst_node_id) {
2030
2031     xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
2032     xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
2033     xbt_edge_t edge =
2034         xbt_graph_get_edge(routing->route_graph, node_s_v, node_e_v);
2035
2036     xbt_assert(edge != NULL, "no route between host %d and %d", *src_id,
2037                 *dst_id);
2038
2039     e_route = (route_extended_t) xbt_graph_edge_get_data(edge);
2040
2041     links = e_route->generic_route.link_list;
2042     xbt_dynar_foreach(links, cpt, link) {
2043       xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
2044     }
2045
2046     return new_e_route;
2047   }
2048
2049   if (routing->cached) {
2050     /*check if there is a cached predecessor list avail */
2051     elm = (route_cache_element_t)
2052         xbt_dict_get_or_null_ext(routing->route_cache, (char *) (&src_id),
2053                                  sizeof(int));
2054   }
2055
2056   if (elm) {                    /* cached mode and cache hit */
2057     pred_arr = elm->pred_arr;
2058   } else {                      /* not cached mode or cache miss */
2059     double *cost_arr = NULL;
2060     xbt_heap_t pqueue = NULL;
2061     int i = 0;
2062
2063     int nr_nodes = xbt_dynar_length(nodes);
2064     cost_arr = xbt_new0(double, nr_nodes);      /* link cost from src to other hosts */
2065     pred_arr = xbt_new0(int, nr_nodes); /* predecessors in path from src */
2066     pqueue = xbt_heap_new(nr_nodes, xbt_free);
2067
2068     /* initialize */
2069     cost_arr[src_node_id] = 0.0;
2070
2071     for (i = 0; i < nr_nodes; i++) {
2072       if (i != src_node_id) {
2073         cost_arr[i] = DBL_MAX;
2074       }
2075
2076       pred_arr[i] = 0;
2077
2078       /* initialize priority queue */
2079       nodeid = xbt_new0(int, 1);
2080       *nodeid = i;
2081       xbt_heap_push(pqueue, nodeid, cost_arr[i]);
2082
2083     }
2084
2085     /* apply dijkstra using the indexes from the graph's node array */
2086     while (xbt_heap_size(pqueue) > 0) {
2087       int *v_id = xbt_heap_pop(pqueue);
2088       xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
2089       xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node);
2090       xbt_edge_t edge = NULL;
2091       unsigned int cursor;
2092
2093       xbt_dynar_foreach(out_edges, cursor, edge) {
2094         xbt_node_t u_node = xbt_graph_edge_get_target(edge);
2095         graph_node_data_t data = xbt_graph_node_get_data(u_node);
2096         int u_id = data->graph_id;
2097         route_extended_t tmp_e_route =
2098             (route_extended_t) xbt_graph_edge_get_data(edge);
2099         int cost_v_u = (tmp_e_route->generic_route.link_list)->used;    /* count of links, old model assume 1 */
2100
2101         if (cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
2102           pred_arr[u_id] = *v_id;
2103           cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
2104           nodeid = xbt_new0(int, 1);
2105           *nodeid = u_id;
2106           xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
2107         }
2108       }
2109
2110       /* free item popped from pqueue */
2111       xbt_free(v_id);
2112     }
2113
2114     xbt_free(cost_arr);
2115     xbt_heap_free(pqueue);
2116   }
2117
2118   /* compose route path with links */
2119   char *gw_src = NULL, *gw_dst =
2120       NULL, *prev_gw_src, *prev_gw_dst, *first_gw = NULL;
2121
2122   for (v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
2123     xbt_node_t node_pred_v =
2124         xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
2125     xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
2126     xbt_edge_t edge =
2127         xbt_graph_get_edge(routing->route_graph, node_pred_v, node_v);
2128
2129     xbt_assert(edge != NULL, "no route between host %d and %d", *src_id,
2130                 *dst_id);
2131
2132     prev_gw_src = gw_src;
2133     prev_gw_dst = gw_dst;
2134
2135     e_route = (route_extended_t) xbt_graph_edge_get_data(edge);
2136     gw_src = e_route->src_gateway;
2137     gw_dst = e_route->dst_gateway;
2138
2139     if (v == dst_node_id)
2140       first_gw = gw_dst;
2141
2142     if (rc->hierarchy == SURF_ROUTING_RECURSIVE && v != dst_node_id
2143         && strcmp(gw_dst, prev_gw_src)) {
2144       xbt_dynar_t e_route_as_to_as =
2145           (*(global_routing->get_route)) (gw_dst, prev_gw_src);
2146       xbt_assert(e_route_as_to_as, "no route between \"%s\" and \"%s\"",
2147                   gw_dst, prev_gw_src);
2148       links = e_route_as_to_as;
2149       int pos = 0;
2150       xbt_dynar_foreach(links, cpt, link) {
2151         xbt_dynar_insert_at(new_e_route->generic_route.link_list, pos,
2152                             &link);
2153         pos++;
2154       }
2155     }
2156
2157     links = e_route->generic_route.link_list;
2158     xbt_dynar_foreach(links, cpt, link) {
2159       xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
2160     }
2161     size++;
2162   }
2163
2164   if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
2165     new_e_route->src_gateway = xbt_strdup(gw_src);
2166     new_e_route->dst_gateway = xbt_strdup(first_gw);
2167   }
2168
2169   if (routing->cached && elm == NULL) {
2170     /* add to predecessor list of the current src-host to cache */
2171     elm = xbt_new0(struct route_cache_element, 1);
2172     elm->pred_arr = pred_arr;
2173     elm->size = size;
2174     xbt_dict_set_ext(routing->route_cache, (char *) (&src_id), sizeof(int),
2175                      (xbt_set_elm_t) elm, &route_cache_elem_free);
2176   }
2177
2178   if (!routing->cached)
2179     xbt_free(pred_arr);
2180
2181   return new_e_route;
2182 }
2183
2184 static void dijkstra_finalize(routing_component_t rc)
2185 {
2186   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
2187
2188   if (routing) {
2189     xbt_graph_free_graph(routing->route_graph, &xbt_free,
2190                          &graph_edge_data_free, &xbt_free);
2191     xbt_dict_free(&routing->graph_node_map);
2192     if (routing->cached)
2193       xbt_dict_free(&routing->route_cache);
2194     /* Delete bypass dict */
2195     xbt_dict_free(&routing->generic_routing.bypassRoutes);
2196     /* Delete index dict */
2197     xbt_dict_free(&(routing->generic_routing.to_index));
2198     /* Delete structure */
2199     xbt_free(routing);
2200   }
2201 }
2202
2203 /* Creation routing model functions */
2204
2205 static void *model_dijkstra_both_create(int cached)
2206 {
2207   routing_component_dijkstra_t new_component =
2208       xbt_new0(s_routing_component_dijkstra_t, 1);
2209   new_component->generic_routing.set_processing_unit =
2210       generic_set_processing_unit;
2211   new_component->generic_routing.set_autonomous_system =
2212       generic_set_autonomous_system;
2213   new_component->generic_routing.set_route = model_dijkstra_both_set_route;
2214   new_component->generic_routing.set_ASroute = model_dijkstra_both_set_route;
2215   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
2216   new_component->generic_routing.get_route = dijkstra_get_route;
2217   new_component->generic_routing.get_latency = generic_get_link_latency;
2218   new_component->generic_routing.get_onelink_routes =
2219       dijkstra_get_onelink_routes;
2220   new_component->generic_routing.get_bypass_route =
2221       generic_get_bypassroute;
2222   new_component->generic_routing.finalize = dijkstra_finalize;
2223   new_component->cached = cached;
2224   new_component->generic_routing.to_index = xbt_dict_new();
2225   new_component->generic_routing.bypassRoutes = xbt_dict_new();
2226   new_component->generic_routing.get_network_element_type = get_network_element_type;
2227   return new_component;
2228 }
2229
2230 static void *model_dijkstra_create(void)
2231 {
2232   return model_dijkstra_both_create(0);
2233 }
2234
2235 static void *model_dijkstracache_create(void)
2236 {
2237   return model_dijkstra_both_create(1);
2238 }
2239
2240 static void model_dijkstra_both_load(void)
2241 {
2242   /* use "surfxml_add_callback" to add a parse function call */
2243 }
2244
2245 static void model_dijkstra_both_unload(void)
2246 {
2247   /* use "surfxml_del_callback" to remove a parse function call */
2248 }
2249
2250 static void model_dijkstra_both_end(void)
2251 {
2252   routing_component_dijkstra_t routing =
2253       (routing_component_dijkstra_t) current_routing;
2254
2255   xbt_node_t node = NULL;
2256   unsigned int cursor2;
2257   xbt_dynar_t nodes = NULL;
2258
2259   /* Create the topology graph */
2260   if(!routing->route_graph)
2261   routing->route_graph = xbt_graph_new_graph(1, NULL);
2262   if(!routing->graph_node_map)
2263   routing->graph_node_map = xbt_dict_new();
2264
2265   if (routing->cached && !routing->route_cache)
2266   routing->route_cache = xbt_dict_new();
2267
2268   /* Add the loopback if needed */
2269   if (current_routing->hierarchy == SURF_ROUTING_BASE)
2270     add_loopback_dijkstra(routing);
2271
2272   /* initialize graph indexes in nodes after graph has been built */
2273   nodes = xbt_graph_get_nodes(routing->route_graph);
2274
2275   xbt_dynar_foreach(nodes, cursor2, node) {
2276     graph_node_data_t data = xbt_graph_node_get_data(node);
2277     data->graph_id = cursor2;
2278   }
2279
2280 }
2281 static void model_dijkstra_both_set_route (routing_component_t rc, const char *src,
2282                      const char *dst, name_route_extended_t route)
2283 {
2284         routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
2285         int *src_id, *dst_id;
2286         src_id = xbt_dict_get_or_null(rc->to_index, src);
2287         dst_id = xbt_dict_get_or_null(rc->to_index, dst);
2288
2289     /* Create the topology graph */
2290         if(!routing->route_graph)
2291         routing->route_graph = xbt_graph_new_graph(1, NULL);
2292         if(!routing->graph_node_map)
2293         routing->graph_node_map = xbt_dict_new();
2294
2295         if (routing->cached && !routing->route_cache)
2296         routing->route_cache = xbt_dict_new();
2297
2298         if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
2299                 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
2300                 xbt_die("Route symmetrical not supported on model dijkstra");
2301
2302         if(!route->dst_gateway && !route->src_gateway)
2303           XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
2304         else{
2305           XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
2306                          route->src_gateway, dst, route->dst_gateway);
2307           if(global_routing->get_network_element_type((const char*)route->dst_gateway) == SURF_NETWORK_ELEMENT_NULL)
2308                   xbt_die("The dst_gateway '%s' does not exist!",route->dst_gateway);
2309           if(global_routing->get_network_element_type((const char*)route->src_gateway) == SURF_NETWORK_ELEMENT_NULL)
2310                   xbt_die("The src_gateway '%s' does not exist!",route->src_gateway);
2311         }
2312
2313         route_extended_t e_route =
2314                 generic_new_extended_route(current_routing->hierarchy, route, 1);
2315         route_new_dijkstra(routing, *src_id, *dst_id, e_route);
2316 }
2317
2318 #ifdef HAVE_PCRE_LIB
2319 /* ************************************************** */
2320 /* ************** RULE-BASED ROUTING **************** */
2321
2322 /* Routing model structure */
2323
2324 typedef struct {
2325   s_routing_component_t generic_routing;
2326   xbt_dict_t dict_processing_units;
2327   xbt_dict_t dict_autonomous_systems;
2328   xbt_dynar_t list_route;
2329   xbt_dynar_t list_ASroute;
2330 } s_routing_component_rulebased_t, *routing_component_rulebased_t;
2331
2332 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
2333 typedef struct s_rule_route_extended s_rule_route_extended_t,
2334     *rule_route_extended_t;
2335
2336 struct s_rule_route {
2337   xbt_dynar_t re_str_link;      // dynar of char*
2338   pcre *re_src;
2339   pcre *re_dst;
2340 };
2341
2342 struct s_rule_route_extended {
2343   s_rule_route_t generic_rule_route;
2344   char *re_src_gateway;
2345   char *re_dst_gateway;
2346 };
2347
2348 static void rule_route_free(void *e)
2349 {
2350   rule_route_t *elem = (rule_route_t *) (e);
2351   if (*elem) {
2352     xbt_dynar_free(&(*elem)->re_str_link);
2353     pcre_free((*elem)->re_src);
2354     pcre_free((*elem)->re_dst);
2355     xbt_free(*elem);
2356   }
2357   *elem = NULL;
2358 }
2359
2360 static void rule_route_extended_free(void *e)
2361 {
2362   rule_route_extended_t *elem = (rule_route_extended_t *) e;
2363   if (*elem) {
2364     xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
2365     pcre_free((*elem)->generic_rule_route.re_src);
2366     pcre_free((*elem)->generic_rule_route.re_dst);
2367     xbt_free((*elem)->re_src_gateway);
2368     xbt_free((*elem)->re_dst_gateway);
2369     xbt_free(*elem);
2370   }
2371 }
2372
2373 /* Parse routing model functions */
2374
2375 static void model_rulebased_set_processing_unit(routing_component_t rc,
2376                                                 const char *name)
2377 {
2378   routing_component_rulebased_t routing =
2379       (routing_component_rulebased_t) rc;
2380   xbt_dict_set(routing->dict_processing_units, name, (void *) (-1), NULL);
2381 }
2382
2383 static void model_rulebased_set_autonomous_system(routing_component_t rc,
2384                                                   const char *name)
2385 {
2386   routing_component_rulebased_t routing =
2387       (routing_component_rulebased_t) rc;
2388   xbt_dict_set(routing->dict_autonomous_systems, name, (void *) (-1),
2389                NULL);
2390 }
2391
2392 static void model_rulebased_set_route(routing_component_t rc,
2393                                       const char *src, const char *dst,
2394                                       name_route_extended_t route)
2395 {
2396   routing_component_rulebased_t routing =
2397       (routing_component_rulebased_t) rc;
2398   rule_route_t ruleroute = xbt_new0(s_rule_route_t, 1);
2399   const char *error;
2400   int erroffset;
2401
2402   if(!strcmp(rc->routing->name,"Vivaldi")){
2403           if(xbt_dynar_length(route->generic_route.link_list) != 0)
2404                   xbt_die("You can't have link_ctn with Model Vivaldi.");
2405   }
2406
2407   ruleroute->re_src = pcre_compile(src, 0, &error, &erroffset, NULL);
2408   xbt_assert(ruleroute->re_src,
2409               "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2410               erroffset, src, error);
2411   ruleroute->re_dst = pcre_compile(dst, 0, &error, &erroffset, NULL);
2412   xbt_assert(ruleroute->re_src,
2413               "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2414               erroffset, dst, error);
2415   ruleroute->re_str_link = route->generic_route.link_list;
2416   xbt_dynar_push(routing->list_route, &ruleroute);
2417   xbt_free(route);
2418 }
2419
2420 static void model_rulebased_set_ASroute(routing_component_t rc,
2421                                         const char *src, const char *dst,
2422                                         name_route_extended_t route)
2423 {
2424   routing_component_rulebased_t routing =
2425       (routing_component_rulebased_t) rc;
2426   rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t, 1);
2427   const char *error;
2428   int erroffset;
2429
2430   if(!strcmp(rc->routing->name,"Vivaldi")){
2431           if(xbt_dynar_length(route->generic_route.link_list) != 0)
2432                   xbt_die("You can't have link_ctn with Model Vivaldi.");
2433   }
2434
2435   ruleroute_e->generic_rule_route.re_src =
2436       pcre_compile(src, 0, &error, &erroffset, NULL);
2437   xbt_assert(ruleroute_e->generic_rule_route.re_src,
2438               "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2439               erroffset, src, error);
2440   ruleroute_e->generic_rule_route.re_dst =
2441       pcre_compile(dst, 0, &error, &erroffset, NULL);
2442   xbt_assert(ruleroute_e->generic_rule_route.re_src,
2443               "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2444               erroffset, dst, error);
2445   ruleroute_e->generic_rule_route.re_str_link =
2446       route->generic_route.link_list;
2447   ruleroute_e->re_src_gateway = route->src_gateway;
2448   ruleroute_e->re_dst_gateway = route->dst_gateway;
2449   xbt_dynar_push(routing->list_ASroute, &ruleroute_e);
2450 //  xbt_free(route->src_gateway);
2451 //  xbt_free(route->dst_gateway);
2452   xbt_free(route);
2453 }
2454
2455 static void model_rulebased_set_bypassroute(routing_component_t rc,
2456                                             const char *src,
2457                                             const char *dst,
2458                                             route_extended_t e_route)
2459 {
2460   xbt_die("bypass routing not supported for Route-Based model");
2461 }
2462
2463 #define BUFFER_SIZE 4096        /* result buffer size */
2464 #define OVECCOUNT 30            /* should be a multiple of 3 */
2465
2466 static char *remplace(char *value, const char **src_list, int src_size,
2467                       const char **dst_list, int dst_size)
2468 {
2469
2470   char result_result[BUFFER_SIZE];
2471   int i_result_buffer;
2472   int value_length = (int) strlen(value);
2473   int number = 0;
2474
2475   int i = 0;
2476   i_result_buffer = 0;
2477   do {
2478     if (value[i] == '$') {
2479       i++;                      // skip $
2480
2481       // find the number      
2482       int number_length = 0;
2483       while ('0' <= value[i + number_length]
2484              && value[i + number_length] <= '9') {
2485         number_length++;
2486       }
2487       xbt_assert(number_length != 0,
2488                   "bad string parameter, no number indication, at offset: %d (\"%s\")",
2489                   i, value);
2490
2491       // solve number
2492       number = atoi(value + i);
2493       i = i + number_length;
2494       xbt_assert(i + 2 < value_length,
2495                   "bad string parameter, too few chars, at offset: %d (\"%s\")",
2496                   i, value);
2497
2498       // solve the indication
2499       const char **param_list;
2500       int param_size;
2501       if (value[i] == 's' && value[i + 1] == 'r' && value[i + 2] == 'c') {
2502         param_list = src_list;
2503         param_size = src_size;
2504       } else if (value[i] == 'd' && value[i + 1] == 's'
2505                  && value[i + 2] == 't') {
2506         param_list = dst_list;
2507         param_size = dst_size;
2508       } else {
2509         xbt_die("bad string parameter, support only \"src\" and \"dst\", "
2510                 "at offset: %d (\"%s\")", i, value);
2511       }
2512       i = i + 3;
2513
2514       xbt_assert(param_size >= number,
2515                   "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",
2516                   i, value, param_size, number);
2517
2518       const char *param = param_list[number];
2519       int size = strlen(param);
2520       int cp;
2521       for (cp = 0; cp < size; cp++) {
2522         result_result[i_result_buffer] = param[cp];
2523         i_result_buffer++;
2524         if (i_result_buffer >= BUFFER_SIZE)
2525           break;
2526       }
2527     } else {
2528       result_result[i_result_buffer] = value[i];
2529       i_result_buffer++;
2530       i++;                      // next char
2531     }
2532
2533   } while (i < value_length && i_result_buffer < BUFFER_SIZE);
2534
2535   xbt_assert(i_result_buffer < BUFFER_SIZE,
2536               "solving string \"%s\", small buffer size (%d)", value,
2537               BUFFER_SIZE);
2538   result_result[i_result_buffer] = 0;
2539   return xbt_strdup(result_result);
2540 }
2541
2542 static route_extended_t rulebased_get_route(routing_component_t rc,
2543                                             const char *src,
2544                                             const char *dst);
2545 static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
2546 {
2547   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
2548   routing_component_rulebased_t routing = (routing_component_rulebased_t)rc;
2549
2550   xbt_dict_cursor_t c1 = NULL;
2551   char *k1, *d1;
2552
2553   //find router
2554   char *router = NULL;
2555   xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
2556     if (strstr (k1, "router")){
2557       router = k1;
2558     }
2559   }
2560   if (!router){
2561     xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
2562   }
2563
2564   xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
2565     route_extended_t route = rulebased_get_route (rc, router, k1);
2566
2567     int number_of_links = xbt_dynar_length(route->generic_route.link_list);
2568     if (number_of_links != 3) {
2569       xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
2570     }
2571
2572     void *link_ptr;
2573     xbt_dynar_get_cpy (route->generic_route.link_list, 2, &link_ptr);
2574     onelink_t onelink = xbt_new0 (s_onelink_t, 1);
2575     onelink->src = xbt_strdup (k1);
2576     onelink->dst = xbt_strdup (router);
2577     onelink->link_ptr = link_ptr;
2578     xbt_dynar_push (ret, &onelink);
2579   }
2580   return ret;
2581 }
2582
2583 /* Business methods */
2584 static route_extended_t rulebased_get_route(routing_component_t rc,
2585                                             const char *src,
2586                                             const char *dst)
2587 {
2588   xbt_assert(rc && src
2589               && dst,
2590               "Invalid params for \"get_route\" function at AS \"%s\"",
2591               rc->name);
2592
2593   /* set utils vars */
2594   routing_component_rulebased_t routing =
2595       (routing_component_rulebased_t) rc;
2596
2597   int are_processing_units=0;
2598   xbt_dynar_t rule_list;
2599   if (xbt_dict_get_or_null(routing->dict_processing_units, src)
2600       && xbt_dict_get_or_null(routing->dict_processing_units, dst)) {
2601     are_processing_units = 1;
2602     rule_list = routing->list_route;
2603   } else if (xbt_dict_get_or_null(routing->dict_autonomous_systems, src)
2604              && xbt_dict_get_or_null(routing->dict_autonomous_systems,
2605                                      dst)) {
2606     are_processing_units = 0;
2607     rule_list = routing->list_ASroute;
2608   } else
2609     xbt_die("Ask for route \"from\"(%s)  or \"to\"(%s) no found in "
2610             "the local table", src, dst);
2611
2612   int rc_src = -1;
2613   int rc_dst = -1;
2614   int src_length = (int) strlen(src);
2615   int dst_length = (int) strlen(dst);
2616
2617   xbt_dynar_t links_list =
2618       xbt_dynar_new(global_routing->size_of_link, NULL);
2619
2620   rule_route_t ruleroute;
2621   unsigned int cpt;
2622   int ovector_src[OVECCOUNT];
2623   int ovector_dst[OVECCOUNT];
2624   const char **list_src = NULL;
2625   const char **list_dst = NULL;
2626   int res;
2627   xbt_dynar_foreach(rule_list, cpt, ruleroute) {
2628     rc_src =
2629         pcre_exec(ruleroute->re_src, NULL, src, src_length, 0, 0,
2630                   ovector_src, OVECCOUNT);
2631     if (rc_src >= 0) {
2632       rc_dst =
2633           pcre_exec(ruleroute->re_dst, NULL, dst, dst_length, 0, 0,
2634                     ovector_dst, OVECCOUNT);
2635       if (rc_dst >= 0) {
2636         res = pcre_get_substring_list(src, ovector_src, rc_src, &list_src);
2637         xbt_assert(!res, "error solving substring list for src \"%s\"", src);
2638         res = pcre_get_substring_list(dst, ovector_dst, rc_dst, &list_dst);
2639         xbt_assert(!res, "error solving substring list for src \"%s\"", dst);
2640         char *link_name;
2641         xbt_dynar_foreach(ruleroute->re_str_link, cpt, link_name) {
2642           char *new_link_name =
2643               remplace(link_name, list_src, rc_src, list_dst, rc_dst);
2644           void *link =
2645                           xbt_lib_get_or_null(link_lib, new_link_name, SURF_LINK_LEVEL);
2646           if (link)
2647             xbt_dynar_push(links_list, &link);
2648           else
2649             THROWF(mismatch_error, 0, "Link %s not found", new_link_name);
2650           xbt_free(new_link_name);
2651         }
2652       }
2653     }
2654     if (rc_src >= 0 && rc_dst >= 0)
2655       break;
2656   }
2657
2658   route_extended_t new_e_route = NULL;
2659   if (rc_src >= 0 && rc_dst >= 0) {
2660     new_e_route = xbt_new0(s_route_extended_t, 1);
2661     new_e_route->generic_route.link_list = links_list;
2662   } else if (!strcmp(src, dst) && are_processing_units) {
2663     new_e_route = xbt_new0(s_route_extended_t, 1);
2664     xbt_dynar_push(links_list, &(global_routing->loopback));
2665     new_e_route->generic_route.link_list = links_list;
2666   } else {
2667     xbt_dynar_free(&link_list);
2668   }
2669
2670   if (!are_processing_units && new_e_route) {
2671     rule_route_extended_t ruleroute_extended =
2672         (rule_route_extended_t) ruleroute;
2673     new_e_route->src_gateway =
2674         remplace(ruleroute_extended->re_src_gateway, list_src, rc_src,
2675                  list_dst, rc_dst);
2676     new_e_route->dst_gateway =
2677         remplace(ruleroute_extended->re_dst_gateway, list_src, rc_src,
2678                  list_dst, rc_dst);
2679   }
2680
2681   if (list_src)
2682     pcre_free_substring_list(list_src);
2683   if (list_dst)
2684     pcre_free_substring_list(list_dst);
2685
2686   return new_e_route;
2687 }
2688
2689 static route_extended_t rulebased_get_bypass_route(routing_component_t rc,
2690                                                    const char *src,
2691                                                    const char *dst)
2692 {
2693   return NULL;
2694 }
2695
2696 static void rulebased_finalize(routing_component_t rc)
2697 {
2698   routing_component_rulebased_t routing =
2699       (routing_component_rulebased_t) rc;
2700   if (routing) {
2701     xbt_dict_free(&routing->dict_processing_units);
2702     xbt_dict_free(&routing->dict_autonomous_systems);
2703     xbt_dynar_free(&routing->list_route);
2704     xbt_dynar_free(&routing->list_ASroute);
2705     /* Delete structure */
2706     xbt_free(routing);
2707   }
2708 }
2709
2710 /* Creation routing model functions */
2711 static void *model_rulebased_create(void)
2712 {
2713   routing_component_rulebased_t new_component =
2714       xbt_new0(s_routing_component_rulebased_t, 1);
2715   new_component->generic_routing.set_processing_unit =
2716       model_rulebased_set_processing_unit;
2717   new_component->generic_routing.set_autonomous_system =
2718       model_rulebased_set_autonomous_system;
2719   new_component->generic_routing.set_route = model_rulebased_set_route;
2720   new_component->generic_routing.set_ASroute = model_rulebased_set_ASroute;
2721   new_component->generic_routing.set_bypassroute = model_rulebased_set_bypassroute;
2722   new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes;
2723   new_component->generic_routing.get_route = rulebased_get_route;
2724   new_component->generic_routing.get_latency = generic_get_link_latency;
2725   new_component->generic_routing.get_bypass_route = rulebased_get_bypass_route;
2726   new_component->generic_routing.finalize = rulebased_finalize;
2727   new_component->generic_routing.get_network_element_type = get_network_element_type;
2728   /* initialization of internal structures */
2729   new_component->dict_processing_units = xbt_dict_new();
2730   new_component->dict_autonomous_systems = xbt_dict_new();
2731   new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free);
2732   new_component->list_ASroute =
2733       xbt_dynar_new(sizeof(rule_route_extended_t),
2734                     &rule_route_extended_free);
2735   return new_component;
2736 }
2737
2738 static void model_rulebased_load(void)
2739 {
2740   /* use "surfxml_add_callback" to add a parse function call */
2741 }
2742
2743 static void model_rulebased_unload(void)
2744 {
2745   /* use "surfxml_del_callback" to remove a parse function call */
2746 }
2747
2748 static void model_rulebased_end(void)
2749 {
2750 }
2751
2752 #endif                          /* HAVE_PCRE_LIB */
2753
2754 /* ************************************************************************** */
2755 /* ******************************* NO ROUTING ******************************* */
2756
2757 /* Routing model structure */
2758 typedef struct {
2759   s_routing_component_t generic_routing;
2760 } s_routing_component_none_t, *routing_component_none_t;
2761
2762 /* Business methods */
2763 static xbt_dynar_t none_get_onelink_routes(routing_component_t rc)
2764 {
2765   return NULL;
2766 }
2767
2768 static route_extended_t none_get_route(routing_component_t rc,
2769                                        const char *src, const char *dst)
2770 {
2771   return NULL;
2772 }
2773
2774 static route_extended_t none_get_bypass_route(routing_component_t rc,
2775                                               const char *src,
2776                                               const char *dst)
2777 {
2778   return NULL;
2779 }
2780
2781 static void none_finalize(routing_component_t rc)
2782 {
2783   xbt_free(rc);
2784 }
2785
2786 static void none_set_processing_unit(routing_component_t rc,
2787                                      const char *name)
2788 {
2789 }
2790
2791 static void none_set_autonomous_system(routing_component_t rc,
2792                                        const char *name)
2793 {
2794 }
2795
2796 /* Creation routing model functions */
2797 static void *model_none_create(void)
2798 {
2799   routing_component_none_t new_component =
2800       xbt_new0(s_routing_component_none_t, 1);
2801   new_component->generic_routing.set_processing_unit =
2802       none_set_processing_unit;
2803   new_component->generic_routing.set_autonomous_system =
2804       none_set_autonomous_system;
2805   new_component->generic_routing.set_route = NULL;
2806   new_component->generic_routing.set_ASroute = NULL;
2807   new_component->generic_routing.set_bypassroute = NULL;
2808   new_component->generic_routing.get_route = none_get_route;
2809   new_component->generic_routing.get_onelink_routes =
2810       none_get_onelink_routes;
2811   new_component->generic_routing.get_bypass_route = none_get_bypass_route;
2812   new_component->generic_routing.finalize = none_finalize;
2813   return new_component;
2814 }
2815
2816 static void model_none_load(void)
2817 {
2818 }
2819
2820 static void model_none_unload(void)
2821 {
2822 }
2823
2824 static void model_none_end(void)
2825 {
2826 }
2827
2828 /* ************************************************** */
2829 /* ********** PATERN FOR NEW ROUTING **************** */
2830
2831 /* The minimal configuration of a new routing model need the next functions,
2832  * also you need to set at the start of the file, the new model in the model
2833  * list. Remember keep the null ending of the list.
2834  */
2835 /*** Routing model structure ***/
2836 // typedef struct {
2837 //   s_routing_component_t generic_routing;
2838 //   /* things that your routing model need */
2839 // } s_routing_component_NEW_t,*routing_component_NEW_t;
2840
2841 /*** Parse routing model functions ***/
2842 // static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
2843 // static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
2844 // static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
2845 // static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
2846 // static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
2847
2848 /*** Business methods ***/
2849 // static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2850 // static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2851 // static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
2852
2853 /*** Creation routing model functions ***/
2854 // static void* model_NEW_create(void) {
2855 //   routing_component_NEW_t new_component =  xbt_new0(s_routing_component_NEW_t,1);
2856 //   new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
2857 //   new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
2858 //   new_component->generic_routing.set_route = model_NEW_set_route;
2859 //   new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
2860 //   new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
2861 //   new_component->generic_routing.get_route = NEW_get_route;
2862 //   new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
2863 //   new_component->generic_routing.finalize = NEW_finalize;
2864 //   /* initialization of internal structures */
2865 //   return new_component;
2866 // } /* mandatory */
2867 // static void  model_NEW_load(void) {}   /* mandatory */
2868 // static void  model_NEW_unload(void) {} /* mandatory */
2869 // static void  model_NEW_end(void) {}    /* mandatory */
2870
2871 /* ************************************************************************** */
2872 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
2873
2874 static void generic_set_processing_unit(routing_component_t rc,
2875                                         const char *name)
2876 {
2877   XBT_DEBUG("Load process unit \"%s\"", name);
2878   int *id = xbt_new0(int, 1);
2879   xbt_dict_t _to_index;
2880   _to_index = current_routing->to_index;
2881   *id = xbt_dict_length(_to_index);
2882   xbt_dict_set(_to_index, name, id, xbt_free);
2883 }
2884
2885 static void generic_set_autonomous_system(routing_component_t rc,
2886                                           const char *name)
2887 {
2888   XBT_DEBUG("Load Autonomous system \"%s\"", name);
2889   int *id = xbt_new0(int, 1);
2890   xbt_dict_t _to_index;
2891   _to_index = current_routing->to_index;
2892   *id = xbt_dict_length(_to_index);
2893   xbt_dict_set(_to_index, name, id, xbt_free);
2894 }
2895
2896 static int surf_pointer_resource_cmp(const void *a, const void *b)
2897 {
2898   return a != b;
2899 }
2900
2901 static int surf_link_resource_cmp(const void *a, const void *b)
2902 {
2903   return !!memcmp(a,b,global_routing->size_of_link);
2904 }
2905
2906 static void generic_set_bypassroute(routing_component_t rc,
2907                                     const char *src, const char *dst,
2908                                     route_extended_t e_route)
2909 {
2910   XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
2911   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
2912   char *route_name;
2913
2914   route_name = bprintf("%s#%s", src, dst);
2915   xbt_assert(xbt_dynar_length(e_route->generic_route.link_list) > 0,
2916               "Invalid count of links, must be greater than zero (%s,%s)",
2917               src, dst);
2918   xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
2919               "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
2920               src, e_route->src_gateway, dst, e_route->dst_gateway);
2921
2922   route_extended_t new_e_route =
2923       generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 0);
2924   xbt_dynar_free(&(e_route->generic_route.link_list));
2925   xbt_free(e_route);
2926
2927   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route,
2928                (void (*)(void *)) generic_free_extended_route);
2929   xbt_free(route_name);
2930 }
2931
2932 /* ************************************************************************** */
2933 /* *********************** GENERIC BUSINESS METHODS ************************* */
2934
2935 static double generic_get_link_latency(routing_component_t rc,
2936                                        const char *src, const char *dst,
2937                                        route_extended_t route)
2938 {
2939         int need_to_clean = route?0:1;
2940         void * link;
2941         unsigned int i;
2942         double latency = 0.0;
2943
2944         route = route?route:rc->get_route(rc,src,dst);
2945
2946         xbt_dynar_foreach(route->generic_route.link_list,i,link) {
2947                 latency += get_link_latency(link);
2948         }
2949         if(need_to_clean) generic_free_extended_route(route);
2950   return latency;
2951 }
2952
2953 static xbt_dynar_t generic_get_onelink_routes(routing_component_t rc)
2954 {
2955   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
2956 }
2957
2958 static route_extended_t generic_get_bypassroute(routing_component_t rc,
2959                                                 const char *src,
2960                                                 const char *dst)
2961 {
2962   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
2963   routing_component_t src_as, dst_as;
2964   int index_src, index_dst;
2965   xbt_dynar_t path_src = NULL;
2966   xbt_dynar_t path_dst = NULL;
2967   routing_component_t current = NULL;
2968   routing_component_t *current_src = NULL;
2969   routing_component_t *current_dst = NULL;
2970
2971   /* (1) find the as where the src and dst are located */
2972   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
2973   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
2974   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
2975   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
2976
2977   if(src_data == NULL || dst_data == NULL)
2978           xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
2979                      src, dst, rc->name);
2980
2981   src_as = ((network_element_info_t)src_data)->rc_component;
2982   dst_as = ((network_element_info_t)dst_data)->rc_component;
2983
2984   /* (2) find the path to the root routing component */
2985   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
2986   current = src_as;
2987   while (current != NULL) {
2988     xbt_dynar_push(path_src, &current);
2989     current = current->routing_father;
2990   }
2991   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
2992   current = dst_as;
2993   while (current != NULL) {
2994     xbt_dynar_push(path_dst, &current);
2995     current = current->routing_father;
2996   }
2997
2998   /* (3) find the common father */
2999   index_src = path_src->used - 1;
3000   index_dst = path_dst->used - 1;
3001   current_src = xbt_dynar_get_ptr(path_src, index_src);
3002   current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
3003   while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
3004     routing_component_t *tmp_src, *tmp_dst;
3005     tmp_src = xbt_dynar_pop_ptr(path_src);
3006     tmp_dst = xbt_dynar_pop_ptr(path_dst);
3007     index_src--;
3008     index_dst--;
3009     current_src = xbt_dynar_get_ptr(path_src, index_src);
3010     current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
3011   }
3012
3013   int max_index_src = path_src->used - 1;
3014   int max_index_dst = path_dst->used - 1;
3015
3016   int max_index = max(max_index_src, max_index_dst);
3017   int i, max;
3018
3019   route_extended_t e_route_bypass = NULL;
3020
3021   for (max = 0; max <= max_index; max++) {
3022     for (i = 0; i < max; i++) {
3023       if (i <= max_index_src && max <= max_index_dst) {
3024         char *route_name = bprintf("%s#%s",
3025                                    (*(routing_component_t *)
3026                                     (xbt_dynar_get_ptr
3027                                      (path_src, i)))->name,
3028                                    (*(routing_component_t *)
3029                                     (xbt_dynar_get_ptr
3030                                      (path_dst, max)))->name);
3031         e_route_bypass =
3032             xbt_dict_get_or_null(dict_bypassRoutes, route_name);
3033         xbt_free(route_name);
3034       }
3035       if (e_route_bypass)
3036         break;
3037       if (max <= max_index_src && i <= max_index_dst) {
3038         char *route_name = bprintf("%s#%s",
3039                                    (*(routing_component_t *)
3040                                     (xbt_dynar_get_ptr
3041                                      (path_src, max)))->name,
3042                                    (*(routing_component_t *)
3043                                     (xbt_dynar_get_ptr
3044                                      (path_dst, i)))->name);
3045         e_route_bypass =
3046             xbt_dict_get_or_null(dict_bypassRoutes, route_name);
3047         xbt_free(route_name);
3048       }
3049       if (e_route_bypass)
3050         break;
3051     }
3052
3053     if (e_route_bypass)
3054       break;
3055
3056     if (max <= max_index_src && max <= max_index_dst) {
3057       char *route_name = bprintf("%s#%s",
3058                                  (*(routing_component_t *)
3059                                   (xbt_dynar_get_ptr
3060                                    (path_src, max)))->name,
3061                                  (*(routing_component_t *)
3062                                   (xbt_dynar_get_ptr
3063                                    (path_dst, max)))->name);
3064       e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
3065       xbt_free(route_name);
3066     }
3067     if (e_route_bypass)
3068       break;
3069   }
3070
3071   xbt_dynar_free(&path_src);
3072   xbt_dynar_free(&path_dst);
3073
3074   route_extended_t new_e_route = NULL;
3075
3076   if (e_route_bypass) {
3077     void *link;
3078     unsigned int cpt = 0;
3079     new_e_route = xbt_new0(s_route_extended_t, 1);
3080     new_e_route->src_gateway = xbt_strdup(e_route_bypass->src_gateway);
3081     new_e_route->dst_gateway = xbt_strdup(e_route_bypass->dst_gateway);
3082     new_e_route->generic_route.link_list =
3083         xbt_dynar_new(global_routing->size_of_link, NULL);
3084     xbt_dynar_foreach(e_route_bypass->generic_route.link_list, cpt, link) {
3085       xbt_dynar_push(new_e_route->generic_route.link_list, &link);
3086     }
3087   }
3088
3089   return new_e_route;
3090 }
3091
3092 /* ************************************************************************** */
3093 /* ************************* GENERIC AUX FUNCTIONS ************************** */
3094
3095 static route_t
3096 generic_new_route(e_surf_routing_hierarchy_t hierarchy,
3097                            void *data, int order)
3098 {
3099
3100   char *link_name;
3101   route_t new_route;
3102   unsigned int cpt;
3103   xbt_dynar_t links = NULL, links_id = NULL;
3104
3105   new_route = xbt_new0(s_route_t, 1);
3106   new_route->link_list =
3107       xbt_dynar_new(global_routing->size_of_link, NULL);
3108
3109   xbt_assert(hierarchy == SURF_ROUTING_BASE,
3110               "the hierarchy type is not SURF_ROUTING_BASE");
3111
3112   links = ((route_t) data)->link_list;
3113
3114
3115   links_id = new_route->link_list;
3116
3117   xbt_dynar_foreach(links, cpt, link_name) {
3118
3119     void *link =
3120                 xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
3121     if (link) {
3122       if (order)
3123         xbt_dynar_push(links_id, &link);
3124       else
3125         xbt_dynar_unshift(links_id, &link);
3126     } else
3127       THROWF(mismatch_error, 0, "Link %s not found", link_name);
3128   }
3129
3130   return new_route;
3131 }
3132
3133 static route_extended_t
3134 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
3135                            void *data, int order)
3136 {
3137
3138   char *link_name;
3139   route_extended_t e_route, new_e_route;
3140   route_t route;
3141   unsigned int cpt;
3142   xbt_dynar_t links = NULL, links_id = NULL;
3143
3144   new_e_route = xbt_new0(s_route_extended_t, 1);
3145   new_e_route->generic_route.link_list =
3146       xbt_dynar_new(global_routing->size_of_link, NULL);
3147   new_e_route->src_gateway = NULL;
3148   new_e_route->dst_gateway = NULL;
3149
3150   xbt_assert(hierarchy == SURF_ROUTING_BASE
3151               || hierarchy == SURF_ROUTING_RECURSIVE,
3152               "the hierarchy type is not defined");
3153
3154   if (hierarchy == SURF_ROUTING_BASE) {
3155
3156     route = (route_t) data;
3157     links = route->link_list;
3158
3159   } else if (hierarchy == SURF_ROUTING_RECURSIVE) {
3160
3161     e_route = (route_extended_t) data;
3162     xbt_assert(e_route->src_gateway
3163                 && e_route->dst_gateway, "bad gateway, is null");
3164     links = e_route->generic_route.link_list;
3165
3166     /* remeber not erase the gateway names */
3167     new_e_route->src_gateway = strdup(e_route->src_gateway);
3168     new_e_route->dst_gateway = strdup(e_route->dst_gateway);
3169   }
3170
3171   links_id = new_e_route->generic_route.link_list;
3172
3173   xbt_dynar_foreach(links, cpt, link_name) {
3174
3175     void *link =
3176                 xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
3177     if (link) {
3178       if (order)
3179         xbt_dynar_push(links_id, &link);
3180       else
3181         xbt_dynar_unshift(links_id, &link);
3182     } else
3183       THROWF(mismatch_error, 0, "Link %s not found", link_name);
3184   }
3185
3186   return new_e_route;
3187 }
3188
3189 static void generic_free_route(route_t route)
3190 {
3191   if (route) {
3192     xbt_dynar_free(&(route->link_list));
3193     xbt_free(route);
3194   }
3195 }
3196
3197 static void generic_free_extended_route(route_extended_t e_route)
3198 {
3199   if (e_route) {
3200     xbt_dynar_free(&(e_route->generic_route.link_list));
3201     if (e_route->src_gateway)
3202       xbt_free(e_route->src_gateway);
3203     if (e_route->dst_gateway)
3204       xbt_free(e_route->dst_gateway);
3205     xbt_free(e_route);
3206   }
3207 }
3208
3209 static routing_component_t generic_as_exist(routing_component_t find_from,
3210                                             routing_component_t to_find)
3211 {
3212   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
3213   xbt_dict_cursor_t cursor = NULL;
3214   char *key;
3215   int found = 0;
3216   routing_component_t elem;
3217   xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
3218     if (to_find == elem || generic_as_exist(elem, to_find)) {
3219       found = 1;
3220       break;
3221     }
3222   }
3223   if (found)
3224     return to_find;
3225   return NULL;
3226 }
3227
3228 static routing_component_t
3229 generic_autonomous_system_exist(routing_component_t rc, char *element)
3230 {
3231   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
3232   routing_component_t element_as, result, elem;
3233   xbt_dict_cursor_t cursor = NULL;
3234   char *key;
3235   element_as = ((network_element_info_t)
3236                 xbt_lib_get_or_null(as_router_lib, element, ROUTING_ASR_LEVEL))->rc_component;
3237   result = ((routing_component_t) - 1);
3238   if (element_as != rc)
3239     result = generic_as_exist(rc, element_as);
3240
3241   int found = 0;
3242   if (result) {
3243     xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
3244       found = !strcmp(elem->name, element);
3245       if (found)
3246         break;
3247     }
3248     if (found)
3249       return element_as;
3250   }
3251   return NULL;
3252 }
3253
3254 static routing_component_t
3255 generic_processing_units_exist(routing_component_t rc, char *element)
3256 {
3257   routing_component_t element_as;
3258   element_as = ((network_element_info_t)
3259                 xbt_lib_get_or_null(host_lib,
3260                  element, ROUTING_HOST_LEVEL))->rc_component;
3261   if (element_as == rc)
3262     return element_as;
3263   return generic_as_exist(rc, element_as);
3264 }
3265
3266 static void generic_src_dst_check(routing_component_t rc, const char *src,
3267                                   const char *dst)
3268 {
3269
3270   void * src_data = xbt_lib_get_or_null(host_lib,src, ROUTING_HOST_LEVEL);
3271   void * dst_data = xbt_lib_get_or_null(host_lib,dst, ROUTING_HOST_LEVEL);
3272   if(!src_data) src_data = xbt_lib_get_or_null(as_router_lib,src, ROUTING_ASR_LEVEL);
3273   if(!dst_data) dst_data = xbt_lib_get_or_null(as_router_lib,dst, ROUTING_ASR_LEVEL);
3274
3275   if(src_data == NULL || dst_data == NULL)
3276           xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
3277                      src, dst, rc->name);
3278
3279   routing_component_t src_as = ((network_element_info_t)src_data)->rc_component;
3280   routing_component_t dst_as = ((network_element_info_t)dst_data)->rc_component;
3281
3282   if(src_as != dst_as)
3283           xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
3284               src, src_as->name, dst, dst_as->name);
3285   if(rc != dst_as)
3286          xbt_die("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
3287      src,dst,src_as->name, dst_as->name,rc->name);
3288 }
3289
3290 static void routing_parse_Sconfig(void)
3291 {
3292   XBT_DEBUG("START configuration name = %s",A_surfxml_config_id);
3293 }
3294
3295 static void routing_parse_Econfig(void)
3296 {
3297   xbt_dict_cursor_t cursor = NULL;
3298   char *key;
3299   char *elem;
3300   char *cfg;
3301   xbt_dict_foreach(current_property_set, cursor, key, elem) {
3302           cfg = bprintf("%s:%s",key,elem);
3303           if(xbt_cfg_is_default_value(_surf_cfg_set, key))
3304                   xbt_cfg_set_parse(_surf_cfg_set, cfg);
3305           else
3306                   XBT_INFO("The custom configuration '%s' is already define by user!",key);
3307           free(cfg);
3308   }
3309   XBT_DEBUG("End configuration name = %s",A_surfxml_config_id);
3310 }
3311
3312 static void routing_parse_Scluster(void)
3313 {
3314   static int AX_ptr = 0;
3315
3316   char *cluster_id = A_surfxml_cluster_id;
3317   char *cluster_prefix = A_surfxml_cluster_prefix;
3318   char *cluster_suffix = A_surfxml_cluster_suffix;
3319   char *cluster_radical = A_surfxml_cluster_radical;
3320   char *cluster_power = A_surfxml_cluster_power;
3321   char *cluster_core = A_surfxml_cluster_core;
3322   char *cluster_bw = A_surfxml_cluster_bw;
3323   char *cluster_lat = A_surfxml_cluster_lat;
3324   char *temp_cluster_bw = NULL;
3325   char *temp_cluster_lat = NULL;
3326   char *temp_cluster_power = NULL;
3327   char *cluster_bb_bw = A_surfxml_cluster_bb_bw;
3328   char *cluster_bb_lat = A_surfxml_cluster_bb_lat;
3329   char *cluster_availability_file = A_surfxml_cluster_availability_file;
3330   char *cluster_state_file = A_surfxml_cluster_state_file;
3331   char *host_id, *groups, *link_id = NULL;
3332   char *router_id, *link_router, *link_backbone;
3333   char *availability_file = xbt_strdup(cluster_availability_file);
3334   char *state_file = xbt_strdup(cluster_state_file);
3335
3336   if(xbt_dict_size(patterns)==0)
3337           patterns = xbt_dict_new();
3338
3339   xbt_dict_set(patterns,"id",cluster_id,NULL);
3340   xbt_dict_set(patterns,"prefix",cluster_prefix,NULL);
3341   xbt_dict_set(patterns,"suffix",cluster_suffix,NULL);
3342
3343 #ifdef HAVE_PCRE_LIB
3344   char *route_src_dst;
3345 #endif
3346   unsigned int iter;
3347   int start, end, i;
3348   xbt_dynar_t radical_elements;
3349   xbt_dynar_t radical_ends;
3350   int cluster_sharing_policy = AX_surfxml_cluster_sharing_policy;
3351   int cluster_bb_sharing_policy = AX_surfxml_cluster_bb_sharing_policy;
3352
3353 #ifndef HAVE_PCRE_LIB
3354   xbt_dynar_t tab_elements_num = xbt_dynar_new(sizeof(int), NULL);
3355   char *route_src, *route_dst;
3356   int j;
3357 #endif
3358
3359   static unsigned int surfxml_buffer_stack_stack_ptr = 1;
3360   static unsigned int surfxml_buffer_stack_stack[1024];
3361
3362   surfxml_buffer_stack_stack[0] = 0;
3363
3364   surfxml_bufferstack_push(1);
3365
3366   SURFXML_BUFFER_SET(AS_id, cluster_id);
3367 #ifdef HAVE_PCRE_LIB
3368   SURFXML_BUFFER_SET(AS_routing, "RuleBased");
3369   XBT_DEBUG("<AS id=\"%s\"\trouting=\"RuleBased\">", cluster_id);
3370 #else
3371   SURFXML_BUFFER_SET(AS_routing, "Full");
3372   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", cluster_id);
3373 #endif
3374   SURFXML_START_TAG(AS);
3375
3376   radical_elements = xbt_str_split(cluster_radical, ",");
3377   xbt_dynar_foreach(radical_elements, iter, groups) {
3378     radical_ends = xbt_str_split(groups, "-");
3379     switch (xbt_dynar_length(radical_ends)) {
3380     case 1:
3381       surf_parse_get_int(&start,
3382                          xbt_dynar_get_as(radical_ends, 0, char *));
3383       host_id = bprintf("%s%d%s", cluster_prefix, start, cluster_suffix);
3384 #ifndef HAVE_PCRE_LIB
3385       xbt_dynar_push_as(tab_elements_num, int, start);
3386 #endif
3387       link_id = bprintf("%s_link_%d", cluster_id, start);
3388
3389       xbt_dict_set(patterns, "radical", bprintf("%d", start), xbt_free);
3390       temp_cluster_power = xbt_strdup(cluster_power);
3391       temp_cluster_power = replace_random_parameter(temp_cluster_power);
3392       XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\">", host_id, temp_cluster_power);
3393       A_surfxml_host_state = A_surfxml_host_state_ON;
3394       SURFXML_BUFFER_SET(host_id, host_id);
3395       SURFXML_BUFFER_SET(host_power, temp_cluster_power);
3396       SURFXML_BUFFER_SET(host_core, cluster_core);
3397       SURFXML_BUFFER_SET(host_availability, "1.0");
3398       SURFXML_BUFFER_SET(host_coordinates, "");
3399       xbt_free(availability_file);
3400       availability_file = xbt_strdup(cluster_availability_file);
3401       xbt_free(state_file);
3402       state_file = xbt_strdup(cluster_state_file);
3403       XBT_DEBUG("\tavailability_file=\"%s\"",xbt_str_varsubst(availability_file,patterns));
3404       XBT_DEBUG("\tstate_file=\"%s\"",xbt_str_varsubst(state_file,patterns));
3405       SURFXML_BUFFER_SET(host_availability_file, xbt_str_varsubst(availability_file,patterns));
3406       SURFXML_BUFFER_SET(host_state_file, xbt_str_varsubst(state_file,patterns));
3407       XBT_DEBUG("</host>");
3408       SURFXML_START_TAG(host);
3409       SURFXML_END_TAG(host);
3410
3411
3412       temp_cluster_bw = xbt_strdup(cluster_bw);
3413       temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
3414       temp_cluster_lat = xbt_strdup(cluster_lat);
3415       temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
3416       XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,temp_cluster_bw, cluster_lat);
3417       A_surfxml_link_state = A_surfxml_link_state_ON;
3418       A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3419       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3420           {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
3421       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3422           {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
3423       SURFXML_BUFFER_SET(link_id, link_id);
3424       SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
3425       SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
3426       SURFXML_BUFFER_SET(link_bandwidth_file, "");
3427       SURFXML_BUFFER_SET(link_latency_file, "");
3428       SURFXML_BUFFER_SET(link_state_file, "");
3429       SURFXML_START_TAG(link);
3430       SURFXML_END_TAG(link);
3431
3432       xbt_free(temp_cluster_bw);
3433       xbt_free(temp_cluster_lat);
3434       xbt_free(temp_cluster_power);
3435       free(link_id);
3436       free(host_id);
3437       break;
3438
3439     case 2:
3440
3441       surf_parse_get_int(&start,
3442                          xbt_dynar_get_as(radical_ends, 0, char *));
3443       surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
3444       for (i = start; i <= end; i++) {
3445         host_id = bprintf("%s%d%s", cluster_prefix, i, cluster_suffix);
3446 #ifndef HAVE_PCRE_LIB
3447         xbt_dynar_push_as(tab_elements_num, int, i);
3448 #endif
3449         link_id = bprintf("%s_link_%d", cluster_id, i);
3450
3451         xbt_dict_set(patterns, "radical", bprintf("%d", i), xbt_free);
3452         temp_cluster_power = xbt_strdup(cluster_power);
3453         temp_cluster_power = replace_random_parameter(temp_cluster_power);
3454         XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\">", host_id, temp_cluster_power);
3455         A_surfxml_host_state = A_surfxml_host_state_ON;
3456         SURFXML_BUFFER_SET(host_id, host_id);
3457         SURFXML_BUFFER_SET(host_power, temp_cluster_power);
3458         SURFXML_BUFFER_SET(host_core, cluster_core);
3459         SURFXML_BUFFER_SET(host_availability, "1.0");
3460         SURFXML_BUFFER_SET(host_coordinates, "");
3461         xbt_free(availability_file);
3462         availability_file = xbt_strdup(cluster_availability_file);
3463         xbt_free(state_file);
3464         state_file = xbt_strdup(cluster_state_file);
3465         XBT_DEBUG("\tavailability_file=\"%s\"",xbt_str_varsubst(availability_file,patterns));
3466         XBT_DEBUG("\tstate_file=\"%s\"",xbt_str_varsubst(state_file,patterns));
3467         SURFXML_BUFFER_SET(host_availability_file, xbt_str_varsubst(availability_file,patterns));
3468         SURFXML_BUFFER_SET(host_state_file, xbt_str_varsubst(state_file,patterns));
3469         XBT_DEBUG("</host>");
3470         SURFXML_START_TAG(host);
3471         SURFXML_END_TAG(host);
3472
3473         xbt_free(temp_cluster_power);
3474
3475         temp_cluster_bw = xbt_strdup(cluster_bw);
3476         temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
3477         temp_cluster_lat = xbt_strdup(cluster_lat);
3478         temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
3479         XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,temp_cluster_bw, cluster_lat);
3480         A_surfxml_link_state = A_surfxml_link_state_ON;
3481         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3482         if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3483             {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
3484         if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3485             {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
3486         SURFXML_BUFFER_SET(link_id, link_id);
3487         SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
3488         SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
3489         SURFXML_BUFFER_SET(link_bandwidth_file, "");
3490         SURFXML_BUFFER_SET(link_latency_file, "");
3491         SURFXML_BUFFER_SET(link_state_file, "");
3492         SURFXML_START_TAG(link);
3493         SURFXML_END_TAG(link);
3494
3495         xbt_free(temp_cluster_bw);
3496         xbt_free(temp_cluster_lat);
3497         free(link_id);
3498         free(host_id);
3499       }
3500       break;
3501
3502     default:
3503       XBT_DEBUG("Malformed radical");
3504     }
3505
3506     xbt_dynar_free(&radical_ends);
3507   }
3508   xbt_dynar_free(&radical_elements);
3509
3510   XBT_DEBUG(" ");
3511   router_id =
3512       bprintf("%s%s_router%s", cluster_prefix, cluster_id,
3513               cluster_suffix);
3514   link_router = bprintf("%s_link_%s_router", cluster_id, cluster_id);
3515   link_backbone = bprintf("%s_backbone", cluster_id);
3516
3517   XBT_DEBUG("<router id=\"%s\"/>", router_id);
3518   SURFXML_BUFFER_SET(router_id, router_id);
3519   SURFXML_BUFFER_SET(router_coordinates, "");
3520   SURFXML_START_TAG(router);
3521   SURFXML_END_TAG(router);
3522
3523   //TODO
3524   xbt_dict_set(patterns, "radical", xbt_strdup("_router"), xbt_free);
3525   temp_cluster_bw = xbt_strdup(cluster_bw);
3526   temp_cluster_bw = replace_random_parameter(temp_cluster_bw);
3527   temp_cluster_lat = xbt_strdup(cluster_lat);
3528   temp_cluster_lat = replace_random_parameter(temp_cluster_lat);
3529   XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_router,temp_cluster_bw, temp_cluster_lat);
3530   A_surfxml_link_state = A_surfxml_link_state_ON;
3531   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3532   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3533   {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FULLDUPLEX;}
3534   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3535   {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
3536   SURFXML_BUFFER_SET(link_id, link_router);
3537   SURFXML_BUFFER_SET(link_bandwidth, temp_cluster_bw);
3538   SURFXML_BUFFER_SET(link_latency, temp_cluster_lat);
3539   SURFXML_BUFFER_SET(link_bandwidth_file, "");
3540   SURFXML_BUFFER_SET(link_latency_file, "");
3541   SURFXML_BUFFER_SET(link_state_file, "");
3542   SURFXML_START_TAG(link);
3543   SURFXML_END_TAG(link);
3544
3545   xbt_free(temp_cluster_bw);
3546   xbt_free(temp_cluster_lat);
3547
3548   XBT_DEBUG("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_backbone,cluster_bb_bw, cluster_bb_lat);
3549   A_surfxml_link_state = A_surfxml_link_state_ON;
3550   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3551   if(cluster_bb_sharing_policy == A_surfxml_cluster_bb_sharing_policy_FATPIPE)
3552   {A_surfxml_link_sharing_policy =  A_surfxml_link_sharing_policy_FATPIPE;}
3553   SURFXML_BUFFER_SET(link_id, link_backbone);
3554   SURFXML_BUFFER_SET(link_bandwidth, cluster_bb_bw);
3555   SURFXML_BUFFER_SET(link_latency, cluster_bb_lat);
3556   SURFXML_BUFFER_SET(link_bandwidth_file, "");
3557   SURFXML_BUFFER_SET(link_latency_file, "");
3558   SURFXML_BUFFER_SET(link_state_file, "");
3559   SURFXML_START_TAG(link);
3560   SURFXML_END_TAG(link);
3561
3562   XBT_DEBUG(" ");
3563
3564 #ifdef HAVE_PCRE_LIB
3565   char *new_suffix = xbt_strdup("");
3566
3567   radical_elements = xbt_str_split(cluster_suffix, ".");
3568   xbt_dynar_foreach(radical_elements, iter, groups) {
3569     if (strcmp(groups, "")) {
3570       char *old_suffix = new_suffix;
3571       new_suffix = bprintf("%s\\.%s", old_suffix, groups);
3572       free(old_suffix);
3573     }
3574   }
3575   route_src_dst = bprintf("%s(.*)%s", cluster_prefix, new_suffix);
3576   xbt_dynar_free(&radical_elements);
3577   free(new_suffix);
3578
3579   char *pcre_link_src = bprintf("%s_link_$1src", cluster_id);
3580   char *pcre_link_backbone = bprintf("%s_backbone", cluster_id);
3581   char *pcre_link_dst = bprintf("%s_link_$1dst", cluster_id);
3582
3583   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, route_src_dst);
3584   XBT_DEBUG("symmetrical=\"NO\">");
3585   SURFXML_BUFFER_SET(route_src, route_src_dst);
3586   SURFXML_BUFFER_SET(route_dst, route_src_dst);
3587   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3588   SURFXML_START_TAG(route);
3589
3590   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_src);
3591   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_src);
3592   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3593   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3594   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
3595   SURFXML_START_TAG(link_ctn);
3596   SURFXML_END_TAG(link_ctn);
3597
3598   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
3599   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
3600   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3601   SURFXML_START_TAG(link_ctn);
3602   SURFXML_END_TAG(link_ctn);
3603
3604   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", pcre_link_dst);
3605   SURFXML_BUFFER_SET(link_ctn_id, pcre_link_dst);
3606   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3607   if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3608   {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
3609   SURFXML_START_TAG(link_ctn);
3610   SURFXML_END_TAG(link_ctn);
3611
3612   XBT_DEBUG("</route>");
3613   SURFXML_END_TAG(route);
3614
3615   free(pcre_link_dst);
3616   free(pcre_link_backbone);
3617   free(pcre_link_src);
3618   free(route_src_dst);
3619 #else
3620   for (i = 0; i <= xbt_dynar_length(tab_elements_num); i++) {
3621     for (j = 0; j <= xbt_dynar_length(tab_elements_num); j++) {
3622       if (i == xbt_dynar_length(tab_elements_num)) {
3623         route_src = router_id;
3624       } else {
3625         route_src =
3626             bprintf("%s%d%s", cluster_prefix,
3627                     xbt_dynar_get_as(tab_elements_num, i, int),
3628                     cluster_suffix);
3629       }
3630
3631       if (j == xbt_dynar_length(tab_elements_num)) {
3632         route_dst = router_id;
3633       } else {
3634         route_dst =
3635             bprintf("%s%d%s", cluster_prefix,
3636                     xbt_dynar_get_as(tab_elements_num, j, int),
3637                     cluster_suffix);
3638       }
3639
3640       XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src, route_dst);
3641       XBT_DEBUG("symmetrical=\"NO\">");
3642       SURFXML_BUFFER_SET(route_src, route_src);
3643       SURFXML_BUFFER_SET(route_dst, route_dst);
3644       A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3645       SURFXML_START_TAG(route);
3646
3647       if (i == xbt_dynar_length(tab_elements_num)) {
3648         route_src = link_router;
3649       } else {
3650         route_src =
3651             bprintf("%s_link_%d", cluster_id,
3652                     xbt_dynar_get_as(tab_elements_num, i, int));
3653       }
3654
3655       if (j == xbt_dynar_length(tab_elements_num)) {
3656         route_dst = link_router;
3657       } else {
3658         route_dst =
3659             bprintf("%s_link_%d", cluster_id,
3660                     xbt_dynar_get_as(tab_elements_num, j, int));
3661       }
3662
3663       XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_src);
3664       SURFXML_BUFFER_SET(link_ctn_id, route_src);
3665       A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3666       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3667       {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
3668       SURFXML_START_TAG(link_ctn);
3669       SURFXML_END_TAG(link_ctn);
3670
3671       XBT_DEBUG("<link_ctn\tid=\"%s_backbone\"/>", cluster_id);
3672       SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone", cluster_id));
3673       A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3674       SURFXML_START_TAG(link_ctn);
3675       SURFXML_END_TAG(link_ctn);
3676
3677       XBT_DEBUG("<link_ctn\tid=\"%s\"/>", route_dst);
3678       SURFXML_BUFFER_SET(link_ctn_id, route_dst);
3679       A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3680       if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3681       {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
3682       SURFXML_START_TAG(link_ctn);
3683       SURFXML_END_TAG(link_ctn);
3684
3685       XBT_DEBUG("</route>");
3686       SURFXML_END_TAG(route);
3687     }
3688   }
3689   xbt_dynar_free(&tab_elements_num);
3690
3691 #endif
3692
3693   free(router_id);
3694   free(link_backbone);
3695   free(link_router);
3696   xbt_dict_free(&patterns);
3697   free(availability_file);
3698   free(state_file);
3699
3700   XBT_DEBUG("</AS>");
3701   SURFXML_END_TAG(AS);
3702   XBT_DEBUG(" ");
3703
3704   surfxml_bufferstack_pop(1);
3705 }
3706 /*
3707  * This function take a string and replace parameters from patterns dict.
3708  * It returns the new value.
3709  */
3710 static char* replace_random_parameter(char * string)
3711 {
3712   char *test_string = NULL;
3713
3714   if(xbt_dict_size(random_value)==0)
3715     return string;
3716
3717   string = xbt_str_varsubst(string, patterns); // for patterns of cluster
3718   test_string = bprintf("${%s}", string);
3719   test_string = xbt_str_varsubst(test_string,random_value); //Add ${xxxxx} for random Generator
3720
3721   if (strcmp(test_string,"")) { //if not empty, keep this value.
3722     xbt_free(string);
3723     string = test_string;
3724   } //In other case take old value (without ${})
3725   else
3726         free(test_string);
3727   return string;
3728 }
3729
3730 static void clean_dict_random(void)
3731 {
3732         xbt_dict_free(&random_value);
3733         xbt_dict_free(&patterns);
3734 }
3735
3736 static void routing_parse_Speer(void)
3737 {
3738   static int AX_ptr = 0;
3739
3740   char *peer_id = A_surfxml_peer_id;
3741   char *peer_power = A_surfxml_peer_power;
3742   char *peer_bw_in = A_surfxml_peer_bw_in;
3743   char *peer_bw_out = A_surfxml_peer_bw_out;
3744   char *peer_lat = A_surfxml_peer_lat;
3745   char *peer_coord = A_surfxml_peer_coordinates;
3746   char *peer_state_file = A_surfxml_peer_state_file;
3747   char *peer_availability_file = A_surfxml_peer_availability_file;
3748
3749   char *host_id = NULL;
3750   char *router_id, *link_router, *link_backbone, *link_id_up, *link_id_down;
3751
3752   static unsigned int surfxml_buffer_stack_stack_ptr = 1;
3753   static unsigned int surfxml_buffer_stack_stack[1024];
3754
3755   surfxml_buffer_stack_stack[0] = 0;
3756
3757   surfxml_bufferstack_push(1);
3758
3759   SURFXML_BUFFER_SET(AS_id, peer_id);
3760
3761   SURFXML_BUFFER_SET(AS_routing, "Full");
3762   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Full\">", peer_id);
3763
3764   SURFXML_START_TAG(AS);
3765
3766   XBT_DEBUG(" ");
3767   host_id = bprintf("peer_%s", peer_id);
3768   router_id = bprintf("router_%s", peer_id);
3769   link_id_up = bprintf("link_%s_up", peer_id);
3770   link_id_down = bprintf("link_%s_down", peer_id);
3771
3772   link_router = bprintf("%s_link_router", peer_id);
3773   link_backbone = bprintf("%s_backbone", peer_id);
3774
3775   XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%s\"/>", host_id, peer_power);
3776   A_surfxml_host_state = A_surfxml_host_state_ON;
3777   SURFXML_BUFFER_SET(host_id, host_id);
3778   SURFXML_BUFFER_SET(host_power, peer_power);
3779   SURFXML_BUFFER_SET(host_availability, "1.0");
3780   SURFXML_BUFFER_SET(host_availability_file, peer_availability_file);
3781   SURFXML_BUFFER_SET(host_state_file, peer_state_file);
3782   SURFXML_BUFFER_SET(host_coordinates, "");
3783   SURFXML_START_TAG(host);
3784   SURFXML_END_TAG(host);
3785
3786   XBT_DEBUG("<router id=\"%s\"\tcoordinates=\"%s\"/>", router_id, peer_coord);
3787   SURFXML_BUFFER_SET(router_id, router_id);
3788   SURFXML_BUFFER_SET(router_coordinates, peer_coord);
3789   SURFXML_START_TAG(router);
3790   SURFXML_END_TAG(router);
3791
3792   XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id_up, peer_bw_in, peer_lat);
3793   A_surfxml_link_state = A_surfxml_link_state_ON;
3794   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3795   SURFXML_BUFFER_SET(link_id, link_id_up);
3796   SURFXML_BUFFER_SET(link_bandwidth, peer_bw_in);
3797   SURFXML_BUFFER_SET(link_latency, peer_lat);
3798   SURFXML_BUFFER_SET(link_bandwidth_file, "");
3799   SURFXML_BUFFER_SET(link_latency_file, "");
3800   SURFXML_BUFFER_SET(link_state_file, "");
3801   SURFXML_START_TAG(link);
3802   SURFXML_END_TAG(link);
3803
3804   XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id_down, peer_bw_out, peer_lat);
3805   A_surfxml_link_state = A_surfxml_link_state_ON;
3806   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3807   SURFXML_BUFFER_SET(link_id, link_id_down);
3808   SURFXML_BUFFER_SET(link_bandwidth, peer_bw_out);
3809   SURFXML_BUFFER_SET(link_latency, peer_lat);
3810   SURFXML_BUFFER_SET(link_bandwidth_file, "");
3811   SURFXML_BUFFER_SET(link_latency_file, "");
3812   SURFXML_BUFFER_SET(link_state_file, "");
3813   SURFXML_START_TAG(link);
3814   SURFXML_END_TAG(link);
3815
3816   XBT_DEBUG(" ");
3817
3818   // begin here
3819   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", host_id, router_id);
3820   XBT_DEBUG("symmetrical=\"NO\">");
3821   SURFXML_BUFFER_SET(route_src, host_id);
3822   SURFXML_BUFFER_SET(route_dst, router_id);
3823   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3824   SURFXML_START_TAG(route);
3825
3826   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", link_id_up);
3827   SURFXML_BUFFER_SET(link_ctn_id, link_id_up);
3828   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3829   SURFXML_START_TAG(link_ctn);
3830   SURFXML_END_TAG(link_ctn);
3831
3832   XBT_DEBUG("</route>");
3833   SURFXML_END_TAG(route);
3834
3835   //Opposite Route
3836   XBT_DEBUG("<route\tsrc=\"%s\"\tdst=\"%s\"", router_id, host_id);
3837   XBT_DEBUG("symmetrical=\"NO\">");
3838   SURFXML_BUFFER_SET(route_src, router_id);
3839   SURFXML_BUFFER_SET(route_dst, host_id);
3840   A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3841   SURFXML_START_TAG(route);
3842
3843   XBT_DEBUG("<link_ctn\tid=\"%s\"/>", link_id_down);
3844   SURFXML_BUFFER_SET(link_ctn_id, link_id_down);
3845   A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3846   SURFXML_START_TAG(link_ctn);
3847   SURFXML_END_TAG(link_ctn);
3848
3849   XBT_DEBUG("</route>");
3850   SURFXML_END_TAG(route);
3851
3852   XBT_DEBUG("</AS>");
3853   SURFXML_END_TAG(AS);
3854   XBT_DEBUG(" ");
3855
3856   //xbt_dynar_free(&tab_elements_num);
3857         free(host_id);
3858         free(router_id);
3859         free(link_router);
3860         free(link_backbone);
3861         free(link_id_up);
3862         free(link_id_down);
3863   surfxml_bufferstack_pop(1);
3864 }
3865
3866 static void routing_parse_Srandom(void)
3867 {
3868           double mean, std, min, max, seed;
3869           char *random_id = A_surfxml_random_id;
3870           char *random_radical = A_surfxml_random_radical;
3871           char *rd_name = NULL;
3872           char *rd_value;
3873           surf_parse_get_double(&mean,A_surfxml_random_mean);
3874           surf_parse_get_double(&std,A_surfxml_random_std_deviation);
3875           surf_parse_get_double(&min,A_surfxml_random_min);
3876           surf_parse_get_double(&max,A_surfxml_random_max);
3877           surf_parse_get_double(&seed,A_surfxml_random_seed);
3878
3879           double res = 0;
3880           int i = 0;
3881           random_data_t random = xbt_new0(s_random_data_t, 1);
3882           char *tmpbuf;
3883
3884           xbt_dynar_t radical_elements;
3885           unsigned int iter;
3886           char *groups;
3887           int start, end;
3888           xbt_dynar_t radical_ends;
3889
3890           random->generator = A_surfxml_random_generator;
3891           random->seed = seed;
3892           random->min = min;
3893           random->max = max;
3894
3895           /* Check user stupidities */
3896           if (max < min)
3897             THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
3898           if (mean < min)
3899             THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean,
3900                    min);
3901           if (mean > max)
3902             THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean,
3903                    max);
3904
3905           /* normalize the mean and standard deviation before storing */
3906           random->mean = (mean - min) / (max - min);
3907           random->std = std / (max - min);
3908
3909           if (random->mean * (1 - random->mean) < random->std * random->std)
3910             THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
3911                    random->mean, random->std);
3912
3913           XBT_DEBUG("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
3914           random_id,
3915           random->min,
3916           random->max,
3917           random->mean,
3918           random->std,
3919           random->generator,
3920           random->seed,
3921           random_radical);
3922
3923           if(xbt_dict_size(random_value)==0)
3924                   random_value = xbt_dict_new();
3925
3926           if(!strcmp(random_radical,""))
3927           {
3928                   res = random_generate(random);
3929                   rd_value = bprintf("%f",res);
3930                   xbt_dict_set(random_value, random_id, rd_value, free);
3931           }
3932           else
3933           {
3934                   radical_elements = xbt_str_split(random_radical, ",");
3935                   xbt_dynar_foreach(radical_elements, iter, groups) {
3936                         radical_ends = xbt_str_split(groups, "-");
3937                         switch (xbt_dynar_length(radical_ends)) {
3938                         case 1:
3939                                           xbt_assert(!xbt_dict_get_or_null(random_value,random_id),"Custom Random '%s' already exists !",random_id);
3940                                           res = random_generate(random);
3941                                           tmpbuf = bprintf("%s%d",random_id,atoi(xbt_dynar_getfirst_as(radical_ends,char *)));
3942                                           xbt_dict_set(random_value, tmpbuf, bprintf("%f",res), free);
3943                                           xbt_free(tmpbuf);
3944                                           break;
3945
3946                         case 2:   surf_parse_get_int(&start,
3947                                                                                  xbt_dynar_get_as(radical_ends, 0, char *));
3948                                           surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
3949                                           for (i = start; i <= end; i++) {
3950                                                   xbt_assert(!xbt_dict_get_or_null(random_value,random_id),"Custom Random '%s' already exists !",bprintf("%s%d",random_id,i));
3951                                                   res = random_generate(random);
3952                           tmpbuf = bprintf("%s%d",random_id,i);
3953                                                   xbt_dict_set(random_value, tmpbuf, bprintf("%f",res), free);
3954                           xbt_free(tmpbuf);
3955                                           }
3956                                           break;
3957                         default:
3958                                 XBT_INFO("Malformed radical");
3959                         }
3960                         res = random_generate(random);
3961                         rd_name  = bprintf("%s_router",random_id);
3962                         rd_value = bprintf("%f",res);
3963                         xbt_dict_set(random_value, rd_name, rd_value, free);
3964
3965                         xbt_dynar_free(&radical_ends);
3966                   }
3967                   free(rd_name);
3968                   xbt_dynar_free(&radical_elements);
3969           }
3970 }
3971
3972 static void routing_parse_Erandom(void)
3973 {
3974         xbt_dict_cursor_t cursor = NULL;
3975         char *key;
3976         char *elem;
3977
3978         xbt_dict_foreach(random_value, cursor, key, elem) {
3979           XBT_DEBUG("%s = %s",key,elem);
3980         }
3981
3982 }
3983
3984
3985 /*
3986  * New methods to init the routing model component from the lua script
3987  */
3988
3989 /*
3990  * calling parse_S_AS_lua with lua values
3991  */
3992 void routing_AS_init(const char *AS_id, const char *AS_routing)
3993 {
3994   parse_S_AS_lua((char *) AS_id, (char *) AS_routing);
3995 }
3996
3997 /*
3998  * calling parse_E_AS_lua to fisnish the creation of routing component
3999  */
4000 void routing_AS_end(const char *AS_id)
4001 {
4002   parse_E_AS_lua((char *) AS_id);
4003 }
4004
4005 /*
4006  * add a host to the network element list
4007  */
4008
4009 void routing_add_host(const char *host_id)
4010 {
4011   parse_S_host_lua((char *) host_id, (char*)""); // FIXME propagate coordinate system to lua
4012 }
4013
4014 /*
4015  * Set a new link on the actual list of link for a route or ASroute
4016  */
4017 void routing_add_link(const char *link_id)
4018 {
4019   parse_E_link_c_ctn_new_elem_lua((char *) link_id);
4020 }
4021
4022 /*
4023  *Set the endpoints for a route
4024  */
4025 void routing_set_route(const char *src_id, const char *dst_id)
4026 {
4027   parse_S_route_new_and_endpoints_lua(src_id, dst_id);
4028 }
4029
4030 /*
4031  * Store the route by calling parse_E_route_store_route
4032  */
4033 void routing_store_route(void)
4034 {
4035   parse_E_route_store_route();
4036 }