Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Implementation of function is router
[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
29 /* Prototypes of each model */
30 static void* model_full_create(void); /* create structures for full routing model */
31 static void  model_full_load(void);   /* load parse functions for full routing model */
32 static void  model_full_unload(void); /* unload parse functions for full routing model */
33 static void  model_full_end(void);    /* finalize the creation of full routing model */
34
35 static void* model_floyd_create(void); /* create structures for floyd routing model */
36 static void  model_floyd_load(void);   /* load parse functions for floyd routing model */
37 static void  model_floyd_unload(void); /* unload parse functions for floyd routing model */
38 static void  model_floyd_end(void);    /* finalize the creation of floyd routing model */
39
40 static void* model_dijkstra_both_create(int cached); /* create by calling dijkstra or dijkstracache */
41 static void* model_dijkstra_create(void);      /* create structures for dijkstra routing model */
42 static void* model_dijkstracache_create(void); /* create structures for dijkstracache routing model */
43 static void  model_dijkstra_both_load(void);   /* load parse functions for dijkstra routing model */
44 static void  model_dijkstra_both_unload(void); /* unload parse functions for dijkstra routing model */
45 static void  model_dijkstra_both_end(void);    /* finalize the creation of dijkstra routing model */
46
47 static void* model_rulebased_create(void); /* create structures for rulebased routing model */
48 static void  model_rulebased_load(void);   /* load parse functions for rulebased routing model */
49 static void  model_rulebased_unload(void); /* unload parse functions for rulebased routing model */
50 static void  model_rulebased_end(void);    /* finalize the creation of rulebased routing model */
51
52 static void* model_none_create(void); /* none routing model */
53 static void  model_none_load(void);   /* none routing model */
54 static void  model_none_unload(void); /* none routing model */
55 static void  model_none_end(void);    /* none routing model */
56
57 static void routing_full_parse_Scluster(void);/*cluster bypass*/
58
59 /* this lines are only for replace use like index in the model table */
60 typedef enum {
61         SURF_MODEL_FULL=0,
62         SURF_MODEL_FLOYD,
63         SURF_MODEL_DIJKSTRA,
64         SURF_MODEL_DIJKSTRACACHE,
65         SURF_MODEL_NONE,
66 #ifdef HAVE_PCRE_LIB
67         SURF_MODEL_RULEBASED
68 #endif
69 } e_routing_types;
70
71
72 /* must be finish with null and carefull if change de order */
73 struct s_model_type routing_models[] =
74 { {"Full", "Full routing data (fast, large memory requirements, fully expressive)",
75   model_full_create, model_full_load, model_full_unload, model_full_end },  
76   {"Floyd", "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
77   model_floyd_create, model_floyd_load, model_floyd_unload, model_floyd_end },
78   {"Dijkstra", "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
79   model_dijkstra_create ,model_dijkstra_both_load, model_dijkstra_both_unload, model_dijkstra_both_end },
80   {"DijkstraCache", "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
81   model_dijkstracache_create, model_dijkstra_both_load, model_dijkstra_both_unload, model_dijkstra_both_end },
82   {"none", "No routing (usable with Constant network only)",
83   model_none_create, model_none_load, model_none_unload, model_none_end },
84 #ifdef HAVE_PCRE_LIB
85   {"RuleBased", "Rule-Based routing data (...)", model_rulebased_create, model_rulebased_load, model_rulebased_unload, model_rulebased_end },
86 #endif
87   {NULL,NULL,NULL,NULL,NULL,NULL}};
88
89 /* ************************************************************************** */
90 /* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
91
92 static void generic_set_processing_unit(routing_component_t rc, const char* name);
93 static void generic_set_autonomous_system(routing_component_t rc, const char* name);
94 static void generic_set_route(routing_component_t rc, const char* src, const char* dst, route_t route);
95 static void generic_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route);
96 static void generic_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route);
97
98 /* ************************************************************************** */
99 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
100
101 static xbt_dynar_t generic_get_onelink_routes (routing_component_t rc);
102 static int generic_is_router (routing_component_t rc, const char *name);
103 static route_extended_t generic_get_bypassroute(routing_component_t rc, const char* src, const char* dst);
104
105 /* ************************************************************************** */
106 /* ****************** GENERIC AUX FUNCTIONS (declarations) ****************** */
107
108 static route_extended_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy, void* data, int order);
109 static void generic_free_route(route_t route);
110 static void generic_free_extended_route(route_extended_t e_route);
111 static routing_component_t generic_autonomous_system_exist(routing_component_t rc, char* element);
112 static routing_component_t generic_processing_units_exist(routing_component_t rc, char* element);
113 static void generic_src_dst_check(routing_component_t rc, const char* src, const char* dst);
114
115 /* ************************************************************************** */
116 /* **************************** GLOBAL FUNCTIONS **************************** */
117   
118 /* global parse functions */
119 static char* src = NULL;    /* temporary store the source name of a route */
120 static char* dst = NULL;    /* temporary store the destination name of a route */
121 static char* gw_src = NULL; /* temporary store the gateway source name of a route */
122 static char* gw_dst = NULL; /* temporary store the gateway destination name of a route */
123 static xbt_dynar_t link_list = NULL; /* temporary store of current list link of a route */ 
124
125 /**
126  * \brief Add a "host" to the network element list
127  */
128 static void  parse_S_host(char* host_id) {
129   if( current_routing->hierarchy == SURF_ROUTING_NULL ) current_routing->hierarchy = SURF_ROUTING_BASE;
130   xbt_assert1(!xbt_dict_get_or_null(global_routing->where_network_elements,host_id),
131       "Reading a host, processing unit \"%s\" already exist",host_id);
132   xbt_assert1(current_routing->set_processing_unit,
133       "no defined method \"set_processing_unit\" in \"%s\"",current_routing->name);
134   (*(current_routing->set_processing_unit))(current_routing,host_id);
135   xbt_dict_set(global_routing->where_network_elements,host_id,(void*)current_routing,NULL);
136 }
137
138 /*
139  * \brief Add a host to the network element list from XML
140  */
141 static void parse_S_host_XML(void)
142 {
143         parse_S_host(A_surfxml_host_id);
144 }
145
146 /*
147  * \brief Add a host to the network element list from lua script
148  */
149 static void parse_S_host_lua(char *host_id)
150 {
151         parse_S_host(host_id);
152 }
153 /*
154  *
155  */
156
157 /**
158  * \brief Add a "router" to the network element list
159  */
160 static void parse_S_router(void) {
161   if( current_routing->hierarchy == SURF_ROUTING_NULL ) current_routing->hierarchy = SURF_ROUTING_BASE;
162   xbt_assert1(!xbt_dict_get_or_null(global_routing->where_network_elements,A_surfxml_router_id),
163       "Reading a router, processing unit \"%s\" already exist",A_surfxml_router_id);
164   xbt_assert1(current_routing->set_processing_unit,
165       "no defined method \"set_processing_unit\" in \"%s\"",current_routing->name);
166   (*(current_routing->set_processing_unit))(current_routing,A_surfxml_router_id);
167   xbt_dict_set(global_routing->where_network_elements,A_surfxml_router_id,(void*)current_routing,NULL); 
168   #ifdef HAVE_TRACING
169     TRACE_surf_host_declaration (A_surfxml_router_id, 0);
170   #endif
171 }
172
173 /**
174  * \brief Set the endponints for a route
175  */
176 static void parse_S_route_new_and_endpoints(char *src_id,char *dst_id) {
177   if( src != NULL && dst != NULL && link_list != NULL )
178     THROW2(arg_error,0,"Route between %s to %s can not be defined",src_id,dst_id);
179   src = src_id;
180   dst = dst_id;
181   xbt_assert2(strlen(src)>0||strlen(dst)>0,
182       "Some limits are null in the route between \"%s\" and \"%s\"",src,dst);
183   link_list = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
184 }
185
186 /**
187  * \breif Set the endpoints for a route from XML
188  */
189 static void parse_S_route_new_and_endpoints_XML(void)
190 {
191         parse_S_route_new_and_endpoints(A_surfxml_route_src,A_surfxml_route_dst);
192 }
193
194 /**
195  * \breif Set the endpoints for a route from lua
196  */
197 static void parse_S_route_new_and_endpoints_lua(char *id_src,char *id_dst)
198 {
199         parse_S_route_new_and_endpoints(id_src,id_dst);
200 }
201
202 /**
203  * \brief Set the endponints and gateways for a ASroute
204  */
205 static void parse_S_ASroute_new_and_endpoints(void) {
206   if( src != NULL && dst != NULL && link_list != NULL )
207     THROW2(arg_error,0,"Route between %s to %s can not be defined",A_surfxml_ASroute_src,A_surfxml_ASroute_dst);
208   src = A_surfxml_ASroute_src;
209   dst = A_surfxml_ASroute_dst;
210   gw_src = A_surfxml_ASroute_gw_src;
211   gw_dst = A_surfxml_ASroute_gw_dst;
212   xbt_assert2(strlen(src)>0||strlen(dst)>0||strlen(gw_src)>0||strlen(gw_dst)>0,
213       "Some limits are null in the route between \"%s\" and \"%s\"",src,dst);
214   link_list = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
215 }
216
217 /**
218  * \brief Set the endponints for a bypassRoute
219  */
220 static void parse_S_bypassRoute_new_and_endpoints(void) {
221   if( src != NULL && dst != NULL && link_list != NULL )
222     THROW2(arg_error,0,"Bypass Route between %s to %s can not be defined",A_surfxml_bypassRoute_src,A_surfxml_bypassRoute_dst);
223   src = A_surfxml_bypassRoute_src;
224   dst = A_surfxml_bypassRoute_dst;
225   gw_src = A_surfxml_bypassRoute_gw_src;
226   gw_dst = A_surfxml_bypassRoute_gw_dst;
227   xbt_assert2(strlen(src)>0||strlen(dst)>0||strlen(gw_src)>0||strlen(gw_dst)>0,
228       "Some limits are null in the route between \"%s\" and \"%s\"",src,dst);
229   link_list = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
230 }
231
232 /**
233  * \brief Set a new link on the actual list of link for a route or ASroute
234  */
235 static void parse_E_link_ctn_new_elem(char *link_id) {
236   char *val;
237   val = xbt_strdup(link_id);
238   xbt_dynar_push(link_list, &val);
239 }
240
241 /**
242  * \brief Set a new link on the actual list of link for a route or ASroute from XML
243  */
244
245 static void parse_E_link_ctn_new_elem_XML(void)
246 {
247         parse_E_link_ctn_new_elem(A_surfxml_link_ctn_id);
248 }
249
250 /**
251  * \brief Set a new link on the actual list of link for a route or ASroute from lua
252  */
253 static void parse_E_link_c_ctn_new_elem_lua(char *link_id) {
254
255         parse_E_link_ctn_new_elem(link_id);
256 }
257
258 /**
259  * \brief Store the route by calling the set_route function of the current routing component
260  */
261 static void parse_E_route_store_route(void) {
262   route_t route = xbt_new0(s_route_t,1);
263   route->link_list = link_list;
264 //   xbt_assert1(generic_processing_units_exist(current_routing,src),"the \"%s\" processing units gateway does not exist",src);
265 //   xbt_assert1(generic_processing_units_exist(current_routing,dst),"the \"%s\" processing units gateway does not exist",dst);
266     xbt_assert1(current_routing->set_route,"no defined method \"set_route\" in \"%s\"",current_routing->name);
267   (*(current_routing->set_route))(current_routing,src,dst,route);
268   link_list = NULL;
269   src = NULL;
270   dst = NULL;
271 }
272
273 /**
274  * \brief Store the ASroute by calling the set_ASroute function of the current routing component
275  */
276 static void parse_E_ASroute_store_route(void) {
277   route_extended_t e_route = xbt_new0(s_route_extended_t,1);
278   e_route->generic_route.link_list = link_list;
279   e_route->src_gateway = xbt_strdup(gw_src);
280   e_route->dst_gateway = xbt_strdup(gw_dst);  
281 //   xbt_assert1(generic_autonomous_system_exist(current_routing,src),"the \"%s\" autonomous system does not exist",src);
282 //   xbt_assert1(generic_autonomous_system_exist(current_routing,dst),"the \"%s\" autonomous system does not exist",dst);
283 //   xbt_assert1(generic_processing_units_exist(current_routing,gw_src),"the \"%s\" processing units gateway does not exist",gw_src);
284 //   xbt_assert1(generic_processing_units_exist(current_routing,gw_dst),"the \"%s\" processing units gateway does not exist",gw_dst);
285   xbt_assert1(current_routing->set_ASroute,"no defined method \"set_ASroute\" in \"%s\"",current_routing->name);
286   (*(current_routing->set_ASroute))(current_routing,src,dst,e_route);
287   link_list = NULL;
288   src = NULL;
289   dst = NULL;
290   gw_src = NULL;
291   gw_dst = NULL;
292 }
293
294 /**
295  * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
296  */
297 static void parse_E_bypassRoute_store_route(void) {
298   route_extended_t e_route = xbt_new0(s_route_extended_t,1);
299   e_route->generic_route.link_list = link_list;
300   e_route->src_gateway = xbt_strdup(gw_src);
301   e_route->dst_gateway = xbt_strdup(gw_dst);
302 //   xbt_assert1(generic_autonomous_system_exist(current_routing,src),"the \"%s\" autonomous system does not exist",src);
303 //   xbt_assert1(generic_autonomous_system_exist(current_routing,dst),"the \"%s\" autonomous system does not exist",dst);
304 //   xbt_assert1(generic_processing_units_exist(current_routing,gw_src),"the \"%s\" processing units gateway does not exist",gw_src);
305 //   xbt_assert1(generic_processing_units_exist(current_routing,gw_dst),"the \"%s\" processing units gateway does not exist",gw_dst);
306   xbt_assert1(current_routing->set_bypassroute,"no defined method \"set_bypassroute\" in \"%s\"",current_routing->name);
307   (*(current_routing->set_bypassroute))(current_routing,src,dst,e_route);
308   link_list = NULL;
309   src = NULL;
310   dst = NULL;
311   gw_src = NULL;
312   gw_dst = NULL;
313 }
314
315 /**
316  * \brief Make a new routing component
317  *
318  * make the new structure and
319  * set the parsing functions to allows parsing the part of the routing tree
320  */
321 static void parse_S_AS(char* AS_id,char* AS_routing) {
322   routing_component_t new_routing;
323   model_type_t model = NULL;
324   char* wanted = AS_routing;
325   int cpt;
326   /* seach the routing model */
327   for (cpt=0;routing_models[cpt].name;cpt++)
328     if (!strcmp(wanted,routing_models[cpt].name))
329           model = &routing_models[cpt];
330   /* if its not exist, error */
331   if( model == NULL ) {
332     fprintf(stderr,"Routing model %s not found. Existing models:\n",wanted);
333     for (cpt=0;routing_models[cpt].name;cpt++)
334       if (!strcmp(wanted,routing_models[cpt].name))
335         fprintf(stderr,"   %s: %s\n",routing_models[cpt].name,routing_models[cpt].desc);
336     xbt_die(NULL);
337   }
338
339   /* make a new routing component */
340   new_routing = (routing_component_t)(*(model->create))();
341   new_routing->routing = model;
342   new_routing->hierarchy = SURF_ROUTING_NULL;
343   new_routing->name = xbt_strdup(AS_id);
344   new_routing->routing_sons = xbt_dict_new();
345   //INFO2("Routing %s for AS %s",A_surfxml_AS_routing,A_surfxml_AS_id);
346   
347   if( current_routing == NULL && global_routing->root == NULL ){
348     
349     /* it is the first one */
350     new_routing->routing_father = NULL;
351     global_routing->root = new_routing;
352     
353   } else if( current_routing != NULL && global_routing->root != NULL ) { 
354     
355     xbt_assert1(!xbt_dict_get_or_null(current_routing->routing_sons,AS_id),
356            "The AS \"%s\" already exist",AS_id);
357      /* it is a part of the tree */
358     new_routing->routing_father = current_routing;
359     /* set the father behavior */
360     if( current_routing->hierarchy == SURF_ROUTING_NULL ) current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
361     /* add to the sons dictionary */
362     xbt_dict_set(current_routing->routing_sons,AS_id,(void*)new_routing,NULL);
363     /* add to the father element list */
364     (*(current_routing->set_autonomous_system))(current_routing,AS_id);
365     /* unload the prev parse rules */
366     (*(current_routing->routing->unload))();
367     
368   } else {
369     THROW0(arg_error,0,"All defined components must be belong to a AS");
370   }
371   /* set the new parse rules */
372   (*(new_routing->routing->load))();
373   /* set the new current component of the tree */
374   current_routing = new_routing;
375 }
376
377 /*
378  * Detect the routing model type of the routing component from XML platforms
379  */
380 static void parse_S_AS_XML(void)
381 {
382         parse_S_AS(A_surfxml_AS_id,A_surfxml_AS_routing);
383 }
384
385 /*
386  * define the routing model type of routing component from lua script
387  */
388 static void parse_S_AS_lua(char* id,char* mode)
389 {
390         parse_S_AS(id,mode);
391 }
392
393
394 /**
395  * \brief Finish the creation of a new routing component
396  *
397  * When you finish to read the routing component, other structures must be created. 
398  * the "end" method allow to do that for any routing model type
399  */
400 static void parse_E_AS(char *AS_id) {
401
402   if( current_routing == NULL ) {
403     THROW1(arg_error,0,"Close AS(%s), that never open",AS_id);
404   } else {
405       xbt_assert1(!xbt_dict_get_or_null(global_routing->where_network_elements,current_routing->name),
406           "The AS \"%s\" already exist",current_routing->name);
407       xbt_dict_set(global_routing->where_network_elements,current_routing->name,current_routing->routing_father,NULL);
408       (*(current_routing->routing->unload))();
409       (*(current_routing->routing->end))();
410       current_routing = current_routing->routing_father;
411       if( current_routing != NULL )
412         (*(current_routing->routing->load))();
413   }
414 }
415
416 /*
417  * \brief Finish the creation of a new routing component from XML
418  */
419 static void parse_E_AS_XML(void)
420 {
421         parse_E_AS(A_surfxml_AS_id);
422 }
423
424 /*
425  * \brief Finish the creation of a new routing component from lua
426  */
427 static void parse_E_AS_lua(char *id)
428 {
429         parse_E_AS(id);
430 }
431
432 /* Aux Business methods */
433
434 /**
435  * \brief Get the AS father and the first elements of the chain
436  *
437  * \param src the source host name 
438  * \param dst the destination host name
439  * 
440  * Get the common father of the to processing units, and the first different 
441  * father in the chain
442  */
443 static xbt_dynar_t elements_father(const char* src,const char* dst) {
444   
445   xbt_assert0(src&&dst,"bad parameters for \"elements_father\" method");
446   
447   xbt_dynar_t result = xbt_dynar_new(sizeof(char*), NULL);
448   
449   routing_component_t src_as, dst_as;
450   int index_src, index_dst, index_father_src, index_father_dst;
451   xbt_dynar_t path_src = NULL;
452   xbt_dynar_t path_dst = NULL;
453   routing_component_t current = NULL;
454   routing_component_t* current_src = NULL;
455   routing_component_t* current_dst = NULL;
456   routing_component_t* father = NULL;
457   
458   /* (1) find the as where the src and dst are located */
459   src_as = xbt_dict_get_or_null(global_routing->where_network_elements,src);
460   dst_as = xbt_dict_get_or_null(global_routing->where_network_elements,dst); 
461   xbt_assert2(src_as&&dst_as, "Ask for route \"from\"(%s) or \"to\"(%s) no found",src,dst);
462   
463   /* (2) find the path to the root routing component */
464   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
465   current = src_as; 
466   while( current != NULL ) {
467     xbt_dynar_push(path_src,&current);
468     current = current->routing_father;
469   }
470   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
471   current = dst_as; 
472   while( current != NULL ) {
473     xbt_dynar_push(path_dst,&current);
474     current = current->routing_father;
475   }
476   
477   /* (3) find the common father */
478   index_src  = (path_src->used)-1;
479   index_dst  = (path_dst->used)-1;
480   current_src = xbt_dynar_get_ptr(path_src,index_src);
481   current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
482   while( index_src >= 0 && index_dst >= 0 && *current_src == *current_dst ) {
483     current_src = xbt_dynar_get_ptr(path_src,index_src);
484     current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
485     index_src--;
486     index_dst--;
487   }
488   index_src++;
489   index_dst++;
490   current_src = xbt_dynar_get_ptr(path_src,index_src);
491   current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
492
493   /* (4) they are not in the same routing component, make the path */
494   index_father_src = index_src+1;
495   index_father_dst = index_dst+1;
496    
497   if(*current_src==*current_dst)
498     father = current_src;
499   else
500     father = xbt_dynar_get_ptr(path_src,index_father_src);
501   
502   /* (5) result generation */
503   xbt_dynar_push(result,father); /* first same the father of src and dst */
504   xbt_dynar_push(result,current_src); /* second the first different father of src */
505   xbt_dynar_push(result,current_dst); /* three  the first different father of dst */
506   
507   xbt_dynar_free(&path_src);
508   xbt_dynar_free(&path_dst);
509   
510   return result;
511 }
512
513 /* Global Business methods */
514
515 /**
516  * \brief Recursive function for get_route
517  *
518  * \param src the source host name 
519  * \param dst the destination host name
520  * 
521  * This fuction is call by "get_route". It allow to walk through the 
522  * routing components tree.
523  */
524 static route_extended_t _get_route(const char* src,const char* dst) {
525   
526   void* link;
527   unsigned int cpt=0;
528   
529   DEBUG2("Solve route  \"%s\" to \"%s\"",src,dst);
530      
531   xbt_assert0(src&&dst,"bad parameters for \"_get_route\" method");
532   
533   route_extended_t e_route, e_route_cnt, e_route_src=NULL, e_route_dst=NULL;
534   
535   xbt_dynar_t elem_father_list = elements_father(src,dst);
536   
537   routing_component_t common_father = xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
538   routing_component_t src_father    = xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
539   routing_component_t dst_father    = xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
540   
541   e_route = xbt_new0(s_route_extended_t,1);
542   e_route->src_gateway = NULL;
543   e_route->dst_gateway = NULL;
544   e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
545   
546   if(src_father==dst_father) { /* SURF_ROUTING_BASE */
547     
548     if( strcmp(src,dst) ){
549       e_route_cnt = (*(common_father->get_route))(common_father,src,dst);
550       xbt_assert2(e_route_cnt,"no route between \"%s\" and \"%s\"",src,dst);
551       xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
552         xbt_dynar_push(e_route->generic_route.link_list,&link);
553       }
554       generic_free_extended_route(e_route_cnt);
555     }
556     
557   } else { /* SURF_ROUTING_RECURSIVE */
558
559     route_extended_t e_route_bypass = NULL;
560     
561     if(common_father->get_bypass_route)
562       e_route_bypass = (*(common_father->get_bypass_route))(common_father,src,dst);
563     
564     if(e_route_bypass)
565       e_route_cnt = e_route_bypass;    
566     else
567       e_route_cnt = (*(common_father->get_route))(common_father,src_father->name,dst_father->name);
568     
569     xbt_assert2(e_route_cnt,"no route between \"%s\" and \"%s\"",src_father->name,dst_father->name);
570
571     xbt_assert2( (e_route_cnt->src_gateway==NULL) == (e_route_cnt->dst_gateway==NULL) ,
572       "bad gateway for route between \"%s\" and \"%s\"",src,dst);
573
574     if( src != e_route_cnt->src_gateway ) {
575       e_route_src = _get_route(src,e_route_cnt->src_gateway);
576       xbt_assert2(e_route_src,"no route between \"%s\" and \"%s\"",src,e_route_cnt->src_gateway);
577       xbt_dynar_foreach(e_route_src->generic_route.link_list, cpt, link) {
578         xbt_dynar_push(e_route->generic_route.link_list,&link);
579       }
580     }
581     
582     xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
583       xbt_dynar_push(e_route->generic_route.link_list,&link);
584     }
585     
586     if( e_route_cnt->dst_gateway != dst ) {
587       e_route_dst = _get_route(e_route_cnt->dst_gateway,dst);
588       xbt_assert2(e_route_dst,"no route between \"%s\" and \"%s\"",e_route_cnt->dst_gateway,dst);
589       xbt_dynar_foreach(e_route_dst->generic_route.link_list, cpt, link) {
590         xbt_dynar_push(e_route->generic_route.link_list,&link);
591       }
592     }
593     
594     e_route->src_gateway = xbt_strdup(e_route_cnt->src_gateway);
595     e_route->dst_gateway = xbt_strdup(e_route_cnt->dst_gateway);
596
597     generic_free_extended_route(e_route_src);
598     generic_free_extended_route(e_route_cnt);
599     generic_free_extended_route(e_route_dst);
600   }
601   
602   xbt_dynar_free(&elem_father_list);
603   
604   return e_route; 
605 }
606
607 /**
608  * \brief Generic method: find a route between hosts
609  *
610  * \param src the source host name 
611  * \param dst the destination host name
612  * 
613  * walk through the routing components tree and find a route between hosts
614  * by calling the differents "get_route" functions in each routing component
615  */
616 static xbt_dynar_t get_route(const char* src,const char* dst) {
617   
618   route_extended_t e_route;
619   xbt_dynar_t elem_father_list = elements_father(src,dst);
620   routing_component_t common_father = xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
621   
622   if(strcmp(src,dst))
623     e_route = _get_route(src,dst);
624   else
625     e_route = (*(common_father->get_route))(common_father,src,dst);
626   
627   xbt_assert2(e_route,"no route between \"%s\" and \"%s\"",src,dst);
628   
629   if(global_routing->last_route) xbt_dynar_free( &(global_routing->last_route) );
630   global_routing->last_route = e_route->generic_route.link_list;
631  
632   if(e_route->src_gateway) xbt_free(e_route->src_gateway);
633   if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
634   
635   xbt_free(e_route);
636   xbt_dynar_free(&elem_father_list);
637   
638   if( xbt_dynar_length(global_routing->last_route)==0 )
639     return NULL;
640   else
641     return global_routing->last_route;
642 }
643
644 /**
645  * \brief Recursive function for finalize
646  *
647  * \param rc the source host name 
648  * 
649  * This fuction is call by "finalize". It allow to finalize the 
650  * AS or routing components. It delete all the structures.
651  */
652 static void _finalize(routing_component_t rc) {
653   if(rc) {
654     xbt_dict_cursor_t cursor = NULL;
655     char *key;
656     routing_component_t elem;
657     xbt_dict_foreach(rc->routing_sons, cursor, key, elem) {
658       _finalize(elem);
659     }
660     xbt_dict_t tmp_sons = rc->routing_sons;
661     char* tmp_name = rc->name;
662     xbt_dict_free(&tmp_sons);
663     xbt_free(tmp_name);
664     xbt_assert1(rc->finalize,"no defined method \"finalize\" in \"%s\"",current_routing->name);
665     (*(rc->finalize))(rc);
666   }
667 }
668
669 /**
670  * \brief Generic method: delete all the routing structures
671  * 
672  * walk through the routing components tree and delete the structures
673  * by calling the differents "finalize" functions in each routing component
674  */
675 static void finalize(void) {
676   /* delete recursibly all the tree */  
677   _finalize(global_routing->root);
678   /* delete "where" dict */
679   xbt_dict_free(&(global_routing->where_network_elements));
680   /* delete last_route */
681   xbt_dynar_free(&(global_routing->last_route));
682   /* delete global routing structure */
683   xbt_free(global_routing);
684 }
685
686 static xbt_dynar_t recursive_get_onelink_routes (routing_component_t rc)
687 {
688   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
689
690   //adding my one link routes
691   unsigned int cpt;
692   void *link;
693   xbt_dynar_t onelink_mine = rc->get_onelink_routes (rc);
694   if (onelink_mine){
695     xbt_dynar_foreach(onelink_mine, cpt, link) {
696       xbt_dynar_push(ret,&link);
697     }
698   }
699
700   //recursing
701   char *key;
702   xbt_dict_cursor_t cursor=NULL;
703   routing_component_t rc_child;
704   xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
705     xbt_dynar_t onelink_child = recursive_get_onelink_routes (rc_child);
706     if (onelink_child){
707       xbt_dynar_foreach(onelink_child, cpt, link) {
708         xbt_dynar_push(ret,&link);
709       }
710     }
711   }
712   return ret;
713 }
714
715 static xbt_dynar_t get_onelink_routes(void)
716 {
717   return recursive_get_onelink_routes (global_routing->root);
718 }
719
720 static int is_router(const char *name)
721 {
722         routing_component_t rc=NULL;
723         rc = xbt_dict_get(global_routing->where_network_elements,name);
724         return rc->is_router(rc, name);
725 }
726
727 /**
728  * \brief Generic method: create the global routing schema
729  * 
730  * Make a global routing structure and set all the parsing functions.
731  */
732 void routing_model_create(size_t size_of_links, void* loopback) {
733   
734   /* config the uniq global routing */
735   global_routing = xbt_new0(s_routing_global_t,1);
736   global_routing->where_network_elements = xbt_dict_new();
737   global_routing->root = NULL;
738   global_routing->get_route = get_route;
739   global_routing->get_onelink_routes = get_onelink_routes;
740   global_routing->is_router = is_router;
741   global_routing->finalize = finalize;
742   global_routing->loopback = loopback;
743   global_routing->size_of_link = size_of_links;
744   global_routing->last_route = xbt_dynar_new(size_of_links, NULL);
745   
746   /* no current routing at moment */
747   current_routing = NULL;
748
749   /* parse generic elements */
750   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_S_host_XML);
751   surfxml_add_callback(STag_surfxml_router_cb_list, &parse_S_router);
752
753   surfxml_add_callback(STag_surfxml_route_cb_list, &parse_S_route_new_and_endpoints_XML);
754   surfxml_add_callback(STag_surfxml_ASroute_cb_list, &parse_S_ASroute_new_and_endpoints);
755   surfxml_add_callback(STag_surfxml_bypassRoute_cb_list, &parse_S_bypassRoute_new_and_endpoints);
756   
757   surfxml_add_callback(ETag_surfxml_link_ctn_cb_list, &parse_E_link_ctn_new_elem_XML);
758   
759   surfxml_add_callback(ETag_surfxml_route_cb_list, &parse_E_route_store_route);
760   surfxml_add_callback(ETag_surfxml_ASroute_cb_list, &parse_E_ASroute_store_route);
761   surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list, &parse_E_bypassRoute_store_route);
762   
763   surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
764   surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
765
766   surfxml_add_callback(STag_surfxml_cluster_cb_list, &routing_full_parse_Scluster);
767
768 }
769
770 /* ************************************************************************** */
771 /* *************************** FULL ROUTING ********************************* */
772
773 #define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
774
775 /* Routing model structure */
776
777 typedef struct {
778   s_routing_component_t generic_routing;
779   xbt_dict_t parse_routes; /* store data during the parse process */
780   xbt_dict_t to_index; /* char* -> network_element_t */
781   xbt_dict_t bypassRoutes;
782   route_extended_t *routing_table;
783 } s_routing_component_full_t,*routing_component_full_t;
784
785 /* Business methods */
786 static xbt_dynar_t full_get_onelink_routes(routing_component_t rc)
787 {
788   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
789
790   routing_component_full_t routing = (routing_component_full_t)rc;
791   int table_size = xbt_dict_length(routing->to_index);
792   xbt_dict_cursor_t c1 = NULL, c2 = NULL;
793   char *k1, *d1, *k2, *d2;
794   xbt_dict_foreach(routing->to_index, c1, k1, d1) {
795     xbt_dict_foreach (routing->to_index, c2, k2, d2) {
796       int *src_id = xbt_dict_get_or_null(routing->to_index, k1);
797       int *dst_id = xbt_dict_get_or_null(routing->to_index, k2);
798       xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst);
799       route_extended_t route = TO_ROUTE_FULL(*src_id,*dst_id);
800       if (route){
801         if (xbt_dynar_length(route->generic_route.link_list) == 1){
802           void *link = *(void**)xbt_dynar_get_ptr(route->generic_route.link_list,0);
803
804           onelink_t onelink = xbt_new0 (s_onelink_t, 1);
805           onelink->src = xbt_strdup (k1);
806           onelink->dst = xbt_strdup (k2);
807           onelink->link_ptr = link;
808           xbt_dynar_push (ret, &onelink);
809         }
810       }
811     }
812   }
813   return ret;
814 }
815
816 static int full_is_router(routing_component_t rc, const char *name)
817 {
818   routing_component_full_t routing = (routing_component_full_t)rc;
819
820   if(SURF_NETWORK_ELEMENT_ROUTER == ( (network_element_t) xbt_dict_get(routing->to_index , name) )->type )
821           return 1;
822   else
823           return 0;
824 }
825
826 static route_extended_t full_get_route(routing_component_t rc, const char* src,const char* dst) {
827   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
828   
829   /* set utils vars */
830   routing_component_full_t routing = (routing_component_full_t)rc;
831   int table_size = xbt_dict_length(routing->to_index);
832   
833   generic_src_dst_check(rc,src,dst);
834   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
835   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
836   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
837
838   route_extended_t e_route = NULL;
839   route_extended_t new_e_route = NULL;
840   void* link;
841   unsigned int cpt=0;
842
843   e_route = TO_ROUTE_FULL(*src_id,*dst_id);
844   
845   if(e_route) {
846     new_e_route = xbt_new0(s_route_extended_t,1);
847     new_e_route->src_gateway = xbt_strdup(e_route->src_gateway);
848     new_e_route->dst_gateway = xbt_strdup(e_route->dst_gateway);
849     new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
850     xbt_dynar_foreach(e_route->generic_route.link_list, cpt, link) {
851       xbt_dynar_push(new_e_route->generic_route.link_list,&link);
852     }
853   }
854   return new_e_route;
855 }
856
857 static void full_finalize(routing_component_t rc) {
858   routing_component_full_t routing = (routing_component_full_t)rc;
859   int table_size = xbt_dict_length(routing->to_index);
860   int i,j;
861   if (routing) {
862     /* Delete routing table */
863     for (i=0;i<table_size;i++)
864       for (j=0;j<table_size;j++)
865         generic_free_extended_route(TO_ROUTE_FULL(i,j));
866     xbt_free(routing->routing_table);
867     /* Delete bypass dict */
868     xbt_dict_free(&routing->bypassRoutes);
869     /* Delete index dict */
870     xbt_dict_free(&(routing->to_index));
871     /* Delete structure */
872     xbt_free(rc);
873   }
874 }
875
876 /* Creation routing model functions */
877
878 static void* model_full_create(void) {
879   routing_component_full_t new_component =  xbt_new0(s_routing_component_full_t,1);
880   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
881   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
882   new_component->generic_routing.set_route = generic_set_route;
883   new_component->generic_routing.set_ASroute = generic_set_ASroute;
884   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
885   new_component->generic_routing.get_route = full_get_route;
886   new_component->generic_routing.get_onelink_routes = full_get_onelink_routes;
887   new_component->generic_routing.is_router = full_is_router;
888   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
889   new_component->generic_routing.finalize = full_finalize;
890   new_component->to_index = xbt_dict_new();
891   new_component->bypassRoutes = xbt_dict_new();
892   new_component->parse_routes = xbt_dict_new();
893   return new_component;
894 }
895
896 static void model_full_load(void) {
897  /* use "surfxml_add_callback" to add a parse function call */
898 }
899
900 static void model_full_unload(void) {
901  /* use "surfxml_del_callback" to remove a parse function call */
902 }
903
904 static void  model_full_end(void) {
905   
906   char *key, *end;
907   const char* sep = "#";
908   int src_id, dst_id;
909   unsigned int i, j;
910   route_t route;
911   route_extended_t e_route;
912   void* data;
913   
914   xbt_dict_cursor_t cursor = NULL;
915   xbt_dynar_t keys = NULL;
916   
917   /* set utils vars */
918   routing_component_full_t routing = ((routing_component_full_t)current_routing);
919   int table_size = xbt_dict_length(routing->to_index);
920   
921   /* Create the routing table */
922   routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
923   
924   /* Put the routes in position */
925   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
926     keys = xbt_str_split_str(key, sep);
927     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
928     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
929     TO_ROUTE_FULL(src_id,dst_id) = generic_new_extended_route(current_routing->hierarchy,data,1);
930      xbt_dynar_free(&keys);
931    }
932
933    /* delete the parse table */
934   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
935     route = (route_t)data;
936     xbt_dynar_free(&(route->link_list));
937     xbt_free(data);
938   }
939       
940   /* delete parse dict */
941   xbt_dict_free(&(routing->parse_routes));
942
943   /* Add the loopback if needed */
944   if(current_routing->hierarchy == SURF_ROUTING_BASE) {
945     for (i = 0; i < table_size; i++) {
946       e_route = TO_ROUTE_FULL(i, i);
947       if(!e_route) {
948         e_route = xbt_new0(s_route_extended_t,1);
949         e_route->src_gateway = NULL;
950         e_route->dst_gateway = NULL;
951         e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
952         xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
953         TO_ROUTE_FULL(i, i) = e_route;
954       }
955     }
956   }
957
958   /* Shrink the dynar routes (save unused slots) */
959   for (i=0;i<table_size;i++)
960     for (j=0;j<table_size;j++)
961       if(TO_ROUTE_FULL(i,j))
962         xbt_dynar_shrink(TO_ROUTE_FULL(i,j)->generic_route.link_list,0);
963 }
964
965 /* ************************************************************************** */
966 /* *************************** FLOYD ROUTING ******************************** */
967
968 #define TO_FLOYD_COST(i,j) cost_table[(i)+(j)*table_size]
969 #define TO_FLOYD_PRED(i,j) (routing->predecessor_table)[(i)+(j)*table_size]
970 #define TO_FLOYD_LINK(i,j) (routing->link_table)[(i)+(j)*table_size]
971
972 /* Routing model structure */
973
974 typedef struct {
975   s_routing_component_t generic_routing;
976   /* vars for calculate the floyd algorith. */
977   int *predecessor_table;
978   route_extended_t *link_table; /* char* -> int* */
979   xbt_dict_t to_index;
980   xbt_dict_t bypassRoutes;
981   /* store data during the parse process */  
982   xbt_dict_t parse_routes; 
983 } s_routing_component_floyd_t,*routing_component_floyd_t;
984
985 static route_extended_t floyd_get_route(routing_component_t rc, const char* src,const char* dst);
986
987 /* Business methods */
988 static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
989 {
990   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
991
992   routing_component_floyd_t routing = (routing_component_floyd_t)rc;
993   //int table_size = xbt_dict_length(routing->to_index);
994   xbt_dict_cursor_t c1 = NULL, c2 = NULL;
995   char *k1, *d1, *k2, *d2;
996   xbt_dict_foreach(routing->to_index, c1, k1, d1) {
997     xbt_dict_foreach (routing->to_index, c2, k2, d2) {
998       route_extended_t route = floyd_get_route (rc, k1, k2);
999       if (route){
1000         if (xbt_dynar_length(route->generic_route.link_list) == 1){
1001           void *link = *(void**)xbt_dynar_get_ptr(route->generic_route.link_list,0);
1002           onelink_t onelink = xbt_new0 (s_onelink_t, 1);
1003           onelink->src = xbt_strdup (k1);
1004           onelink->dst = xbt_strdup (k2);
1005           onelink->link_ptr = link;
1006           xbt_dynar_push (ret, &onelink);
1007         }
1008       }
1009     }
1010   }
1011   return ret;
1012 }
1013
1014 static int floyd_is_router(routing_component_t rc, const char *name)
1015 {
1016   routing_component_floyd_t routing = (routing_component_floyd_t)rc;
1017
1018   if(SURF_NETWORK_ELEMENT_ROUTER == ( (network_element_t) xbt_dict_get(routing->to_index , name) )->type )
1019           return 1;
1020   else
1021           return 0;
1022 }
1023
1024 static route_extended_t floyd_get_route(routing_component_t rc, const char* src,const char* dst) {
1025   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
1026   
1027   /* set utils vars */
1028   routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1029   int table_size = xbt_dict_length(routing->to_index);
1030   
1031   generic_src_dst_check(rc,src,dst);
1032   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
1033   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
1034   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
1035   
1036   /* create a result route */
1037   route_extended_t new_e_route = xbt_new0(s_route_extended_t,1);
1038   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1039   new_e_route->src_gateway = NULL;
1040   new_e_route->dst_gateway = NULL;
1041   
1042   int first = 1;
1043   int pred = *dst_id;
1044   int prev_pred = 0;
1045   char *gw_src=NULL,*gw_dst=NULL, *prev_gw_src,*prev_gw_dst, *first_gw=NULL;
1046   unsigned int cpt;
1047   void* link;
1048   xbt_dynar_t links;
1049   
1050   do {
1051     prev_pred = pred;
1052     pred = TO_FLOYD_PRED(*src_id, pred);
1053     if(pred == -1) /* if no pred in route -> no route to host */
1054       break;      
1055     xbt_assert2(TO_FLOYD_LINK(pred,prev_pred),"Invalid link for the route between \"%s\" or \"%s\"", src, dst);
1056     
1057     prev_gw_src = gw_src;
1058     prev_gw_dst = gw_dst;
1059     
1060     route_extended_t e_route = TO_FLOYD_LINK(pred,prev_pred);
1061     gw_src = e_route->src_gateway;
1062     gw_dst = e_route->dst_gateway;
1063     
1064     if(first) first_gw = gw_dst;
1065     
1066     if(rc->hierarchy == SURF_ROUTING_RECURSIVE && !first && strcmp(gw_dst,prev_gw_src)) {
1067       xbt_dynar_t e_route_as_to_as = (*(global_routing->get_route))(gw_dst,prev_gw_src);
1068       xbt_assert2(e_route_as_to_as,"no route between \"%s\" and \"%s\"",gw_dst,prev_gw_src);
1069       links = e_route_as_to_as;
1070       int pos = 0;
1071       xbt_dynar_foreach(links, cpt, link) {
1072         xbt_dynar_insert_at(new_e_route->generic_route.link_list,pos,&link);
1073         pos++;
1074       }
1075     }
1076     
1077     links = e_route->generic_route.link_list;
1078     xbt_dynar_foreach(links, cpt, link) {
1079       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1080     }
1081     first=0;
1082     
1083   } while(pred != *src_id);
1084   xbt_assert4(pred != -1, "no route from host %d to %d (\"%s\" to \"%s\")", *src_id, *dst_id,src,dst);
1085   
1086   if(rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1087     new_e_route->src_gateway = xbt_strdup(gw_src);
1088     new_e_route->dst_gateway = xbt_strdup(first_gw);
1089   }
1090   
1091   return new_e_route;
1092 }
1093
1094 static void floyd_finalize(routing_component_t rc) {
1095    routing_component_floyd_t routing = (routing_component_floyd_t)rc;
1096   int i,j,table_size;
1097   if (routing) {
1098     table_size = xbt_dict_length(routing->to_index);
1099     /* Delete link_table */
1100     for (i=0;i<table_size;i++)
1101       for (j=0;j<table_size;j++)
1102         generic_free_extended_route(TO_FLOYD_LINK(i,j));
1103     xbt_free(routing->link_table);
1104     /* Delete bypass dict */
1105     xbt_dict_free(&routing->bypassRoutes);
1106     /* Delete index dict */
1107     xbt_dict_free(&(routing->to_index));
1108     /* Delete dictionary index dict, predecessor and links table */
1109     xbt_free(routing->predecessor_table);
1110     /* Delete structure */
1111     xbt_free(rc);
1112   }
1113 }
1114
1115 static void* model_floyd_create(void) {
1116   routing_component_floyd_t new_component = xbt_new0(s_routing_component_floyd_t,1);
1117   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
1118   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
1119   new_component->generic_routing.set_route = generic_set_route;
1120   new_component->generic_routing.set_ASroute = generic_set_ASroute;
1121   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1122   new_component->generic_routing.get_route = floyd_get_route;
1123   new_component->generic_routing.get_onelink_routes = floyd_get_onelink_routes;
1124   new_component->generic_routing.is_router = floyd_is_router;
1125   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
1126   new_component->generic_routing.finalize = floyd_finalize;
1127   new_component->to_index = xbt_dict_new();
1128   new_component->bypassRoutes = xbt_dict_new();
1129   new_component->parse_routes = xbt_dict_new();
1130   return new_component;
1131 }
1132
1133 static void  model_floyd_load(void) {
1134  /* use "surfxml_add_callback" to add a parse function call */
1135 }
1136
1137 static void  model_floyd_unload(void) {
1138  /* use "surfxml_del_callback" to remove a parse function call */
1139 }
1140
1141 static void  model_floyd_end(void) {
1142   
1143   routing_component_floyd_t routing = ((routing_component_floyd_t)current_routing);
1144   xbt_dict_cursor_t cursor = NULL;
1145   double * cost_table;
1146   char *key,*data, *end;
1147   const char *sep = "#";
1148   xbt_dynar_t keys;
1149   int src_id, dst_id;
1150   unsigned int i,j,a,b,c;
1151
1152   /* set the size of inicial table */
1153   int table_size = xbt_dict_length(routing->to_index);
1154   
1155   /* Create Cost, Predecessor and Link tables */
1156   cost_table = xbt_new0(double, table_size*table_size); /* link cost from host to host */
1157   routing->predecessor_table = xbt_new0(int, table_size*table_size); /* predecessor host numbers */
1158   routing->link_table = xbt_new0(route_extended_t, table_size*table_size); /* actual link between src and dst */
1159
1160   /* Initialize costs and predecessors*/
1161   for(i = 0; i<table_size;i++)
1162     for(j = 0; j<table_size;j++) {
1163         TO_FLOYD_COST(i,j) = DBL_MAX;
1164         TO_FLOYD_PRED(i,j) = -1;
1165         TO_FLOYD_LINK(i,j) = NULL; /* fixed, missing in the previous version */
1166     }
1167
1168    /* Put the routes in position */
1169   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1170     keys = xbt_str_split_str(key, sep);
1171     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
1172     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
1173     TO_FLOYD_LINK(src_id,dst_id) = generic_new_extended_route(current_routing->hierarchy,data,0);
1174     TO_FLOYD_PRED(src_id,dst_id) = src_id;
1175     /* set link cost */
1176     TO_FLOYD_COST(src_id,dst_id) = ((TO_FLOYD_LINK(src_id,dst_id))->generic_route.link_list)->used; /* count of links, old model assume 1 */
1177     xbt_dynar_free(&keys);
1178   }
1179
1180   /* Add the loopback if needed */
1181   if(current_routing->hierarchy == SURF_ROUTING_BASE) {
1182     for (i = 0; i < table_size; i++) {
1183       route_extended_t e_route = TO_FLOYD_LINK(i, i);
1184       if(!e_route) {
1185         e_route = xbt_new0(s_route_extended_t,1);
1186         e_route->src_gateway = NULL;
1187         e_route->dst_gateway = NULL;
1188         e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1189         xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
1190         TO_FLOYD_LINK(i,i) = e_route;
1191         TO_FLOYD_PRED(i,i) = i;
1192         TO_FLOYD_COST(i,i) = 1;
1193       }
1194     }
1195   }
1196   /* Calculate path costs */
1197   for(c=0;c<table_size;c++) {
1198     for(a=0;a<table_size;a++) {
1199       for(b=0;b<table_size;b++) {
1200         if(TO_FLOYD_COST(a,c) < DBL_MAX && TO_FLOYD_COST(c,b) < DBL_MAX) {
1201           if(TO_FLOYD_COST(a,b) == DBL_MAX || 
1202             (TO_FLOYD_COST(a,c)+TO_FLOYD_COST(c,b) < TO_FLOYD_COST(a,b))) {
1203             TO_FLOYD_COST(a,b) = TO_FLOYD_COST(a,c)+TO_FLOYD_COST(c,b);
1204             TO_FLOYD_PRED(a,b) = TO_FLOYD_PRED(c,b);
1205           }
1206         }
1207       }
1208     }
1209   }
1210
1211    /* delete the parse table */
1212   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1213     route_t route = (route_t)data;
1214     xbt_dynar_free(&(route->link_list));
1215     xbt_free(data);
1216   }
1217   
1218   /* delete parse dict */
1219   xbt_dict_free(&(routing->parse_routes));
1220
1221   /* cleanup */
1222   xbt_free(cost_table);
1223 }
1224
1225 /* ************************************************************************** */
1226 /* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
1227
1228 typedef struct {
1229   s_routing_component_t generic_routing;
1230   xbt_dict_t to_index;
1231   xbt_dict_t bypassRoutes;
1232   xbt_graph_t route_graph;   /* xbt_graph */
1233   xbt_dict_t graph_node_map; /* map */
1234   xbt_dict_t route_cache;    /* use in cache mode */
1235   int cached;
1236   xbt_dict_t parse_routes;
1237 } s_routing_component_dijkstra_t,*routing_component_dijkstra_t;
1238
1239
1240 typedef struct graph_node_data {
1241   int id; 
1242   int graph_id; /* used for caching internal graph id's */
1243 } s_graph_node_data_t, * graph_node_data_t;
1244
1245 typedef struct graph_node_map_element {
1246   xbt_node_t node;
1247 } s_graph_node_map_element_t, * graph_node_map_element_t;
1248
1249 typedef struct route_cache_element {
1250   int * pred_arr;
1251   int size;
1252 } s_route_cache_element_t, * route_cache_element_t;     
1253
1254 /* Free functions */
1255
1256 static void route_cache_elem_free(void *e) {
1257   route_cache_element_t elm=(route_cache_element_t)e;
1258   if (elm) {
1259     xbt_free(elm->pred_arr);
1260     xbt_free(elm);
1261   }
1262 }
1263
1264 static void graph_node_map_elem_free(void *e) {
1265   graph_node_map_element_t elm = (graph_node_map_element_t)e;
1266   if(elm) {
1267     xbt_free(elm);
1268   }
1269 }
1270
1271 static void graph_edge_data_free(void *e) {
1272   route_extended_t e_route = (route_extended_t)e;
1273   if(e_route) {
1274     xbt_dynar_free(&(e_route->generic_route.link_list));
1275     if(e_route->src_gateway) xbt_free(e_route->src_gateway);
1276     if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
1277     xbt_free(e_route);
1278   }
1279 }
1280
1281 /* Utility functions */
1282
1283 static xbt_node_t route_graph_new_node(routing_component_dijkstra_t rc, int id, int graph_id) {
1284   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1285   xbt_node_t node = NULL;
1286   graph_node_data_t data = NULL;
1287   graph_node_map_element_t elm = NULL;
1288
1289   data = xbt_new0(struct graph_node_data, 1);
1290   data->id = id;
1291   data->graph_id = graph_id;
1292   node = xbt_graph_new_node(routing->route_graph, data);
1293
1294   elm = xbt_new0(struct graph_node_map_element, 1);
1295   elm->node = node;
1296   xbt_dict_set_ext(routing->graph_node_map, (char*)(&id), sizeof(int), (xbt_set_elm_t)elm, &graph_node_map_elem_free);
1297
1298   return node;
1299 }
1300  
1301 static graph_node_map_element_t graph_node_map_search(routing_component_dijkstra_t rc, int id) {
1302   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1303   graph_node_map_element_t elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&id), sizeof(int));
1304   return elm;
1305 }
1306
1307 /* Parsing */
1308
1309 static void route_new_dijkstra(routing_component_dijkstra_t rc, int src_id, int dst_id, route_extended_t e_route ) {
1310   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1311
1312   xbt_node_t src = NULL;
1313   xbt_node_t dst = NULL;
1314   graph_node_map_element_t src_elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&src_id), sizeof(int));
1315   graph_node_map_element_t dst_elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&dst_id), sizeof(int));
1316
1317   if(src_elm)
1318     src = src_elm->node;
1319
1320   if(dst_elm)
1321     dst = dst_elm->node;
1322
1323   /* add nodes if they don't exist in the graph */
1324   if(src_id == dst_id && src == NULL && dst == NULL) {
1325     src = route_graph_new_node(rc,src_id, -1);
1326     dst = src;
1327   } else {
1328     if(src == NULL) {
1329       src = route_graph_new_node(rc,src_id, -1);
1330     }
1331     if(dst == NULL) {
1332       dst = route_graph_new_node(rc,dst_id, -1);
1333     }
1334   }
1335
1336   /* add link as edge to graph */
1337   xbt_graph_new_edge(routing->route_graph, src, dst, e_route);
1338 }
1339
1340 static void add_loopback_dijkstra(routing_component_dijkstra_t rc) {
1341   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1342
1343   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1344
1345   xbt_node_t node = NULL;
1346   unsigned int cursor2;
1347   xbt_dynar_foreach(nodes, cursor2, node) {
1348     xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node); 
1349     xbt_edge_t edge = NULL;
1350     unsigned int cursor;
1351
1352     int found = 0;
1353     xbt_dynar_foreach(out_edges, cursor, edge) {
1354       xbt_node_t other_node = xbt_graph_edge_get_target(edge);
1355       if(other_node == node) {
1356         found = 1;
1357         break;
1358       }
1359     }
1360
1361     if(!found) {
1362       route_extended_t e_route = xbt_new0(s_route_extended_t,1);
1363       e_route->src_gateway = NULL;
1364       e_route->dst_gateway = NULL;
1365       e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1366       xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
1367       xbt_graph_new_edge(routing->route_graph, node, node, e_route);
1368     }
1369   }
1370 }
1371
1372 /* Business methods */
1373 static xbt_dynar_t dijkstra_get_onelink_routes(routing_component_t rc)
1374 {
1375   xbt_die("\"dijkstra_get_onelink_routes\" function not implemented yet");
1376 }
1377
1378 static int dijkstra_is_router(routing_component_t rc, const char *name)
1379 {
1380   routing_component_dijkstra_t routing = (routing_component_dijkstra_t)rc;
1381
1382   if(SURF_NETWORK_ELEMENT_ROUTER == ( (network_element_t) xbt_dict_get(routing->to_index , name) )->type )
1383           return 1;
1384   else
1385           return 0;
1386 }
1387
1388 static route_extended_t dijkstra_get_route(routing_component_t rc, const char* src,const char* dst) {
1389   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
1390   
1391   /* set utils vars */
1392   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1393   
1394   generic_src_dst_check(rc,src,dst);
1395   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
1396   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
1397   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
1398   
1399   /* create a result route */
1400   route_extended_t new_e_route = xbt_new0(s_route_extended_t,1);
1401   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1402   new_e_route->src_gateway = NULL;
1403   new_e_route->dst_gateway = NULL;
1404   
1405   int *pred_arr = NULL;
1406   int src_node_id = 0;
1407   int dst_node_id = 0;
1408   int * nodeid = NULL;
1409   int v;
1410   route_extended_t e_route;
1411   int size = 0;
1412   unsigned int cpt;
1413   void* link;
1414   xbt_dynar_t links = NULL;
1415   route_cache_element_t elm = NULL;
1416   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1417   
1418   /* Use the graph_node id mapping set to quickly find the nodes */
1419   graph_node_map_element_t src_elm = graph_node_map_search(routing,*src_id);
1420   graph_node_map_element_t dst_elm = graph_node_map_search(routing,*dst_id);
1421   xbt_assert2(src_elm != NULL && dst_elm != NULL, "src %d or dst %d does not exist", *src_id, *dst_id);
1422   src_node_id = ((graph_node_data_t)xbt_graph_node_get_data(src_elm->node))->graph_id;
1423   dst_node_id = ((graph_node_data_t)xbt_graph_node_get_data(dst_elm->node))->graph_id;
1424
1425   /* if the src and dst are the same */  /* fixed, missing in the previous version */
1426   if( src_node_id == dst_node_id ) {
1427     
1428     xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
1429     xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
1430     xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_s_v, node_e_v);
1431
1432     xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
1433     
1434     e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1435
1436     links = e_route->generic_route.link_list;
1437     xbt_dynar_foreach(links, cpt, link) {
1438       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1439     }
1440   
1441     return new_e_route;
1442   }
1443   
1444   if(routing->cached) {
1445     /*check if there is a cached predecessor list avail */
1446     elm = (route_cache_element_t)xbt_dict_get_or_null_ext(routing->route_cache, (char*)(&src_id), sizeof(int));
1447   }
1448
1449   if(elm) { /* cached mode and cache hit */
1450     pred_arr = elm->pred_arr;
1451   } else { /* not cached mode or cache miss */
1452     double * cost_arr = NULL;
1453     xbt_heap_t pqueue = NULL;
1454     int i = 0;
1455
1456     int nr_nodes = xbt_dynar_length(nodes);
1457     cost_arr = xbt_new0(double, nr_nodes); /* link cost from src to other hosts */
1458     pred_arr = xbt_new0(int, nr_nodes);    /* predecessors in path from src */
1459     pqueue = xbt_heap_new(nr_nodes, xbt_free);
1460
1461     /* initialize */
1462     cost_arr[src_node_id] = 0.0;
1463
1464     for(i = 0; i < nr_nodes; i++) {
1465       if(i != src_node_id) {
1466         cost_arr[i] = DBL_MAX;
1467       }
1468
1469       pred_arr[i] = 0;
1470
1471       /* initialize priority queue */
1472       nodeid = xbt_new0(int, 1);
1473       *nodeid = i;
1474       xbt_heap_push(pqueue, nodeid, cost_arr[i]);
1475
1476     }
1477
1478     /* apply dijkstra using the indexes from the graph's node array */
1479     while(xbt_heap_size(pqueue) > 0) {
1480       int * v_id = xbt_heap_pop(pqueue);
1481       xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
1482       xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node); 
1483       xbt_edge_t edge = NULL;
1484       unsigned int cursor;
1485
1486       xbt_dynar_foreach(out_edges, cursor, edge) {
1487         xbt_node_t u_node = xbt_graph_edge_get_target(edge);
1488         graph_node_data_t data = xbt_graph_node_get_data(u_node);
1489         int u_id = data->graph_id;
1490         route_extended_t tmp_e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1491         int cost_v_u = (tmp_e_route->generic_route.link_list)->used;  /* count of links, old model assume 1 */
1492
1493         if(cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
1494           pred_arr[u_id] = *v_id;
1495           cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
1496           nodeid = xbt_new0(int, 1);
1497           *nodeid = u_id;
1498           xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
1499         }
1500       }
1501
1502       /* free item popped from pqueue */
1503       xbt_free(v_id);
1504     }
1505
1506     xbt_free(cost_arr);
1507     xbt_heap_free(pqueue);
1508   }
1509   
1510   /* compose route path with links */
1511   char *gw_src=NULL,*gw_dst=NULL, *prev_gw_src,*prev_gw_dst, *first_gw=NULL;
1512   
1513   for(v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
1514     xbt_node_t node_pred_v = xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
1515     xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
1516     xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_pred_v, node_v);
1517
1518     xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
1519     
1520     prev_gw_src = gw_src;
1521     prev_gw_dst = gw_dst;
1522     
1523     e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1524     gw_src = e_route->src_gateway;
1525     gw_dst = e_route->dst_gateway;
1526     
1527     if(v==dst_node_id) first_gw = gw_dst;
1528     
1529     if(rc->hierarchy == SURF_ROUTING_RECURSIVE && v!=dst_node_id && strcmp(gw_dst,prev_gw_src)) {
1530       xbt_dynar_t e_route_as_to_as = (*(global_routing->get_route))(gw_dst,prev_gw_src);
1531       xbt_assert2(e_route_as_to_as,"no route between \"%s\" and \"%s\"",gw_dst,prev_gw_src);
1532       links = e_route_as_to_as;
1533       int pos = 0;
1534       xbt_dynar_foreach(links, cpt, link) {
1535         xbt_dynar_insert_at(new_e_route->generic_route.link_list,pos,&link);
1536         pos++;
1537       }
1538     }
1539     
1540     links = e_route->generic_route.link_list;
1541     xbt_dynar_foreach(links, cpt, link) {
1542       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1543     }
1544     size++;
1545   }
1546
1547   if(rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1548     new_e_route->src_gateway = xbt_strdup(gw_src);
1549     new_e_route->dst_gateway = xbt_strdup(first_gw);
1550   }
1551
1552   if(routing->cached && elm == NULL) {
1553     /* add to predecessor list of the current src-host to cache */
1554     elm = xbt_new0(struct route_cache_element, 1);
1555     elm->pred_arr = pred_arr;
1556     elm->size = size;
1557     xbt_dict_set_ext(routing->route_cache, (char*)(&src_id), sizeof(int), (xbt_set_elm_t)elm, &route_cache_elem_free);
1558   }
1559
1560   if(!routing->cached)
1561     xbt_free(pred_arr);
1562   
1563   return new_e_route;
1564 }
1565
1566 static void dijkstra_finalize(routing_component_t rc) {
1567   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1568
1569   if (routing) {
1570     xbt_graph_free_graph(routing->route_graph, &xbt_free, &graph_edge_data_free, &xbt_free);
1571     xbt_dict_free(&routing->graph_node_map);
1572     if(routing->cached)
1573       xbt_dict_free(&routing->route_cache);
1574     /* Delete bypass dict */
1575     xbt_dict_free(&routing->bypassRoutes);
1576     /* Delete index dict */
1577     xbt_dict_free(&(routing->to_index));
1578     /* Delete structure */
1579     xbt_free(routing);
1580   }
1581 }
1582
1583 /* Creation routing model functions */
1584
1585 static void* model_dijkstra_both_create(int cached) {
1586   routing_component_dijkstra_t new_component = xbt_new0(s_routing_component_dijkstra_t,1);
1587   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
1588   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
1589   new_component->generic_routing.set_route = generic_set_route;
1590   new_component->generic_routing.set_ASroute = generic_set_ASroute;
1591   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1592   new_component->generic_routing.get_route = dijkstra_get_route;
1593   new_component->generic_routing.get_onelink_routes = dijkstra_get_onelink_routes;
1594   new_component->generic_routing.is_router = dijkstra_is_router;
1595   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
1596   new_component->generic_routing.finalize = dijkstra_finalize;
1597   new_component->cached = cached;
1598   new_component->to_index = xbt_dict_new();
1599   new_component->bypassRoutes = xbt_dict_new();
1600   new_component->parse_routes = xbt_dict_new();
1601   return new_component;
1602 }
1603
1604 static void* model_dijkstra_create(void) {
1605   return model_dijkstra_both_create(0);
1606 }
1607
1608 static void* model_dijkstracache_create(void) {
1609   return model_dijkstra_both_create(1);
1610 }
1611
1612 static void  model_dijkstra_both_load(void) {
1613  /* use "surfxml_add_callback" to add a parse function call */
1614 }
1615
1616 static void  model_dijkstra_both_unload(void) {
1617  /* use "surfxml_del_callback" to remove a parse function call */
1618 }
1619
1620 static void  model_dijkstra_both_end(void) {
1621   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) current_routing;
1622    xbt_dict_cursor_t cursor = NULL;
1623    char *key, *data, *end;
1624    const char *sep = "#";
1625    xbt_dynar_t keys;
1626   xbt_node_t node = NULL;
1627   unsigned int cursor2;
1628   xbt_dynar_t nodes = NULL;
1629   int src_id, dst_id;
1630   route_t route;
1631   
1632   /* Create the topology graph */
1633   routing->route_graph = xbt_graph_new_graph(1, NULL);
1634   routing->graph_node_map = xbt_dict_new();
1635   
1636   if(routing->cached)
1637     routing->route_cache = xbt_dict_new();
1638
1639   /* Put the routes in position */
1640   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1641     keys = xbt_str_split_str(key, sep);
1642     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
1643     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
1644     route_extended_t e_route = generic_new_extended_route(current_routing->hierarchy,data,0);
1645     route_new_dijkstra(routing,src_id,dst_id,e_route);
1646     xbt_dynar_free(&keys);
1647   }
1648
1649   /* delete the parse table */
1650   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1651     route = (route_t)data;
1652     xbt_dynar_free(&(route->link_list));
1653     xbt_free(data);
1654   }
1655       
1656   /* delete parse dict */
1657   xbt_dict_free(&(routing->parse_routes));
1658   
1659   /* Add the loopback if needed */
1660   if(current_routing->hierarchy == SURF_ROUTING_BASE)
1661     add_loopback_dijkstra(routing);
1662
1663   /* initialize graph indexes in nodes after graph has been built */
1664   nodes = xbt_graph_get_nodes(routing->route_graph);
1665
1666   xbt_dynar_foreach(nodes, cursor2, node) {
1667     graph_node_data_t data = xbt_graph_node_get_data(node);
1668     data->graph_id = cursor2;
1669   }
1670   
1671 }
1672
1673 #ifdef HAVE_PCRE_LIB
1674 /* ************************************************** */
1675 /* ************** RULE-BASED ROUTING **************** */
1676
1677 /* Routing model structure */
1678
1679 typedef struct {
1680   s_routing_component_t generic_routing;
1681   xbt_dict_t  dict_processing_units;
1682   xbt_dict_t  dict_autonomous_systems;
1683   xbt_dynar_t list_route;
1684   xbt_dynar_t list_ASroute;
1685 } s_routing_component_rulebased_t,*routing_component_rulebased_t;
1686
1687 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
1688 typedef struct s_rule_route_extended s_rule_route_extended_t, *rule_route_extended_t;
1689
1690 struct s_rule_route {
1691   xbt_dynar_t re_str_link; // dynar of char*
1692   pcre* re_src;
1693   pcre* re_dst;
1694 };
1695
1696 struct s_rule_route_extended {
1697   s_rule_route_t generic_rule_route;
1698   char* re_src_gateway;
1699   char* re_dst_gateway;
1700 };
1701
1702 static void rule_route_free(void *e) {
1703   rule_route_t* elem = (rule_route_t*)(e);
1704   if (*elem) {
1705     xbt_dynar_free(&(*elem)->re_str_link);
1706     pcre_free((*elem)->re_src);
1707     pcre_free((*elem)->re_dst);
1708     xbt_free((*elem));
1709   }
1710   (*elem) = NULL;
1711 }
1712
1713 static void rule_route_extended_free(void *e) {
1714   rule_route_extended_t* elem = (rule_route_extended_t*)e;
1715   if (*elem) {
1716     xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
1717     pcre_free((*elem)->generic_rule_route.re_src);
1718     pcre_free((*elem)->generic_rule_route.re_dst);
1719     xbt_free((*elem)->re_src_gateway);
1720     xbt_free((*elem)->re_dst_gateway);
1721     xbt_free((*elem));
1722   }
1723 }
1724
1725 /* Parse routing model functions */
1726
1727 static void model_rulebased_set_processing_unit(routing_component_t rc, const char* name) {
1728   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1729   xbt_dict_set(routing->dict_processing_units, name, (void*)(-1), NULL);
1730 }
1731
1732 static void model_rulebased_set_autonomous_system(routing_component_t rc, const char* name) {
1733   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1734   xbt_dict_set(routing->dict_autonomous_systems, name, (void*)(-1), NULL);  
1735 }
1736
1737 static void model_rulebased_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {
1738   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1739   rule_route_t ruleroute = xbt_new0(s_rule_route_t,1);
1740   const char *error;
1741   int erroffset;
1742   ruleroute->re_src = pcre_compile(src,0,&error,&erroffset,NULL);
1743   xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
1744   ruleroute->re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
1745   xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
1746   ruleroute->re_str_link = route->link_list;
1747   xbt_dynar_push(routing->list_route,&ruleroute);
1748   xbt_free(route);
1749 }
1750
1751 static void model_rulebased_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {
1752   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1753   rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t,1);
1754   const char *error;
1755   int erroffset;
1756   ruleroute_e->generic_rule_route.re_src = pcre_compile(src,0,&error,&erroffset,NULL);
1757   xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
1758   ruleroute_e->generic_rule_route.re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
1759   xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
1760   ruleroute_e->generic_rule_route.re_str_link = route->generic_route.link_list;
1761   ruleroute_e->re_src_gateway = route->src_gateway;
1762   ruleroute_e->re_dst_gateway = route->dst_gateway;
1763   xbt_dynar_push(routing->list_ASroute,&ruleroute_e);
1764   xbt_free(route->src_gateway);
1765   xbt_free(route->dst_gateway);
1766   xbt_free(route);
1767 }
1768
1769 static void model_rulebased_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
1770   xbt_die("bypass routing not supported for Route-Based model");
1771 }
1772
1773 #define BUFFER_SIZE 4096  /* result buffer size */
1774 #define OVECCOUNT 30      /* should be a multiple of 3 */
1775
1776 static char* remplace(char* value, const char** src_list, int src_size, const char** dst_list, int dst_size ) {
1777
1778   char result_result[BUFFER_SIZE];
1779   int i_result_buffer;
1780   int value_length = (int)strlen(value);
1781   int number=0;
1782   
1783   int i=0;
1784   i_result_buffer = 0;
1785   do {
1786     if( value[i] == '$' ) {
1787       i++; // skip $
1788       
1789       // find the number      
1790       int number_length = 0;
1791       while( '0' <= value[i+number_length] && value[i+number_length] <= '9' ) {
1792         number_length++;
1793       }
1794       xbt_assert2( number_length!=0, "bad string parameter, no number indication, at offset: %d (\"%s\")",i,value);
1795       
1796       // solve number
1797       number = atoi(value+i);
1798       i=i+number_length;
1799       xbt_assert2(i+2<value_length,"bad string parameter, too few chars, at offset: %d (\"%s\")",i,value);
1800       
1801       // solve the indication
1802       const char** param_list;
1803       int param_size;
1804       if( value[i] == 's' && value[i+1] == 'r' && value[i+2] == 'c' ) {
1805         param_list = src_list;
1806         param_size = src_size;
1807       } else  if( value[i] == 'd' && value[i+1] == 's' && value[i+2] == 't' ) {
1808         param_list = dst_list;
1809         param_size = dst_size;
1810       } else {
1811         xbt_assert2(0,"bad string parameter, support only \"src\" and \"dst\", at offset: %d (\"%s\")",i,value);
1812       }
1813       i=i+3;
1814       
1815       xbt_assert4( param_size >= number, "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",i,value,param_size,number);
1816       
1817       const char* param = param_list[number];
1818       int size = strlen(param);
1819       int cp;
1820       for(cp = 0; cp < size; cp++ ) {
1821         result_result[i_result_buffer] = param[cp];
1822         i_result_buffer++;
1823         if( i_result_buffer >= BUFFER_SIZE ) break;
1824       }
1825     } else {
1826       result_result[i_result_buffer] = value[i];
1827       i_result_buffer++;
1828       i++; // next char
1829     }
1830     
1831   } while(i<value_length && i_result_buffer < BUFFER_SIZE);
1832   
1833   xbt_assert2( i_result_buffer < BUFFER_SIZE, "solving string \"%s\", small buffer size (%d)",value,BUFFER_SIZE);
1834   result_result[i_result_buffer] = 0;
1835   return xbt_strdup(result_result);
1836 }
1837
1838 static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
1839 {
1840   xbt_die("\"rulebased_get_onelink_routes\" function not implemented yet");
1841 }
1842
1843 static int rulebased_is_router(routing_component_t rc, const char *name)
1844 {
1845           //routing_component_rulebased_t routing = (routing_component_rulebased_t)rc;
1846
1847 //PIERRE FIXME
1848
1849         xbt_die("\"rulebased_is_router\" function not implemented yet");
1850 }
1851
1852 /* Business methods */
1853 static route_extended_t rulebased_get_route(routing_component_t rc, const char* src,const char* dst) {
1854   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
1855
1856   /* set utils vars */
1857   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1858
1859   int are_processing_units;
1860   xbt_dynar_t rule_list;
1861   if( xbt_dict_get_or_null(routing->dict_processing_units,src) && xbt_dict_get_or_null(routing->dict_processing_units,dst) ) {
1862     are_processing_units = 1;
1863     rule_list = routing->list_route;
1864   } else if( xbt_dict_get_or_null(routing->dict_autonomous_systems,src) && xbt_dict_get_or_null(routing->dict_autonomous_systems,dst) ) {
1865     are_processing_units = 0;
1866     rule_list = routing->list_ASroute;    
1867   } else
1868      xbt_assert2(NULL, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
1869
1870   int rc_src = -1;
1871   int rc_dst = -1;
1872   int src_length = (int)strlen(src);
1873   int dst_length = (int)strlen(dst);
1874   
1875   xbt_dynar_t links_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1876   
1877   rule_route_t ruleroute;
1878   unsigned int cpt;
1879   int ovector_src[OVECCOUNT];
1880   int ovector_dst[OVECCOUNT];
1881   const char** list_src = NULL;
1882   const char** list_dst = NULL;
1883   xbt_dynar_foreach(rule_list, cpt, ruleroute) {
1884     rc_src = pcre_exec(ruleroute->re_src,NULL,src,src_length,0,0,ovector_src,OVECCOUNT);
1885     if( rc_src >= 0 ) {
1886       rc_dst = pcre_exec(ruleroute->re_dst,NULL,dst,dst_length,0,0,ovector_dst,OVECCOUNT);
1887       if( rc_dst >= 0 ) {
1888         xbt_assert1(!pcre_get_substring_list(src,ovector_src,rc_src,&list_src),"error solving substring list for src \"%s\"",src);
1889         xbt_assert1(!pcre_get_substring_list(dst,ovector_dst,rc_dst,&list_dst),"error solving substring list for src \"%s\"",dst);
1890         char* link_name;
1891         xbt_dynar_foreach(ruleroute->re_str_link, cpt, link_name) {
1892           char* new_link_name = remplace(link_name,list_src,rc_src,list_dst,rc_dst);
1893           void* link = xbt_dict_get_or_null(surf_network_model->resource_set, new_link_name);
1894           if (link)
1895             xbt_dynar_push(links_list,&link);
1896           else
1897             THROW1(mismatch_error,0,"Link %s not found", new_link_name);
1898           xbt_free(new_link_name);
1899         }
1900       }
1901     }
1902     if( rc_src >= 0 && rc_dst >= 0 ) break;
1903   }
1904   
1905   route_extended_t new_e_route = NULL;
1906   if(rc_src >= 0 && rc_dst >= 0) {
1907     new_e_route = xbt_new0(s_route_extended_t,1);
1908     new_e_route->generic_route.link_list = links_list;
1909   } else if( !strcmp(src,dst) && are_processing_units ) {
1910     new_e_route = xbt_new0(s_route_extended_t,1);
1911     xbt_dynar_push(links_list,&(global_routing->loopback));
1912     new_e_route->generic_route.link_list = links_list;
1913   } else { 
1914     xbt_dynar_free(&link_list);
1915   }
1916
1917   if(!are_processing_units && new_e_route)
1918   {
1919     rule_route_extended_t ruleroute_extended = (rule_route_extended_t)ruleroute;
1920     new_e_route->src_gateway = remplace(ruleroute_extended->re_src_gateway,list_src,rc_src,list_dst,rc_dst);
1921     new_e_route->dst_gateway = remplace(ruleroute_extended->re_dst_gateway,list_src,rc_src,list_dst,rc_dst);
1922   }
1923   
1924   if(list_src) pcre_free_substring_list(list_src);
1925   if(list_dst) pcre_free_substring_list(list_dst);
1926   
1927   return new_e_route;
1928 }
1929
1930 static route_extended_t rulebased_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {
1931   return NULL;
1932 }
1933
1934 static void rulebased_finalize(routing_component_t rc) {
1935   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1936   if (routing) {
1937     xbt_dict_free(&routing->dict_processing_units);
1938     xbt_dict_free(&routing->dict_autonomous_systems);
1939     xbt_dynar_free(&routing->list_route);
1940     xbt_dynar_free(&routing->list_ASroute);
1941     /* Delete structure */
1942     xbt_free(routing);
1943   }
1944 }
1945
1946 /* Creation routing model functions */
1947 static void* model_rulebased_create(void) {  
1948   routing_component_rulebased_t new_component =  xbt_new0(s_routing_component_rulebased_t,1);
1949   new_component->generic_routing.set_processing_unit = model_rulebased_set_processing_unit;
1950   new_component->generic_routing.set_autonomous_system = model_rulebased_set_autonomous_system;
1951   new_component->generic_routing.set_route = model_rulebased_set_route;
1952   new_component->generic_routing.set_ASroute = model_rulebased_set_ASroute;
1953   new_component->generic_routing.set_bypassroute = model_rulebased_set_bypassroute;
1954   new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes;
1955   new_component->generic_routing.is_router = rulebased_is_router;
1956   new_component->generic_routing.get_route = rulebased_get_route;
1957   new_component->generic_routing.get_bypass_route = NULL; //rulebased_get_bypass_route;
1958   new_component->generic_routing.finalize = rulebased_finalize;
1959   /* initialization of internal structures */
1960   new_component->dict_processing_units = xbt_dict_new();
1961   new_component->dict_autonomous_systems = xbt_dict_new();
1962   new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free);
1963   new_component->list_ASroute = xbt_dynar_new(sizeof(rule_route_extended_t), &rule_route_extended_free);
1964   return new_component;
1965 }
1966
1967 static void  model_rulebased_load(void) {
1968  /* use "surfxml_add_callback" to add a parse function call */
1969 }
1970
1971 static void  model_rulebased_unload(void) {
1972  /* use "surfxml_del_callback" to remove a parse function call */
1973 }
1974
1975 static void  model_rulebased_end(void) {
1976 }
1977
1978 #endif /* HAVE_PCRE_LIB */
1979
1980 /* ************************************************************************** */
1981 /* ******************************* NO ROUTING ******************************* */
1982
1983 /* Routing model structure */
1984 typedef struct {
1985   s_routing_component_t generic_routing;
1986 } s_routing_component_none_t,*routing_component_none_t;
1987
1988 /* Business methods */
1989 static xbt_dynar_t none_get_onelink_routes(routing_component_t rc){
1990   return NULL;
1991 }
1992 static int none_is_router(routing_component_t rc, const char *name){
1993   return -1;
1994 }
1995 static route_extended_t none_get_route(routing_component_t rc, const char* src,const char* dst){
1996   return NULL;
1997 }
1998 static route_extended_t none_get_bypass_route(routing_component_t rc, const char* src,const char* dst){
1999   return NULL;
2000 }
2001 static void none_finalize(routing_component_t rc) {
2002   xbt_free(rc);
2003 }
2004
2005 static void none_set_processing_unit(routing_component_t rc, const char* name) {}
2006 static void none_set_autonomous_system(routing_component_t rc, const char* name) {}
2007
2008 /* Creation routing model functions */
2009 static void* model_none_create(void) {
2010   routing_component_none_t new_component =  xbt_new0(s_routing_component_none_t,1);
2011   new_component->generic_routing.set_processing_unit = none_set_processing_unit;
2012   new_component->generic_routing.set_autonomous_system = none_set_autonomous_system;
2013   new_component->generic_routing.set_route = NULL;
2014   new_component->generic_routing.set_ASroute = NULL;
2015   new_component->generic_routing.set_bypassroute = NULL;
2016   new_component->generic_routing.get_route = none_get_route;
2017   new_component->generic_routing.get_onelink_routes = none_get_onelink_routes;
2018   new_component->generic_routing.is_router = none_is_router;
2019   new_component->generic_routing.get_bypass_route = none_get_bypass_route;
2020   new_component->generic_routing.finalize = none_finalize;
2021   return new_component;
2022 }
2023
2024 static void  model_none_load(void) {}
2025 static void  model_none_unload(void) {}
2026 static void  model_none_end(void) {}
2027
2028 /* ************************************************** */
2029 /* ********** PATERN FOR NEW ROUTING **************** */
2030
2031 /* The minimal configuration of a new routing model need the next functions,
2032  * also you need to set at the start of the file, the new model in the model
2033  * list. Remember keep the null ending of the list.
2034  */
2035 /*** Routing model structure ***/
2036 // typedef struct {
2037 //   s_routing_component_t generic_routing;
2038 //   /* things that your routing model need */
2039 // } s_routing_component_NEW_t,*routing_component_NEW_t;
2040
2041 /*** Parse routing model functions ***/
2042 // static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
2043 // static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
2044 // static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
2045 // static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
2046 // static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
2047
2048 /*** Business methods ***/
2049 // static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2050 // static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2051 // static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
2052
2053 /*** Creation routing model functions ***/
2054 // static void* model_NEW_create(void) {
2055 //   routing_component_NEW_t new_component =  xbt_new0(s_routing_component_NEW_t,1);
2056 //   new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
2057 //   new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
2058 //   new_component->generic_routing.set_route = model_NEW_set_route;
2059 //   new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
2060 //   new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
2061 //   new_component->generic_routing.get_route = NEW_get_route;
2062 //   new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
2063 //   new_component->generic_routing.finalize = NEW_finalize;
2064 //   /* initialization of internal structures */
2065 //   return new_component;
2066 // } /* mandatory */
2067 // static void  model_NEW_load(void) {}   /* mandatory */
2068 // static void  model_NEW_unload(void) {} /* mandatory */
2069 // static void  model_NEW_end(void) {}    /* mandatory */
2070
2071 /* ************************************************************************** */
2072 /* ************************* GENERIC PARSE FUNCTIONS ************************ */ 
2073
2074 static void generic_set_processing_unit(routing_component_t rc, const char* name) {
2075   DEBUG1("Load process unit \"%s\"",name);
2076   model_type_t modeltype = rc->routing;
2077   int *id = xbt_new0(int,1);
2078   xbt_dict_t _to_index;
2079   if(modeltype==&routing_models[SURF_MODEL_FULL])
2080     _to_index = ((routing_component_full_t)rc)->to_index;
2081   
2082   else if(modeltype==&routing_models[SURF_MODEL_FLOYD])
2083     _to_index = ((routing_component_floyd_t)rc)->to_index;
2084   
2085   else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2086           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE])
2087     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2088   
2089   else xbt_die("\"generic_set_processing_unit\" not supported");
2090   *id = xbt_dict_length(_to_index);
2091   xbt_dict_set(_to_index,name,id,xbt_free);
2092 }
2093
2094 static void generic_set_autonomous_system(routing_component_t rc, const char* name) {
2095   DEBUG1("Load Autonomous system \"%s\"",name);
2096   model_type_t modeltype = rc->routing;
2097   int *id = xbt_new0(int,1);
2098   xbt_dict_t _to_index;
2099   if(modeltype==&routing_models[SURF_MODEL_FULL])
2100     _to_index = ((routing_component_full_t)rc)->to_index;
2101   
2102   else if(modeltype==&routing_models[SURF_MODEL_FLOYD])
2103     _to_index = ((routing_component_floyd_t)rc)->to_index;
2104   
2105   else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2106           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE])
2107     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2108   
2109   else xbt_die("\"generic_set_autonomous_system\" not supported");
2110   *id = xbt_dict_length(_to_index);
2111   xbt_dict_set(_to_index,name,id,xbt_free);
2112 }
2113
2114 static void generic_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {
2115   DEBUG2("Load Route from \"%s\" to \"%s\"",src,dst);
2116   model_type_t modeltype = rc->routing;
2117   xbt_dict_t _parse_routes;
2118   xbt_dict_t _to_index;
2119   char *route_name;
2120   int *src_id, *dst_id;
2121   
2122   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2123     _parse_routes = ((routing_component_full_t)rc)->parse_routes;
2124     _to_index = ((routing_component_full_t)rc)->to_index;
2125     
2126   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2127     _parse_routes = ((routing_component_floyd_t)rc)->parse_routes;
2128     _to_index = ((routing_component_floyd_t)rc)->to_index;
2129     
2130   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2131           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2132     _parse_routes = ((routing_component_dijkstra_t)rc)->parse_routes;
2133     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2134   
2135   } else xbt_die("\"generic_set_route\" not supported");
2136
2137   src_id = xbt_dict_get_or_null(_to_index, src);
2138   dst_id = xbt_dict_get_or_null(_to_index, dst);
2139   
2140   xbt_assert2(src_id&&dst_id,"Network elements %s or %s not found", src, dst);
2141   route_name = bprintf("%d#%d",*src_id,*dst_id);
2142   
2143   xbt_assert2(xbt_dynar_length(route->link_list)>0, "Invalid count of links, must be greater than zero (%s,%s)",src,dst);   
2144   xbt_assert2(!xbt_dict_get_or_null(_parse_routes,route_name),
2145     "The route between \"%s\" and \"%s\" already exist",src,dst);
2146
2147   xbt_dict_set(_parse_routes, route_name, route, NULL);
2148   xbt_free(route_name);
2149 }
2150
2151 static void generic_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
2152   DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",src,e_route->src_gateway,dst,e_route->dst_gateway);
2153   model_type_t modeltype = rc->routing;
2154   xbt_dict_t _parse_routes;
2155   xbt_dict_t _to_index;
2156   char *route_name;
2157   int *src_id, *dst_id;
2158   
2159   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2160     _parse_routes = ((routing_component_full_t)rc)->parse_routes;
2161     _to_index = ((routing_component_full_t)rc)->to_index;
2162     
2163   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2164     _parse_routes = ((routing_component_floyd_t)rc)->parse_routes;
2165     _to_index = ((routing_component_floyd_t)rc)->to_index;
2166     
2167   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2168           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2169     _parse_routes = ((routing_component_dijkstra_t)rc)->parse_routes;
2170     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2171   
2172   } else xbt_die("\"generic_set_route\" not supported");
2173   
2174   src_id = xbt_dict_get_or_null(_to_index, src);
2175   dst_id = xbt_dict_get_or_null(_to_index, dst);
2176   
2177   xbt_assert2(src_id&&dst_id,"Network elements %s or %s not found", src, dst);
2178   route_name = bprintf("%d#%d",*src_id,*dst_id);
2179   
2180   xbt_assert2(xbt_dynar_length(e_route->generic_route.link_list)>0, "Invalid count of links, must be greater than zero (%s,%s)",src,dst);   
2181   xbt_assert4(!xbt_dict_get_or_null(_parse_routes,route_name),
2182     "The route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exist",src,e_route->src_gateway,dst,e_route->dst_gateway);
2183     
2184   xbt_dict_set(_parse_routes, route_name, e_route, NULL);
2185   xbt_free(route_name);
2186 }
2187
2188 static void generic_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
2189   DEBUG2("Load bypassRoute from \"%s\" to \"%s\"",src,dst);
2190   model_type_t modeltype = rc->routing;
2191   xbt_dict_t dict_bypassRoutes;
2192   char *route_name;
2193   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2194     dict_bypassRoutes = ((routing_component_full_t)rc)->bypassRoutes;
2195   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2196     dict_bypassRoutes = ((routing_component_floyd_t)rc)->bypassRoutes;
2197   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2198           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2199     dict_bypassRoutes = ((routing_component_dijkstra_t)rc)->bypassRoutes;
2200   } else xbt_die("\"generic_set_bypassroute\" not supported");
2201   route_name = bprintf("%s#%s",src,dst);
2202   xbt_assert2(xbt_dynar_length(e_route->generic_route.link_list)>0, "Invalid count of links, must be greater than zero (%s,%s)",src,dst);
2203   xbt_assert4(!xbt_dict_get_or_null(dict_bypassRoutes,route_name),
2204     "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exist",src,e_route->src_gateway,dst,e_route->dst_gateway);
2205     
2206   route_extended_t new_e_route = generic_new_extended_route(SURF_ROUTING_RECURSIVE,e_route,0);
2207   xbt_dynar_free( &(e_route->generic_route.link_list) );
2208   xbt_free(e_route);
2209   
2210   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, (void(*)(void*))generic_free_extended_route ); 
2211   xbt_free(route_name);
2212 }
2213
2214 /* ************************************************************************** */
2215 /* *********************** GENERIC BUSINESS METHODS ************************* */
2216
2217 static xbt_dynar_t generic_get_onelink_routes (routing_component_t rc)
2218 {
2219   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
2220 }
2221
2222 static int generic_is_router (routing_component_t rc, const char *name)
2223 {
2224   xbt_die("\"generic_is_router\" not implemented yet");
2225 }
2226
2227 static route_extended_t generic_get_bypassroute(routing_component_t rc, const char* src, const char* dst) {
2228   model_type_t modeltype = rc->routing;
2229   xbt_dict_t dict_bypassRoutes;
2230   
2231   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2232     dict_bypassRoutes = ((routing_component_full_t)rc)->bypassRoutes;
2233   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2234     dict_bypassRoutes = ((routing_component_floyd_t)rc)->bypassRoutes;
2235   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2236           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2237     dict_bypassRoutes = ((routing_component_dijkstra_t)rc)->bypassRoutes;
2238   } else xbt_die("\"generic_get_bypassroute\" not supported");
2239  
2240
2241   routing_component_t src_as, dst_as;
2242   int index_src, index_dst;
2243   xbt_dynar_t path_src = NULL;
2244   xbt_dynar_t path_dst = NULL;
2245   routing_component_t current = NULL;
2246   routing_component_t* current_src = NULL;
2247   routing_component_t* current_dst = NULL;
2248
2249   /* (1) find the as where the src and dst are located */
2250   src_as = xbt_dict_get_or_null(global_routing->where_network_elements,src);
2251   dst_as = xbt_dict_get_or_null(global_routing->where_network_elements,dst); 
2252   xbt_assert2(src_as&&dst_as, "Ask for route \"from\"(%s) or \"to\"(%s) no found",src,dst);
2253  
2254   /* (2) find the path to the root routing component */
2255   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
2256   current = src_as; 
2257   while( current != NULL ) {
2258     xbt_dynar_push(path_src,&current);
2259     current = current->routing_father;
2260   }
2261   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
2262   current = dst_as; 
2263   while( current != NULL ) {
2264     xbt_dynar_push(path_dst,&current);
2265     current = current->routing_father;
2266   }
2267
2268   /* (3) find the common father */
2269   index_src  = (path_src->used)-1;
2270   index_dst  = (path_dst->used)-1;
2271   current_src = xbt_dynar_get_ptr(path_src,index_src);
2272   current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
2273   while( index_src >= 0 && index_dst >= 0 && *current_src == *current_dst ) {
2274     routing_component_t *tmp_src,*tmp_dst;
2275     tmp_src = xbt_dynar_pop_ptr(path_src);
2276     tmp_dst = xbt_dynar_pop_ptr(path_dst);
2277     index_src--;
2278     index_dst--;
2279     current_src = xbt_dynar_get_ptr(path_src,index_src);
2280     current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
2281   }
2282   
2283   int max_index_src = (path_src->used)-1;
2284   int max_index_dst = (path_dst->used)-1;
2285   
2286   int max_index = max(max_index_src,max_index_dst);
2287   int i, max;
2288  
2289  route_extended_t e_route_bypass = NULL;
2290  
2291   for( max=0;max<=max_index;max++)
2292   {
2293     for(i=0;i<max;i++)
2294     {
2295       if( i <= max_index_src  && max <= max_index_dst ) {
2296         char* route_name = bprintf("%s#%s",
2297           (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,i)))->name,
2298           (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,max)))->name);
2299         e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2300         xbt_free(route_name);
2301       }
2302       if( e_route_bypass ) break;
2303       if( max <= max_index_src  && i <= max_index_dst ) {
2304         char* route_name = bprintf("%s#%s",
2305           (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,max)))->name,
2306           (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,i)))->name);
2307         e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2308         xbt_free(route_name);
2309       }
2310       if( e_route_bypass ) break;
2311     }
2312     
2313     if( e_route_bypass ) break;
2314      
2315     if( max <= max_index_src  && max <= max_index_dst ) {
2316       char* route_name = bprintf("%s#%s",
2317         (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,max)))->name,
2318         (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,max)))->name);
2319       e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2320       xbt_free(route_name);
2321     }
2322     if( e_route_bypass ) break;
2323   }
2324
2325   xbt_dynar_free(&path_src);
2326   xbt_dynar_free(&path_dst);
2327   
2328   route_extended_t new_e_route = NULL;
2329   
2330   if(e_route_bypass) {
2331     void* link;
2332     unsigned int cpt=0;
2333     new_e_route = xbt_new0(s_route_extended_t,1);
2334     new_e_route->src_gateway = xbt_strdup(e_route_bypass->src_gateway);
2335     new_e_route->dst_gateway = xbt_strdup(e_route_bypass->dst_gateway);
2336     new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
2337     xbt_dynar_foreach(e_route_bypass->generic_route.link_list, cpt, link) {
2338       xbt_dynar_push(new_e_route->generic_route.link_list,&link);
2339     }
2340   }
2341
2342   return new_e_route;
2343 }
2344
2345 /* ************************************************************************** */
2346 /* ************************* GENERIC AUX FUNCTIONS ************************** */
2347
2348 static route_extended_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy, void* data, int order) {
2349   
2350   char *link_name;
2351   route_extended_t e_route, new_e_route;
2352   route_t route;
2353   unsigned int cpt;
2354   xbt_dynar_t links, links_id;
2355   
2356   new_e_route = xbt_new0(s_route_extended_t,1);
2357   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
2358   new_e_route->src_gateway = NULL;
2359   new_e_route->dst_gateway = NULL;
2360
2361   xbt_assert0(hierarchy == SURF_ROUTING_BASE || hierarchy == SURF_ROUTING_RECURSIVE,
2362       "the hierarchy type is not defined");
2363   
2364   if(hierarchy == SURF_ROUTING_BASE ) {
2365     
2366     route = (route_t)data;
2367     links = route->link_list;
2368     
2369   } else if(hierarchy == SURF_ROUTING_RECURSIVE ) {
2370
2371     e_route = (route_extended_t)data;
2372     xbt_assert0(e_route->src_gateway&&e_route->dst_gateway,"bad gateway, is null");
2373     links = e_route->generic_route.link_list;
2374     
2375     /* remeber not erase the gateway names */
2376     new_e_route->src_gateway = e_route->src_gateway;
2377     new_e_route->dst_gateway = e_route->dst_gateway;
2378   }
2379   
2380   links_id = new_e_route->generic_route.link_list;
2381   
2382   xbt_dynar_foreach(links, cpt, link_name) {
2383     
2384     void* link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
2385     if (link)
2386     {
2387       if( order )
2388         xbt_dynar_push(links_id,&link);
2389       else
2390         xbt_dynar_unshift(links_id,&link);
2391     }
2392     else
2393       THROW1(mismatch_error,0,"Link %s not found", link_name);
2394   }
2395  
2396   return new_e_route;
2397 }
2398
2399 static void generic_free_route(route_t route) {
2400   if(route) {
2401     xbt_dynar_free(&(route->link_list));
2402     xbt_free(route);
2403   }
2404 }
2405
2406 static void generic_free_extended_route(route_extended_t e_route) {
2407   if(e_route) {
2408     xbt_dynar_free(&(e_route->generic_route.link_list));
2409     if(e_route->src_gateway) xbt_free(e_route->src_gateway);
2410     if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
2411     xbt_free(e_route);
2412   }
2413 }
2414
2415 static routing_component_t generic_as_exist(routing_component_t find_from, routing_component_t to_find) {
2416   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
2417   xbt_dict_cursor_t cursor = NULL;
2418   char *key;
2419   int found=0;
2420   routing_component_t elem;
2421   xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
2422     if( to_find == elem || generic_as_exist(elem,to_find) ){
2423       found=1;
2424       break;
2425     }
2426   }
2427   if(found) return to_find;
2428   return NULL;
2429 }
2430
2431 static routing_component_t generic_autonomous_system_exist(routing_component_t rc, char* element) {
2432   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
2433   routing_component_t element_as, result, elem;
2434   xbt_dict_cursor_t cursor = NULL;
2435   char *key;
2436   element_as = xbt_dict_get_or_null(global_routing->where_network_elements,element);
2437   result = ((routing_component_t)-1);
2438   if(element_as!=rc)
2439     result = generic_as_exist(rc,element_as);
2440   
2441   int found=0;
2442   if(result)
2443   {
2444     xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
2445       found = !strcmp(elem->name,element);
2446       if( found ) break;
2447     }
2448     if( found ) return element_as;
2449   }
2450   return NULL;
2451 }
2452
2453 static routing_component_t generic_processing_units_exist(routing_component_t rc, char* element) {
2454   routing_component_t element_as;
2455   element_as = xbt_dict_get_or_null(global_routing->where_network_elements,element);
2456   if(element_as==rc) return element_as;
2457   return generic_as_exist(rc,element_as);
2458 }
2459
2460 static void generic_src_dst_check(routing_component_t rc, const char* src, const char* dst) {
2461   
2462   routing_component_t src_as = xbt_dict_get_or_null(global_routing->where_network_elements,src);
2463   routing_component_t dst_as = xbt_dict_get_or_null(global_routing->where_network_elements,dst);
2464    
2465   xbt_assert3(src_as != NULL && dst_as  != NULL, 
2466       "Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",src,dst,rc->name);
2467   xbt_assert4(src_as == dst_as,
2468       "The src(%s in %s) and dst(%s in %s) are in differents AS",src,src_as->name,dst,dst_as->name);
2469   xbt_assert2(rc == dst_as,
2470       "The routing component of src and dst is not the same as the network elements belong (%s==%s)",rc->name,dst_as->name);
2471 }
2472
2473 static void routing_full_parse_Scluster(void)
2474 {
2475         static int AX_ptr = 0;
2476
2477         char *cluster_id = A_surfxml_cluster_id;
2478         char *cluster_prefix = A_surfxml_cluster_prefix;
2479         char *cluster_suffix = A_surfxml_cluster_suffix;
2480         char *cluster_radical = A_surfxml_cluster_radical;
2481         char *cluster_power = A_surfxml_cluster_power;
2482         char *cluster_bw = A_surfxml_cluster_bw;
2483         char *cluster_lat = A_surfxml_cluster_lat;
2484         char *cluster_bb_bw = A_surfxml_cluster_bb_bw;
2485         char *cluster_bb_lat = A_surfxml_cluster_bb_lat;
2486         char *host_id, *groups, *link_id;
2487         char *router_id, *link_router, *link_backbone, *route_src_dst;
2488         unsigned int iter;
2489         int start, end, i;
2490         xbt_dynar_t radical_elements;
2491         xbt_dynar_t radical_ends;
2492         #ifndef HAVE_PCRE_LIB
2493                 xbt_dynar_t tab_elements_num = xbt_dynar_new(sizeof(int), NULL);
2494                 char *route_src,*route_dst;
2495                 int j;
2496         #endif
2497
2498         static unsigned int surfxml_buffer_stack_stack_ptr = 1;
2499         static unsigned int surfxml_buffer_stack_stack[1024];
2500
2501         surfxml_buffer_stack_stack[0]= 0;
2502
2503         surfxml_bufferstack_push(1);
2504
2505         SURFXML_BUFFER_SET(AS_id, cluster_id);
2506 #ifdef HAVE_PCRE_LIB
2507         SURFXML_BUFFER_SET(AS_routing, "RuleBased");
2508         DEBUG1("<AS id=\"%s\"\trouting=\"RuleBased\">",cluster_id);
2509 #else
2510         SURFXML_BUFFER_SET(AS_routing, "Full");
2511         DEBUG1("<AS id=\"%s\"\trouting=\"Full\">",cluster_id);
2512 #endif
2513         SURFXML_START_TAG(AS);
2514
2515         radical_elements = xbt_str_split(cluster_radical, ",");
2516         xbt_dynar_foreach(radical_elements, iter, groups)
2517         {
2518                 radical_ends = xbt_str_split(groups, "-");
2519                 switch (xbt_dynar_length(radical_ends))
2520                 {
2521                         case 1:
2522                           surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
2523                           host_id = bprintf("%s_%d%s", cluster_prefix, start, cluster_suffix);
2524                           #ifndef HAVE_PCRE_LIB
2525                           xbt_dynar_push_as(tab_elements_num, int, start);
2526                           #endif
2527                           link_id = bprintf("%s_link_%d", cluster_id, start);
2528
2529                           DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>",host_id,cluster_power);
2530                           SURFXML_BUFFER_SET(host_id, host_id);
2531                           SURFXML_BUFFER_SET(host_power, cluster_power);
2532                           SURFXML_BUFFER_SET(host_availability, "1.0");
2533                           SURFXML_BUFFER_SET(host_availability_file, "");
2534                           A_surfxml_host_state = A_surfxml_host_state_ON;
2535                           SURFXML_BUFFER_SET(host_state_file, "");
2536                           SURFXML_BUFFER_SET(host_interference_send, "1.0");
2537                           SURFXML_BUFFER_SET(host_interference_recv, "1.0");
2538                           SURFXML_BUFFER_SET(host_interference_send_recv, "1.0");
2539                           SURFXML_BUFFER_SET(host_max_outgoing_rate, "-1.0");
2540                           SURFXML_START_TAG(host);
2541                           SURFXML_END_TAG(host);
2542
2543                           DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_id,cluster_bw,cluster_lat);
2544                           SURFXML_BUFFER_SET(link_id, link_id);
2545                           SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2546                           SURFXML_BUFFER_SET(link_latency, cluster_lat);
2547                           SURFXML_BUFFER_SET(link_bandwidth_file, "");
2548                           SURFXML_BUFFER_SET(link_latency_file, "");
2549                           A_surfxml_link_state = A_surfxml_link_state_ON;
2550                           SURFXML_BUFFER_SET(link_state_file, "");
2551                           A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2552                           SURFXML_START_TAG(link);
2553                           SURFXML_END_TAG(link);
2554
2555                           break;
2556
2557                         case 2:
2558
2559                           surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
2560                           surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
2561                           DEBUG2("Create hosts and links from %d to %d",start,end);
2562                           for (i = start; i <= end; i++)
2563                           {
2564                                   host_id = bprintf("%s_%d%s", cluster_prefix, i, cluster_suffix);
2565                                   #ifndef HAVE_PCRE_LIB
2566                                   xbt_dynar_push_as(tab_elements_num, int, i);
2567                                   #endif
2568                                   link_id = bprintf("%s_link_%d", cluster_id, i);
2569
2570                                   DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>",host_id,cluster_power);
2571                                   SURFXML_BUFFER_SET(host_id, host_id);
2572                                   SURFXML_BUFFER_SET(host_power, cluster_power);
2573                                   SURFXML_BUFFER_SET(host_availability, "1.0");
2574                                   SURFXML_BUFFER_SET(host_availability_file, "");
2575                                   A_surfxml_host_state = A_surfxml_host_state_ON;
2576                                   SURFXML_BUFFER_SET(host_state_file, "");
2577                                   SURFXML_BUFFER_SET(host_interference_send, "1.0");
2578                                   SURFXML_BUFFER_SET(host_interference_recv, "1.0");
2579                                   SURFXML_BUFFER_SET(host_interference_send_recv, "1.0");
2580                                   SURFXML_BUFFER_SET(host_max_outgoing_rate, "-1.0");
2581                                   SURFXML_START_TAG(host);
2582                                   SURFXML_END_TAG(host);
2583
2584                                   DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_id,cluster_bw,cluster_lat);
2585                                   SURFXML_BUFFER_SET(link_id, link_id);
2586                                   SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2587                                   SURFXML_BUFFER_SET(link_latency, cluster_lat);
2588                                   SURFXML_BUFFER_SET(link_bandwidth_file, "");
2589                                   SURFXML_BUFFER_SET(link_latency_file, "");
2590                                   A_surfxml_link_state = A_surfxml_link_state_ON;
2591                                   SURFXML_BUFFER_SET(link_state_file, "");
2592                                   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2593                                   SURFXML_START_TAG(link);
2594                                   SURFXML_END_TAG(link);
2595                           }
2596                           break;
2597
2598                         default:
2599                                 DEBUG0("Malformed radical");
2600                 }
2601
2602                 xbt_dynar_free(&radical_ends);
2603         }
2604
2605         DEBUG0(" ");
2606         router_id = bprintf("%s_%s_router%s",cluster_prefix,cluster_id,cluster_suffix);
2607         link_router = bprintf("%s_link_%s_router",cluster_id,cluster_id);
2608         link_backbone = bprintf("%s_backbone",cluster_id);
2609
2610         DEBUG1("<router id=\"%s\"/>",router_id);
2611         SURFXML_BUFFER_SET(router_id, router_id);;
2612         SURFXML_START_TAG(router);
2613         SURFXML_END_TAG(router);
2614
2615         DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_router,cluster_bw,cluster_lat);
2616         SURFXML_BUFFER_SET(link_id, link_router);
2617         SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2618         SURFXML_BUFFER_SET(link_latency, cluster_lat);
2619         SURFXML_BUFFER_SET(link_bandwidth_file, "");
2620         SURFXML_BUFFER_SET(link_latency_file, "");
2621         A_surfxml_link_state = A_surfxml_link_state_ON;
2622         SURFXML_BUFFER_SET(link_state_file, "");
2623         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2624         SURFXML_START_TAG(link);
2625         SURFXML_END_TAG(link);
2626
2627         DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_backbone,cluster_bb_bw,cluster_bb_lat);
2628         SURFXML_BUFFER_SET(link_id, link_backbone);
2629         SURFXML_BUFFER_SET(link_bandwidth, cluster_bb_bw);
2630         SURFXML_BUFFER_SET(link_latency, cluster_bb_lat);
2631         SURFXML_BUFFER_SET(link_bandwidth_file, "");
2632         SURFXML_BUFFER_SET(link_latency_file, "");
2633         A_surfxml_link_state = A_surfxml_link_state_ON;
2634         SURFXML_BUFFER_SET(link_state_file, "");
2635         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2636         SURFXML_START_TAG(link);
2637         SURFXML_END_TAG(link);
2638
2639         char *new_suffix = bprintf("%s","");
2640
2641         radical_elements = xbt_str_split(cluster_suffix, ".");
2642         xbt_dynar_foreach(radical_elements, iter, groups)
2643         {
2644                     if(strcmp(groups,""))
2645                     {
2646                         new_suffix = bprintf("%s\\.%s",new_suffix,groups);
2647                     }
2648         }
2649         route_src_dst = bprintf("%s_(.*)%s",cluster_prefix,new_suffix);
2650
2651         DEBUG0(" ");
2652
2653 #ifdef HAVE_PCRE_LIB
2654
2655         DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\">",route_src_dst,route_src_dst);
2656         SURFXML_BUFFER_SET(route_src, route_src_dst);
2657         SURFXML_BUFFER_SET(route_dst, route_src_dst);
2658         SURFXML_START_TAG(route);
2659
2660         DEBUG1("<link:ctn\tid=\"%s_link_$1src\"/>",cluster_id);
2661         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_$1src",cluster_id));
2662         SURFXML_START_TAG(link_ctn);
2663         SURFXML_END_TAG(link_ctn);
2664
2665         DEBUG1("<link:ctn\tid=\"%s_backbone\"/>",cluster_id);
2666         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone",cluster_id));
2667         SURFXML_START_TAG(link_ctn);
2668         SURFXML_END_TAG(link_ctn);
2669
2670         DEBUG1("<link:ctn\tid=\"%s_link_$1dst\"/>",cluster_id);
2671         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_$1dst",cluster_id));
2672         SURFXML_START_TAG(link_ctn);
2673         SURFXML_END_TAG(link_ctn);
2674
2675         DEBUG0("</route>");
2676         SURFXML_END_TAG(route);
2677 #else
2678         for(i=0 ; i<=xbt_dynar_length(tab_elements_num) ; i++)
2679         {
2680                 for(j=0 ; j<=xbt_dynar_length(tab_elements_num) ; j++)
2681                 {
2682                         if(i == xbt_dynar_length(tab_elements_num))
2683                         {
2684                                 route_src = router_id;
2685                         }
2686                         else
2687                         {
2688                                 route_src = bprintf("%s_%d%s",cluster_prefix,xbt_dynar_get_as(tab_elements_num,i,int),cluster_suffix);
2689                         }
2690
2691                         if(j == xbt_dynar_length(tab_elements_num))
2692                         {
2693                                 route_dst = router_id;
2694                         }
2695                         else
2696                         {
2697                                 route_dst = bprintf("%s_%d%s",cluster_prefix,xbt_dynar_get_as(tab_elements_num,j,int),cluster_suffix);
2698                         }
2699
2700                         DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\">",route_src,route_dst);
2701                         SURFXML_BUFFER_SET(route_src, route_src);
2702                         SURFXML_BUFFER_SET(route_dst, route_dst);
2703                         SURFXML_START_TAG(route);
2704
2705                         if(i == xbt_dynar_length(tab_elements_num))
2706                         {
2707                                 route_src = link_router;
2708                         }
2709                         else
2710                         {
2711                                 route_src = bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,i,int));
2712                         }
2713
2714                         if(j == xbt_dynar_length(tab_elements_num))
2715                         {
2716                                 route_dst = link_router;
2717                         }
2718                         else
2719                         {
2720                                 route_dst = bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,j,int));
2721                         }
2722
2723                         DEBUG1("<link:ctn\tid=\"%s\"/>",route_src);
2724                         SURFXML_BUFFER_SET(link_ctn_id, route_src);
2725                         SURFXML_START_TAG(link_ctn);
2726                         SURFXML_END_TAG(link_ctn);
2727
2728                         DEBUG1("<link:ctn\tid=\"%s_backbone\"/>",cluster_id);
2729                         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone",cluster_id));
2730                         SURFXML_START_TAG(link_ctn);
2731                         SURFXML_END_TAG(link_ctn);
2732
2733                         DEBUG1("<link:ctn\tid=\"%s\"/>",route_dst);
2734                         SURFXML_BUFFER_SET(link_ctn_id, route_dst);
2735                         SURFXML_START_TAG(link_ctn);
2736                         SURFXML_END_TAG(link_ctn);
2737
2738                         DEBUG0("</route>");
2739                         SURFXML_END_TAG(route);
2740                 }
2741         }
2742         xbt_dynar_free(&tab_elements_num);
2743 #endif
2744
2745         DEBUG0("</AS>");
2746         SURFXML_END_TAG(AS);
2747         DEBUG0(" ");
2748
2749         surfxml_bufferstack_pop(1);
2750 }
2751
2752 /*
2753  * New methods to init the routing model component from the lua script
2754  */
2755
2756 /*
2757  * calling parse_S_AS_lua with lua values
2758  */
2759 void routing_AS_init(const char* AS_id,const char* AS_routing)
2760 {
2761         parse_S_AS_lua((char*)AS_id,(char*)AS_routing);
2762 }
2763
2764 /*
2765  * calling parse_E_AS_lua to fisnish the creation of routing component
2766  */
2767 void routing_AS_end(const char *AS_id)
2768 {
2769         parse_E_AS_lua((char*)AS_id);
2770 }
2771
2772 /*
2773  * add a host to the network element list
2774  */
2775
2776 void routing_add_host(const char* host_id)
2777 {
2778         parse_S_host_lua((char*)host_id);
2779 }
2780
2781 /*
2782  * Set a new link on the actual list of link for a route or ASroute
2783  */
2784 void routing_add_link(const char* link_id)
2785 {
2786         parse_E_link_c_ctn_new_elem_lua((char*)link_id);
2787 }
2788
2789 /*
2790  *Set the endpoints for a route
2791  */
2792 void routing_set_route(const char* src_id,const char *dst_id)
2793 {
2794         parse_S_route_new_and_endpoints_lua((char*)src_id,(char*)dst_id);
2795 }
2796
2797 /*
2798  * Store the route by calling parse_E_route_store_route
2799  */
2800 void routing_store_route(void)
2801 {
2802         parse_E_route_store_route();
2803 }