Logo AND Algorithmique Numérique Distribuée

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