Logo AND Algorithmique Numérique Distribuée

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