Logo AND Algorithmique Numérique Distribuée

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