Logo AND Algorithmique Numérique Distribuée

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