1 /* Copyright (c) 2009, 2010, 2011. 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. */
6 #include "surf_routing_private.h"
9 #include <pcre.h> /* regular expression library */
12 extern routing_global_t global_routing;
13 extern routing_component_t current_routing;
14 extern model_type_t current_routing_model;
15 extern xbt_dynar_t link_list;
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_rulebased, surf, "Routing part of surf");
19 /* Routing model structure */
22 s_routing_component_t generic_routing;
23 xbt_dict_t dict_processing_units;
24 xbt_dict_t dict_autonomous_systems;
25 xbt_dynar_t list_route;
26 xbt_dynar_t list_ASroute;
27 } s_routing_component_rulebased_t, *routing_component_rulebased_t;
29 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
30 typedef struct s_rule_route_extended s_rule_route_extended_t,
31 *rule_route_extended_t;
34 xbt_dynar_t re_str_link; // dynar of char*
39 struct s_rule_route_extended {
40 s_rule_route_t generic_rule_route;
45 static void rule_route_free(void *e)
47 rule_route_t *elem = (rule_route_t *) (e);
49 xbt_dynar_free(&(*elem)->re_str_link);
50 pcre_free((*elem)->re_src);
51 pcre_free((*elem)->re_dst);
57 static void rule_route_extended_free(void *e)
59 rule_route_extended_t *elem = (rule_route_extended_t *) e;
61 xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
62 pcre_free((*elem)->generic_rule_route.re_src);
63 pcre_free((*elem)->generic_rule_route.re_dst);
64 xbt_free((*elem)->re_src_gateway);
65 xbt_free((*elem)->re_dst_gateway);
70 /* Parse routing model functions */
72 static void model_rulebased_set_processing_unit(routing_component_t rc,
75 routing_component_rulebased_t routing =
76 (routing_component_rulebased_t) rc;
77 xbt_dict_set(routing->dict_processing_units, name, (void *) (-1), NULL);
80 static void model_rulebased_set_autonomous_system(routing_component_t rc,
83 routing_component_rulebased_t routing =
84 (routing_component_rulebased_t) rc;
85 xbt_dict_set(routing->dict_autonomous_systems, name, (void *) (-1),
89 static void model_rulebased_set_route(routing_component_t rc,
90 const char *src, const char *dst,
91 name_route_extended_t route)
93 routing_component_rulebased_t routing =
94 (routing_component_rulebased_t) rc;
95 rule_route_t ruleroute = xbt_new0(s_rule_route_t, 1);
99 if(!strcmp(rc->routing->name,"Vivaldi")){
100 if(xbt_dynar_length(route->generic_route.link_list) != 0)
101 xbt_die("You can't have link_ctn with Model Vivaldi.");
104 ruleroute->re_src = pcre_compile(src, 0, &error, &erroffset, NULL);
105 xbt_assert(ruleroute->re_src,
106 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
107 erroffset, src, error);
108 ruleroute->re_dst = pcre_compile(dst, 0, &error, &erroffset, NULL);
109 xbt_assert(ruleroute->re_src,
110 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
111 erroffset, dst, error);
112 ruleroute->re_str_link = route->generic_route.link_list;
113 xbt_dynar_push(routing->list_route, &ruleroute);
117 static void model_rulebased_set_ASroute(routing_component_t rc,
118 const char *src, const char *dst,
119 name_route_extended_t route)
121 routing_component_rulebased_t routing =
122 (routing_component_rulebased_t) rc;
123 rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t, 1);
127 if(!strcmp(rc->routing->name,"Vivaldi")){
128 if(xbt_dynar_length(route->generic_route.link_list) != 0)
129 xbt_die("You can't have link_ctn with Model Vivaldi.");
132 ruleroute_e->generic_rule_route.re_src =
133 pcre_compile(src, 0, &error, &erroffset, NULL);
134 xbt_assert(ruleroute_e->generic_rule_route.re_src,
135 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
136 erroffset, src, error);
137 ruleroute_e->generic_rule_route.re_dst =
138 pcre_compile(dst, 0, &error, &erroffset, NULL);
139 xbt_assert(ruleroute_e->generic_rule_route.re_src,
140 "PCRE compilation failed at offset %d (\"%s\"): %s\n",
141 erroffset, dst, error);
142 ruleroute_e->generic_rule_route.re_str_link =
143 route->generic_route.link_list;
144 ruleroute_e->re_src_gateway = route->src_gateway;
145 ruleroute_e->re_dst_gateway = route->dst_gateway;
146 xbt_dynar_push(routing->list_ASroute, &ruleroute_e);
147 // xbt_free(route->src_gateway);
148 // xbt_free(route->dst_gateway);
152 static void model_rulebased_set_bypassroute(routing_component_t rc,
155 route_extended_t e_route)
157 xbt_die("bypass routing not supported for Route-Based model");
160 #define BUFFER_SIZE 4096 /* result buffer size */
161 #define OVECCOUNT 30 /* should be a multiple of 3 */
163 static char *remplace(char *value, const char **src_list, int src_size,
164 const char **dst_list, int dst_size)
167 char result_result[BUFFER_SIZE];
169 int value_length = (int) strlen(value);
175 if (value[i] == '$') {
179 int number_length = 0;
180 while ('0' <= value[i + number_length]
181 && value[i + number_length] <= '9') {
184 xbt_assert(number_length != 0,
185 "bad string parameter, no number indication, at offset: %d (\"%s\")",
189 number = atoi(value + i);
190 i = i + number_length;
191 xbt_assert(i + 2 < value_length,
192 "bad string parameter, too few chars, at offset: %d (\"%s\")",
195 // solve the indication
196 const char **param_list;
198 if (value[i] == 's' && value[i + 1] == 'r' && value[i + 2] == 'c') {
199 param_list = src_list;
200 param_size = src_size;
201 } else if (value[i] == 'd' && value[i + 1] == 's'
202 && value[i + 2] == 't') {
203 param_list = dst_list;
204 param_size = dst_size;
206 xbt_die("bad string parameter, support only \"src\" and \"dst\", "
207 "at offset: %d (\"%s\")", i, value);
211 xbt_assert(param_size >= number,
212 "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",
213 i, value, param_size, number);
215 const char *param = param_list[number];
216 int size = strlen(param);
218 for (cp = 0; cp < size; cp++) {
219 result_result[i_result_buffer] = param[cp];
221 if (i_result_buffer >= BUFFER_SIZE)
225 result_result[i_result_buffer] = value[i];
230 } while (i < value_length && i_result_buffer < BUFFER_SIZE);
232 xbt_assert(i_result_buffer < BUFFER_SIZE,
233 "solving string \"%s\", small buffer size (%d)", value,
235 result_result[i_result_buffer] = 0;
236 return xbt_strdup(result_result);
239 static route_extended_t rulebased_get_route(routing_component_t rc,
242 static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
244 xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
245 routing_component_rulebased_t routing = (routing_component_rulebased_t)rc;
247 xbt_dict_cursor_t c1 = NULL;
252 xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
253 if (rc->get_network_element_type(k1) == SURF_NETWORK_ELEMENT_ROUTER){
259 xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
262 xbt_dict_foreach(routing->dict_processing_units, c1, k1, d1) {
263 route_extended_t route = rulebased_get_route (rc, router, k1);
265 int number_of_links = xbt_dynar_length(route->generic_route.link_list);
267 if(number_of_links == 1) {
271 if (number_of_links != 2) {
272 xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
276 xbt_dynar_get_cpy (route->generic_route.link_list, 1, &link_ptr);
277 onelink_t onelink = xbt_new0 (s_onelink_t, 1);
278 onelink->src = xbt_strdup (k1);
279 onelink->dst = xbt_strdup (router);
280 onelink->link_ptr = link_ptr;
281 xbt_dynar_push (ret, &onelink);
287 /* Business methods */
288 static route_extended_t rulebased_get_route(routing_component_t rc,
294 "Invalid params for \"get_route\" function at AS \"%s\"",
298 routing_component_rulebased_t routing =
299 (routing_component_rulebased_t) rc;
301 int are_processing_units=0;
302 xbt_dynar_t rule_list;
303 if (xbt_dict_get_or_null(routing->dict_processing_units, src)
304 && xbt_dict_get_or_null(routing->dict_processing_units, dst)) {
305 are_processing_units = 1;
306 rule_list = routing->list_route;
307 } else if (xbt_dict_get_or_null(routing->dict_autonomous_systems, src)
308 && xbt_dict_get_or_null(routing->dict_autonomous_systems,
310 are_processing_units = 0;
311 rule_list = routing->list_ASroute;
313 xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found in "
314 "the local table", src, dst);
318 int src_length = (int) strlen(src);
319 int dst_length = (int) strlen(dst);
321 xbt_dynar_t links_list =
322 xbt_dynar_new(global_routing->size_of_link, NULL);
324 rule_route_t ruleroute;
326 int ovector_src[OVECCOUNT];
327 int ovector_dst[OVECCOUNT];
328 const char **list_src = NULL;
329 const char **list_dst = NULL;
331 xbt_dynar_foreach(rule_list, cpt, ruleroute) {
333 pcre_exec(ruleroute->re_src, NULL, src, src_length, 0, 0,
334 ovector_src, OVECCOUNT);
337 pcre_exec(ruleroute->re_dst, NULL, dst, dst_length, 0, 0,
338 ovector_dst, OVECCOUNT);
340 res = pcre_get_substring_list(src, ovector_src, rc_src, &list_src);
341 xbt_assert(!res, "error solving substring list for src \"%s\"", src);
342 res = pcre_get_substring_list(dst, ovector_dst, rc_dst, &list_dst);
343 xbt_assert(!res, "error solving substring list for src \"%s\"", dst);
345 xbt_dynar_foreach(ruleroute->re_str_link, cpt, link_name) {
346 char *new_link_name =
347 remplace(link_name, list_src, rc_src, list_dst, rc_dst);
349 xbt_lib_get_or_null(link_lib, new_link_name, SURF_LINK_LEVEL);
351 xbt_dynar_push(links_list, &link);
353 THROWF(mismatch_error, 0, "Link %s not found", new_link_name);
354 xbt_free(new_link_name);
358 if (rc_src >= 0 && rc_dst >= 0)
362 route_extended_t new_e_route = NULL;
363 if (rc_src >= 0 && rc_dst >= 0) {
364 new_e_route = xbt_new0(s_route_extended_t, 1);
365 new_e_route->generic_route.link_list = links_list;
366 } else if (!strcmp(src, dst) && are_processing_units) {
367 new_e_route = xbt_new0(s_route_extended_t, 1);
368 xbt_dynar_push(links_list, &(global_routing->loopback));
369 new_e_route->generic_route.link_list = links_list;
371 xbt_dynar_free(&link_list);
374 if (!are_processing_units && new_e_route) {
375 rule_route_extended_t ruleroute_extended =
376 (rule_route_extended_t) ruleroute;
377 new_e_route->src_gateway =
378 remplace(ruleroute_extended->re_src_gateway, list_src, rc_src,
380 new_e_route->dst_gateway =
381 remplace(ruleroute_extended->re_dst_gateway, list_src, rc_src,
386 pcre_free_substring_list(list_src);
388 pcre_free_substring_list(list_dst);
393 static route_extended_t rulebased_get_bypass_route(routing_component_t rc,
400 static void rulebased_finalize(routing_component_t rc)
402 routing_component_rulebased_t routing =
403 (routing_component_rulebased_t) rc;
405 xbt_dict_free(&routing->dict_processing_units);
406 xbt_dict_free(&routing->dict_autonomous_systems);
407 xbt_dynar_free(&routing->list_route);
408 xbt_dynar_free(&routing->list_ASroute);
409 /* Delete structure */
414 /* Creation routing model functions */
415 void *model_rulebased_create(void)
417 routing_component_rulebased_t new_component =
418 xbt_new0(s_routing_component_rulebased_t, 1);
419 new_component->generic_routing.set_processing_unit =
420 model_rulebased_set_processing_unit;
421 new_component->generic_routing.set_autonomous_system =
422 model_rulebased_set_autonomous_system;
423 new_component->generic_routing.set_route = model_rulebased_set_route;
424 new_component->generic_routing.set_ASroute = model_rulebased_set_ASroute;
425 new_component->generic_routing.set_bypassroute = model_rulebased_set_bypassroute;
426 new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes;
427 new_component->generic_routing.get_route = rulebased_get_route;
428 new_component->generic_routing.get_latency = generic_get_link_latency;
429 new_component->generic_routing.get_bypass_route = rulebased_get_bypass_route;
430 new_component->generic_routing.finalize = rulebased_finalize;
431 new_component->generic_routing.get_network_element_type = get_network_element_type;
432 /* initialization of internal structures */
433 new_component->dict_processing_units = xbt_dict_new();
434 new_component->dict_autonomous_systems = xbt_dict_new();
435 new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free);
436 new_component->list_ASroute =
437 xbt_dynar_new(sizeof(rule_route_extended_t),
438 &rule_route_extended_free);
439 return new_component;
442 void model_rulebased_load(void)
444 /* use "surfxml_add_callback" to add a parse function call */
447 void model_rulebased_unload(void)
449 /* use "surfxml_del_callback" to remove a parse function call */
452 void model_rulebased_end(void)
456 #endif /* HAVE_PCRE_LIB */