Logo AND Algorithmique Numérique Distribuée

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