Logo AND Algorithmique Numérique Distribuée

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