1 /* Copyright (c) 2009, 2010. The SimGrid Team.
2 * All rights reserved. */
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. */
10 #include "gras_config.h"
13 #include <pcre.h> /* regular expresion library */
15 #include "surf_private.h"
16 #include "xbt/dynar.h"
18 #include "xbt/config.h"
19 #include "xbt/graph.h"
22 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
25 routing_global_t global_routing = NULL;
26 routing_component_t current_routing = NULL;
27 model_type_t current_routing_model = NULL;
28 static double_f_cpvoid_t get_link_latency = NULL;
30 /* Prototypes of each model */
31 static void *model_full_create(void); /* create structures for full routing model */
32 static void model_full_load(void); /* load parse functions for full routing model */
33 static void model_full_unload(void); /* unload parse functions for full routing model */
34 static void model_full_end(void); /* finalize the creation of full routing model */
35 static void model_full_set_route( /* Set the route and ASroute between src and dst */
36 routing_component_t rc, const char *src, const char *dst, name_route_extended_t route);
38 static void *model_floyd_create(void); /* create structures for floyd routing model */
39 static void model_floyd_load(void); /* load parse functions for floyd routing model */
40 static void model_floyd_unload(void); /* unload parse functions for floyd routing model */
41 static void model_floyd_end(void); /* finalize the creation of floyd routing model */
42 static void model_floyd_set_route(routing_component_t rc, const char *src,
43 const char *dst, name_route_extended_t route);
45 static void *model_dijkstra_both_create(int cached); /* create by calling dijkstra or dijkstracache */
46 static void *model_dijkstra_create(void); /* create structures for dijkstra routing model */
47 static void *model_dijkstracache_create(void); /* create structures for dijkstracache routing model */
48 static void model_dijkstra_both_load(void); /* load parse functions for dijkstra routing model */
49 static void model_dijkstra_both_unload(void); /* unload parse functions for dijkstra routing model */
50 static void model_dijkstra_both_end(void); /* finalize the creation of dijkstra routing model */
51 static void model_dijkstra_both_set_route (routing_component_t rc, const char *src,
52 const char *dst, name_route_extended_t route);
54 static void *model_rulebased_create(void); /* create structures for rulebased routing model */
55 static void model_rulebased_load(void); /* load parse functions for rulebased routing model */
56 static void model_rulebased_unload(void); /* unload parse functions for rulebased routing model */
57 static void model_rulebased_end(void); /* finalize the creation of rulebased routing model */
59 static void *model_none_create(void); /* none routing model */
60 static void model_none_load(void); /* none routing model */
61 static void model_none_unload(void); /* none routing model */
62 static void model_none_end(void); /* none routing model */
64 static void routing_parse_Scluster(void); /*cluster bypass */
66 static void routing_parse_Sconfig(void); /*config Tag */
67 static void routing_parse_Econfig(void); /*config Tag */
69 /* this lines are only for replace use like index in the model table */
74 SURF_MODEL_DIJKSTRACACHE,
82 /* must be finish with null and carefull if change de order */
83 struct s_model_type routing_models[] = { {"Full",
84 "Full routing data (fast, large memory requirements, fully expressive)",
90 "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
91 model_floyd_create, model_floyd_load, model_floyd_unload,
94 "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
95 model_dijkstra_create, model_dijkstra_both_load,
96 model_dijkstra_both_unload, model_dijkstra_both_end},
98 "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
99 model_dijkstracache_create, model_dijkstra_both_load,
100 model_dijkstra_both_unload, model_dijkstra_both_end},
101 {"none", "No routing (usable with Constant network only)",
102 model_none_create, model_none_load, model_none_unload, model_none_end},
104 {"RuleBased", "Rule-Based routing data (...)", model_rulebased_create,
105 model_rulebased_load, model_rulebased_unload, model_rulebased_end},
107 {NULL, NULL, NULL, NULL, NULL, NULL}
110 /* ************************************************************************** */
111 /* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
113 static void generic_set_processing_unit(routing_component_t rc,
115 static void generic_set_autonomous_system(routing_component_t rc,
117 static void generic_set_bypassroute(routing_component_t rc,
118 const char *src, const char *dst,
119 route_extended_t e_route);
121 static int surf_link_resource_cmp(const void *a, const void *b);
122 static int surf_pointer_resource_cmp(const void *a, const void *b);
124 /* ************************************************************************** */
125 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
127 static double generic_get_link_latency(routing_component_t rc, const char *src, const char *dst);
128 static xbt_dynar_t generic_get_onelink_routes(routing_component_t rc);
129 static route_extended_t generic_get_bypassroute(routing_component_t rc,
133 /* ************************************************************************** */
134 /* ****************** GENERIC AUX FUNCTIONS (declarations) ****************** */
136 static route_extended_t
137 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
138 void *data, int order);
140 generic_new_route(e_surf_routing_hierarchy_t hierarchy,
141 void *data, int order);
142 static void generic_free_route(route_t route);
143 static void generic_free_extended_route(route_extended_t e_route);
144 static routing_component_t
145 generic_autonomous_system_exist(routing_component_t rc, char *element);
146 static routing_component_t
147 generic_processing_units_exist(routing_component_t rc, char *element);
148 static void generic_src_dst_check(routing_component_t rc, const char *src,
151 /* ************************************************************************** */
152 /* **************************** GLOBAL FUNCTIONS **************************** */
154 /* global parse functions */
155 static const char *src = NULL; /* temporary store the source name of a route */
156 static const char *dst = NULL; /* temporary store the destination name of a route */
157 static char *gw_src = NULL; /* temporary store the gateway source name of a route */
158 static char *gw_dst = NULL; /* temporary store the gateway destination name of a route */
159 static xbt_dynar_t link_list = NULL; /* temporary store of current list link of a route */
161 * \brief Add a "host" to the network element list
163 static void parse_S_host(char *host_id)
165 network_element_info_t info = NULL;
166 if (current_routing->hierarchy == SURF_ROUTING_NULL)
167 current_routing->hierarchy = SURF_ROUTING_BASE;
168 xbt_assert1(!xbt_dict_get_or_null
169 (global_routing->where_network_elements, host_id),
170 "Reading a host, processing unit \"%s\" already exists",
172 xbt_assert1(current_routing->set_processing_unit,
173 "no defined method \"set_processing_unit\" in \"%s\"",
174 current_routing->name);
175 (*(current_routing->set_processing_unit)) (current_routing, host_id);
176 info = xbt_new0(s_network_element_info_t, 1);
177 info->rc_component = current_routing;
178 info->rc_type = SURF_NETWORK_ELEMENT_HOST;
179 xbt_dict_set(global_routing->where_network_elements, host_id,
180 (void *) info, NULL);
184 * \brief Add a host to the network element list from XML
186 static void parse_S_host_XML(void)
188 parse_S_host(A_surfxml_host_id);
192 * \brief Add a host to the network element list from lua script
194 static void parse_S_host_lua(char *host_id)
196 parse_S_host(host_id);
201 * \brief Add a "router" to the network element list
203 static void parse_S_router(void)
205 network_element_info_t info = NULL;
207 if (current_routing->hierarchy == SURF_ROUTING_NULL)
208 current_routing->hierarchy = SURF_ROUTING_BASE;
209 xbt_assert1(!xbt_dict_get_or_null
210 (global_routing->where_network_elements,
211 A_surfxml_router_id),
212 "Reading a router, processing unit \"%s\" already exists",
213 A_surfxml_router_id);
214 xbt_assert1(current_routing->set_processing_unit,
215 "no defined method \"set_processing_unit\" in \"%s\"",
216 current_routing->name);
217 (*(current_routing->set_processing_unit)) (current_routing,
218 A_surfxml_router_id);
219 info = xbt_new0(s_network_element_info_t, 1);
220 info->rc_component = current_routing;
221 info->rc_type = SURF_NETWORK_ELEMENT_ROUTER;
222 xbt_dict_set(global_routing->where_network_elements, A_surfxml_router_id,
223 (void *) info, NULL);
225 TRACE_surf_host_declaration(A_surfxml_router_id, 0);
230 * \brief Set the endponints for a route
232 static void parse_S_route_new_and_endpoints(const char *src_id, const char *dst_id)
234 if (src != NULL && dst != NULL && link_list != NULL)
235 THROW2(arg_error, 0, "Route between %s to %s can not be defined",
239 xbt_assert2(strlen(src) > 0 || strlen(dst) > 0,
240 "Some limits are null in the route between \"%s\" and \"%s\"",
242 link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
246 * \brief Set the endpoints for a route from XML
248 static void parse_S_route_new_and_endpoints_XML(void)
250 parse_S_route_new_and_endpoints(A_surfxml_route_src,
251 A_surfxml_route_dst);
255 * \brief Set the endpoints for a route from lua
257 static void parse_S_route_new_and_endpoints_lua(const char *id_src, const char *id_dst)
259 parse_S_route_new_and_endpoints(id_src, id_dst);
263 * \brief Set the endponints and gateways for a ASroute
265 static void parse_S_ASroute_new_and_endpoints(void)
267 if (src != NULL && dst != NULL && link_list != NULL)
268 THROW2(arg_error, 0, "Route between %s to %s can not be defined",
269 A_surfxml_ASroute_src, A_surfxml_ASroute_dst);
270 src = A_surfxml_ASroute_src;
271 dst = A_surfxml_ASroute_dst;
272 gw_src = A_surfxml_ASroute_gw_src;
273 gw_dst = A_surfxml_ASroute_gw_dst;
274 xbt_assert2(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
275 || strlen(gw_dst) > 0,
276 "Some limits are null in the route between \"%s\" and \"%s\"",
278 link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
282 * \brief Set the endponints for a bypassRoute
284 static void parse_S_bypassRoute_new_and_endpoints(void)
286 if (src != NULL && dst != NULL && link_list != NULL)
288 "Bypass Route between %s to %s can not be defined",
289 A_surfxml_bypassRoute_src, A_surfxml_bypassRoute_dst);
290 src = A_surfxml_bypassRoute_src;
291 dst = A_surfxml_bypassRoute_dst;
292 gw_src = A_surfxml_bypassRoute_gw_src;
293 gw_dst = A_surfxml_bypassRoute_gw_dst;
294 xbt_assert2(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0
295 || strlen(gw_dst) > 0,
296 "Some limits are null in the route between \"%s\" and \"%s\"",
298 link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
302 * \brief Set a new link on the actual list of link for a route or ASroute
304 static void parse_E_link_ctn_new_elem(char *link_id)
307 val = xbt_strdup(link_id);
308 xbt_dynar_push(link_list, &val);
312 * \brief Set a new link on the actual list of link for a route or ASroute from XML
315 static void parse_E_link_ctn_new_elem_XML(void)
317 if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_NONE)
318 parse_E_link_ctn_new_elem(A_surfxml_link_ctn_id);
319 if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_UP) {
320 char *link_id = bprintf("%s_UP", A_surfxml_link_ctn_id);
321 parse_E_link_ctn_new_elem(link_id);
324 if (A_surfxml_link_ctn_direction == A_surfxml_link_ctn_direction_DOWN) {
325 char *link_id = bprintf("%s_DOWN", A_surfxml_link_ctn_id);
326 parse_E_link_ctn_new_elem(link_id);
332 * \brief Set a new link on the actual list of link for a route or ASroute from lua
334 static void parse_E_link_c_ctn_new_elem_lua(char *link_id)
336 parse_E_link_ctn_new_elem(link_id);
340 * \brief Store the route by calling the set_route function of the current routing component
342 static void parse_E_route_store_route(void)
344 name_route_extended_t route = xbt_new0(s_name_route_extended_t, 1);
345 route->generic_route.link_list = link_list;
346 xbt_assert1(current_routing->set_route,
347 "no defined method \"set_route\" in \"%s\"",
348 current_routing->name);
349 (*(current_routing->set_route)) (current_routing, src, dst, route);
356 * \brief Store the ASroute by calling the set_ASroute function of the current routing component
358 static void parse_E_ASroute_store_route(void)
360 name_route_extended_t e_route = xbt_new0(s_name_route_extended_t, 1);
361 e_route->generic_route.link_list = link_list;
362 e_route->src_gateway = xbt_strdup(gw_src);
363 e_route->dst_gateway = xbt_strdup(gw_dst);
364 xbt_assert1(current_routing->set_ASroute,
365 "no defined method \"set_ASroute\" in \"%s\"",
366 current_routing->name);
367 (*(current_routing->set_ASroute)) (current_routing, src, dst, e_route);
376 * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
378 static void parse_E_bypassRoute_store_route(void)
380 route_extended_t e_route = xbt_new0(s_route_extended_t, 1);
381 e_route->generic_route.link_list = link_list;
382 e_route->src_gateway = xbt_strdup(gw_src);
383 e_route->dst_gateway = xbt_strdup(gw_dst);
384 xbt_assert1(current_routing->set_bypassroute,
385 "no defined method \"set_bypassroute\" in \"%s\"",
386 current_routing->name);
387 (*(current_routing->set_bypassroute)) (current_routing, src, dst,
397 * \brief Make a new routing component
399 * make the new structure and
400 * set the parsing functions to allows parsing the part of the routing tree
402 static void parse_S_AS(char *AS_id, char *AS_routing)
404 routing_component_t new_routing;
405 model_type_t model = NULL;
406 char *wanted = AS_routing;
408 /* seach the routing model */
409 for (cpt = 0; routing_models[cpt].name; cpt++)
410 if (!strcmp(wanted, routing_models[cpt].name))
411 model = &routing_models[cpt];
412 /* if its not exist, error */
414 fprintf(stderr, "Routing model %s not found. Existing models:\n",
416 for (cpt = 0; routing_models[cpt].name; cpt++)
417 if (!strcmp(wanted, routing_models[cpt].name))
418 fprintf(stderr, " %s: %s\n", routing_models[cpt].name,
419 routing_models[cpt].desc);
423 /* make a new routing component */
424 new_routing = (routing_component_t) (*(model->create)) ();
425 new_routing->routing = model;
426 new_routing->hierarchy = SURF_ROUTING_NULL;
427 new_routing->name = xbt_strdup(AS_id);
428 new_routing->routing_sons = xbt_dict_new();
430 if (current_routing == NULL && global_routing->root == NULL) {
432 /* it is the first one */
433 new_routing->routing_father = NULL;
434 global_routing->root = new_routing;
436 } else if (current_routing != NULL && global_routing->root != NULL) {
438 xbt_assert1(!xbt_dict_get_or_null
439 (current_routing->routing_sons, AS_id),
440 "The AS \"%s\" already exists", AS_id);
441 /* it is a part of the tree */
442 new_routing->routing_father = current_routing;
443 /* set the father behavior */
444 if (current_routing->hierarchy == SURF_ROUTING_NULL)
445 current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
446 /* add to the sons dictionary */
447 xbt_dict_set(current_routing->routing_sons, AS_id,
448 (void *) new_routing, NULL);
449 /* add to the father element list */
450 (*(current_routing->set_autonomous_system)) (current_routing, AS_id);
451 /* unload the prev parse rules */
452 (*(current_routing->routing->unload)) ();
455 THROW0(arg_error, 0, "All defined components must be belong to a AS");
457 /* set the new parse rules */
458 (*(new_routing->routing->load)) ();
459 /* set the new current component of the tree */
460 current_routing = new_routing;
464 * Detect the routing model type of the routing component from XML platforms
466 static void parse_S_AS_XML(void)
468 parse_S_AS(A_surfxml_AS_id, A_surfxml_AS_routing);
472 * define the routing model type of routing component from lua script
474 static void parse_S_AS_lua(char *id, char *mode)
476 parse_S_AS(id, mode);
481 * \brief Finish the creation of a new routing component
483 * When you finish to read the routing component, other structures must be created.
484 * the "end" method allow to do that for any routing model type
486 static void parse_E_AS(char *AS_id)
489 if (current_routing == NULL) {
490 THROW1(arg_error, 0, "Close AS(%s), that never open", AS_id);
492 network_element_info_t info = NULL;
493 xbt_assert1(!xbt_dict_get_or_null
494 (global_routing->where_network_elements,
495 current_routing->name), "The AS \"%s\" already exists",
496 current_routing->name);
497 info = xbt_new0(s_network_element_info_t, 1);
498 info->rc_component = current_routing->routing_father;
499 info->rc_type = SURF_NETWORK_ELEMENT_AS;
500 xbt_dict_set(global_routing->where_network_elements,
501 current_routing->name, info, NULL);
502 (*(current_routing->routing->unload)) ();
503 (*(current_routing->routing->end)) ();
504 current_routing = current_routing->routing_father;
505 if (current_routing != NULL)
506 (*(current_routing->routing->load)) ();
511 * \brief Finish the creation of a new routing component from XML
513 static void parse_E_AS_XML(void)
515 parse_E_AS(A_surfxml_AS_id);
519 * \brief Finish the creation of a new routing component from lua
521 static void parse_E_AS_lua(char *id)
526 /* Aux Business methods */
529 * \brief Get the AS father and the first elements of the chain
531 * \param src the source host name
532 * \param dst the destination host name
534 * Get the common father of the to processing units, and the first different
535 * father in the chain
537 static xbt_dynar_t elements_father(const char *src, const char *dst)
540 xbt_assert0(src && dst, "bad parameters for \"elements_father\" method");
542 xbt_dynar_t result = xbt_dynar_new(sizeof(char *), NULL);
544 routing_component_t src_as, dst_as;
545 int index_src, index_dst, index_father_src, index_father_dst;
546 xbt_dynar_t path_src = NULL;
547 xbt_dynar_t path_dst = NULL;
548 routing_component_t current = NULL;
549 routing_component_t *current_src = NULL;
550 routing_component_t *current_dst = NULL;
551 routing_component_t *father = NULL;
553 /* (1) find the as where the src and dst are located */
554 src_as = ((network_element_info_t)
555 xbt_dict_get_or_null(global_routing->where_network_elements,
557 dst_as = ((network_element_info_t)
558 xbt_dict_get_or_null(global_routing->where_network_elements,
562 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src,
565 /* (2) find the path to the root routing component */
566 path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
568 while (current != NULL) {
569 xbt_dynar_push(path_src, ¤t);
570 current = current->routing_father;
572 path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
574 while (current != NULL) {
575 xbt_dynar_push(path_dst, ¤t);
576 current = current->routing_father;
579 /* (3) find the common father */
580 index_src = path_src->used - 1;
581 index_dst = path_dst->used - 1;
582 current_src = xbt_dynar_get_ptr(path_src, index_src);
583 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
584 while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
585 current_src = xbt_dynar_get_ptr(path_src, index_src);
586 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
592 current_src = xbt_dynar_get_ptr(path_src, index_src);
593 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
595 /* (4) they are not in the same routing component, make the path */
596 index_father_src = index_src + 1;
597 index_father_dst = index_dst + 1;
599 if (*current_src == *current_dst)
600 father = current_src;
602 father = xbt_dynar_get_ptr(path_src, index_father_src);
604 /* (5) result generation */
605 xbt_dynar_push(result, father); /* first same the father of src and dst */
606 xbt_dynar_push(result, current_src); /* second the first different father of src */
607 xbt_dynar_push(result, current_dst); /* three the first different father of dst */
609 xbt_dynar_free(&path_src);
610 xbt_dynar_free(&path_dst);
615 /* Global Business methods */
618 * \brief Recursive function for get_route
620 * \param src the source host name
621 * \param dst the destination host name
623 * This fuction is call by "get_route". It allow to walk through the
624 * routing components tree.
626 static route_extended_t _get_route(const char *src, const char *dst)
630 unsigned int cpt = 0;
632 DEBUG2("Solve route \"%s\" to \"%s\"", src, dst);
634 xbt_assert0(src && dst, "bad parameters for \"_get_route\" method");
636 route_extended_t e_route, e_route_cnt, e_route_src = NULL, e_route_dst =
639 xbt_dynar_t elem_father_list = elements_father(src, dst);
641 routing_component_t common_father =
642 xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
643 routing_component_t src_father =
644 xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
645 routing_component_t dst_father =
646 xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
648 e_route = xbt_new0(s_route_extended_t, 1);
649 e_route->src_gateway = NULL;
650 e_route->dst_gateway = NULL;
651 e_route->generic_route.link_list =
652 xbt_dynar_new(global_routing->size_of_link, NULL);
654 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
656 if (strcmp(src, dst)) {
658 (*(common_father->get_route)) (common_father, src, dst);
659 xbt_assert2(e_route_cnt, "no route between \"%s\" and \"%s\"", src,
661 xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
662 xbt_dynar_push(e_route->generic_route.link_list, &link);
664 generic_free_extended_route(e_route_cnt);
667 } else { /* SURF_ROUTING_RECURSIVE */
669 route_extended_t e_route_bypass = NULL;
671 if (common_father->get_bypass_route)
673 (*(common_father->get_bypass_route)) (common_father, src, dst);
676 e_route_cnt = e_route_bypass;
679 (*(common_father->get_route)) (common_father, src_father->name,
682 xbt_assert2(e_route_cnt, "no route between \"%s\" and \"%s\"",
683 src_father->name, dst_father->name);
685 xbt_assert2((e_route_cnt->src_gateway == NULL) ==
686 (e_route_cnt->dst_gateway == NULL),
687 "bad gateway for route between \"%s\" and \"%s\"", src,
690 if (src != e_route_cnt->src_gateway) {
691 e_route_src = _get_route(src, e_route_cnt->src_gateway);
692 xbt_assert2(e_route_src, "no route between \"%s\" and \"%s\"", src,
693 e_route_cnt->src_gateway);
694 xbt_dynar_foreach(e_route_src->generic_route.link_list, cpt, link) {
695 xbt_dynar_push(e_route->generic_route.link_list, &link);
699 xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
700 xbt_dynar_push(e_route->generic_route.link_list, &link);
703 if (e_route_cnt->dst_gateway != dst) {
704 e_route_dst = _get_route(e_route_cnt->dst_gateway, dst);
705 xbt_assert2(e_route_dst, "no route between \"%s\" and \"%s\"",
706 e_route_cnt->dst_gateway, dst);
707 xbt_dynar_foreach(e_route_dst->generic_route.link_list, cpt, link) {
708 xbt_dynar_push(e_route->generic_route.link_list, &link);
712 e_route->src_gateway = xbt_strdup(e_route_cnt->src_gateway);
713 e_route->dst_gateway = xbt_strdup(e_route_cnt->dst_gateway);
715 generic_free_extended_route(e_route_src);
716 generic_free_extended_route(e_route_cnt);
717 generic_free_extended_route(e_route_dst);
720 xbt_dynar_free(&elem_father_list);
725 static double _get_latency(const char *src, const char *dst)
728 double latency, latency_src, latency_dst = 0.0;
730 DEBUG2("Solve route \"%s\" to \"%s\"", src, dst);
732 xbt_assert0(src && dst, "bad parameters for \"_get_route\" method");
734 route_extended_t e_route, e_route_cnt;
736 xbt_dynar_t elem_father_list = elements_father(src, dst);
738 routing_component_t common_father =
739 xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
740 routing_component_t src_father =
741 xbt_dynar_get_as(elem_father_list, 1, routing_component_t);
742 routing_component_t dst_father =
743 xbt_dynar_get_as(elem_father_list, 2, routing_component_t);
745 e_route = xbt_new0(s_route_extended_t, 1);
746 e_route->src_gateway = NULL;
747 e_route->dst_gateway = NULL;
748 e_route->generic_route.link_list =
749 xbt_dynar_new(global_routing->size_of_link, NULL);
751 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
753 if (strcmp(src, dst)) {
755 (*(common_father->get_latency)) (common_father, src, dst);
756 xbt_assert2(latency>=0, "no route between \"%s\" and \"%s\"", src,
759 } else { /* SURF_ROUTING_RECURSIVE */
760 route_extended_t e_route_bypass = NULL;
762 if (common_father->get_bypass_route)
764 (*(common_father->get_bypass_route)) (common_father, src, dst);
766 xbt_assert0(!e_route_bypass,"Bypass cannot work yet with get_latency");
769 (*(common_father->get_route)) (common_father, src_father->name,
772 xbt_assert2(e_route_cnt, "no route between \"%s\" and \"%s\"",
773 src_father->name, dst_father->name);
775 xbt_assert2((e_route_cnt->src_gateway == NULL) ==
776 (e_route_cnt->dst_gateway == NULL),
777 "bad gateway for route between \"%s\" and \"%s\"", src,
780 (*(common_father->get_latency)) (common_father, src_father->name,
782 xbt_assert2(latency>=0, "no route between \"%s\" and \"%s\"",
783 src_father->name, dst_father->name);
786 if (src != e_route_cnt->src_gateway) {
788 e_route_src = _get_route(src, e_route_cnt->src_gateway);
789 xbt_assert2(e_route_src, "no route between \"%s\" and \"%s\"", src,
790 e_route_cnt->src_gateway);
791 xbt_dynar_foreach(e_route_src->generic_route.link_list, cpt, link) {
792 xbt_dynar_push(e_route->generic_route.link_list, &link);
795 latency_src = _get_latency(src, e_route_cnt->src_gateway);
796 xbt_assert2(latency_src>=0, "no route between \"%s\" and \"%s\"", src,
797 e_route_cnt->src_gateway);
798 latency += latency_src;
802 xbt_dynar_foreach(e_route_cnt->generic_route.link_list, cpt, link) {
803 xbt_dynar_push(e_route->generic_route.link_list, &link);
807 if (e_route_cnt->dst_gateway != dst) {
809 e_route_dst = _get_route(e_route_cnt->dst_gateway, dst);
810 xbt_assert2(e_route_dst, "no route between \"%s\" and \"%s\"",
811 e_route_cnt->dst_gateway, dst);
812 xbt_dynar_foreach(e_route_dst->generic_route.link_list, cpt, link) {
813 xbt_dynar_push(e_route->generic_route.link_list, &link);
816 latency_dst = _get_latency(e_route_cnt->dst_gateway, dst);
817 xbt_assert2(latency_dst>=0, "no route between \"%s\" and \"%s\"",
818 e_route_cnt->dst_gateway, dst);
819 latency += latency_dst;
823 e_route->src_gateway = xbt_strdup(e_route_cnt->src_gateway);
824 e_route->dst_gateway = xbt_strdup(e_route_cnt->dst_gateway);
826 generic_free_extended_route(e_route_src);
827 generic_free_extended_route(e_route_cnt);
828 generic_free_extended_route(e_route_dst);
832 xbt_dynar_free(&elem_father_list);
838 * \brief Generic method: find a route between hosts
840 * \param src the source host name
841 * \param dst the destination host name
843 * walk through the routing components tree and find a route between hosts
844 * by calling the differents "get_route" functions in each routing component.
845 * No need to free the returned dynar. It will be freed at the next call.
847 static xbt_dynar_t get_route(const char *src, const char *dst)
850 route_extended_t e_route;
851 xbt_dynar_t elem_father_list = elements_father(src, dst);
852 routing_component_t common_father =
853 xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
855 if (strcmp(src, dst))
856 e_route = _get_route(src, dst);
858 e_route = (*(common_father->get_route)) (common_father, src, dst);
860 xbt_assert2(e_route, "no route between \"%s\" and \"%s\"", src, dst);
862 if (global_routing->last_route)
863 xbt_dynar_free(&(global_routing->last_route));
864 global_routing->last_route = e_route->generic_route.link_list;
866 if (e_route->src_gateway)
867 xbt_free(e_route->src_gateway);
868 if (e_route->dst_gateway)
869 xbt_free(e_route->dst_gateway);
872 xbt_dynar_free(&elem_father_list);
874 if (xbt_dynar_length(global_routing->last_route) == 0)
877 return global_routing->last_route;
881 * \brief Generic method: find a route between hosts
883 * \param src the source host name
884 * \param dst the destination host name
886 * walk through the routing components tree and find a route between hosts
887 * by calling the differents "get_route" functions in each routing component.
888 * Leaves the caller the responsability to clean the returned dynar.
890 static xbt_dynar_t get_route_no_cleanup(const char *src, const char *dst)
892 xbt_dynar_t d = get_route(src,dst);
893 global_routing->last_route = NULL;
898 static double get_latency(const char *src, const char *dst)
901 double latency = -1.0;
902 xbt_dynar_t elem_father_list = elements_father(src, dst);
903 routing_component_t common_father =
904 xbt_dynar_get_as(elem_father_list, 0, routing_component_t);
906 if (strcmp(src, dst))
907 latency = _get_latency(src, dst);
909 latency = (*(common_father->get_latency)) (common_father, src, dst);
911 xbt_assert2(latency>=0.0, "no route between \"%s\" and \"%s\"", src, dst);
917 * \brief Recursive function for finalize
919 * \param rc the source host name
921 * This fuction is call by "finalize". It allow to finalize the
922 * AS or routing components. It delete all the structures.
924 static void _finalize(routing_component_t rc)
927 xbt_dict_cursor_t cursor = NULL;
929 routing_component_t elem;
930 xbt_dict_foreach(rc->routing_sons, cursor, key, elem) {
933 xbt_dict_t tmp_sons = rc->routing_sons;
934 char *tmp_name = rc->name;
935 xbt_dict_free(&tmp_sons);
937 xbt_assert1(rc->finalize, "no defined method \"finalize\" in \"%s\"",
938 current_routing->name);
939 (*(rc->finalize)) (rc);
944 * \brief Generic method: delete all the routing structures
946 * walk through the routing components tree and delete the structures
947 * by calling the differents "finalize" functions in each routing component
949 static void finalize(void)
951 /* delete recursibly all the tree */
952 _finalize(global_routing->root);
953 /* delete "where" dict */
954 xbt_dict_free(&(global_routing->where_network_elements));
955 /* delete last_route */
956 xbt_dynar_free(&(global_routing->last_route));
957 /* delete global routing structure */
958 xbt_free(global_routing);
961 static xbt_dynar_t recursive_get_onelink_routes(routing_component_t rc)
963 xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
965 //adding my one link routes
968 xbt_dynar_t onelink_mine = rc->get_onelink_routes(rc);
970 xbt_dynar_foreach(onelink_mine, cpt, link) {
971 xbt_dynar_push(ret, &link);
976 xbt_dict_cursor_t cursor = NULL;
977 routing_component_t rc_child;
978 xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
979 xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
981 xbt_dynar_foreach(onelink_child, cpt, link) {
982 xbt_dynar_push(ret, &link);
989 static xbt_dynar_t get_onelink_routes(void)
991 return recursive_get_onelink_routes(global_routing->root);
994 static e_surf_network_element_type_t get_network_element_type(const char
997 network_element_info_t rc = NULL;
998 rc = xbt_dict_get(global_routing->where_network_elements, name);
1003 * \brief Generic method: create the global routing schema
1005 * Make a global routing structure and set all the parsing functions.
1007 void routing_model_create(size_t size_of_links, void *loopback, double_f_cpvoid_t get_link_latency_fun)
1010 /* config the uniq global routing */
1011 global_routing = xbt_new0(s_routing_global_t, 1);
1012 global_routing->where_network_elements = xbt_dict_new();
1013 global_routing->root = NULL;
1014 global_routing->get_route = get_route;
1015 global_routing->get_latency = get_latency;
1016 global_routing->get_route_no_cleanup = get_route_no_cleanup;
1017 global_routing->get_onelink_routes = get_onelink_routes;
1018 global_routing->get_network_element_type = get_network_element_type;
1019 global_routing->finalize = finalize;
1020 global_routing->loopback = loopback;
1021 global_routing->size_of_link = size_of_links;
1022 global_routing->last_route = NULL;
1023 get_link_latency = get_link_latency_fun;
1024 /* no current routing at moment */
1025 current_routing = NULL;
1027 /* parse generic elements */
1028 surfxml_add_callback(STag_surfxml_host_cb_list, &parse_S_host_XML);
1029 surfxml_add_callback(STag_surfxml_router_cb_list, &parse_S_router);
1031 surfxml_add_callback(STag_surfxml_route_cb_list,
1032 &parse_S_route_new_and_endpoints_XML);
1033 surfxml_add_callback(STag_surfxml_ASroute_cb_list,
1034 &parse_S_ASroute_new_and_endpoints);
1035 surfxml_add_callback(STag_surfxml_bypassRoute_cb_list,
1036 &parse_S_bypassRoute_new_and_endpoints);
1038 surfxml_add_callback(ETag_surfxml_link_ctn_cb_list,
1039 &parse_E_link_ctn_new_elem_XML);
1041 surfxml_add_callback(ETag_surfxml_route_cb_list,
1042 &parse_E_route_store_route);
1043 surfxml_add_callback(ETag_surfxml_ASroute_cb_list,
1044 &parse_E_ASroute_store_route);
1045 surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list,
1046 &parse_E_bypassRoute_store_route);
1048 surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
1049 surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
1051 surfxml_add_callback(STag_surfxml_cluster_cb_list,
1052 &routing_parse_Scluster);
1054 surfxml_add_callback(STag_surfxml_config_cb_list,
1055 &routing_parse_Sconfig);
1056 surfxml_add_callback(ETag_surfxml_config_cb_list,
1057 &routing_parse_Econfig);
1060 /* ************************************************************************** */
1061 /* *************************** FULL ROUTING ********************************* */
1063 #define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
1065 /* Routing model structure */
1068 s_routing_component_t generic_routing;
1069 route_extended_t *routing_table;
1070 } s_routing_component_full_t, *routing_component_full_t;
1072 /* Business methods */
1073 static xbt_dynar_t full_get_onelink_routes(routing_component_t rc)
1075 xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
1077 routing_component_full_t routing = (routing_component_full_t) rc;
1078 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1079 xbt_dict_cursor_t c1 = NULL, c2 = NULL;
1080 char *k1, *d1, *k2, *d2;
1081 xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
1082 xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
1083 int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k1);
1084 int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k2);
1087 "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
1089 route_extended_t route = TO_ROUTE_FULL(*src_id, *dst_id);
1091 if (xbt_dynar_length(route->generic_route.link_list) == 1) {
1093 *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
1095 onelink_t onelink = xbt_new0(s_onelink_t, 1);
1096 onelink->link_ptr = link;
1097 if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
1098 onelink->src = xbt_strdup(k1);
1099 onelink->dst = xbt_strdup(k2);
1100 } else if (routing->generic_routing.hierarchy ==
1101 SURF_ROUTING_RECURSIVE) {
1102 onelink->src = xbt_strdup(route->src_gateway);
1103 onelink->dst = xbt_strdup(route->dst_gateway);
1105 xbt_dynar_push(ret, &onelink);
1113 static route_extended_t full_get_route(routing_component_t rc,
1114 const char *src, const char *dst)
1116 xbt_assert1(rc && src
1118 "Invalid params for \"get_route\" function at AS \"%s\"",
1121 /* set utils vars */
1122 routing_component_full_t routing = (routing_component_full_t) rc;
1123 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1125 generic_src_dst_check(rc, src, dst);
1126 int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1127 int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1130 "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
1133 route_extended_t e_route = NULL;
1134 route_extended_t new_e_route = NULL;
1136 unsigned int cpt = 0;
1138 e_route = TO_ROUTE_FULL(*src_id, *dst_id);
1141 new_e_route = xbt_new0(s_route_extended_t, 1);
1142 new_e_route->src_gateway = xbt_strdup(e_route->src_gateway);
1143 new_e_route->dst_gateway = xbt_strdup(e_route->dst_gateway);
1144 new_e_route->generic_route.link_list =
1145 xbt_dynar_new(global_routing->size_of_link, NULL);
1146 xbt_dynar_foreach(e_route->generic_route.link_list, cpt, link) {
1147 xbt_dynar_push(new_e_route->generic_route.link_list, &link);
1153 static void full_finalize(routing_component_t rc)
1155 routing_component_full_t routing = (routing_component_full_t) rc;
1156 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1159 /* Delete routing table */
1160 for (i = 0; i < table_size; i++)
1161 for (j = 0; j < table_size; j++)
1162 generic_free_extended_route(TO_ROUTE_FULL(i, j));
1163 xbt_free(routing->routing_table);
1164 /* Delete bypass dict */
1165 xbt_dict_free(&rc->bypassRoutes);
1166 /* Delete index dict */
1167 xbt_dict_free(&rc->to_index);
1168 /* Delete structure */
1173 /* Creation routing model functions */
1175 static void *model_full_create(void)
1177 routing_component_full_t new_component =
1178 xbt_new0(s_routing_component_full_t, 1);
1179 new_component->generic_routing.set_processing_unit =
1180 generic_set_processing_unit;
1181 new_component->generic_routing.set_autonomous_system =
1182 generic_set_autonomous_system;
1183 new_component->generic_routing.set_route = model_full_set_route;
1184 new_component->generic_routing.set_ASroute = model_full_set_route;
1185 new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1186 new_component->generic_routing.get_route = full_get_route;
1187 new_component->generic_routing.get_latency = generic_get_link_latency;
1188 new_component->generic_routing.get_onelink_routes =
1189 full_get_onelink_routes;
1190 new_component->generic_routing.get_bypass_route =
1191 generic_get_bypassroute;
1192 new_component->generic_routing.finalize = full_finalize;
1193 new_component->generic_routing.to_index = xbt_dict_new();
1194 new_component->generic_routing.bypassRoutes = xbt_dict_new();
1195 return new_component;
1198 static void model_full_load(void)
1200 /* use "surfxml_add_callback" to add a parse function call */
1203 static void model_full_unload(void)
1205 /* use "surfxml_del_callback" to remove a parse function call */
1208 static void model_full_end(void)
1211 route_extended_t e_route;
1213 /* set utils vars */
1214 routing_component_full_t routing =
1215 ((routing_component_full_t) current_routing);
1216 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1218 /* Create table if necessary */
1219 if(!routing->routing_table)
1220 routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
1222 /* Add the loopback if needed */
1223 if (current_routing->hierarchy == SURF_ROUTING_BASE) {
1224 for (i = 0; i < table_size; i++) {
1225 e_route = TO_ROUTE_FULL(i, i);
1227 e_route = xbt_new0(s_route_extended_t, 1);
1228 e_route->src_gateway = NULL;
1229 e_route->dst_gateway = NULL;
1230 e_route->generic_route.link_list =
1231 xbt_dynar_new(global_routing->size_of_link, NULL);
1232 xbt_dynar_push(e_route->generic_route.link_list,
1233 &global_routing->loopback);
1234 TO_ROUTE_FULL(i, i) = e_route;
1240 static void model_full_set_route(routing_component_t rc, const char *src,
1241 const char *dst, name_route_extended_t route)
1243 int *src_id, *dst_id;
1244 src_id = xbt_dict_get_or_null(rc->to_index, src);
1245 dst_id = xbt_dict_get_or_null(rc->to_index, dst);
1246 routing_component_full_t routing = ((routing_component_full_t) rc);
1247 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1250 && dst_id, "Network elements %s or %s not found", src, dst);
1252 xbt_assert2(xbt_dynar_length(route->generic_route.link_list) > 0,
1253 "Invalid count of links, must be greater than zero (%s,%s)",
1256 if(!routing->routing_table)
1257 routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
1259 if(TO_ROUTE_FULL(*src_id, *dst_id))
1263 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1264 xbt_dynar_foreach(route->generic_route.link_list,i,link_name)
1266 void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
1267 xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
1268 xbt_dynar_push(link_route_to_test,&link);
1270 xbt_assert2(!xbt_dynar_compare(
1271 (void*)TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list,
1272 (void*)link_route_to_test,
1273 (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1274 "The route between \"%s\" and \"%s\" already exists", src,dst);
1275 xbt_free(link_route_to_test);
1279 if(!route->dst_gateway && !route->src_gateway)
1280 DEBUG2("Load Route from \"%s\" to \"%s\"", src, dst);
1282 DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1283 route->src_gateway, dst, route->dst_gateway);
1284 TO_ROUTE_FULL(*src_id, *dst_id) = generic_new_extended_route(rc->hierarchy,route,1);
1285 xbt_dynar_shrink(TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list, 0);
1288 if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
1289 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
1291 if(route->dst_gateway && route->src_gateway)
1293 char *gw_src = xbt_strdup(route->src_gateway);
1294 char *gw_dst = xbt_strdup(route->dst_gateway);
1295 route->src_gateway = gw_dst;
1296 route->dst_gateway = gw_src;
1298 if(TO_ROUTE_FULL(*dst_id, *src_id))
1302 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1303 for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
1305 link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
1306 void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
1307 xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
1308 xbt_dynar_push(link_route_to_test,&link);
1310 xbt_assert2(!xbt_dynar_compare(
1311 (void*)TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list,
1312 (void*)link_route_to_test,
1313 (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1314 "The route between \"%s\" and \"%s\" already exists", src,dst);
1315 xbt_free(link_route_to_test);
1319 if(!route->dst_gateway && !route->src_gateway)
1320 DEBUG2("Load Route from \"%s\" to \"%s\"", dst, src);
1322 DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1323 route->src_gateway, src, route->dst_gateway);
1324 TO_ROUTE_FULL(*dst_id, *src_id) = generic_new_extended_route(rc->hierarchy,route,0);
1325 xbt_dynar_shrink(TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list, 0);
1331 /* ************************************************************************** */
1332 /* *************************** FLOYD ROUTING ******************************** */
1334 #define TO_FLOYD_COST(i,j) (routing->cost_table)[(i)+(j)*table_size]
1335 #define TO_FLOYD_PRED(i,j) (routing->predecessor_table)[(i)+(j)*table_size]
1336 #define TO_FLOYD_LINK(i,j) (routing->link_table)[(i)+(j)*table_size]
1338 /* Routing model structure */
1341 s_routing_component_t generic_routing;
1342 /* vars for calculate the floyd algorith. */
1343 int *predecessor_table;
1345 route_extended_t *link_table; /* char* -> int* */
1346 } s_routing_component_floyd_t, *routing_component_floyd_t;
1348 static route_extended_t floyd_get_route(routing_component_t rc,
1349 const char *src, const char *dst);
1351 /* Business methods */
1352 static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
1354 xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
1356 routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1357 //size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1358 xbt_dict_cursor_t c1 = NULL, c2 = NULL;
1359 char *k1, *d1, *k2, *d2;
1360 xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
1361 xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
1362 route_extended_t route = floyd_get_route(rc, k1, k2);
1364 if (xbt_dynar_length(route->generic_route.link_list) == 1) {
1366 *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
1368 onelink_t onelink = xbt_new0(s_onelink_t, 1);
1369 onelink->link_ptr = link;
1370 if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
1371 onelink->src = xbt_strdup(k1);
1372 onelink->dst = xbt_strdup(k2);
1373 } else if (routing->generic_routing.hierarchy ==
1374 SURF_ROUTING_RECURSIVE) {
1375 onelink->src = xbt_strdup(route->src_gateway);
1376 onelink->dst = xbt_strdup(route->dst_gateway);
1378 xbt_dynar_push(ret, &onelink);
1386 static route_extended_t floyd_get_route(routing_component_t rc,
1387 const char *src, const char *dst)
1389 xbt_assert1(rc && src
1391 "Invalid params for \"get_route\" function at AS \"%s\"",
1394 /* set utils vars */
1395 routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1396 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1398 generic_src_dst_check(rc, src, dst);
1399 int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1400 int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1403 "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
1406 /* create a result route */
1407 route_extended_t new_e_route = xbt_new0(s_route_extended_t, 1);
1408 new_e_route->generic_route.link_list =
1409 xbt_dynar_new(global_routing->size_of_link, NULL);
1410 new_e_route->src_gateway = NULL;
1411 new_e_route->dst_gateway = NULL;
1416 char *gw_src = NULL, *gw_dst =
1417 NULL, *prev_gw_src, *prev_gw_dst, *first_gw = NULL;
1424 pred = TO_FLOYD_PRED(*src_id, pred);
1425 if (pred == -1) /* if no pred in route -> no route to host */
1427 xbt_assert2(TO_FLOYD_LINK(pred, prev_pred),
1428 "Invalid link for the route between \"%s\" or \"%s\"", src,
1431 prev_gw_src = gw_src;
1432 prev_gw_dst = gw_dst;
1434 route_extended_t e_route = TO_FLOYD_LINK(pred, prev_pred);
1435 gw_src = e_route->src_gateway;
1436 gw_dst = e_route->dst_gateway;
1441 if (rc->hierarchy == SURF_ROUTING_RECURSIVE && !first
1442 && strcmp(gw_dst, prev_gw_src)) {
1443 xbt_dynar_t e_route_as_to_as =
1444 (*(global_routing->get_route)) (gw_dst, prev_gw_src);
1445 xbt_assert2(e_route_as_to_as, "no route between \"%s\" and \"%s\"",
1446 gw_dst, prev_gw_src);
1447 links = e_route_as_to_as;
1449 xbt_dynar_foreach(links, cpt, link) {
1450 xbt_dynar_insert_at(new_e_route->generic_route.link_list, pos,
1456 links = e_route->generic_route.link_list;
1457 xbt_dynar_foreach(links, cpt, link) {
1458 xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
1462 } while (pred != *src_id);
1463 xbt_assert4(pred != -1, "no route from host %d to %d (\"%s\" to \"%s\")",
1464 *src_id, *dst_id, src, dst);
1466 if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
1467 new_e_route->src_gateway = xbt_strdup(gw_src);
1468 new_e_route->dst_gateway = xbt_strdup(first_gw);
1474 static void floyd_finalize(routing_component_t rc)
1476 routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1480 table_size = xbt_dict_length(routing->generic_routing.to_index);
1481 /* Delete link_table */
1482 for (i = 0; i < table_size; i++)
1483 for (j = 0; j < table_size; j++)
1484 generic_free_extended_route(TO_FLOYD_LINK(i, j));
1485 xbt_free(routing->link_table);
1486 /* Delete bypass dict */
1487 xbt_dict_free(&routing->generic_routing.bypassRoutes);
1488 /* Delete index dict */
1489 xbt_dict_free(&(routing->generic_routing.to_index));
1490 /* Delete dictionary index dict, predecessor and links table */
1491 xbt_free(routing->predecessor_table);
1492 /* Delete structure */
1497 static void *model_floyd_create(void)
1499 routing_component_floyd_t new_component =
1500 xbt_new0(s_routing_component_floyd_t, 1);
1501 new_component->generic_routing.set_processing_unit =
1502 generic_set_processing_unit;
1503 new_component->generic_routing.set_autonomous_system =
1504 generic_set_autonomous_system;
1505 new_component->generic_routing.set_route = model_floyd_set_route;
1506 new_component->generic_routing.set_ASroute = model_floyd_set_route;
1507 new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
1508 new_component->generic_routing.get_route = floyd_get_route;
1509 new_component->generic_routing.get_latency = generic_get_link_latency;
1510 new_component->generic_routing.get_onelink_routes =
1511 floyd_get_onelink_routes;
1512 new_component->generic_routing.get_bypass_route =
1513 generic_get_bypassroute;
1514 new_component->generic_routing.finalize = floyd_finalize;
1515 new_component->generic_routing.to_index = xbt_dict_new();
1516 new_component->generic_routing.bypassRoutes = xbt_dict_new();
1517 return new_component;
1520 static void model_floyd_load(void)
1522 /* use "surfxml_add_callback" to add a parse function call */
1525 static void model_floyd_unload(void)
1527 /* use "surfxml_del_callback" to remove a parse function call */
1530 static void model_floyd_end(void)
1533 routing_component_floyd_t routing =
1534 ((routing_component_floyd_t) current_routing);
1536 unsigned int i, j, a, b, c;
1538 /* set the size of table routing */
1539 size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
1541 if(!routing->link_table)
1543 /* Create Cost, Predecessor and Link tables */
1544 routing->cost_table = xbt_new0(double, table_size * table_size); /* link cost from host to host */
1545 routing->predecessor_table = xbt_new0(int, table_size * table_size); /* predecessor host numbers */
1546 routing->link_table = xbt_new0(route_extended_t, table_size * table_size); /* actual link between src and dst */
1548 /* Initialize costs and predecessors */
1549 for (i = 0; i < table_size; i++)
1550 for (j = 0; j < table_size; j++) {
1551 TO_FLOYD_COST(i, j) = DBL_MAX;
1552 TO_FLOYD_PRED(i, j) = -1;
1553 TO_FLOYD_LINK(i, j) = NULL; /* fixed, missing in the previous version */
1557 /* Add the loopback if needed */
1558 if (current_routing->hierarchy == SURF_ROUTING_BASE) {
1559 for (i = 0; i < table_size; i++) {
1560 route_extended_t e_route = TO_FLOYD_LINK(i, i);
1562 e_route = xbt_new0(s_route_extended_t, 1);
1563 e_route->src_gateway = NULL;
1564 e_route->dst_gateway = NULL;
1565 e_route->generic_route.link_list =
1566 xbt_dynar_new(global_routing->size_of_link, NULL);
1567 xbt_dynar_push(e_route->generic_route.link_list,
1568 &global_routing->loopback);
1569 TO_FLOYD_LINK(i, i) = e_route;
1570 TO_FLOYD_PRED(i, i) = i;
1571 TO_FLOYD_COST(i, i) = 1;
1575 /* Calculate path costs */
1576 for (c = 0; c < table_size; c++) {
1577 for (a = 0; a < table_size; a++) {
1578 for (b = 0; b < table_size; b++) {
1579 if (TO_FLOYD_COST(a, c) < DBL_MAX && TO_FLOYD_COST(c, b) < DBL_MAX) {
1580 if (TO_FLOYD_COST(a, b) == DBL_MAX ||
1581 (TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b) <
1582 TO_FLOYD_COST(a, b))) {
1583 TO_FLOYD_COST(a, b) =
1584 TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b);
1585 TO_FLOYD_PRED(a, b) = TO_FLOYD_PRED(c, b);
1593 static void model_floyd_set_route(routing_component_t rc, const char *src,
1594 const char *dst, name_route_extended_t route)
1596 routing_component_floyd_t routing = (routing_component_floyd_t) rc;
1598 /* set the size of table routing */
1599 size_t table_size = xbt_dict_length(rc->to_index);
1600 int *src_id, *dst_id;
1603 src_id = xbt_dict_get_or_null(rc->to_index, src);
1604 dst_id = xbt_dict_get_or_null(rc->to_index, dst);
1606 if(!routing->link_table)
1608 /* Create Cost, Predecessor and Link tables */
1609 routing->cost_table = xbt_new0(double, table_size * table_size); /* link cost from host to host */
1610 routing->predecessor_table = xbt_new0(int, table_size * table_size); /* predecessor host numbers */
1611 routing->link_table = xbt_new0(route_extended_t, table_size * table_size); /* actual link between src and dst */
1613 /* Initialize costs and predecessors */
1614 for (i = 0; i < table_size; i++)
1615 for (j = 0; j < table_size; j++) {
1616 TO_FLOYD_COST(i, j) = DBL_MAX;
1617 TO_FLOYD_PRED(i, j) = -1;
1618 TO_FLOYD_LINK(i, j) = NULL; /* fixed, missing in the previous version */
1622 if(TO_FLOYD_LINK(*src_id, *dst_id))
1624 if(!route->dst_gateway && !route->src_gateway)
1625 DEBUG2("See Route from \"%s\" to \"%s\"", src, dst);
1627 DEBUG4("See ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1628 route->src_gateway, dst, route->dst_gateway);
1631 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1632 xbt_dynar_foreach(route->generic_route.link_list,cpt,link_name)
1634 void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
1635 xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
1636 xbt_dynar_push(link_route_to_test,&link);
1638 xbt_assert2(!xbt_dynar_compare(
1639 (void*)TO_FLOYD_LINK(*src_id, *dst_id)->generic_route.link_list,
1640 (void*)link_route_to_test,
1641 (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1642 "The route between \"%s\" and \"%s\" already exists", src,dst);
1643 xbt_free(link_route_to_test);
1647 if(!route->dst_gateway && !route->src_gateway)
1648 DEBUG2("Load Route from \"%s\" to \"%s\"", src, dst);
1650 DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
1651 route->src_gateway, dst, route->dst_gateway);
1653 TO_FLOYD_LINK(*src_id, *dst_id) =
1654 generic_new_extended_route(rc->hierarchy, route, 1);
1655 TO_FLOYD_PRED(*src_id, *dst_id) = *src_id;
1656 TO_FLOYD_COST(*src_id, *dst_id) =
1657 ((TO_FLOYD_LINK(*src_id, *dst_id))->generic_route.link_list)->used; /* count of links, old model assume 1 */
1660 if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
1661 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
1663 if(TO_FLOYD_LINK(*dst_id, *src_id))
1665 if(!route->dst_gateway && !route->src_gateway)
1666 DEBUG2("See Route from \"%s\" to \"%s\"", dst, src);
1668 DEBUG4("See ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1669 route->src_gateway, src, route->dst_gateway);
1672 xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
1673 for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
1675 link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
1676 void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
1677 xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
1678 xbt_dynar_push(link_route_to_test,&link);
1680 xbt_assert2(!xbt_dynar_compare(
1681 (void*)TO_FLOYD_LINK(*dst_id, *src_id)->generic_route.link_list,
1682 (void*)link_route_to_test,
1683 (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
1684 "The route between \"%s\" and \"%s\" already exists", src,dst);
1685 xbt_free(link_route_to_test);
1689 if(route->dst_gateway && route->src_gateway)
1691 char *gw_src = xbt_strdup(route->src_gateway);
1692 char *gw_dst = xbt_strdup(route->dst_gateway);
1693 route->src_gateway = gw_dst;
1694 route->dst_gateway = gw_src;
1697 if(!route->dst_gateway && !route->src_gateway)
1698 DEBUG2("Load Route from \"%s\" to \"%s\"", dst, src);
1700 DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
1701 route->src_gateway, src, route->dst_gateway);
1703 TO_FLOYD_LINK(*dst_id, *src_id) =
1704 generic_new_extended_route(rc->hierarchy, route, 0);
1705 TO_FLOYD_PRED(*dst_id, *src_id) = *dst_id;
1706 TO_FLOYD_COST(*dst_id, *src_id) =
1707 ((TO_FLOYD_LINK(*dst_id, *src_id))->generic_route.link_list)->used; /* count of links, old model assume 1 */
1712 /* ************************************************************************** */
1713 /* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
1716 s_routing_component_t generic_routing;
1717 xbt_graph_t route_graph; /* xbt_graph */
1718 xbt_dict_t graph_node_map; /* map */
1719 xbt_dict_t route_cache; /* use in cache mode */
1721 } s_routing_component_dijkstra_t, *routing_component_dijkstra_t;
1724 typedef struct graph_node_data {
1726 int graph_id; /* used for caching internal graph id's */
1727 } s_graph_node_data_t, *graph_node_data_t;
1729 typedef struct graph_node_map_element {
1731 } s_graph_node_map_element_t, *graph_node_map_element_t;
1733 typedef struct route_cache_element {
1736 } s_route_cache_element_t, *route_cache_element_t;
1738 /* Free functions */
1740 static void route_cache_elem_free(void *e)
1742 route_cache_element_t elm = (route_cache_element_t) e;
1744 xbt_free(elm->pred_arr);
1749 static void graph_node_map_elem_free(void *e)
1751 graph_node_map_element_t elm = (graph_node_map_element_t) e;
1757 static void graph_edge_data_free(void *e)
1759 route_extended_t e_route = (route_extended_t) e;
1761 xbt_dynar_free(&(e_route->generic_route.link_list));
1762 if (e_route->src_gateway)
1763 xbt_free(e_route->src_gateway);
1764 if (e_route->dst_gateway)
1765 xbt_free(e_route->dst_gateway);
1770 /* Utility functions */
1772 static xbt_node_t route_graph_new_node(routing_component_dijkstra_t rc,
1773 int id, int graph_id)
1775 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1776 xbt_node_t node = NULL;
1777 graph_node_data_t data = NULL;
1778 graph_node_map_element_t elm = NULL;
1780 data = xbt_new0(struct graph_node_data, 1);
1782 data->graph_id = graph_id;
1783 node = xbt_graph_new_node(routing->route_graph, data);
1785 elm = xbt_new0(struct graph_node_map_element, 1);
1787 xbt_dict_set_ext(routing->graph_node_map, (char *) (&id), sizeof(int),
1788 (xbt_set_elm_t) elm, &graph_node_map_elem_free);
1793 static graph_node_map_element_t
1794 graph_node_map_search(routing_component_dijkstra_t rc, int id)
1796 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1797 graph_node_map_element_t elm = (graph_node_map_element_t)
1798 xbt_dict_get_or_null_ext(routing->graph_node_map,
1806 static void route_new_dijkstra(routing_component_dijkstra_t rc, int src_id,
1807 int dst_id, route_extended_t e_route)
1809 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1811 xbt_node_t src = NULL;
1812 xbt_node_t dst = NULL;
1813 graph_node_map_element_t src_elm = (graph_node_map_element_t)
1814 xbt_dict_get_or_null_ext(routing->graph_node_map,
1817 graph_node_map_element_t dst_elm = (graph_node_map_element_t)
1818 xbt_dict_get_or_null_ext(routing->graph_node_map,
1823 src = src_elm->node;
1826 dst = dst_elm->node;
1828 /* add nodes if they don't exist in the graph */
1829 if (src_id == dst_id && src == NULL && dst == NULL) {
1830 src = route_graph_new_node(rc, src_id, -1);
1834 src = route_graph_new_node(rc, src_id, -1);
1837 dst = route_graph_new_node(rc, dst_id, -1);
1841 /* add link as edge to graph */
1842 xbt_graph_new_edge(routing->route_graph, src, dst, e_route);
1845 static void add_loopback_dijkstra(routing_component_dijkstra_t rc)
1847 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1849 xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1851 xbt_node_t node = NULL;
1852 unsigned int cursor2;
1853 xbt_dynar_foreach(nodes, cursor2, node) {
1854 xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node);
1855 xbt_edge_t edge = NULL;
1856 unsigned int cursor;
1859 xbt_dynar_foreach(out_edges, cursor, edge) {
1860 xbt_node_t other_node = xbt_graph_edge_get_target(edge);
1861 if (other_node == node) {
1868 route_extended_t e_route = xbt_new0(s_route_extended_t, 1);
1869 e_route->src_gateway = NULL;
1870 e_route->dst_gateway = NULL;
1871 e_route->generic_route.link_list =
1872 xbt_dynar_new(global_routing->size_of_link, NULL);
1873 xbt_dynar_push(e_route->generic_route.link_list,
1874 &global_routing->loopback);
1875 xbt_graph_new_edge(routing->route_graph, node, node, e_route);
1880 /* Business methods */
1881 static xbt_dynar_t dijkstra_get_onelink_routes(routing_component_t rc)
1883 xbt_die("\"dijkstra_get_onelink_routes\" function not implemented yet");
1886 static route_extended_t dijkstra_get_route(routing_component_t rc,
1890 xbt_assert1(rc && src
1892 "Invalid params for \"get_route\" function at AS \"%s\"",
1895 /* set utils vars */
1896 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
1898 generic_src_dst_check(rc, src, dst);
1899 int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
1900 int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
1903 "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
1906 /* create a result route */
1907 route_extended_t new_e_route = xbt_new0(s_route_extended_t, 1);
1908 new_e_route->generic_route.link_list =
1909 xbt_dynar_new(global_routing->size_of_link, NULL);
1910 new_e_route->src_gateway = NULL;
1911 new_e_route->dst_gateway = NULL;
1913 int *pred_arr = NULL;
1914 int src_node_id = 0;
1915 int dst_node_id = 0;
1918 route_extended_t e_route;
1922 xbt_dynar_t links = NULL;
1923 route_cache_element_t elm = NULL;
1924 xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
1926 /* Use the graph_node id mapping set to quickly find the nodes */
1927 graph_node_map_element_t src_elm =
1928 graph_node_map_search(routing, *src_id);
1929 graph_node_map_element_t dst_elm =
1930 graph_node_map_search(routing, *dst_id);
1931 xbt_assert2(src_elm != NULL
1932 && dst_elm != NULL, "src %d or dst %d does not exist",
1934 src_node_id = ((graph_node_data_t)
1935 xbt_graph_node_get_data(src_elm->node))->graph_id;
1936 dst_node_id = ((graph_node_data_t)
1937 xbt_graph_node_get_data(dst_elm->node))->graph_id;
1939 /* if the src and dst are the same *//* fixed, missing in the previous version */
1940 if (src_node_id == dst_node_id) {
1942 xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
1943 xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
1945 xbt_graph_get_edge(routing->route_graph, node_s_v, node_e_v);
1947 xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id,
1950 e_route = (route_extended_t) xbt_graph_edge_get_data(edge);
1952 links = e_route->generic_route.link_list;
1953 xbt_dynar_foreach(links, cpt, link) {
1954 xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
1960 if (routing->cached) {
1961 /*check if there is a cached predecessor list avail */
1962 elm = (route_cache_element_t)
1963 xbt_dict_get_or_null_ext(routing->route_cache, (char *) (&src_id),
1967 if (elm) { /* cached mode and cache hit */
1968 pred_arr = elm->pred_arr;
1969 } else { /* not cached mode or cache miss */
1970 double *cost_arr = NULL;
1971 xbt_heap_t pqueue = NULL;
1974 int nr_nodes = xbt_dynar_length(nodes);
1975 cost_arr = xbt_new0(double, nr_nodes); /* link cost from src to other hosts */
1976 pred_arr = xbt_new0(int, nr_nodes); /* predecessors in path from src */
1977 pqueue = xbt_heap_new(nr_nodes, xbt_free);
1980 cost_arr[src_node_id] = 0.0;
1982 for (i = 0; i < nr_nodes; i++) {
1983 if (i != src_node_id) {
1984 cost_arr[i] = DBL_MAX;
1989 /* initialize priority queue */
1990 nodeid = xbt_new0(int, 1);
1992 xbt_heap_push(pqueue, nodeid, cost_arr[i]);
1996 /* apply dijkstra using the indexes from the graph's node array */
1997 while (xbt_heap_size(pqueue) > 0) {
1998 int *v_id = xbt_heap_pop(pqueue);
1999 xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
2000 xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node);
2001 xbt_edge_t edge = NULL;
2002 unsigned int cursor;
2004 xbt_dynar_foreach(out_edges, cursor, edge) {
2005 xbt_node_t u_node = xbt_graph_edge_get_target(edge);
2006 graph_node_data_t data = xbt_graph_node_get_data(u_node);
2007 int u_id = data->graph_id;
2008 route_extended_t tmp_e_route =
2009 (route_extended_t) xbt_graph_edge_get_data(edge);
2010 int cost_v_u = (tmp_e_route->generic_route.link_list)->used; /* count of links, old model assume 1 */
2012 if (cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
2013 pred_arr[u_id] = *v_id;
2014 cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
2015 nodeid = xbt_new0(int, 1);
2017 xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
2021 /* free item popped from pqueue */
2026 xbt_heap_free(pqueue);
2029 /* compose route path with links */
2030 char *gw_src = NULL, *gw_dst =
2031 NULL, *prev_gw_src, *prev_gw_dst, *first_gw = NULL;
2033 for (v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
2034 xbt_node_t node_pred_v =
2035 xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
2036 xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
2038 xbt_graph_get_edge(routing->route_graph, node_pred_v, node_v);
2040 xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id,
2043 prev_gw_src = gw_src;
2044 prev_gw_dst = gw_dst;
2046 e_route = (route_extended_t) xbt_graph_edge_get_data(edge);
2047 gw_src = e_route->src_gateway;
2048 gw_dst = e_route->dst_gateway;
2050 if (v == dst_node_id)
2053 if (rc->hierarchy == SURF_ROUTING_RECURSIVE && v != dst_node_id
2054 && strcmp(gw_dst, prev_gw_src)) {
2055 xbt_dynar_t e_route_as_to_as =
2056 (*(global_routing->get_route)) (gw_dst, prev_gw_src);
2057 xbt_assert2(e_route_as_to_as, "no route between \"%s\" and \"%s\"",
2058 gw_dst, prev_gw_src);
2059 links = e_route_as_to_as;
2061 xbt_dynar_foreach(links, cpt, link) {
2062 xbt_dynar_insert_at(new_e_route->generic_route.link_list, pos,
2068 links = e_route->generic_route.link_list;
2069 xbt_dynar_foreach(links, cpt, link) {
2070 xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
2075 if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
2076 new_e_route->src_gateway = xbt_strdup(gw_src);
2077 new_e_route->dst_gateway = xbt_strdup(first_gw);
2080 if (routing->cached && elm == NULL) {
2081 /* add to predecessor list of the current src-host to cache */
2082 elm = xbt_new0(struct route_cache_element, 1);
2083 elm->pred_arr = pred_arr;
2085 xbt_dict_set_ext(routing->route_cache, (char *) (&src_id), sizeof(int),
2086 (xbt_set_elm_t) elm, &route_cache_elem_free);
2089 if (!routing->cached)
2095 static void dijkstra_finalize(routing_component_t rc)
2097 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
2100 xbt_graph_free_graph(routing->route_graph, &xbt_free,
2101 &graph_edge_data_free, &xbt_free);
2102 xbt_dict_free(&routing->graph_node_map);
2103 if (routing->cached)
2104 xbt_dict_free(&routing->route_cache);
2105 /* Delete bypass dict */
2106 xbt_dict_free(&routing->generic_routing.bypassRoutes);
2107 /* Delete index dict */
2108 xbt_dict_free(&(routing->generic_routing.to_index));
2109 /* Delete structure */
2114 /* Creation routing model functions */
2116 static void *model_dijkstra_both_create(int cached)
2118 routing_component_dijkstra_t new_component =
2119 xbt_new0(s_routing_component_dijkstra_t, 1);
2120 new_component->generic_routing.set_processing_unit =
2121 generic_set_processing_unit;
2122 new_component->generic_routing.set_autonomous_system =
2123 generic_set_autonomous_system;
2124 new_component->generic_routing.set_route = model_dijkstra_both_set_route;
2125 new_component->generic_routing.set_ASroute = model_dijkstra_both_set_route; //TODO
2126 new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
2127 new_component->generic_routing.get_route = dijkstra_get_route;
2128 new_component->generic_routing.get_latency = generic_get_link_latency;
2129 new_component->generic_routing.get_onelink_routes =
2130 dijkstra_get_onelink_routes;
2131 new_component->generic_routing.get_bypass_route =
2132 generic_get_bypassroute;
2133 new_component->generic_routing.finalize = dijkstra_finalize;
2134 new_component->cached = cached;
2135 new_component->generic_routing.to_index = xbt_dict_new();
2136 new_component->generic_routing.bypassRoutes = xbt_dict_new();
2137 return new_component;
2140 static void *model_dijkstra_create(void)
2142 return model_dijkstra_both_create(0);
2145 static void *model_dijkstracache_create(void)
2147 return model_dijkstra_both_create(1);
2150 static void model_dijkstra_both_load(void)
2152 /* use "surfxml_add_callback" to add a parse function call */
2155 static void model_dijkstra_both_unload(void)
2157 /* use "surfxml_del_callback" to remove a parse function call */
2160 static void model_dijkstra_both_end(void)
2162 routing_component_dijkstra_t routing =
2163 (routing_component_dijkstra_t) current_routing;
2165 xbt_node_t node = NULL;
2166 unsigned int cursor2;
2167 xbt_dynar_t nodes = NULL;
2169 /* Create the topology graph */
2170 routing->route_graph = xbt_graph_new_graph(1, NULL);
2171 routing->graph_node_map = xbt_dict_new();
2173 if (routing->cached && !routing->route_cache)
2174 routing->route_cache = xbt_dict_new();
2176 /* Add the loopback if needed */
2177 if (current_routing->hierarchy == SURF_ROUTING_BASE)
2178 add_loopback_dijkstra(routing);
2180 /* initialize graph indexes in nodes after graph has been built */
2181 nodes = xbt_graph_get_nodes(routing->route_graph);
2183 xbt_dynar_foreach(nodes, cursor2, node) {
2184 graph_node_data_t data = xbt_graph_node_get_data(node);
2185 data->graph_id = cursor2;
2189 static void model_dijkstra_both_set_route (routing_component_t rc, const char *src,
2190 const char *dst, name_route_extended_t route)
2192 routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
2193 int *src_id, *dst_id;
2194 src_id = xbt_dict_get_or_null(rc->to_index, src);
2195 dst_id = xbt_dict_get_or_null(rc->to_index, dst);
2197 if (routing->cached && !routing->route_cache)
2198 routing->route_cache = xbt_dict_new();
2200 if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
2201 || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
2202 xbt_die("Route symmetrical not supported on model dijkstra");
2204 if(!route->dst_gateway && !route->src_gateway)
2205 DEBUG2("Load Route from \"%s\" to \"%s\"", src, dst);
2207 DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
2208 route->src_gateway, dst, route->dst_gateway);
2210 route_extended_t e_route =
2211 generic_new_extended_route(current_routing->hierarchy, route, 1);
2212 route_new_dijkstra(routing, *src_id, *dst_id, e_route);
2215 #ifdef HAVE_PCRE_LIB
2216 /* ************************************************** */
2217 /* ************** RULE-BASED ROUTING **************** */
2219 /* Routing model structure */
2222 s_routing_component_t generic_routing;
2223 xbt_dict_t dict_processing_units;
2224 xbt_dict_t dict_autonomous_systems;
2225 xbt_dynar_t list_route;
2226 xbt_dynar_t list_ASroute;
2227 } s_routing_component_rulebased_t, *routing_component_rulebased_t;
2229 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
2230 typedef struct s_rule_route_extended s_rule_route_extended_t,
2231 *rule_route_extended_t;
2233 struct s_rule_route {
2234 xbt_dynar_t re_str_link; // dynar of char*
2239 struct s_rule_route_extended {
2240 s_rule_route_t generic_rule_route;
2241 char *re_src_gateway;
2242 char *re_dst_gateway;
2245 static void rule_route_free(void *e)
2247 rule_route_t *elem = (rule_route_t *) (e);
2249 xbt_dynar_free(&(*elem)->re_str_link);
2250 pcre_free((*elem)->re_src);
2251 pcre_free((*elem)->re_dst);
2257 static void rule_route_extended_free(void *e)
2259 rule_route_extended_t *elem = (rule_route_extended_t *) e;
2261 xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
2262 pcre_free((*elem)->generic_rule_route.re_src);
2263 pcre_free((*elem)->generic_rule_route.re_dst);
2264 xbt_free((*elem)->re_src_gateway);
2265 xbt_free((*elem)->re_dst_gateway);
2270 /* Parse routing model functions */
2272 static void model_rulebased_set_processing_unit(routing_component_t rc,
2275 routing_component_rulebased_t routing =
2276 (routing_component_rulebased_t) rc;
2277 xbt_dict_set(routing->dict_processing_units, name, (void *) (-1), NULL);
2280 static void model_rulebased_set_autonomous_system(routing_component_t rc,
2283 routing_component_rulebased_t routing =
2284 (routing_component_rulebased_t) rc;
2285 xbt_dict_set(routing->dict_autonomous_systems, name, (void *) (-1),
2289 static void model_rulebased_set_route(routing_component_t rc,
2290 const char *src, const char *dst,
2291 name_route_extended_t route)
2293 routing_component_rulebased_t routing =
2294 (routing_component_rulebased_t) rc;
2295 rule_route_t ruleroute = xbt_new0(s_rule_route_t, 1);
2298 ruleroute->re_src = pcre_compile(src, 0, &error, &erroffset, NULL);
2299 xbt_assert3(ruleroute->re_src,
2300 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2301 erroffset, src, error);
2302 ruleroute->re_dst = pcre_compile(dst, 0, &error, &erroffset, NULL);
2303 xbt_assert3(ruleroute->re_src,
2304 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2305 erroffset, dst, error);
2306 ruleroute->re_str_link = route->generic_route.link_list;
2307 xbt_dynar_push(routing->list_route, &ruleroute);
2311 static void model_rulebased_set_ASroute(routing_component_t rc,
2312 const char *src, const char *dst,
2313 name_route_extended_t route)
2315 routing_component_rulebased_t routing =
2316 (routing_component_rulebased_t) rc;
2317 rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t, 1);
2320 ruleroute_e->generic_rule_route.re_src =
2321 pcre_compile(src, 0, &error, &erroffset, NULL);
2322 xbt_assert3(ruleroute_e->generic_rule_route.re_src,
2323 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2324 erroffset, src, error);
2325 ruleroute_e->generic_rule_route.re_dst =
2326 pcre_compile(dst, 0, &error, &erroffset, NULL);
2327 xbt_assert3(ruleroute_e->generic_rule_route.re_src,
2328 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
2329 erroffset, dst, error);
2330 ruleroute_e->generic_rule_route.re_str_link =
2331 route->generic_route.link_list;
2332 ruleroute_e->re_src_gateway = route->src_gateway;
2333 ruleroute_e->re_dst_gateway = route->dst_gateway;
2334 xbt_dynar_push(routing->list_ASroute, &ruleroute_e);
2335 xbt_free(route->src_gateway);
2336 xbt_free(route->dst_gateway);
2340 static void model_rulebased_set_bypassroute(routing_component_t rc,
2343 route_extended_t e_route)
2345 xbt_die("bypass routing not supported for Route-Based model");
2348 #define BUFFER_SIZE 4096 /* result buffer size */
2349 #define OVECCOUNT 30 /* should be a multiple of 3 */
2351 static char *remplace(char *value, const char **src_list, int src_size,
2352 const char **dst_list, int dst_size)
2355 char result_result[BUFFER_SIZE];
2356 int i_result_buffer;
2357 int value_length = (int) strlen(value);
2361 i_result_buffer = 0;
2363 if (value[i] == '$') {
2367 int number_length = 0;
2368 while ('0' <= value[i + number_length]
2369 && value[i + number_length] <= '9') {
2372 xbt_assert2(number_length != 0,
2373 "bad string parameter, no number indication, at offset: %d (\"%s\")",
2377 number = atoi(value + i);
2378 i = i + number_length;
2379 xbt_assert2(i + 2 < value_length,
2380 "bad string parameter, too few chars, at offset: %d (\"%s\")",
2383 // solve the indication
2384 const char **param_list;
2386 if (value[i] == 's' && value[i + 1] == 'r' && value[i + 2] == 'c') {
2387 param_list = src_list;
2388 param_size = src_size;
2389 } else if (value[i] == 'd' && value[i + 1] == 's'
2390 && value[i + 2] == 't') {
2391 param_list = dst_list;
2392 param_size = dst_size;
2395 "bad string parameter, support only \"src\" and \"dst\", at offset: %d (\"%s\")",
2400 xbt_assert4(param_size >= number,
2401 "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",
2402 i, value, param_size, number);
2404 const char *param = param_list[number];
2405 int size = strlen(param);
2407 for (cp = 0; cp < size; cp++) {
2408 result_result[i_result_buffer] = param[cp];
2410 if (i_result_buffer >= BUFFER_SIZE)
2414 result_result[i_result_buffer] = value[i];
2419 } while (i < value_length && i_result_buffer < BUFFER_SIZE);
2421 xbt_assert2(i_result_buffer < BUFFER_SIZE,
2422 "solving string \"%s\", small buffer size (%d)", value,
2424 result_result[i_result_buffer] = 0;
2425 return xbt_strdup(result_result);
2428 static route_extended_t rulebased_get_route(routing_component_t rc,
2431 static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
2433 xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
2434 routing_component_rulebased_t routing = (routing_component_rulebased_t)rc;
2436 xbt_dict_cursor_t c1 = NULL;
2440 char *router = NULL;
2441 xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
2442 if (strstr (k1, "router")){
2447 xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
2450 xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
2451 route_extended_t route = rulebased_get_route (rc, router, k1);
2453 int number_of_links = xbt_dynar_length(route->generic_route.link_list);
2454 if (number_of_links != 3) {
2455 xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
2459 xbt_dynar_get_cpy (route->generic_route.link_list, 2, &link_ptr);
2460 onelink_t onelink = xbt_new0 (s_onelink_t, 1);
2461 onelink->src = xbt_strdup (k1);
2462 onelink->dst = xbt_strdup (router);
2463 onelink->link_ptr = link_ptr;
2464 xbt_dynar_push (ret, &onelink);
2469 /* Business methods */
2470 static route_extended_t rulebased_get_route(routing_component_t rc,
2474 xbt_assert1(rc && src
2476 "Invalid params for \"get_route\" function at AS \"%s\"",
2479 /* set utils vars */
2480 routing_component_rulebased_t routing =
2481 (routing_component_rulebased_t) rc;
2483 int are_processing_units;
2484 xbt_dynar_t rule_list;
2485 if (xbt_dict_get_or_null(routing->dict_processing_units, src)
2486 && xbt_dict_get_or_null(routing->dict_processing_units, dst)) {
2487 are_processing_units = 1;
2488 rule_list = routing->list_route;
2489 } else if (xbt_dict_get_or_null(routing->dict_autonomous_systems, src)
2490 && xbt_dict_get_or_null(routing->dict_autonomous_systems,
2492 are_processing_units = 0;
2493 rule_list = routing->list_ASroute;
2496 "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
2501 int src_length = (int) strlen(src);
2502 int dst_length = (int) strlen(dst);
2504 xbt_dynar_t links_list =
2505 xbt_dynar_new(global_routing->size_of_link, NULL);
2507 rule_route_t ruleroute;
2509 int ovector_src[OVECCOUNT];
2510 int ovector_dst[OVECCOUNT];
2511 const char **list_src = NULL;
2512 const char **list_dst = NULL;
2513 xbt_dynar_foreach(rule_list, cpt, ruleroute) {
2515 pcre_exec(ruleroute->re_src, NULL, src, src_length, 0, 0,
2516 ovector_src, OVECCOUNT);
2519 pcre_exec(ruleroute->re_dst, NULL, dst, dst_length, 0, 0,
2520 ovector_dst, OVECCOUNT);
2522 xbt_assert1(!pcre_get_substring_list
2523 (src, ovector_src, rc_src, &list_src),
2524 "error solving substring list for src \"%s\"", src);
2525 xbt_assert1(!pcre_get_substring_list
2526 (dst, ovector_dst, rc_dst, &list_dst),
2527 "error solving substring list for src \"%s\"", dst);
2529 xbt_dynar_foreach(ruleroute->re_str_link, cpt, link_name) {
2530 char *new_link_name =
2531 remplace(link_name, list_src, rc_src, list_dst, rc_dst);
2533 xbt_dict_get_or_null(surf_network_model->resource_set,
2536 xbt_dynar_push(links_list, &link);
2538 THROW1(mismatch_error, 0, "Link %s not found", new_link_name);
2539 xbt_free(new_link_name);
2543 if (rc_src >= 0 && rc_dst >= 0)
2547 route_extended_t new_e_route = NULL;
2548 if (rc_src >= 0 && rc_dst >= 0) {
2549 new_e_route = xbt_new0(s_route_extended_t, 1);
2550 new_e_route->generic_route.link_list = links_list;
2551 } else if (!strcmp(src, dst) && are_processing_units) {
2552 new_e_route = xbt_new0(s_route_extended_t, 1);
2553 xbt_dynar_push(links_list, &(global_routing->loopback));
2554 new_e_route->generic_route.link_list = links_list;
2556 xbt_dynar_free(&link_list);
2559 if (!are_processing_units && new_e_route) {
2560 rule_route_extended_t ruleroute_extended =
2561 (rule_route_extended_t) ruleroute;
2562 new_e_route->src_gateway =
2563 remplace(ruleroute_extended->re_src_gateway, list_src, rc_src,
2565 new_e_route->dst_gateway =
2566 remplace(ruleroute_extended->re_dst_gateway, list_src, rc_src,
2571 pcre_free_substring_list(list_src);
2573 pcre_free_substring_list(list_dst);
2578 static route_extended_t rulebased_get_bypass_route(routing_component_t rc,
2585 static void rulebased_finalize(routing_component_t rc)
2587 routing_component_rulebased_t routing =
2588 (routing_component_rulebased_t) rc;
2590 xbt_dict_free(&routing->dict_processing_units);
2591 xbt_dict_free(&routing->dict_autonomous_systems);
2592 xbt_dynar_free(&routing->list_route);
2593 xbt_dynar_free(&routing->list_ASroute);
2594 /* Delete structure */
2599 /* Creation routing model functions */
2600 static void *model_rulebased_create(void)
2602 routing_component_rulebased_t new_component =
2603 xbt_new0(s_routing_component_rulebased_t, 1);
2604 new_component->generic_routing.set_processing_unit =
2605 model_rulebased_set_processing_unit;
2606 new_component->generic_routing.set_autonomous_system =
2607 model_rulebased_set_autonomous_system;
2608 new_component->generic_routing.set_route = model_rulebased_set_route;
2609 new_component->generic_routing.set_ASroute = model_rulebased_set_ASroute;
2610 new_component->generic_routing.set_bypassroute = model_rulebased_set_bypassroute;
2611 new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes;
2612 new_component->generic_routing.get_route = rulebased_get_route;
2613 new_component->generic_routing.get_bypass_route = generic_get_bypassroute; //rulebased_get_bypass_route;
2614 new_component->generic_routing.finalize = rulebased_finalize;
2615 /* initialization of internal structures */
2616 new_component->dict_processing_units = xbt_dict_new();
2617 new_component->dict_autonomous_systems = xbt_dict_new();
2618 new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free);
2619 new_component->list_ASroute =
2620 xbt_dynar_new(sizeof(rule_route_extended_t),
2621 &rule_route_extended_free);
2622 return new_component;
2625 static void model_rulebased_load(void)
2627 /* use "surfxml_add_callback" to add a parse function call */
2630 static void model_rulebased_unload(void)
2632 /* use "surfxml_del_callback" to remove a parse function call */
2635 static void model_rulebased_end(void)
2639 #endif /* HAVE_PCRE_LIB */
2641 /* ************************************************************************** */
2642 /* ******************************* NO ROUTING ******************************* */
2644 /* Routing model structure */
2646 s_routing_component_t generic_routing;
2647 } s_routing_component_none_t, *routing_component_none_t;
2649 /* Business methods */
2650 static xbt_dynar_t none_get_onelink_routes(routing_component_t rc)
2655 static route_extended_t none_get_route(routing_component_t rc,
2656 const char *src, const char *dst)
2661 static route_extended_t none_get_bypass_route(routing_component_t rc,
2668 static void none_finalize(routing_component_t rc)
2673 static void none_set_processing_unit(routing_component_t rc,
2678 static void none_set_autonomous_system(routing_component_t rc,
2683 /* Creation routing model functions */
2684 static void *model_none_create(void)
2686 routing_component_none_t new_component =
2687 xbt_new0(s_routing_component_none_t, 1);
2688 new_component->generic_routing.set_processing_unit =
2689 none_set_processing_unit;
2690 new_component->generic_routing.set_autonomous_system =
2691 none_set_autonomous_system;
2692 new_component->generic_routing.set_route = NULL;
2693 new_component->generic_routing.set_ASroute = NULL;
2694 new_component->generic_routing.set_bypassroute = NULL;
2695 new_component->generic_routing.get_route = none_get_route;
2696 new_component->generic_routing.get_onelink_routes =
2697 none_get_onelink_routes;
2698 new_component->generic_routing.get_bypass_route = none_get_bypass_route;
2699 new_component->generic_routing.finalize = none_finalize;
2700 return new_component;
2703 static void model_none_load(void)
2707 static void model_none_unload(void)
2711 static void model_none_end(void)
2715 /* ************************************************** */
2716 /* ********** PATERN FOR NEW ROUTING **************** */
2718 /* The minimal configuration of a new routing model need the next functions,
2719 * also you need to set at the start of the file, the new model in the model
2720 * list. Remember keep the null ending of the list.
2722 /*** Routing model structure ***/
2724 // s_routing_component_t generic_routing;
2725 // /* things that your routing model need */
2726 // } s_routing_component_NEW_t,*routing_component_NEW_t;
2728 /*** Parse routing model functions ***/
2729 // static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
2730 // static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
2731 // static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
2732 // static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
2733 // static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
2735 /*** Business methods ***/
2736 // static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2737 // static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
2738 // static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
2740 /*** Creation routing model functions ***/
2741 // static void* model_NEW_create(void) {
2742 // routing_component_NEW_t new_component = xbt_new0(s_routing_component_NEW_t,1);
2743 // new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
2744 // new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
2745 // new_component->generic_routing.set_route = model_NEW_set_route;
2746 // new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
2747 // new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
2748 // new_component->generic_routing.get_route = NEW_get_route;
2749 // new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
2750 // new_component->generic_routing.finalize = NEW_finalize;
2751 // /* initialization of internal structures */
2752 // return new_component;
2753 // } /* mandatory */
2754 // static void model_NEW_load(void) {} /* mandatory */
2755 // static void model_NEW_unload(void) {} /* mandatory */
2756 // static void model_NEW_end(void) {} /* mandatory */
2758 /* ************************************************************************** */
2759 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
2761 static void generic_set_processing_unit(routing_component_t rc,
2764 DEBUG1("Load process unit \"%s\"", name);
2765 int *id = xbt_new0(int, 1);
2766 xbt_dict_t _to_index;
2767 _to_index = current_routing->to_index;
2768 *id = xbt_dict_length(_to_index);
2769 xbt_dict_set(_to_index, name, id, xbt_free);
2772 static void generic_set_autonomous_system(routing_component_t rc,
2775 DEBUG1("Load Autonomous system \"%s\"", name);
2776 int *id = xbt_new0(int, 1);
2777 xbt_dict_t _to_index;
2778 _to_index = current_routing->to_index;
2779 *id = xbt_dict_length(_to_index);
2780 xbt_dict_set(_to_index, name, id, xbt_free);
2783 static int surf_pointer_resource_cmp(const void *a, const void *b)
2788 static int surf_link_resource_cmp(const void *a, const void *b)
2790 return !!memcmp(a,b,global_routing->size_of_link);
2793 static void generic_set_bypassroute(routing_component_t rc,
2794 const char *src, const char *dst,
2795 route_extended_t e_route)
2797 DEBUG2("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
2798 xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
2801 route_name = bprintf("%s#%s", src, dst);
2802 xbt_assert2(xbt_dynar_length(e_route->generic_route.link_list) > 0,
2803 "Invalid count of links, must be greater than zero (%s,%s)",
2805 xbt_assert4(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
2806 "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
2807 src, e_route->src_gateway, dst, e_route->dst_gateway);
2809 route_extended_t new_e_route =
2810 generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 0);
2811 xbt_dynar_free(&(e_route->generic_route.link_list));
2814 xbt_dict_set(dict_bypassRoutes, route_name, new_e_route,
2815 (void (*)(void *)) generic_free_extended_route);
2816 xbt_free(route_name);
2819 /* ************************************************************************** */
2820 /* *********************** GENERIC BUSINESS METHODS ************************* */
2822 static double generic_get_link_latency(routing_component_t rc,
2823 const char *src, const char *dst)
2825 route_extended_t route = rc->get_route(rc,src,dst);
2828 double latency = 0.0;
2830 xbt_dynar_foreach(route->generic_route.link_list,i,link) {
2831 latency += get_link_latency(link);
2836 static xbt_dynar_t generic_get_onelink_routes(routing_component_t rc)
2838 xbt_die("\"generic_get_onelink_routes\" not implemented yet");
2841 static route_extended_t generic_get_bypassroute(routing_component_t rc,
2845 xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
2846 routing_component_t src_as, dst_as;
2847 int index_src, index_dst;
2848 xbt_dynar_t path_src = NULL;
2849 xbt_dynar_t path_dst = NULL;
2850 routing_component_t current = NULL;
2851 routing_component_t *current_src = NULL;
2852 routing_component_t *current_dst = NULL;
2854 /* (1) find the as where the src and dst are located */
2855 src_as = ((network_element_info_t)
2856 xbt_dict_get_or_null(global_routing->where_network_elements,
2857 src))->rc_component;
2858 dst_as = ((network_element_info_t)
2859 xbt_dict_get_or_null(global_routing->where_network_elements,
2860 dst))->rc_component;
2863 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src,
2866 /* (2) find the path to the root routing component */
2867 path_src = xbt_dynar_new(sizeof(routing_component_t), NULL);
2869 while (current != NULL) {
2870 xbt_dynar_push(path_src, ¤t);
2871 current = current->routing_father;
2873 path_dst = xbt_dynar_new(sizeof(routing_component_t), NULL);
2875 while (current != NULL) {
2876 xbt_dynar_push(path_dst, ¤t);
2877 current = current->routing_father;
2880 /* (3) find the common father */
2881 index_src = path_src->used - 1;
2882 index_dst = path_dst->used - 1;
2883 current_src = xbt_dynar_get_ptr(path_src, index_src);
2884 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
2885 while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
2886 routing_component_t *tmp_src, *tmp_dst;
2887 tmp_src = xbt_dynar_pop_ptr(path_src);
2888 tmp_dst = xbt_dynar_pop_ptr(path_dst);
2891 current_src = xbt_dynar_get_ptr(path_src, index_src);
2892 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
2895 int max_index_src = path_src->used - 1;
2896 int max_index_dst = path_dst->used - 1;
2898 int max_index = max(max_index_src, max_index_dst);
2901 route_extended_t e_route_bypass = NULL;
2903 for (max = 0; max <= max_index; max++) {
2904 for (i = 0; i < max; i++) {
2905 if (i <= max_index_src && max <= max_index_dst) {
2906 char *route_name = bprintf("%s#%s",
2907 (*(routing_component_t *)
2909 (path_src, i)))->name,
2910 (*(routing_component_t *)
2912 (path_dst, max)))->name);
2914 xbt_dict_get_or_null(dict_bypassRoutes, route_name);
2915 xbt_free(route_name);
2919 if (max <= max_index_src && i <= max_index_dst) {
2920 char *route_name = bprintf("%s#%s",
2921 (*(routing_component_t *)
2923 (path_src, max)))->name,
2924 (*(routing_component_t *)
2926 (path_dst, i)))->name);
2928 xbt_dict_get_or_null(dict_bypassRoutes, route_name);
2929 xbt_free(route_name);
2938 if (max <= max_index_src && max <= max_index_dst) {
2939 char *route_name = bprintf("%s#%s",
2940 (*(routing_component_t *)
2942 (path_src, max)))->name,
2943 (*(routing_component_t *)
2945 (path_dst, max)))->name);
2946 e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
2947 xbt_free(route_name);
2953 xbt_dynar_free(&path_src);
2954 xbt_dynar_free(&path_dst);
2956 route_extended_t new_e_route = NULL;
2958 if (e_route_bypass) {
2960 unsigned int cpt = 0;
2961 new_e_route = xbt_new0(s_route_extended_t, 1);
2962 new_e_route->src_gateway = xbt_strdup(e_route_bypass->src_gateway);
2963 new_e_route->dst_gateway = xbt_strdup(e_route_bypass->dst_gateway);
2964 new_e_route->generic_route.link_list =
2965 xbt_dynar_new(global_routing->size_of_link, NULL);
2966 xbt_dynar_foreach(e_route_bypass->generic_route.link_list, cpt, link) {
2967 xbt_dynar_push(new_e_route->generic_route.link_list, &link);
2974 /* ************************************************************************** */
2975 /* ************************* GENERIC AUX FUNCTIONS ************************** */
2978 generic_new_route(e_surf_routing_hierarchy_t hierarchy,
2979 void *data, int order)
2985 xbt_dynar_t links = NULL, links_id = NULL;
2987 new_route = xbt_new0(s_route_t, 1);
2988 new_route->link_list =
2989 xbt_dynar_new(global_routing->size_of_link, NULL);
2991 xbt_assert0(hierarchy == SURF_ROUTING_BASE,
2992 "the hierarchy type is not SURF_ROUTING_BASE");
2994 links = ((route_t) data)->link_list;
2997 links_id = new_route->link_list;
2999 xbt_dynar_foreach(links, cpt, link_name) {
3002 xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
3005 xbt_dynar_push(links_id, &link);
3007 xbt_dynar_unshift(links_id, &link);
3009 THROW1(mismatch_error, 0, "Link %s not found", link_name);
3015 static route_extended_t
3016 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
3017 void *data, int order)
3021 route_extended_t e_route, new_e_route;
3024 xbt_dynar_t links = NULL, links_id = NULL;
3026 new_e_route = xbt_new0(s_route_extended_t, 1);
3027 new_e_route->generic_route.link_list =
3028 xbt_dynar_new(global_routing->size_of_link, NULL);
3029 new_e_route->src_gateway = NULL;
3030 new_e_route->dst_gateway = NULL;
3032 xbt_assert0(hierarchy == SURF_ROUTING_BASE
3033 || hierarchy == SURF_ROUTING_RECURSIVE,
3034 "the hierarchy type is not defined");
3036 if (hierarchy == SURF_ROUTING_BASE) {
3038 route = (route_t) data;
3039 links = route->link_list;
3041 } else if (hierarchy == SURF_ROUTING_RECURSIVE) {
3043 e_route = (route_extended_t) data;
3044 xbt_assert0(e_route->src_gateway
3045 && e_route->dst_gateway, "bad gateway, is null");
3046 links = e_route->generic_route.link_list;
3048 /* remeber not erase the gateway names */
3049 new_e_route->src_gateway = e_route->src_gateway;
3050 new_e_route->dst_gateway = e_route->dst_gateway;
3053 links_id = new_e_route->generic_route.link_list;
3055 xbt_dynar_foreach(links, cpt, link_name) {
3058 xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
3061 xbt_dynar_push(links_id, &link);
3063 xbt_dynar_unshift(links_id, &link);
3065 THROW1(mismatch_error, 0, "Link %s not found", link_name);
3071 static void generic_free_route(route_t route)
3074 xbt_dynar_free(&(route->link_list));
3079 static void generic_free_extended_route(route_extended_t e_route)
3082 xbt_dynar_free(&(e_route->generic_route.link_list));
3083 if (e_route->src_gateway)
3084 xbt_free(e_route->src_gateway);
3085 if (e_route->dst_gateway)
3086 xbt_free(e_route->dst_gateway);
3091 static routing_component_t generic_as_exist(routing_component_t find_from,
3092 routing_component_t to_find)
3094 //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
3095 xbt_dict_cursor_t cursor = NULL;
3098 routing_component_t elem;
3099 xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
3100 if (to_find == elem || generic_as_exist(elem, to_find)) {
3110 static routing_component_t
3111 generic_autonomous_system_exist(routing_component_t rc, char *element)
3113 //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
3114 routing_component_t element_as, result, elem;
3115 xbt_dict_cursor_t cursor = NULL;
3117 element_as = ((network_element_info_t)
3118 xbt_dict_get_or_null
3119 (global_routing->where_network_elements,
3120 element))->rc_component;
3121 result = ((routing_component_t) - 1);
3122 if (element_as != rc)
3123 result = generic_as_exist(rc, element_as);
3127 xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
3128 found = !strcmp(elem->name, element);
3138 static routing_component_t
3139 generic_processing_units_exist(routing_component_t rc, char *element)
3141 routing_component_t element_as;
3142 element_as = ((network_element_info_t)
3143 xbt_dict_get_or_null
3144 (global_routing->where_network_elements,
3145 element))->rc_component;
3146 if (element_as == rc)
3148 return generic_as_exist(rc, element_as);
3151 static void generic_src_dst_check(routing_component_t rc, const char *src,
3155 routing_component_t src_as = ((network_element_info_t)
3156 xbt_dict_get_or_null
3157 (global_routing->where_network_elements,
3158 src))->rc_component;
3159 routing_component_t dst_as = ((network_element_info_t)
3160 xbt_dict_get_or_null
3161 (global_routing->where_network_elements,
3162 dst))->rc_component;
3164 xbt_assert3(src_as != NULL && dst_as != NULL,
3165 "Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
3166 src, dst, rc->name);
3167 xbt_assert4(src_as == dst_as,
3168 "The src(%s in %s) and dst(%s in %s) are in differents AS",
3169 src, src_as->name, dst, dst_as->name);
3170 xbt_assert2(rc == dst_as,
3171 "The routing component of src and dst is not the same as the network elements belong (%s==%s)",
3172 rc->name, dst_as->name);
3175 static void routing_parse_Sconfig(void)
3178 DEBUG0("WARNING tag config not yet implemented.");
3179 DEBUG1("Configuration name = %s",A_surfxml_config_id);
3182 static void routing_parse_Econfig(void)
3185 xbt_dict_cursor_t cursor = NULL;
3188 xbt_dict_foreach(current_property_set, cursor, key, elem) {
3189 DEBUG2("property : %s = %s",key,elem);
3193 static void routing_parse_Scluster(void)
3195 static int AX_ptr = 0;
3197 char *cluster_id = A_surfxml_cluster_id;
3198 char *cluster_prefix = A_surfxml_cluster_prefix;
3199 char *cluster_suffix = A_surfxml_cluster_suffix;
3200 char *cluster_radical = A_surfxml_cluster_radical;
3201 char *cluster_power = A_surfxml_cluster_power;
3202 char *cluster_bw = A_surfxml_cluster_bw;
3203 char *cluster_lat = A_surfxml_cluster_lat;
3204 char *cluster_bb_bw = A_surfxml_cluster_bb_bw;
3205 char *cluster_bb_lat = A_surfxml_cluster_bb_lat;
3206 char *host_id, *groups, *link_id = NULL;
3207 char *router_id, *link_router, *link_backbone;
3208 #ifdef HAVE_PCRE_LIB
3209 char *route_src_dst;
3213 xbt_dynar_t radical_elements;
3214 xbt_dynar_t radical_ends;
3215 int cluster_sharing_policy = AX_surfxml_cluster_sharing_policy;
3216 int cluster_bb_sharing_policy = AX_surfxml_cluster_bb_sharing_policy;
3218 #ifndef HAVE_PCRE_LIB
3219 xbt_dynar_t tab_elements_num = xbt_dynar_new(sizeof(int), NULL);
3220 char *route_src, *route_dst;
3224 static unsigned int surfxml_buffer_stack_stack_ptr = 1;
3225 static unsigned int surfxml_buffer_stack_stack[1024];
3227 surfxml_buffer_stack_stack[0] = 0;
3229 surfxml_bufferstack_push(1);
3231 SURFXML_BUFFER_SET(AS_id, cluster_id);
3232 #ifdef HAVE_PCRE_LIB
3233 SURFXML_BUFFER_SET(AS_routing, "RuleBased");
3234 DEBUG1("<AS id=\"%s\"\trouting=\"RuleBased\">", cluster_id);
3236 SURFXML_BUFFER_SET(AS_routing, "Full");
3237 DEBUG1("<AS id=\"%s\"\trouting=\"Full\">", cluster_id);
3239 SURFXML_START_TAG(AS);
3241 radical_elements = xbt_str_split(cluster_radical, ",");
3242 xbt_dynar_foreach(radical_elements, iter, groups) {
3243 radical_ends = xbt_str_split(groups, "-");
3244 switch (xbt_dynar_length(radical_ends)) {
3246 surf_parse_get_int(&start,
3247 xbt_dynar_get_as(radical_ends, 0, char *));
3248 host_id = bprintf("%s%d%s", cluster_prefix, start, cluster_suffix);
3249 #ifndef HAVE_PCRE_LIB
3250 xbt_dynar_push_as(tab_elements_num, int, start);
3252 link_id = bprintf("%s_link_%d", cluster_id, start);
3254 DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>", host_id, cluster_power);
3255 A_surfxml_host_state = A_surfxml_host_state_ON;
3256 SURFXML_BUFFER_SET(host_id, host_id);
3257 SURFXML_BUFFER_SET(host_power, cluster_power);
3258 SURFXML_BUFFER_SET(host_availability, "1.0");
3259 SURFXML_BUFFER_SET(host_availability_file, "");
3260 SURFXML_BUFFER_SET(host_state_file, "");
3261 SURFXML_START_TAG(host);
3262 SURFXML_END_TAG(host);
3264 DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,cluster_bw, cluster_lat);
3265 A_surfxml_link_state = A_surfxml_link_state_ON;
3266 A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3267 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3268 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FULLDUPLEX;}
3269 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3270 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FATPIPE;}
3271 SURFXML_BUFFER_SET(link_id, link_id);
3272 SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
3273 SURFXML_BUFFER_SET(link_latency, cluster_lat);
3274 SURFXML_BUFFER_SET(link_bandwidth_file, "");
3275 SURFXML_BUFFER_SET(link_latency_file, "");
3276 SURFXML_BUFFER_SET(link_state_file, "");
3277 SURFXML_START_TAG(link);
3278 SURFXML_END_TAG(link);
3286 surf_parse_get_int(&start,
3287 xbt_dynar_get_as(radical_ends, 0, char *));
3288 surf_parse_get_int(&end, xbt_dynar_get_as(radical_ends, 1, char *));
3289 DEBUG2("Create hosts and links from %d to %d", start, end);
3290 for (i = start; i <= end; i++) {
3291 host_id = bprintf("%s%d%s", cluster_prefix, i, cluster_suffix);
3292 #ifndef HAVE_PCRE_LIB
3293 xbt_dynar_push_as(tab_elements_num, int, i);
3295 link_id = bprintf("%s_link_%d", cluster_id, i);
3297 DEBUG2("<host\tid=\"%s\"\tpower=\"%s\"/>", host_id, cluster_power);
3298 A_surfxml_host_state = A_surfxml_host_state_ON;
3299 SURFXML_BUFFER_SET(host_id, host_id);
3300 SURFXML_BUFFER_SET(host_power, cluster_power);
3301 SURFXML_BUFFER_SET(host_availability, "1.0");
3302 SURFXML_BUFFER_SET(host_availability_file, "");
3303 SURFXML_BUFFER_SET(host_state_file, "");
3304 SURFXML_START_TAG(host);
3305 SURFXML_END_TAG(host);
3307 DEBUG3("<link\tid=\"%s\"\tbw=\"%s\"\tlat=\"%s\"/>", link_id,cluster_bw, cluster_lat);
3308 A_surfxml_link_state = A_surfxml_link_state_ON;
3309 A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3310 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3311 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FULLDUPLEX;}
3312 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3313 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FATPIPE;}
3314 SURFXML_BUFFER_SET(link_id, link_id);
3315 SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
3316 SURFXML_BUFFER_SET(link_latency, cluster_lat);
3317 SURFXML_BUFFER_SET(link_bandwidth_file, "");
3318 SURFXML_BUFFER_SET(link_latency_file, "");
3319 SURFXML_BUFFER_SET(link_state_file, "");
3320 SURFXML_START_TAG(link);
3321 SURFXML_END_TAG(link);
3329 DEBUG0("Malformed radical");
3332 xbt_dynar_free(&radical_ends);
3334 xbt_dynar_free(&radical_elements);
3338 bprintf("%s%s_router%s", cluster_prefix, cluster_id,
3340 link_router = bprintf("%s_link_%s_router", cluster_id, cluster_id);
3341 link_backbone = bprintf("%s_backbone", cluster_id);
3343 DEBUG1("<router id=\"%s\"/>", router_id);
3344 SURFXML_BUFFER_SET(router_id, router_id);;
3345 SURFXML_START_TAG(router);
3346 SURFXML_END_TAG(router);
3348 DEBUG3("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_router,cluster_bw, cluster_lat);
3349 A_surfxml_link_state = A_surfxml_link_state_ON;
3350 A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3351 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3352 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FULLDUPLEX;}
3353 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FATPIPE)
3354 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FATPIPE;}
3355 SURFXML_BUFFER_SET(link_id, link_router);
3356 SURFXML_BUFFER_SET(link_bandwidth, cluster_bw);
3357 SURFXML_BUFFER_SET(link_latency, cluster_lat);
3358 SURFXML_BUFFER_SET(link_bandwidth_file, "");
3359 SURFXML_BUFFER_SET(link_latency_file, "");
3360 SURFXML_BUFFER_SET(link_state_file, "");
3361 SURFXML_START_TAG(link);
3362 SURFXML_END_TAG(link);
3364 DEBUG3("<link\tid=\"%s\" bw=\"%s\" lat=\"%s\"/>", link_backbone,cluster_bw, cluster_lat);
3365 A_surfxml_link_state = A_surfxml_link_state_ON;
3366 A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_SHARED;
3367 if(cluster_bb_sharing_policy == A_surfxml_cluster_bb_sharing_policy_FATPIPE)
3368 {A_surfxml_link_sharing_policy = A_surfxml_link_sharing_policy_FATPIPE;}
3369 SURFXML_BUFFER_SET(link_id, link_backbone);
3370 SURFXML_BUFFER_SET(link_bandwidth, cluster_bb_bw);
3371 SURFXML_BUFFER_SET(link_latency, cluster_bb_lat);
3372 SURFXML_BUFFER_SET(link_bandwidth_file, "");
3373 SURFXML_BUFFER_SET(link_latency_file, "");
3374 SURFXML_BUFFER_SET(link_state_file, "");
3375 SURFXML_START_TAG(link);
3376 SURFXML_END_TAG(link);
3378 free(link_backbone);
3383 #ifdef HAVE_PCRE_LIB
3384 char *new_suffix = xbt_strdup("");
3386 radical_elements = xbt_str_split(cluster_suffix, ".");
3387 xbt_dynar_foreach(radical_elements, iter, groups) {
3388 if (strcmp(groups, "")) {
3389 char *old_suffix = new_suffix;
3390 new_suffix = bprintf("%s\\.%s", old_suffix, groups);
3394 route_src_dst = bprintf("%s(.*)%s", cluster_prefix, new_suffix);
3395 xbt_dynar_free(&radical_elements);
3398 char *pcre_link_src = bprintf("%s_link_$1src", cluster_id);
3399 char *pcre_link_backbone = bprintf("%s_backbone", cluster_id);
3400 char *pcre_link_dst = bprintf("%s_link_$1dst", cluster_id);
3402 DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src_dst, route_src_dst);
3403 DEBUG0("symmetrical=\"NO\">");
3404 SURFXML_BUFFER_SET(route_src, route_src_dst);
3405 SURFXML_BUFFER_SET(route_dst, route_src_dst);
3406 A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3407 SURFXML_START_TAG(route);
3409 DEBUG1("<link_ctn\tid=\"%s\"/>", pcre_link_src);
3410 SURFXML_BUFFER_SET(link_ctn_id, pcre_link_src);
3411 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3412 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3413 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
3414 SURFXML_START_TAG(link_ctn);
3415 SURFXML_END_TAG(link_ctn);
3417 DEBUG1("<link_ctn\tid=\"%s\"/>", pcre_link_backbone);
3418 SURFXML_BUFFER_SET(link_ctn_id, pcre_link_backbone);
3419 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3420 SURFXML_START_TAG(link_ctn);
3421 SURFXML_END_TAG(link_ctn);
3423 DEBUG1("<link_ctn\tid=\"%s\"/>", pcre_link_dst);
3424 SURFXML_BUFFER_SET(link_ctn_id, pcre_link_dst);
3425 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3426 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3427 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
3428 SURFXML_START_TAG(link_ctn);
3429 SURFXML_END_TAG(link_ctn);
3432 SURFXML_END_TAG(route);
3434 free(pcre_link_dst);
3435 free(pcre_link_backbone);
3436 free(pcre_link_src);
3437 free(route_src_dst);
3439 for (i = 0; i <= xbt_dynar_length(tab_elements_num); i++) {
3440 for (j = 0; j <= xbt_dynar_length(tab_elements_num); j++) {
3441 if (i == xbt_dynar_length(tab_elements_num)) {
3442 route_src = router_id;
3445 bprintf("%s%d%s", cluster_prefix,
3446 xbt_dynar_get_as(tab_elements_num, i, int),
3450 if (j == xbt_dynar_length(tab_elements_num)) {
3451 route_dst = router_id;
3454 bprintf("%s%d%s", cluster_prefix,
3455 xbt_dynar_get_as(tab_elements_num, j, int),
3459 DEBUG2("<route\tsrc=\"%s\"\tdst=\"%s\"", route_src, route_dst);
3460 DEBUG0("symmetrical=\"NO\">");
3461 SURFXML_BUFFER_SET(route_src, route_src);
3462 SURFXML_BUFFER_SET(route_dst, route_dst);
3463 A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
3464 SURFXML_START_TAG(route);
3466 if (i == xbt_dynar_length(tab_elements_num)) {
3467 route_src = link_router;
3470 bprintf("%s_link_%d", cluster_id,
3471 xbt_dynar_get_as(tab_elements_num, i, int));
3474 if (j == xbt_dynar_length(tab_elements_num)) {
3475 route_dst = link_router;
3478 bprintf("%s_link_%d", cluster_id,
3479 xbt_dynar_get_as(tab_elements_num, j, int));
3482 DEBUG1("<link_ctn\tid=\"%s\"/>", route_src);
3483 SURFXML_BUFFER_SET(link_ctn_id, route_src);
3484 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3485 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3486 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_UP;}
3487 SURFXML_START_TAG(link_ctn);
3488 SURFXML_END_TAG(link_ctn);
3490 DEBUG1("<link_ctn\tid=\"%s_backbone\"/>", cluster_id);
3491 SURFXML_BUFFER_SET(link_ctn_id, bprintf("%s_backbone", cluster_id));
3492 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3493 SURFXML_START_TAG(link_ctn);
3494 SURFXML_END_TAG(link_ctn);
3496 DEBUG1("<link_ctn\tid=\"%s\"/>", route_dst);
3497 SURFXML_BUFFER_SET(link_ctn_id, route_dst);
3498 A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_NONE;
3499 if(cluster_sharing_policy == A_surfxml_cluster_sharing_policy_FULLDUPLEX)
3500 {A_surfxml_link_ctn_direction = A_surfxml_link_ctn_direction_DOWN;}
3501 SURFXML_START_TAG(link_ctn);
3502 SURFXML_END_TAG(link_ctn);
3505 SURFXML_END_TAG(route);
3508 xbt_dynar_free(&tab_elements_num);
3515 SURFXML_END_TAG(AS);
3518 surfxml_bufferstack_pop(1);
3522 * New methods to init the routing model component from the lua script
3526 * calling parse_S_AS_lua with lua values
3528 void routing_AS_init(const char *AS_id, const char *AS_routing)
3530 parse_S_AS_lua((char *) AS_id, (char *) AS_routing);
3534 * calling parse_E_AS_lua to fisnish the creation of routing component
3536 void routing_AS_end(const char *AS_id)
3538 parse_E_AS_lua((char *) AS_id);
3542 * add a host to the network element list
3545 void routing_add_host(const char *host_id)
3547 parse_S_host_lua((char *) host_id);
3551 * Set a new link on the actual list of link for a route or ASroute
3553 void routing_add_link(const char *link_id)
3555 parse_E_link_c_ctn_new_elem_lua((char *) link_id);
3559 *Set the endpoints for a route
3561 void routing_set_route(const char *src_id, const char *dst_id)
3563 parse_S_route_new_and_endpoints_lua(src_id, dst_id);
3567 * Store the route by calling parse_E_route_store_route
3569 void routing_store_route(void)
3571 parse_E_route_store_route();