Logo AND Algorithmique Numérique Distribuée

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