Logo AND Algorithmique Numérique Distribuée

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