Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a0b74ee2ae0de9119cad66d37b842b95c0c70f69
[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 recursive_get_onelink_routes (routing_component_t rc)
681 {
682   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
683
684   //adding my one link routes
685   unsigned int cpt;
686   void *link;
687   xbt_dynar_t onelink_mine = rc->get_onelink_routes (rc);
688   if (onelink_mine){
689     xbt_dynar_foreach(onelink_mine, cpt, link) {
690       xbt_dynar_push(ret,&link);
691     }
692   }
693
694   //recursing
695   char *key;
696   xbt_dict_cursor_t cursor=NULL;
697   routing_component_t rc_child;
698   xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
699     xbt_dynar_t onelink_child = recursive_get_onelink_routes (rc_child);//->get_onelink_routes (rc_child);
700     if (onelink_child){
701       xbt_dynar_foreach(onelink_child, cpt, link) {
702         xbt_dynar_push(ret,&link);
703       }
704     }
705   }
706   return ret;
707 }
708
709 static xbt_dynar_t get_onelink_routes(void)
710 {
711   return recursive_get_onelink_routes (global_routing->root);
712 }
713
714 static int is_router(const char *name)
715 {
716         xbt_die("global \"is_router\" function not implemented yet");
717 }
718
719 /**
720  * \brief Generic method: create the global routing schema
721  * 
722  * Make a global routing structure and set all the parsing functions.
723  */
724 void routing_model_create(size_t size_of_links, void* loopback) {
725   
726   /* config the uniq global routing */
727   global_routing = xbt_new0(s_routing_global_t,1);
728   global_routing->where_network_elements = xbt_dict_new();
729   global_routing->root = NULL;
730   global_routing->get_route = get_route;
731   global_routing->get_onelink_routes = get_onelink_routes;
732   global_routing->is_router = is_router;
733   global_routing->finalize = finalize;
734   global_routing->loopback = loopback;
735   global_routing->size_of_link = size_of_links;
736   global_routing->last_route = xbt_dynar_new(size_of_links, NULL);
737   
738   /* no current routing at moment */
739   current_routing = NULL;
740
741   /* parse generic elements */
742   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_S_host_XML);
743   surfxml_add_callback(STag_surfxml_router_cb_list, &parse_S_router);
744
745   surfxml_add_callback(STag_surfxml_route_cb_list, &parse_S_route_new_and_endpoints_XML);
746   surfxml_add_callback(STag_surfxml_ASroute_cb_list, &parse_S_ASroute_new_and_endpoints);
747   surfxml_add_callback(STag_surfxml_bypassRoute_cb_list, &parse_S_bypassRoute_new_and_endpoints);
748   
749   surfxml_add_callback(ETag_surfxml_link_ctn_cb_list, &parse_E_link_ctn_new_elem_XML);
750   
751   surfxml_add_callback(ETag_surfxml_route_cb_list, &parse_E_route_store_route);
752   surfxml_add_callback(ETag_surfxml_ASroute_cb_list, &parse_E_ASroute_store_route);
753   surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list, &parse_E_bypassRoute_store_route);
754   
755   surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
756   surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
757
758   surfxml_add_callback(STag_surfxml_cluster_cb_list, &routing_full_parse_Scluster);
759
760 }
761
762 /* ************************************************************************** */
763 /* *************************** FULL ROUTING ********************************* */
764
765 #define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
766
767 /* Routing model structure */
768
769 typedef struct {
770   s_routing_component_t generic_routing;
771   xbt_dict_t parse_routes; /* store data during the parse process */
772   xbt_dict_t to_index; /* char* -> network_element_t */
773   xbt_dict_t bypassRoutes;
774   route_extended_t *routing_table;
775 } s_routing_component_full_t,*routing_component_full_t;
776
777 /* Business methods */
778 static xbt_dynar_t full_get_onelink_routes(routing_component_t rc)
779 {
780   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
781
782   routing_component_full_t routing = (routing_component_full_t)rc;
783   int table_size = xbt_dict_length(routing->to_index);
784   xbt_dict_cursor_t c1 = NULL, c2 = NULL;
785   char *k1, *d1, *k2, *d2;
786   xbt_dict_foreach(routing->to_index, c1, k1, d1) {
787     xbt_dict_foreach (routing->to_index, c2, k2, d2) {
788       int *src_id = xbt_dict_get_or_null(routing->to_index, k1);
789       int *dst_id = xbt_dict_get_or_null(routing->to_index, k2);
790       xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst);
791       route_extended_t route = TO_ROUTE_FULL(*src_id,*dst_id);
792       if (route){
793         if (xbt_dynar_length(route->generic_route.link_list) == 1){
794           void *link = *(void**)xbt_dynar_get_ptr(route->generic_route.link_list,0);
795
796           onelink_t onelink = xbt_new0 (s_onelink_t, 1);
797           onelink->src = xbt_strdup (k1);
798           onelink->dst = xbt_strdup (k2);
799           onelink->link_ptr = link;
800           xbt_dynar_push (ret, &onelink);
801         }
802       }
803     }
804   }
805   return ret;
806 }
807
808 static int full_is_router(const char *name)
809 {
810   xbt_die("\"full_is_router\" function not implemented yet");
811 }
812
813 static route_extended_t full_get_route(routing_component_t rc, const char* src,const char* dst) {
814   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
815   
816   /* set utils vars */
817   routing_component_full_t routing = (routing_component_full_t)rc;
818   int table_size = xbt_dict_length(routing->to_index);
819   
820   generic_src_dst_check(rc,src,dst);
821   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
822   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
823   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
824
825   route_extended_t e_route = NULL;
826   route_extended_t new_e_route = NULL;
827   void* link;
828   unsigned int cpt=0;
829
830   e_route = TO_ROUTE_FULL(*src_id,*dst_id);
831   
832   if(e_route) {
833     new_e_route = xbt_new0(s_route_extended_t,1);
834     new_e_route->src_gateway = xbt_strdup(e_route->src_gateway);
835     new_e_route->dst_gateway = xbt_strdup(e_route->dst_gateway);
836     new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
837     xbt_dynar_foreach(e_route->generic_route.link_list, cpt, link) {
838       xbt_dynar_push(new_e_route->generic_route.link_list,&link);
839     }
840   }
841   return new_e_route;
842 }
843
844 static void full_finalize(routing_component_t rc) {
845   routing_component_full_t routing = (routing_component_full_t)rc;
846   int table_size = xbt_dict_length(routing->to_index);
847   int i,j;
848   if (routing) {
849     /* Delete routing table */
850     for (i=0;i<table_size;i++)
851       for (j=0;j<table_size;j++)
852         generic_free_extended_route(TO_ROUTE_FULL(i,j));
853     xbt_free(routing->routing_table);
854     /* Delete bypass dict */
855     xbt_dict_free(&routing->bypassRoutes);
856     /* Delete index dict */
857     xbt_dict_free(&(routing->to_index));
858     /* Delete structure */
859     xbt_free(rc);
860   }
861 }
862
863 /* Creation routing model functions */
864
865 static void* model_full_create(void) {
866   routing_component_full_t new_component =  xbt_new0(s_routing_component_full_t,1);
867   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
868   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
869   new_component->generic_routing.set_route = generic_set_route;
870   new_component->generic_routing.set_ASroute = generic_set_ASroute;
871   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
872   new_component->generic_routing.get_route = full_get_route;
873   new_component->generic_routing.get_onelink_routes = full_get_onelink_routes;
874   new_component->generic_routing.is_router = full_is_router;
875   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
876   new_component->generic_routing.finalize = full_finalize;
877   new_component->to_index = xbt_dict_new();
878   new_component->bypassRoutes = xbt_dict_new();
879   new_component->parse_routes = xbt_dict_new();
880   return new_component;
881 }
882
883 static void model_full_load(void) {
884  /* use "surfxml_add_callback" to add a parse function call */
885 }
886
887 static void model_full_unload(void) {
888  /* use "surfxml_del_callback" to remove a parse function call */
889 }
890
891 static void  model_full_end(void) {
892   
893   char *key, *end;
894   const char* sep = "#";
895   int src_id, dst_id;
896   unsigned int i, j;
897   route_t route;
898   route_extended_t e_route;
899   void* data;
900   
901   xbt_dict_cursor_t cursor = NULL;
902   xbt_dynar_t keys = NULL;
903   
904   /* set utils vars */
905   routing_component_full_t routing = ((routing_component_full_t)current_routing);
906   int table_size = xbt_dict_length(routing->to_index);
907   
908   /* Create the routing table */
909   routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
910   
911   /* Put the routes in position */
912   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
913     keys = xbt_str_split_str(key, sep);
914     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
915     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
916     TO_ROUTE_FULL(src_id,dst_id) = generic_new_extended_route(current_routing->hierarchy,data,1);
917      xbt_dynar_free(&keys);
918    }
919
920    /* delete the parse table */
921   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
922     route = (route_t)data;
923     xbt_dynar_free(&(route->link_list));
924     xbt_free(data);
925   }
926       
927   /* delete parse dict */
928   xbt_dict_free(&(routing->parse_routes));
929
930   /* Add the loopback if needed */
931   if(current_routing->hierarchy == SURF_ROUTING_BASE) {
932     for (i = 0; i < table_size; i++) {
933       e_route = TO_ROUTE_FULL(i, i);
934       if(!e_route) {
935         e_route = xbt_new0(s_route_extended_t,1);
936         e_route->src_gateway = NULL;
937         e_route->dst_gateway = NULL;
938         e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
939         xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
940         TO_ROUTE_FULL(i, i) = e_route;
941       }
942     }
943   }
944
945   /* Shrink the dynar routes (save unused slots) */
946   for (i=0;i<table_size;i++)
947     for (j=0;j<table_size;j++)
948       if(TO_ROUTE_FULL(i,j))
949         xbt_dynar_shrink(TO_ROUTE_FULL(i,j)->generic_route.link_list,0);
950 }
951
952 /* ************************************************************************** */
953 /* *************************** FLOYD ROUTING ******************************** */
954
955 #define TO_FLOYD_COST(i,j) cost_table[(i)+(j)*table_size]
956 #define TO_FLOYD_PRED(i,j) (routing->predecessor_table)[(i)+(j)*table_size]
957 #define TO_FLOYD_LINK(i,j) (routing->link_table)[(i)+(j)*table_size]
958
959 /* Routing model structure */
960
961 typedef struct {
962   s_routing_component_t generic_routing;
963   /* vars for calculate the floyd algorith. */
964   int *predecessor_table;
965   route_extended_t *link_table; /* char* -> int* */
966   xbt_dict_t to_index;
967   xbt_dict_t bypassRoutes;
968   /* store data during the parse process */  
969   xbt_dict_t parse_routes; 
970 } s_routing_component_floyd_t,*routing_component_floyd_t;
971
972 /* Business methods */
973 static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
974 {
975   xbt_die("\"floyd_get_onelink_routes\" function not implemented yet");
976 }
977
978 static int floyd_is_router(const char *name)
979 {
980   xbt_die("\"floyd_is_router\" function not implemented yet");
981 }
982
983 static route_extended_t floyd_get_route(routing_component_t rc, const char* src,const char* dst) {
984   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
985   
986   /* set utils vars */
987   routing_component_floyd_t routing = (routing_component_floyd_t) rc;
988   int table_size = xbt_dict_length(routing->to_index);
989   
990   generic_src_dst_check(rc,src,dst);
991   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
992   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
993   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
994   
995   /* create a result route */
996   route_extended_t new_e_route = xbt_new0(s_route_extended_t,1);
997   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
998   new_e_route->src_gateway = NULL;
999   new_e_route->dst_gateway = NULL;
1000   
1001   int first = 1;
1002   int pred = *dst_id;
1003   int prev_pred = 0;
1004   char *gw_src=NULL,*gw_dst=NULL, *prev_gw_src,*prev_gw_dst, *first_gw=NULL;
1005   unsigned int cpt;
1006   void* link;
1007   xbt_dynar_t links;
1008   
1009   do {
1010     prev_pred = pred;
1011     pred = TO_FLOYD_PRED(*src_id, pred);
1012     if(pred == -1) /* if no pred in route -> no route to host */
1013       break;      
1014     xbt_assert2(TO_FLOYD_LINK(pred,prev_pred),"Invalid link for the route between \"%s\" or \"%s\"", src, dst);
1015     
1016     prev_gw_src = gw_src;
1017     prev_gw_dst = gw_dst;
1018     
1019     route_extended_t e_route = TO_FLOYD_LINK(pred,prev_pred);
1020     gw_src = e_route->src_gateway;
1021     gw_dst = e_route->dst_gateway;
1022     
1023     if(first) first_gw = gw_dst;
1024     
1025     if(rc->hierarchy == SURF_ROUTING_RECURSIVE && !first && strcmp(gw_dst,prev_gw_src)) {
1026       xbt_dynar_t e_route_as_to_as = (*(global_routing->get_route))(gw_dst,prev_gw_src);
1027       xbt_assert2(e_route_as_to_as,"no route between \"%s\" and \"%s\"",gw_dst,prev_gw_src);
1028       links = e_route_as_to_as;
1029       int pos = 0;
1030       xbt_dynar_foreach(links, cpt, link) {
1031         xbt_dynar_insert_at(new_e_route->generic_route.link_list,pos,&link);
1032         pos++;
1033       }
1034     }
1035     
1036     links = e_route->generic_route.link_list;
1037     xbt_dynar_foreach(links, cpt, link) {
1038       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1039     }
1040     first=0;
1041     
1042   } while(pred != *src_id);
1043   xbt_assert4(pred != -1, "no route from host %d to %d (\"%s\" to \"%s\")", *src_id, *dst_id,src,dst);
1044   
1045   if(rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1046     new_e_route->src_gateway = xbt_strdup(gw_src);
1047     new_e_route->dst_gateway = xbt_strdup(first_gw);
1048   }
1049   
1050   return new_e_route;
1051 }
1052
1053 static void floyd_finalize(routing_component_t rc) {
1054    routing_component_floyd_t routing = (routing_component_floyd_t)rc;
1055   int i,j,table_size;
1056   if (routing) {
1057     table_size = xbt_dict_length(routing->to_index);
1058     /* Delete link_table */
1059     for (i=0;i<table_size;i++)
1060       for (j=0;j<table_size;j++)
1061         generic_free_extended_route(TO_FLOYD_LINK(i,j));
1062     xbt_free(routing->link_table);
1063     /* Delete bypass dict */
1064     xbt_dict_free(&routing->bypassRoutes);
1065     /* Delete index dict */
1066     xbt_dict_free(&(routing->to_index));
1067     /* Delete dictionary index dict, predecessor and links table */
1068     xbt_free(routing->predecessor_table);
1069     /* Delete structure */
1070     xbt_free(rc);
1071   }
1072 }
1073
1074 static void* model_floyd_create(void) {
1075   routing_component_floyd_t new_component = xbt_new0(s_routing_component_floyd_t,1);
1076   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
1077   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
1078   new_component->generic_routing.set_route = generic_set_route;
1079   new_component->generic_routing.set_ASroute = generic_set_ASroute;
1080   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1081   new_component->generic_routing.get_route = floyd_get_route;
1082   new_component->generic_routing.get_onelink_routes = floyd_get_onelink_routes;
1083   new_component->generic_routing.is_router = floyd_is_router;
1084   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
1085   new_component->generic_routing.finalize = floyd_finalize;
1086   new_component->to_index = xbt_dict_new();
1087   new_component->bypassRoutes = xbt_dict_new();
1088   new_component->parse_routes = xbt_dict_new();
1089   return new_component;
1090 }
1091
1092 static void  model_floyd_load(void) {
1093  /* use "surfxml_add_callback" to add a parse function call */
1094 }
1095
1096 static void  model_floyd_unload(void) {
1097  /* use "surfxml_del_callback" to remove a parse function call */
1098 }
1099
1100 static void  model_floyd_end(void) {
1101   
1102   routing_component_floyd_t routing = ((routing_component_floyd_t)current_routing);
1103   xbt_dict_cursor_t cursor = NULL;
1104   double * cost_table;
1105   char *key,*data, *end;
1106   const char *sep = "#";
1107   xbt_dynar_t keys;
1108   int src_id, dst_id;
1109   unsigned int i,j,a,b,c;
1110
1111   /* set the size of inicial table */
1112   int table_size = xbt_dict_length(routing->to_index);
1113   
1114   /* Create Cost, Predecessor and Link tables */
1115   cost_table = xbt_new0(double, table_size*table_size); /* link cost from host to host */
1116   routing->predecessor_table = xbt_new0(int, table_size*table_size); /* predecessor host numbers */
1117   routing->link_table = xbt_new0(route_extended_t, table_size*table_size); /* actual link between src and dst */
1118
1119   /* Initialize costs and predecessors*/
1120   for(i = 0; i<table_size;i++)
1121     for(j = 0; j<table_size;j++) {
1122         TO_FLOYD_COST(i,j) = DBL_MAX;
1123         TO_FLOYD_PRED(i,j) = -1;
1124         TO_FLOYD_LINK(i,j) = NULL; /* fixed, missing in the previous version */
1125     }
1126
1127    /* Put the routes in position */
1128   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1129     keys = xbt_str_split_str(key, sep);
1130     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
1131     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
1132     TO_FLOYD_LINK(src_id,dst_id) = generic_new_extended_route(current_routing->hierarchy,data,0);
1133     TO_FLOYD_PRED(src_id,dst_id) = src_id;
1134     /* set link cost */
1135     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 */
1136     xbt_dynar_free(&keys);
1137   }
1138
1139   /* Add the loopback if needed */
1140   if(current_routing->hierarchy == SURF_ROUTING_BASE) {
1141     for (i = 0; i < table_size; i++) {
1142       route_extended_t e_route = TO_FLOYD_LINK(i, i);
1143       if(!e_route) {
1144         e_route = xbt_new0(s_route_extended_t,1);
1145         e_route->src_gateway = NULL;
1146         e_route->dst_gateway = NULL;
1147         e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1148         xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
1149         TO_FLOYD_LINK(i,i) = e_route;
1150         TO_FLOYD_PRED(i,i) = i;
1151         TO_FLOYD_COST(i,i) = 1;
1152       }
1153     }
1154   }
1155   /* Calculate path costs */
1156   for(c=0;c<table_size;c++) {
1157     for(a=0;a<table_size;a++) {
1158       for(b=0;b<table_size;b++) {
1159         if(TO_FLOYD_COST(a,c) < DBL_MAX && TO_FLOYD_COST(c,b) < DBL_MAX) {
1160           if(TO_FLOYD_COST(a,b) == DBL_MAX || 
1161             (TO_FLOYD_COST(a,c)+TO_FLOYD_COST(c,b) < TO_FLOYD_COST(a,b))) {
1162             TO_FLOYD_COST(a,b) = TO_FLOYD_COST(a,c)+TO_FLOYD_COST(c,b);
1163             TO_FLOYD_PRED(a,b) = TO_FLOYD_PRED(c,b);
1164           }
1165         }
1166       }
1167     }
1168   }
1169
1170    /* delete the parse table */
1171   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1172     route_t route = (route_t)data;
1173     xbt_dynar_free(&(route->link_list));
1174     xbt_free(data);
1175   }
1176   
1177   /* delete parse dict */
1178   xbt_dict_free(&(routing->parse_routes));
1179
1180   /* cleanup */
1181   xbt_free(cost_table);
1182 }
1183
1184 /* ************************************************************************** */
1185 /* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
1186
1187 typedef struct {
1188   s_routing_component_t generic_routing;
1189   xbt_dict_t to_index;
1190   xbt_dict_t bypassRoutes;
1191   xbt_graph_t route_graph;   /* xbt_graph */
1192   xbt_dict_t graph_node_map; /* map */
1193   xbt_dict_t route_cache;    /* use in cache mode */
1194   int cached;
1195   xbt_dict_t parse_routes;
1196 } s_routing_component_dijkstra_t,*routing_component_dijkstra_t;
1197
1198
1199 typedef struct graph_node_data {
1200   int id; 
1201   int graph_id; /* used for caching internal graph id's */
1202 } s_graph_node_data_t, * graph_node_data_t;
1203
1204 typedef struct graph_node_map_element {
1205   xbt_node_t node;
1206 } s_graph_node_map_element_t, * graph_node_map_element_t;
1207
1208 typedef struct route_cache_element {
1209   int * pred_arr;
1210   int size;
1211 } s_route_cache_element_t, * route_cache_element_t;     
1212
1213 /* Free functions */
1214
1215 static void route_cache_elem_free(void *e) {
1216   route_cache_element_t elm=(route_cache_element_t)e;
1217   if (elm) {
1218     xbt_free(elm->pred_arr);
1219     xbt_free(elm);
1220   }
1221 }
1222
1223 static void graph_node_map_elem_free(void *e) {
1224   graph_node_map_element_t elm = (graph_node_map_element_t)e;
1225   if(elm) {
1226     xbt_free(elm);
1227   }
1228 }
1229
1230 static void graph_edge_data_free(void *e) {
1231   route_extended_t e_route = (route_extended_t)e;
1232   if(e_route) {
1233     xbt_dynar_free(&(e_route->generic_route.link_list));
1234     if(e_route->src_gateway) xbt_free(e_route->src_gateway);
1235     if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
1236     xbt_free(e_route);
1237   }
1238 }
1239
1240 /* Utility functions */
1241
1242 static xbt_node_t route_graph_new_node(routing_component_dijkstra_t rc, int id, int graph_id) {
1243   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1244   xbt_node_t node = NULL;
1245   graph_node_data_t data = NULL;
1246   graph_node_map_element_t elm = NULL;
1247
1248   data = xbt_new0(struct graph_node_data, 1);
1249   data->id = id;
1250   data->graph_id = graph_id;
1251   node = xbt_graph_new_node(routing->route_graph, data);
1252
1253   elm = xbt_new0(struct graph_node_map_element, 1);
1254   elm->node = node;
1255   xbt_dict_set_ext(routing->graph_node_map, (char*)(&id), sizeof(int), (xbt_set_elm_t)elm, &graph_node_map_elem_free);
1256
1257   return node;
1258 }
1259  
1260 static graph_node_map_element_t graph_node_map_search(routing_component_dijkstra_t rc, int id) {
1261   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1262   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));
1263   return elm;
1264 }
1265
1266 /* Parsing */
1267
1268 static void route_new_dijkstra(routing_component_dijkstra_t rc, int src_id, int dst_id, route_extended_t e_route ) {
1269   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1270
1271   xbt_node_t src = NULL;
1272   xbt_node_t dst = NULL;
1273   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));
1274   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));
1275
1276   if(src_elm)
1277     src = src_elm->node;
1278
1279   if(dst_elm)
1280     dst = dst_elm->node;
1281
1282   /* add nodes if they don't exist in the graph */
1283   if(src_id == dst_id && src == NULL && dst == NULL) {
1284     src = route_graph_new_node(rc,src_id, -1);
1285     dst = src;
1286   } else {
1287     if(src == NULL) {
1288       src = route_graph_new_node(rc,src_id, -1);
1289     }
1290     if(dst == NULL) {
1291       dst = route_graph_new_node(rc,dst_id, -1);
1292     }
1293   }
1294
1295   /* add link as edge to graph */
1296   xbt_graph_new_edge(routing->route_graph, src, dst, e_route);
1297 }
1298
1299 static void add_loopback_dijkstra(routing_component_dijkstra_t rc) {
1300   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1301
1302   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1303
1304   xbt_node_t node = NULL;
1305   unsigned int cursor2;
1306   xbt_dynar_foreach(nodes, cursor2, node) {
1307     xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node); 
1308     xbt_edge_t edge = NULL;
1309     unsigned int cursor;
1310
1311     int found = 0;
1312     xbt_dynar_foreach(out_edges, cursor, edge) {
1313       xbt_node_t other_node = xbt_graph_edge_get_target(edge);
1314       if(other_node == node) {
1315         found = 1;
1316         break;
1317       }
1318     }
1319
1320     if(!found) {
1321       route_extended_t e_route = xbt_new0(s_route_extended_t,1);
1322       e_route->src_gateway = NULL;
1323       e_route->dst_gateway = NULL;
1324       e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1325       xbt_dynar_push(e_route->generic_route.link_list,&global_routing->loopback);
1326       xbt_graph_new_edge(routing->route_graph, node, node, e_route);
1327     }
1328   }
1329 }
1330
1331 /* Business methods */
1332 static xbt_dynar_t dijkstra_get_onelink_routes(routing_component_t rc)
1333 {
1334   xbt_die("\"dijkstra_get_onelink_routes\" function not implemented yet");
1335 }
1336
1337 static int dijkstra_is_router(const char *name)
1338 {
1339   xbt_die("\"dijkstra_is_router\" function not implemented yet");
1340 }
1341
1342 static route_extended_t dijkstra_get_route(routing_component_t rc, const char* src,const char* dst) {
1343   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
1344   
1345   /* set utils vars */
1346   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1347   
1348   generic_src_dst_check(rc,src,dst);
1349   int *src_id = xbt_dict_get_or_null(routing->to_index,src);
1350   int *dst_id = xbt_dict_get_or_null(routing->to_index,dst);
1351   xbt_assert2(src_id && dst_id, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
1352   
1353   /* create a result route */
1354   route_extended_t new_e_route = xbt_new0(s_route_extended_t,1);
1355   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1356   new_e_route->src_gateway = NULL;
1357   new_e_route->dst_gateway = NULL;
1358   
1359   int *pred_arr = NULL;
1360   int src_node_id = 0;
1361   int dst_node_id = 0;
1362   int * nodeid = NULL;
1363   int v;
1364   route_extended_t e_route;
1365   int size = 0;
1366   unsigned int cpt;
1367   void* link;
1368   xbt_dynar_t links = NULL;
1369   route_cache_element_t elm = NULL;
1370   xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1371   
1372   /* Use the graph_node id mapping set to quickly find the nodes */
1373   graph_node_map_element_t src_elm = graph_node_map_search(routing,*src_id);
1374   graph_node_map_element_t dst_elm = graph_node_map_search(routing,*dst_id);
1375   xbt_assert2(src_elm != NULL && dst_elm != NULL, "src %d or dst %d does not exist", *src_id, *dst_id);
1376   src_node_id = ((graph_node_data_t)xbt_graph_node_get_data(src_elm->node))->graph_id;
1377   dst_node_id = ((graph_node_data_t)xbt_graph_node_get_data(dst_elm->node))->graph_id;
1378
1379   /* if the src and dst are the same */  /* fixed, missing in the previous version */
1380   if( src_node_id == dst_node_id ) {
1381     
1382     xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
1383     xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
1384     xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_s_v, node_e_v);
1385
1386     xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
1387     
1388     e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1389
1390     links = e_route->generic_route.link_list;
1391     xbt_dynar_foreach(links, cpt, link) {
1392       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1393     }
1394   
1395     return new_e_route;
1396   }
1397   
1398   if(routing->cached) {
1399     /*check if there is a cached predecessor list avail */
1400     elm = (route_cache_element_t)xbt_dict_get_or_null_ext(routing->route_cache, (char*)(&src_id), sizeof(int));
1401   }
1402
1403   if(elm) { /* cached mode and cache hit */
1404     pred_arr = elm->pred_arr;
1405   } else { /* not cached mode or cache miss */
1406     double * cost_arr = NULL;
1407     xbt_heap_t pqueue = NULL;
1408     int i = 0;
1409
1410     int nr_nodes = xbt_dynar_length(nodes);
1411     cost_arr = xbt_new0(double, nr_nodes); /* link cost from src to other hosts */
1412     pred_arr = xbt_new0(int, nr_nodes);    /* predecessors in path from src */
1413     pqueue = xbt_heap_new(nr_nodes, xbt_free);
1414
1415     /* initialize */
1416     cost_arr[src_node_id] = 0.0;
1417
1418     for(i = 0; i < nr_nodes; i++) {
1419       if(i != src_node_id) {
1420         cost_arr[i] = DBL_MAX;
1421       }
1422
1423       pred_arr[i] = 0;
1424
1425       /* initialize priority queue */
1426       nodeid = xbt_new0(int, 1);
1427       *nodeid = i;
1428       xbt_heap_push(pqueue, nodeid, cost_arr[i]);
1429
1430     }
1431
1432     /* apply dijkstra using the indexes from the graph's node array */
1433     while(xbt_heap_size(pqueue) > 0) {
1434       int * v_id = xbt_heap_pop(pqueue);
1435       xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
1436       xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node); 
1437       xbt_edge_t edge = NULL;
1438       unsigned int cursor;
1439
1440       xbt_dynar_foreach(out_edges, cursor, edge) {
1441         xbt_node_t u_node = xbt_graph_edge_get_target(edge);
1442         graph_node_data_t data = xbt_graph_node_get_data(u_node);
1443         int u_id = data->graph_id;
1444         route_extended_t tmp_e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1445         int cost_v_u = (tmp_e_route->generic_route.link_list)->used;  /* count of links, old model assume 1 */
1446
1447         if(cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
1448           pred_arr[u_id] = *v_id;
1449           cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
1450           nodeid = xbt_new0(int, 1);
1451           *nodeid = u_id;
1452           xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
1453         }
1454       }
1455
1456       /* free item popped from pqueue */
1457       xbt_free(v_id);
1458     }
1459
1460     xbt_free(cost_arr);
1461     xbt_heap_free(pqueue);
1462   }
1463   
1464   /* compose route path with links */
1465   char *gw_src=NULL,*gw_dst=NULL, *prev_gw_src,*prev_gw_dst, *first_gw=NULL;
1466   
1467   for(v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
1468     xbt_node_t node_pred_v = xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
1469     xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
1470     xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_pred_v, node_v);
1471
1472     xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
1473     
1474     prev_gw_src = gw_src;
1475     prev_gw_dst = gw_dst;
1476     
1477     e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
1478     gw_src = e_route->src_gateway;
1479     gw_dst = e_route->dst_gateway;
1480     
1481     if(v==dst_node_id) first_gw = gw_dst;
1482     
1483     if(rc->hierarchy == SURF_ROUTING_RECURSIVE && v!=dst_node_id && strcmp(gw_dst,prev_gw_src)) {
1484       xbt_dynar_t e_route_as_to_as = (*(global_routing->get_route))(gw_dst,prev_gw_src);
1485       xbt_assert2(e_route_as_to_as,"no route between \"%s\" and \"%s\"",gw_dst,prev_gw_src);
1486       links = e_route_as_to_as;
1487       int pos = 0;
1488       xbt_dynar_foreach(links, cpt, link) {
1489         xbt_dynar_insert_at(new_e_route->generic_route.link_list,pos,&link);
1490         pos++;
1491       }
1492     }
1493     
1494     links = e_route->generic_route.link_list;
1495     xbt_dynar_foreach(links, cpt, link) {
1496       xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
1497     }
1498     size++;
1499   }
1500
1501   if(rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1502     new_e_route->src_gateway = xbt_strdup(gw_src);
1503     new_e_route->dst_gateway = xbt_strdup(first_gw);
1504   }
1505
1506   if(routing->cached && elm == NULL) {
1507     /* add to predecessor list of the current src-host to cache */
1508     elm = xbt_new0(struct route_cache_element, 1);
1509     elm->pred_arr = pred_arr;
1510     elm->size = size;
1511     xbt_dict_set_ext(routing->route_cache, (char*)(&src_id), sizeof(int), (xbt_set_elm_t)elm, &route_cache_elem_free);
1512   }
1513
1514   if(!routing->cached)
1515     xbt_free(pred_arr);
1516   
1517   return new_e_route;
1518 }
1519
1520 static void dijkstra_finalize(routing_component_t rc) {
1521   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1522
1523   if (routing) {
1524     xbt_graph_free_graph(routing->route_graph, &xbt_free, &graph_edge_data_free, &xbt_free);
1525     xbt_dict_free(&routing->graph_node_map);
1526     if(routing->cached)
1527       xbt_dict_free(&routing->route_cache);
1528     /* Delete bypass dict */
1529     xbt_dict_free(&routing->bypassRoutes);
1530     /* Delete index dict */
1531     xbt_dict_free(&(routing->to_index));
1532     /* Delete structure */
1533     xbt_free(routing);
1534   }
1535 }
1536
1537 /* Creation routing model functions */
1538
1539 static void* model_dijkstra_both_create(int cached) {
1540   routing_component_dijkstra_t new_component = xbt_new0(s_routing_component_dijkstra_t,1);
1541   new_component->generic_routing.set_processing_unit = generic_set_processing_unit;
1542   new_component->generic_routing.set_autonomous_system = generic_set_autonomous_system;
1543   new_component->generic_routing.set_route = generic_set_route;
1544   new_component->generic_routing.set_ASroute = generic_set_ASroute;
1545   new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1546   new_component->generic_routing.get_route = dijkstra_get_route;
1547   new_component->generic_routing.get_onelink_routes = dijkstra_get_onelink_routes;
1548   new_component->generic_routing.is_router = dijkstra_is_router;
1549   new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
1550   new_component->generic_routing.finalize = dijkstra_finalize;
1551   new_component->cached = cached;
1552   new_component->to_index = xbt_dict_new();
1553   new_component->bypassRoutes = xbt_dict_new();
1554   new_component->parse_routes = xbt_dict_new();
1555   return new_component;
1556 }
1557
1558 static void* model_dijkstra_create(void) {
1559   return model_dijkstra_both_create(0);
1560 }
1561
1562 static void* model_dijkstracache_create(void) {
1563   return model_dijkstra_both_create(1);
1564 }
1565
1566 static void  model_dijkstra_both_load(void) {
1567  /* use "surfxml_add_callback" to add a parse function call */
1568 }
1569
1570 static void  model_dijkstra_both_unload(void) {
1571  /* use "surfxml_del_callback" to remove a parse function call */
1572 }
1573
1574 static void  model_dijkstra_both_end(void) {
1575   routing_component_dijkstra_t routing = (routing_component_dijkstra_t) current_routing;
1576    xbt_dict_cursor_t cursor = NULL;
1577    char *key, *data, *end;
1578    const char *sep = "#";
1579    xbt_dynar_t keys;
1580   xbt_node_t node = NULL;
1581   unsigned int cursor2;
1582   xbt_dynar_t nodes = NULL;
1583   int src_id, dst_id;
1584   route_t route;
1585   
1586   /* Create the topology graph */
1587   routing->route_graph = xbt_graph_new_graph(1, NULL);
1588   routing->graph_node_map = xbt_dict_new();
1589   
1590   if(routing->cached)
1591     routing->route_cache = xbt_dict_new();
1592
1593   /* Put the routes in position */
1594   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1595     keys = xbt_str_split_str(key, sep);
1596     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
1597     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
1598     route_extended_t e_route = generic_new_extended_route(current_routing->hierarchy,data,0);
1599     route_new_dijkstra(routing,src_id,dst_id,e_route);
1600     xbt_dynar_free(&keys);
1601   }
1602
1603   /* delete the parse table */
1604   xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
1605     route = (route_t)data;
1606     xbt_dynar_free(&(route->link_list));
1607     xbt_free(data);
1608   }
1609       
1610   /* delete parse dict */
1611   xbt_dict_free(&(routing->parse_routes));
1612   
1613   /* Add the loopback if needed */
1614   if(current_routing->hierarchy == SURF_ROUTING_BASE)
1615     add_loopback_dijkstra(routing);
1616
1617   /* initialize graph indexes in nodes after graph has been built */
1618   nodes = xbt_graph_get_nodes(routing->route_graph);
1619
1620   xbt_dynar_foreach(nodes, cursor2, node) {
1621     graph_node_data_t data = xbt_graph_node_get_data(node);
1622     data->graph_id = cursor2;
1623   }
1624   
1625 }
1626
1627 /* ************************************************** */
1628 /* ************** RULE-BASED ROUTING **************** */
1629
1630 /* Routing model structure */
1631
1632 typedef struct {
1633   s_routing_component_t generic_routing;
1634   xbt_dict_t  dict_processing_units;
1635   xbt_dict_t  dict_autonomous_systems;
1636   xbt_dynar_t list_route;
1637   xbt_dynar_t list_ASroute;
1638 } s_routing_component_rulebased_t,*routing_component_rulebased_t;
1639
1640 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
1641 typedef struct s_rule_route_extended s_rule_route_extended_t, *rule_route_extended_t;
1642
1643 struct s_rule_route {
1644   xbt_dynar_t re_str_link; // dynar of char*
1645   pcre* re_src;
1646   pcre* re_dst;
1647 };
1648
1649 struct s_rule_route_extended {
1650   s_rule_route_t generic_rule_route;
1651   char* re_src_gateway;
1652   char* re_dst_gateway;
1653 };
1654
1655 static void rule_route_free(void *e) {
1656   rule_route_t* elem = (rule_route_t*)(e);
1657   if (*elem) {
1658     xbt_dynar_free(&(*elem)->re_str_link);
1659     pcre_free((*elem)->re_src);
1660     pcre_free((*elem)->re_dst);
1661     xbt_free((*elem));
1662   }
1663   (*elem) = NULL;
1664 }
1665
1666 static void rule_route_extended_free(void *e) {
1667   rule_route_extended_t* elem = (rule_route_extended_t*)e;
1668   if (*elem) {
1669     xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
1670     pcre_free((*elem)->generic_rule_route.re_src);
1671     pcre_free((*elem)->generic_rule_route.re_dst);
1672     xbt_free((*elem)->re_src_gateway);
1673     xbt_free((*elem)->re_dst_gateway);
1674     xbt_free((*elem));
1675   }
1676 }
1677
1678 /* Parse routing model functions */
1679
1680 static void model_rulebased_set_processing_unit(routing_component_t rc, const char* name) {
1681   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1682   xbt_dict_set(routing->dict_processing_units, name, (void*)(-1), NULL);
1683 }
1684
1685 static void model_rulebased_set_autonomous_system(routing_component_t rc, const char* name) {
1686   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1687   xbt_dict_set(routing->dict_autonomous_systems, name, (void*)(-1), NULL);  
1688 }
1689
1690 static void model_rulebased_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {
1691   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1692   rule_route_t ruleroute = xbt_new0(s_rule_route_t,1);
1693   const char *error;
1694   int erroffset;
1695   ruleroute->re_src = pcre_compile(src,0,&error,&erroffset,NULL);
1696   xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
1697   ruleroute->re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
1698   xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
1699   ruleroute->re_str_link = route->link_list;
1700   xbt_dynar_push(routing->list_route,&ruleroute);
1701   xbt_free(route);
1702 }
1703
1704 static void model_rulebased_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {
1705   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1706   rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t,1);
1707   const char *error;
1708   int erroffset;
1709   ruleroute_e->generic_rule_route.re_src = pcre_compile(src,0,&error,&erroffset,NULL);
1710   xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
1711   ruleroute_e->generic_rule_route.re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
1712   xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
1713   ruleroute_e->generic_rule_route.re_str_link = route->generic_route.link_list;
1714   ruleroute_e->re_src_gateway = route->src_gateway;
1715   ruleroute_e->re_dst_gateway = route->dst_gateway;
1716   xbt_dynar_push(routing->list_ASroute,&ruleroute_e);
1717   xbt_free(route->src_gateway);
1718   xbt_free(route->dst_gateway);
1719   xbt_free(route);
1720 }
1721
1722 static void model_rulebased_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
1723   xbt_die("bypass routing not supported for Route-Based model");
1724 }
1725
1726 #define BUFFER_SIZE 4096  /* result buffer size */
1727 #define OVECCOUNT 30      /* should be a multiple of 3 */
1728
1729 static char* remplace(char* value, const char** src_list, int src_size, const char** dst_list, int dst_size ) {
1730
1731   char result_result[BUFFER_SIZE];
1732   int i_result_buffer;
1733   int value_length = (int)strlen(value);
1734   int number=0;
1735   
1736   int i=0;
1737   i_result_buffer = 0;
1738   do {
1739     if( value[i] == '$' ) {
1740       i++; // skip $
1741       
1742       // find the number      
1743       int number_length = 0;
1744       while( '0' <= value[i+number_length] && value[i+number_length] <= '9' ) {
1745         number_length++;
1746       }
1747       xbt_assert2( number_length!=0, "bad string parameter, no number indication, at offset: %d (\"%s\")",i,value);
1748       
1749       // solve number
1750       number = atoi(value+i);
1751       i=i+number_length;
1752       xbt_assert2(i+2<value_length,"bad string parameter, too few chars, at offset: %d (\"%s\")",i,value);
1753       
1754       // solve the indication
1755       const char** param_list;
1756       int param_size;
1757       if( value[i] == 's' && value[i+1] == 'r' && value[i+2] == 'c' ) {
1758         param_list = src_list;
1759         param_size = src_size;
1760       } else  if( value[i] == 'd' && value[i+1] == 's' && value[i+2] == 't' ) {
1761         param_list = dst_list;
1762         param_size = dst_size;
1763       } else {
1764         xbt_assert2(0,"bad string parameter, support only \"src\" and \"dst\", at offset: %d (\"%s\")",i,value);
1765       }
1766       i=i+3;
1767       
1768       xbt_assert4( param_size >= number, "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",i,value,param_size,number);
1769       
1770       const char* param = param_list[number];
1771       int size = strlen(param);
1772       int cp;
1773       for(cp = 0; cp < size; cp++ ) {
1774         result_result[i_result_buffer] = param[cp];
1775         i_result_buffer++;
1776         if( i_result_buffer >= BUFFER_SIZE ) break;
1777       }
1778     } else {
1779       result_result[i_result_buffer] = value[i];
1780       i_result_buffer++;
1781       i++; // next char
1782     }
1783     
1784   } while(i<value_length && i_result_buffer < BUFFER_SIZE);
1785   
1786   xbt_assert2( i_result_buffer < BUFFER_SIZE, "solving string \"%s\", small buffer size (%d)",value,BUFFER_SIZE);
1787   result_result[i_result_buffer] = 0;
1788   return xbt_strdup(result_result);
1789 }
1790
1791 static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
1792 {
1793   xbt_die("\"rulebased_get_onelink_routes\" function not implemented yet");
1794 }
1795
1796 static int rulebased_is_router(const char *name)
1797 {
1798   xbt_die("\"rulebased_is_router\" function not implemented yet");
1799 }
1800
1801 /* Business methods */
1802 static route_extended_t rulebased_get_route(routing_component_t rc, const char* src,const char* dst) {
1803   xbt_assert1(rc&&src&&dst, "Invalid params for \"get_route\" function at AS \"%s\"",rc->name);
1804
1805   /* set utils vars */
1806   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1807
1808   int are_processing_units;
1809   xbt_dynar_t rule_list;
1810   if( xbt_dict_get_or_null(routing->dict_processing_units,src) && xbt_dict_get_or_null(routing->dict_processing_units,dst) ) {
1811     are_processing_units = 1;
1812     rule_list = routing->list_route;
1813   } else if( xbt_dict_get_or_null(routing->dict_autonomous_systems,src) && xbt_dict_get_or_null(routing->dict_autonomous_systems,dst) ) {
1814     are_processing_units = 0;
1815     rule_list = routing->list_ASroute;    
1816   } else
1817      xbt_assert2(NULL, "Ask for route \"from\"(%s)  or \"to\"(%s) no found in the local table",src,dst); 
1818
1819   int rc_src = -1;
1820   int rc_dst = -1;
1821   int src_length = (int)strlen(src);
1822   int dst_length = (int)strlen(dst);
1823   
1824   xbt_dynar_t links_list = xbt_dynar_new(global_routing->size_of_link,NULL);
1825   
1826   rule_route_t ruleroute;
1827   unsigned int cpt;
1828   int ovector_src[OVECCOUNT];
1829   int ovector_dst[OVECCOUNT];
1830   const char** list_src = NULL;
1831   const char** list_dst = NULL;
1832   xbt_dynar_foreach(rule_list, cpt, ruleroute) {
1833     rc_src = pcre_exec(ruleroute->re_src,NULL,src,src_length,0,0,ovector_src,OVECCOUNT);
1834     if( rc_src >= 0 ) {
1835       rc_dst = pcre_exec(ruleroute->re_dst,NULL,dst,dst_length,0,0,ovector_dst,OVECCOUNT);
1836       if( rc_dst >= 0 ) {
1837         xbt_assert1(!pcre_get_substring_list(src,ovector_src,rc_src,&list_src),"error solving substring list for src \"%s\"",src);
1838         xbt_assert1(!pcre_get_substring_list(dst,ovector_dst,rc_dst,&list_dst),"error solving substring list for src \"%s\"",dst);
1839         char* link_name;
1840         xbt_dynar_foreach(ruleroute->re_str_link, cpt, link_name) {
1841           char* new_link_name = remplace(link_name,list_src,rc_src,list_dst,rc_dst);
1842           void* link = xbt_dict_get_or_null(surf_network_model->resource_set, new_link_name);
1843           if (link)
1844             xbt_dynar_push(links_list,&link);
1845           else
1846             THROW1(mismatch_error,0,"Link %s not found", new_link_name);
1847           xbt_free(new_link_name);
1848         }
1849       }
1850     }
1851     if( rc_src >= 0 && rc_dst >= 0 ) break;
1852   }
1853   
1854   route_extended_t new_e_route = NULL;
1855   if(rc_src >= 0 && rc_dst >= 0) {
1856     new_e_route = xbt_new0(s_route_extended_t,1);
1857     new_e_route->generic_route.link_list = links_list;
1858   } else if( !strcmp(src,dst) && are_processing_units ) {
1859     new_e_route = xbt_new0(s_route_extended_t,1);
1860     xbt_dynar_push(links_list,&(global_routing->loopback));
1861     new_e_route->generic_route.link_list = links_list;
1862   } else { 
1863     xbt_dynar_free(&link_list);
1864   }
1865
1866   if(!are_processing_units && new_e_route)
1867   {
1868     rule_route_extended_t ruleroute_extended = (rule_route_extended_t)ruleroute;
1869     new_e_route->src_gateway = remplace(ruleroute_extended->re_src_gateway,list_src,rc_src,list_dst,rc_dst);
1870     new_e_route->dst_gateway = remplace(ruleroute_extended->re_dst_gateway,list_src,rc_src,list_dst,rc_dst);
1871   }
1872   
1873   if(list_src) pcre_free_substring_list(list_src);
1874   if(list_dst) pcre_free_substring_list(list_dst);
1875   
1876   return new_e_route;
1877 }
1878
1879 static route_extended_t rulebased_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {
1880   return NULL;
1881 }
1882
1883 static void rulebased_finalize(routing_component_t rc) {
1884   routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
1885   if (routing) {
1886     xbt_dict_free(&routing->dict_processing_units);
1887     xbt_dict_free(&routing->dict_autonomous_systems);
1888     xbt_dynar_free(&routing->list_route);
1889     xbt_dynar_free(&routing->list_ASroute);
1890     /* Delete structure */
1891     xbt_free(routing);
1892   }
1893 }
1894
1895 /* Creation routing model functions */
1896 static void* model_rulebased_create(void) {  
1897   routing_component_rulebased_t new_component =  xbt_new0(s_routing_component_rulebased_t,1);
1898   new_component->generic_routing.set_processing_unit = model_rulebased_set_processing_unit;
1899   new_component->generic_routing.set_autonomous_system = model_rulebased_set_autonomous_system;
1900   new_component->generic_routing.set_route = model_rulebased_set_route;
1901   new_component->generic_routing.set_ASroute = model_rulebased_set_ASroute;
1902   new_component->generic_routing.set_bypassroute = model_rulebased_set_bypassroute;
1903   new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes;
1904   new_component->generic_routing.is_router = rulebased_is_router;
1905   new_component->generic_routing.get_route = rulebased_get_route;
1906   new_component->generic_routing.get_bypass_route = NULL; //rulebased_get_bypass_route;
1907   new_component->generic_routing.finalize = rulebased_finalize;
1908   /* initialization of internal structures */
1909   new_component->dict_processing_units = xbt_dict_new();
1910   new_component->dict_autonomous_systems = xbt_dict_new();
1911   new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free);
1912   new_component->list_ASroute = xbt_dynar_new(sizeof(rule_route_extended_t), &rule_route_extended_free);
1913   return new_component;
1914 }
1915
1916 static void  model_rulebased_load(void) {
1917  /* use "surfxml_add_callback" to add a parse function call */
1918 }
1919
1920 static void  model_rulebased_unload(void) {
1921  /* use "surfxml_del_callback" to remove a parse function call */
1922 }
1923
1924 static void  model_rulebased_end(void) {
1925 }
1926
1927 /* ************************************************************************** */
1928 /* ******************************* NO ROUTING ******************************* */
1929
1930 /* Routing model structure */
1931 typedef struct {
1932   s_routing_component_t generic_routing;
1933 } s_routing_component_none_t,*routing_component_none_t;
1934
1935 /* Business methods */
1936 static xbt_dynar_t none_get_onelink_routes(routing_component_t rc){
1937   return NULL;
1938 }
1939 static int none_is_router(const char *name){
1940   return -1;
1941 }
1942 static route_extended_t none_get_route(routing_component_t rc, const char* src,const char* dst){
1943   return NULL;
1944 }
1945 static route_extended_t none_get_bypass_route(routing_component_t rc, const char* src,const char* dst){
1946   return NULL;
1947 }
1948 static void none_finalize(routing_component_t rc) {
1949   xbt_free(rc);
1950 }
1951
1952 static void none_set_processing_unit(routing_component_t rc, const char* name) {}
1953 static void none_set_autonomous_system(routing_component_t rc, const char* name) {}
1954
1955 /* Creation routing model functions */
1956 static void* model_none_create(void) {
1957   routing_component_none_t new_component =  xbt_new0(s_routing_component_none_t,1);
1958   new_component->generic_routing.set_processing_unit = none_set_processing_unit;
1959   new_component->generic_routing.set_autonomous_system = none_set_autonomous_system;
1960   new_component->generic_routing.set_route = NULL;
1961   new_component->generic_routing.set_ASroute = NULL;
1962   new_component->generic_routing.set_bypassroute = NULL;
1963   new_component->generic_routing.get_route = none_get_route;
1964   new_component->generic_routing.get_onelink_routes = none_get_onelink_routes;
1965   new_component->generic_routing.is_router = none_is_router;
1966   new_component->generic_routing.get_bypass_route = none_get_bypass_route;
1967   new_component->generic_routing.finalize = none_finalize;
1968   return new_component;
1969 }
1970
1971 static void  model_none_load(void) {}
1972 static void  model_none_unload(void) {}
1973 static void  model_none_end(void) {}
1974
1975 /* ************************************************** */
1976 /* ********** PATERN FOR NEW ROUTING **************** */
1977
1978 /* The minimal configuration of a new routing model need the next functions,
1979  * also you need to set at the start of the file, the new model in the model
1980  * list. Remember keep the null ending of the list.
1981  */
1982 /*** Routing model structure ***/
1983 // typedef struct {
1984 //   s_routing_component_t generic_routing;
1985 //   /* things that your routing model need */
1986 // } s_routing_component_NEW_t,*routing_component_NEW_t;
1987
1988 /*** Parse routing model functions ***/
1989 // static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
1990 // static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
1991 // static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
1992 // static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
1993 // static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
1994
1995 /*** Business methods ***/
1996 // static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
1997 // static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
1998 // static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
1999
2000 /*** Creation routing model functions ***/
2001 // static void* model_NEW_create(void) {
2002 //   routing_component_NEW_t new_component =  xbt_new0(s_routing_component_NEW_t,1);
2003 //   new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
2004 //   new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
2005 //   new_component->generic_routing.set_route = model_NEW_set_route;
2006 //   new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
2007 //   new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
2008 //   new_component->generic_routing.get_route = NEW_get_route;
2009 //   new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
2010 //   new_component->generic_routing.finalize = NEW_finalize;
2011 //   /* initialization of internal structures */
2012 //   return new_component;
2013 // } /* mandatory */
2014 // static void  model_NEW_load(void) {}   /* mandatory */
2015 // static void  model_NEW_unload(void) {} /* mandatory */
2016 // static void  model_NEW_end(void) {}    /* mandatory */
2017
2018 /* ************************************************************************** */
2019 /* ************************* GENERIC PARSE FUNCTIONS ************************ */ 
2020
2021 static void generic_set_processing_unit(routing_component_t rc, const char* name) {
2022   DEBUG1("Load process unit \"%s\"",name);
2023   model_type_t modeltype = rc->routing;
2024   int *id = xbt_new0(int,1);
2025   xbt_dict_t _to_index;
2026   if(modeltype==&routing_models[SURF_MODEL_FULL])
2027     _to_index = ((routing_component_full_t)rc)->to_index;
2028   
2029   else if(modeltype==&routing_models[SURF_MODEL_FLOYD])
2030     _to_index = ((routing_component_floyd_t)rc)->to_index;
2031   
2032   else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2033           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE])
2034     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2035   
2036   else xbt_die("\"generic_set_processing_unit\" not supported");
2037   *id = xbt_dict_length(_to_index);
2038   xbt_dict_set(_to_index,name,id,xbt_free);
2039 }
2040
2041 static void generic_set_autonomous_system(routing_component_t rc, const char* name) {
2042   DEBUG1("Load Autonomous system \"%s\"",name);
2043   model_type_t modeltype = rc->routing;
2044   int *id = xbt_new0(int,1);
2045   xbt_dict_t _to_index;
2046   if(modeltype==&routing_models[SURF_MODEL_FULL])
2047     _to_index = ((routing_component_full_t)rc)->to_index;
2048   
2049   else if(modeltype==&routing_models[SURF_MODEL_FLOYD])
2050     _to_index = ((routing_component_floyd_t)rc)->to_index;
2051   
2052   else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2053           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE])
2054     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2055   
2056   else xbt_die("\"generic_set_autonomous_system\" not supported");
2057   *id = xbt_dict_length(_to_index);
2058   xbt_dict_set(_to_index,name,id,xbt_free);
2059 }
2060
2061 static void generic_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {
2062   DEBUG2("Load Route from \"%s\" to \"%s\"",src,dst);
2063   model_type_t modeltype = rc->routing;
2064   xbt_dict_t _parse_routes;
2065   xbt_dict_t _to_index;
2066   char *route_name;
2067   int *src_id, *dst_id;
2068   
2069   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2070     _parse_routes = ((routing_component_full_t)rc)->parse_routes;
2071     _to_index = ((routing_component_full_t)rc)->to_index;
2072     
2073   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2074     _parse_routes = ((routing_component_floyd_t)rc)->parse_routes;
2075     _to_index = ((routing_component_floyd_t)rc)->to_index;
2076     
2077   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2078           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2079     _parse_routes = ((routing_component_dijkstra_t)rc)->parse_routes;
2080     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2081   
2082   } else xbt_die("\"generic_set_route\" not supported");
2083
2084   src_id = xbt_dict_get_or_null(_to_index, src);
2085   dst_id = xbt_dict_get_or_null(_to_index, dst);
2086   
2087   xbt_assert2(src_id&&dst_id,"Network elements %s or %s not found", src, dst);
2088   route_name = bprintf("%d#%d",*src_id,*dst_id);
2089   
2090   xbt_assert2(xbt_dynar_length(route->link_list)>0, "Invalid count of links, must be greater than zero (%s,%s)",src,dst);   
2091   xbt_assert2(!xbt_dict_get_or_null(_parse_routes,route_name),
2092     "The route between \"%s\" and \"%s\" already exist",src,dst);
2093
2094   xbt_dict_set(_parse_routes, route_name, route, NULL);
2095   xbt_free(route_name);
2096 }
2097
2098 static void generic_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
2099   DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",src,e_route->src_gateway,dst,e_route->dst_gateway);
2100   model_type_t modeltype = rc->routing;
2101   xbt_dict_t _parse_routes;
2102   xbt_dict_t _to_index;
2103   char *route_name;
2104   int *src_id, *dst_id;
2105   
2106   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2107     _parse_routes = ((routing_component_full_t)rc)->parse_routes;
2108     _to_index = ((routing_component_full_t)rc)->to_index;
2109     
2110   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2111     _parse_routes = ((routing_component_floyd_t)rc)->parse_routes;
2112     _to_index = ((routing_component_floyd_t)rc)->to_index;
2113     
2114   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2115           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2116     _parse_routes = ((routing_component_dijkstra_t)rc)->parse_routes;
2117     _to_index = ((routing_component_dijkstra_t)rc)->to_index;
2118   
2119   } else xbt_die("\"generic_set_route\" not supported");
2120   
2121   src_id = xbt_dict_get_or_null(_to_index, src);
2122   dst_id = xbt_dict_get_or_null(_to_index, dst);
2123   
2124   xbt_assert2(src_id&&dst_id,"Network elements %s or %s not found", src, dst);
2125   route_name = bprintf("%d#%d",*src_id,*dst_id);
2126   
2127   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);   
2128   xbt_assert4(!xbt_dict_get_or_null(_parse_routes,route_name),
2129     "The route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exist",src,e_route->src_gateway,dst,e_route->dst_gateway);
2130     
2131   xbt_dict_set(_parse_routes, route_name, e_route, NULL);
2132   xbt_free(route_name);
2133 }
2134
2135 static void generic_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
2136   DEBUG2("Load bypassRoute from \"%s\" to \"%s\"",src,dst);
2137   model_type_t modeltype = rc->routing;
2138   xbt_dict_t dict_bypassRoutes;
2139   char *route_name;
2140   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2141     dict_bypassRoutes = ((routing_component_full_t)rc)->bypassRoutes;
2142   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2143     dict_bypassRoutes = ((routing_component_floyd_t)rc)->bypassRoutes;
2144   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2145           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2146     dict_bypassRoutes = ((routing_component_dijkstra_t)rc)->bypassRoutes;
2147   } else xbt_die("\"generic_set_bypassroute\" not supported");
2148   route_name = bprintf("%s#%s",src,dst);
2149   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);
2150   xbt_assert4(!xbt_dict_get_or_null(dict_bypassRoutes,route_name),
2151     "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exist",src,e_route->src_gateway,dst,e_route->dst_gateway);
2152     
2153   route_extended_t new_e_route = generic_new_extended_route(SURF_ROUTING_RECURSIVE,e_route,0);
2154   xbt_dynar_free( &(e_route->generic_route.link_list) );
2155   xbt_free(e_route);
2156   
2157   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, (void(*)(void*))generic_free_extended_route ); 
2158   xbt_free(route_name);
2159 }
2160
2161 /* ************************************************************************** */
2162 /* *********************** GENERIC BUSINESS METHODS ************************* */
2163
2164 static xbt_dynar_t generic_get_onelink_routes (routing_component_t rc)
2165 {
2166   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
2167 }
2168
2169 static int generic_is_router (const char *name)
2170 {
2171   xbt_die("\"generic_is_router\" not implemented yet");
2172 }
2173
2174 static route_extended_t generic_get_bypassroute(routing_component_t rc, const char* src, const char* dst) {
2175   model_type_t modeltype = rc->routing;
2176   xbt_dict_t dict_bypassRoutes;
2177   
2178   if(modeltype==&routing_models[SURF_MODEL_FULL]) {
2179     dict_bypassRoutes = ((routing_component_full_t)rc)->bypassRoutes;
2180   } else if(modeltype==&routing_models[SURF_MODEL_FLOYD]) {
2181     dict_bypassRoutes = ((routing_component_floyd_t)rc)->bypassRoutes;
2182   } else if(modeltype==&routing_models[SURF_MODEL_DIJKSTRA]||
2183           modeltype==&routing_models[SURF_MODEL_DIJKSTRACACHE]) {
2184     dict_bypassRoutes = ((routing_component_dijkstra_t)rc)->bypassRoutes;
2185   } else xbt_die("\"generic_get_bypassroute\" not supported");
2186  
2187
2188   routing_component_t src_as, dst_as;
2189   int index_src, index_dst;
2190   xbt_dynar_t path_src = NULL;
2191   xbt_dynar_t path_dst = NULL;
2192   routing_component_t current = NULL;
2193   routing_component_t* current_src = NULL;
2194   routing_component_t* current_dst = NULL;
2195
2196   /* (1) find the as where the src and dst are located */
2197   src_as = xbt_dict_get_or_null(global_routing->where_network_elements,src);
2198   dst_as = xbt_dict_get_or_null(global_routing->where_network_elements,dst); 
2199   xbt_assert2(src_as&&dst_as, "Ask for route \"from\"(%s) or \"to\"(%s) no found",src,dst);
2200  
2201   /* (2) find the path to the root routing component */
2202   path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
2203   current = src_as; 
2204   while( current != NULL ) {
2205     xbt_dynar_push(path_src,&current);
2206     current = current->routing_father;
2207   }
2208   path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
2209   current = dst_as; 
2210   while( current != NULL ) {
2211     xbt_dynar_push(path_dst,&current);
2212     current = current->routing_father;
2213   }
2214
2215   /* (3) find the common father */
2216   index_src  = (path_src->used)-1;
2217   index_dst  = (path_dst->used)-1;
2218   current_src = xbt_dynar_get_ptr(path_src,index_src);
2219   current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
2220   while( index_src >= 0 && index_dst >= 0 && *current_src == *current_dst ) {
2221     routing_component_t *tmp_src,*tmp_dst;
2222     tmp_src = xbt_dynar_pop_ptr(path_src);
2223     tmp_dst = xbt_dynar_pop_ptr(path_dst);
2224     index_src--;
2225     index_dst--;
2226     current_src = xbt_dynar_get_ptr(path_src,index_src);
2227     current_dst = xbt_dynar_get_ptr(path_dst,index_dst);
2228   }
2229   
2230   int max_index_src = (path_src->used)-1;
2231   int max_index_dst = (path_dst->used)-1;
2232   
2233   int max_index = max(max_index_src,max_index_dst);
2234   int i, max;
2235  
2236  route_extended_t e_route_bypass = NULL;
2237  
2238   for( max=0;max<=max_index;max++)
2239   {
2240     for(i=0;i<max;i++)
2241     {
2242       if( i <= max_index_src  && max <= max_index_dst ) {
2243         char* route_name = bprintf("%s#%s",
2244           (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,i)))->name,
2245           (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,max)))->name);
2246         e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2247         xbt_free(route_name);
2248       }
2249       if( e_route_bypass ) break;
2250       if( max <= max_index_src  && i <= max_index_dst ) {
2251         char* route_name = bprintf("%s#%s",
2252           (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,max)))->name,
2253           (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,i)))->name);
2254         e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2255         xbt_free(route_name);
2256       }
2257       if( e_route_bypass ) break;
2258     }
2259     
2260     if( e_route_bypass ) break;
2261      
2262     if( max <= max_index_src  && max <= max_index_dst ) {
2263       char* route_name = bprintf("%s#%s",
2264         (*(routing_component_t*)(xbt_dynar_get_ptr(path_src,max)))->name,
2265         (*(routing_component_t*)(xbt_dynar_get_ptr(path_dst,max)))->name);
2266       e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes,route_name);
2267       xbt_free(route_name);
2268     }
2269     if( e_route_bypass ) break;
2270   }
2271
2272   xbt_dynar_free(&path_src);
2273   xbt_dynar_free(&path_dst);
2274   
2275   route_extended_t new_e_route = NULL;
2276   
2277   if(e_route_bypass) {
2278     void* link;
2279     unsigned int cpt=0;
2280     new_e_route = xbt_new0(s_route_extended_t,1);
2281     new_e_route->src_gateway = xbt_strdup(e_route_bypass->src_gateway);
2282     new_e_route->dst_gateway = xbt_strdup(e_route_bypass->dst_gateway);
2283     new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
2284     xbt_dynar_foreach(e_route_bypass->generic_route.link_list, cpt, link) {
2285       xbt_dynar_push(new_e_route->generic_route.link_list,&link);
2286     }
2287   }
2288
2289   return new_e_route;
2290 }
2291
2292 /* ************************************************************************** */
2293 /* ************************* GENERIC AUX FUNCTIONS ************************** */
2294
2295 static route_extended_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy, void* data, int order) {
2296   
2297   char *link_name;
2298   route_extended_t e_route, new_e_route;
2299   route_t route;
2300   unsigned int cpt;
2301   xbt_dynar_t links, links_id;
2302   
2303   new_e_route = xbt_new0(s_route_extended_t,1);
2304   new_e_route->generic_route.link_list = xbt_dynar_new(global_routing->size_of_link,NULL);
2305   new_e_route->src_gateway = NULL;
2306   new_e_route->dst_gateway = NULL;
2307
2308   xbt_assert0(hierarchy == SURF_ROUTING_BASE || hierarchy == SURF_ROUTING_RECURSIVE,
2309       "the hierarchy type is not defined");
2310   
2311   if(hierarchy == SURF_ROUTING_BASE ) {
2312     
2313     route = (route_t)data;
2314     links = route->link_list;
2315     
2316   } else if(hierarchy == SURF_ROUTING_RECURSIVE ) {
2317
2318     e_route = (route_extended_t)data;
2319     xbt_assert0(e_route->src_gateway&&e_route->dst_gateway,"bad gateway, is null");
2320     links = e_route->generic_route.link_list;
2321     
2322     /* remeber not erase the gateway names */
2323     new_e_route->src_gateway = e_route->src_gateway;
2324     new_e_route->dst_gateway = e_route->dst_gateway;
2325   }
2326   
2327   links_id = new_e_route->generic_route.link_list;
2328   
2329   xbt_dynar_foreach(links, cpt, link_name) {
2330     
2331     void* link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
2332     if (link)
2333     {
2334       if( order )
2335         xbt_dynar_push(links_id,&link);
2336       else
2337         xbt_dynar_unshift(links_id,&link);
2338     }
2339     else
2340       THROW1(mismatch_error,0,"Link %s not found", link_name);
2341   }
2342  
2343   return new_e_route;
2344 }
2345
2346 static void generic_free_route(route_t route) {
2347   if(route) {
2348     xbt_dynar_free(&(route->link_list));
2349     xbt_free(route);
2350   }
2351 }
2352
2353 static void generic_free_extended_route(route_extended_t e_route) {
2354   if(e_route) {
2355     xbt_dynar_free(&(e_route->generic_route.link_list));
2356     if(e_route->src_gateway) xbt_free(e_route->src_gateway);
2357     if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
2358     xbt_free(e_route);
2359   }
2360 }
2361
2362 static routing_component_t generic_as_exist(routing_component_t find_from, routing_component_t to_find) {
2363   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
2364   xbt_dict_cursor_t cursor = NULL;
2365   char *key;
2366   int found=0;
2367   routing_component_t elem;
2368   xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
2369     if( to_find == elem || generic_as_exist(elem,to_find) ){
2370       found=1;
2371       break;
2372     }
2373   }
2374   if(found) return to_find;
2375   return NULL;
2376 }
2377
2378 static routing_component_t generic_autonomous_system_exist(routing_component_t rc, char* element) {
2379   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
2380   routing_component_t element_as, result, elem;
2381   xbt_dict_cursor_t cursor = NULL;
2382   char *key;
2383   element_as = xbt_dict_get_or_null(global_routing->where_network_elements,element);
2384   result = ((routing_component_t)-1);
2385   if(element_as!=rc)
2386     result = generic_as_exist(rc,element_as);
2387   
2388   int found=0;
2389   if(result)
2390   {
2391     xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
2392       found = !strcmp(elem->name,element);
2393       if( found ) break;
2394     }
2395     if( found ) return element_as;
2396   }
2397   return NULL;
2398 }
2399
2400 static routing_component_t generic_processing_units_exist(routing_component_t rc, char* element) {
2401   routing_component_t element_as;
2402   element_as = xbt_dict_get_or_null(global_routing->where_network_elements,element);
2403   if(element_as==rc) return element_as;
2404   return generic_as_exist(rc,element_as);
2405 }
2406
2407 static void generic_src_dst_check(routing_component_t rc, const char* src, const char* dst) {
2408   
2409   routing_component_t src_as = xbt_dict_get_or_null(global_routing->where_network_elements,src);
2410   routing_component_t dst_as = xbt_dict_get_or_null(global_routing->where_network_elements,dst);
2411    
2412   xbt_assert3(src_as != NULL && dst_as  != NULL, 
2413       "Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",src,dst,rc->name);
2414   xbt_assert4(src_as == dst_as,
2415       "The src(%s in %s) and dst(%s in %s) are in differents AS",src,src_as->name,dst,dst_as->name);
2416   xbt_assert2(rc == dst_as,
2417       "The routing component of src and dst is not the same as the network elements belong (%s==%s)",rc->name,dst_as->name);
2418 }
2419
2420 static void routing_full_parse_Scluster(void)
2421 {
2422         static int AX_ptr = 0;
2423
2424         char *cluster_id = A_surfxml_cluster_id;
2425         char *cluster_prefix = A_surfxml_cluster_prefix;
2426         char *cluster_suffix = A_surfxml_cluster_suffix;
2427         char *cluster_radical = A_surfxml_cluster_radical;
2428         char *cluster_power = A_surfxml_cluster_power;
2429         char *cluster_bw = A_surfxml_cluster_bw;
2430         char *cluster_lat = A_surfxml_cluster_lat;
2431         char *cluster_bb_bw = A_surfxml_cluster_bb_bw;
2432         char *cluster_bb_lat = A_surfxml_cluster_bb_lat;
2433         char *host_id, *groups, *link_id;
2434         char *router_id, *link_router, *link_backbone, *route_src_dst;
2435         unsigned int iter;
2436         int start, end, i;
2437         xbt_dynar_t radical_elements;
2438         xbt_dynar_t radical_ends;
2439         #ifndef HAVE_PCRE_LIB
2440                 xbt_dynar_t tab_elements_num = xbt_dynar_new(sizeof(int), NULL);
2441                 char *route_src,*route_dst;
2442                 int j;
2443         #endif
2444
2445         static unsigned int surfxml_buffer_stack_stack_ptr = 1;
2446         static unsigned int surfxml_buffer_stack_stack[1024];
2447
2448         surfxml_buffer_stack_stack[0]= 0;
2449
2450         surfxml_bufferstack_push(1);
2451
2452         SURFXML_BUFFER_SET(AS_id, cluster_id);
2453 #ifdef HAVE_PCRE_LIB
2454         SURFXML_BUFFER_SET(AS_routing, "RuleBased");
2455         DEBUG1("<AS id=\"%s\"\trouting=\"RuleBased\">",cluster_id);
2456 #else
2457         SURFXML_BUFFER_SET(AS_routing, "Full");
2458         DEBUG1("<AS id=\"%s\"\trouting=\"Full\">",cluster_id);
2459 #endif
2460         SURFXML_START_TAG(AS);
2461
2462         radical_elements = xbt_str_split(cluster_radical, ",");
2463         xbt_dynar_foreach(radical_elements, iter, groups)
2464         {
2465                 radical_ends = xbt_str_split(groups, "-");
2466                 switch (xbt_dynar_length(radical_ends))
2467                 {
2468                         case 1:
2469                           surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
2470                           host_id = bprintf("%s%d%s", cluster_prefix, start, cluster_suffix);
2471                           #ifndef HAVE_PCRE_LIB
2472                           xbt_dynar_push_as(tab_elements_num, int, start);
2473                           #endif
2474                           link_id = bprintf("%s_link_%d", cluster_id, start);
2475
2476                           DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>",host_id,cluster_power);
2477                           SURFXML_BUFFER_SET(host_id, host_id);
2478                           SURFXML_BUFFER_SET(host_power, cluster_power);
2479                           SURFXML_BUFFER_SET(host_availability, "1.0");
2480                           SURFXML_BUFFER_SET(host_availability_file, "");
2481                           A_surfxml_host_state = A_surfxml_host_state_ON;
2482                           SURFXML_BUFFER_SET(host_state_file, "");
2483                           SURFXML_BUFFER_SET(host_interference_send, "1.0");
2484                           SURFXML_BUFFER_SET(host_interference_recv, "1.0");
2485                           SURFXML_BUFFER_SET(host_interference_send_recv, "1.0");
2486                           SURFXML_BUFFER_SET(host_max_outgoing_rate, "-1.0");
2487                           SURFXML_START_TAG(host);
2488                           SURFXML_END_TAG(host);
2489
2490                           DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_id,cluster_bw,cluster_lat);
2491                           SURFXML_BUFFER_SET(link_id, link_id);
2492                           SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2493                           SURFXML_BUFFER_SET(link_latency, cluster_lat);
2494                           SURFXML_BUFFER_SET(link_bandwidth_file, "");
2495                           SURFXML_BUFFER_SET(link_latency_file, "");
2496                           A_surfxml_link_state = A_surfxml_link_state_ON;
2497                           SURFXML_BUFFER_SET(link_state_file, "");
2498                           A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2499                           SURFXML_START_TAG(link);
2500                           SURFXML_END_TAG(link);
2501
2502                           break;
2503
2504                         case 2:
2505
2506                           surf_parse_get_int(&start, xbt_dynar_get_as(radical_ends, 0, char *));
2507                           surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
2508                           DEBUG2("Create hosts and links from %d to %d",start,end);
2509                           for (i = start; i <= end; i++)
2510                           {
2511                                   host_id = bprintf("%s%d%s", cluster_prefix, i, cluster_suffix);
2512                                   #ifndef HAVE_PCRE_LIB
2513                                   xbt_dynar_push_as(tab_elements_num, int, i);
2514                                   #endif
2515                                   link_id = bprintf("%s_link_%d", cluster_id, i);
2516
2517                                   DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>",host_id,cluster_power);
2518                                   SURFXML_BUFFER_SET(host_id, host_id);
2519                                   SURFXML_BUFFER_SET(host_power, cluster_power);
2520                                   SURFXML_BUFFER_SET(host_availability, "1.0");
2521                                   SURFXML_BUFFER_SET(host_availability_file, "");
2522                                   A_surfxml_host_state = A_surfxml_host_state_ON;
2523                                   SURFXML_BUFFER_SET(host_state_file, "");
2524                                   SURFXML_BUFFER_SET(host_interference_send, "1.0");
2525                                   SURFXML_BUFFER_SET(host_interference_recv, "1.0");
2526                                   SURFXML_BUFFER_SET(host_interference_send_recv, "1.0");
2527                                   SURFXML_BUFFER_SET(host_max_outgoing_rate, "-1.0");
2528                                   SURFXML_START_TAG(host);
2529                                   SURFXML_END_TAG(host);
2530
2531                                   DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_id,cluster_bw,cluster_lat);
2532                                   SURFXML_BUFFER_SET(link_id, link_id);
2533                                   SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2534                                   SURFXML_BUFFER_SET(link_latency, cluster_lat);
2535                                   SURFXML_BUFFER_SET(link_bandwidth_file, "");
2536                                   SURFXML_BUFFER_SET(link_latency_file, "");
2537                                   A_surfxml_link_state = A_surfxml_link_state_ON;
2538                                   SURFXML_BUFFER_SET(link_state_file, "");
2539                                   A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2540                                   SURFXML_START_TAG(link);
2541                                   SURFXML_END_TAG(link);
2542                           }
2543                           break;
2544
2545                         default:
2546                                 DEBUG0("Malformed radical");
2547                 }
2548
2549                 xbt_dynar_free(&radical_ends);
2550         }
2551
2552         DEBUG0(" ");
2553         router_id = bprintf("%srouter%s",cluster_prefix,cluster_suffix);
2554         link_router = bprintf("%s_link_router",cluster_id);
2555         link_backbone = bprintf("%s_backbone",cluster_id);
2556
2557         DEBUG1("<router id=\"%s\"\">",router_id);
2558         SURFXML_BUFFER_SET(router_id, router_id);;
2559         SURFXML_START_TAG(router);
2560         SURFXML_END_TAG(router);
2561
2562         DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_router,cluster_bw,cluster_lat);
2563         SURFXML_BUFFER_SET(link_id, link_router);
2564         SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
2565         SURFXML_BUFFER_SET(link_latency, cluster_lat);
2566         SURFXML_BUFFER_SET(link_bandwidth_file, "");
2567         SURFXML_BUFFER_SET(link_latency_file, "");
2568         A_surfxml_link_state = A_surfxml_link_state_ON;
2569         SURFXML_BUFFER_SET(link_state_file, "");
2570         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2571         SURFXML_START_TAG(link);
2572         SURFXML_END_TAG(link);
2573
2574         DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>",link_backbone,cluster_bb_bw,cluster_bb_lat);
2575         SURFXML_BUFFER_SET(link_id, link_backbone);
2576         SURFXML_BUFFER_SET(link_bandwidth, cluster_bb_bw);
2577         SURFXML_BUFFER_SET(link_latency, cluster_bb_lat);
2578         SURFXML_BUFFER_SET(link_bandwidth_file, "");
2579         SURFXML_BUFFER_SET(link_latency_file, "");
2580         A_surfxml_link_state = A_surfxml_link_state_ON;
2581         SURFXML_BUFFER_SET(link_state_file, "");
2582         A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
2583         SURFXML_START_TAG(link);
2584         SURFXML_END_TAG(link);
2585
2586         char *new_suffix = bprintf("%s","");
2587
2588         radical_elements = xbt_str_split(cluster_suffix, ".");
2589         xbt_dynar_foreach(radical_elements, iter, groups)
2590         {
2591                     if(strcmp(groups,""))
2592                     {
2593                         new_suffix = bprintf("%s\\.%s",new_suffix,groups);
2594                     }
2595         }
2596         route_src_dst = bprintf("%s(.*)%s",cluster_prefix,new_suffix);
2597
2598         DEBUG0(" ");
2599
2600 #ifdef HAVE_PCRE_LIB
2601
2602         DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\">",route_src_dst,route_src_dst);
2603         SURFXML_BUFFER_SET(route_src, route_src_dst);
2604         SURFXML_BUFFER_SET(route_dst, route_src_dst);
2605         SURFXML_START_TAG(route);
2606
2607         DEBUG1("<link:ctn\tid=\"%s_link_$1src\"/>",cluster_id);
2608         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_$1src",cluster_id));
2609         SURFXML_START_TAG(link_ctn);
2610         SURFXML_END_TAG(link_ctn);
2611
2612         DEBUG1("<link:ctn\tid=\"%s_backbone\"/>",cluster_id);
2613         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone",cluster_id));
2614         SURFXML_START_TAG(link_ctn);
2615         SURFXML_END_TAG(link_ctn);
2616
2617         DEBUG1("<link:ctn\tid=\"%s_link_$1dst\"/>",cluster_id);
2618         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_$1dst",cluster_id));
2619         SURFXML_START_TAG(link_ctn);
2620         SURFXML_END_TAG(link_ctn);
2621
2622         DEBUG0("</route>");
2623         SURFXML_END_TAG(route);
2624 #else
2625         for(i=0 ; i<=tab_elements_num->elmsize ; i++)
2626         {
2627                 for(j=0 ; j<=tab_elements_num->elmsize ; j++)
2628                 {
2629                         route_src = bprintf("%s%d%s",cluster_prefix,xbt_dynar_get_as(tab_elements_num,i,int),cluster_suffix);
2630                         route_dst = bprintf("%s%d%s",cluster_prefix,xbt_dynar_get_as(tab_elements_num,j,int),cluster_suffix);
2631
2632                         DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\">",route_src,route_dst);
2633                         SURFXML_BUFFER_SET(route_src, route_src);
2634                         SURFXML_BUFFER_SET(route_dst, route_dst);
2635                         SURFXML_START_TAG(route);
2636
2637                         route_src = bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,i,int));
2638                         route_dst = bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,j,int));
2639
2640                         DEBUG2("<link:ctn\tid=\"%s_link_%d\"/>",cluster_id,xbt_dynar_get_as(tab_elements_num,i,int));
2641                         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,i,int)));
2642                         SURFXML_START_TAG(link_ctn);
2643                         SURFXML_END_TAG(link_ctn);
2644
2645                         DEBUG1("<link:ctn\tid=\"%s_backbone\"/>",cluster_id);
2646                         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone",cluster_id));
2647                         SURFXML_START_TAG(link_ctn);
2648                         SURFXML_END_TAG(link_ctn);
2649
2650                         DEBUG2("<link:ctn\tid=\"%s_link_%d\"/>",cluster_id,xbt_dynar_get_as(tab_elements_num,j,int));
2651                         SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_link_%d",cluster_id,xbt_dynar_get_as(tab_elements_num,j,int)));
2652                         SURFXML_START_TAG(link_ctn);
2653                         SURFXML_END_TAG(link_ctn);
2654
2655                         DEBUG0("</route>");
2656                         SURFXML_END_TAG(route);
2657                 }
2658         }
2659         xbt_dynar_free(&tab_elements_num);
2660 #endif
2661
2662         DEBUG0("</AS>");
2663         SURFXML_END_TAG(AS);
2664         DEBUG0(" ");
2665
2666         surfxml_bufferstack_pop(1);
2667 }
2668
2669 /*
2670  * New methods to init the routing model component from the lua script
2671  */
2672
2673 /*
2674  * calling parse_S_AS_lua with lua values
2675  */
2676 void routing_AS_init(const char* AS_id,const char* AS_routing)
2677 {
2678         parse_S_AS_lua((char*)AS_id,(char*)AS_routing);
2679 }
2680
2681 /*
2682  * calling parse_E_AS_lua to fisnish the creation of routing component
2683  */
2684 void routing_AS_end(const char *AS_id)
2685 {
2686         parse_E_AS_lua((char*)AS_id);
2687 }
2688
2689 /*
2690  * add a host to the network element list
2691  */
2692
2693 void routing_add_host(const char* host_id)
2694 {
2695         parse_S_host_lua((char*)host_id);
2696 }
2697
2698 /*
2699  * Set a new link on the actual list of link for a route or ASroute
2700  */
2701 void routing_add_link(const char* link_id)
2702 {
2703         parse_E_link_c_ctn_new_elem_lua((char*)link_id);
2704 }
2705
2706 /*
2707  *Set the endpoints for a route
2708  */
2709 void routing_set_route(const char* src_id,const char *dst_id)
2710 {
2711         parse_S_route_new_and_endpoints_lua((char*)src_id,(char*)dst_id);
2712 }
2713
2714 /*
2715  * Store the route by calling parse_E_route_store_route
2716  */
2717 void routing_store_route(void)
2718 {
2719         parse_E_route_store_route();
2720 }