Logo AND Algorithmique Numérique Distribuée

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