Logo AND Algorithmique Numérique Distribuée

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