Logo AND Algorithmique Numérique Distribuée

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