Logo AND Algorithmique Numérique Distribuée

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