Logo AND Algorithmique Numérique Distribuée

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