/** * Print the routingtree to STDOUT * */ void olsr_print_routing_table(struct avl_tree *tree) { #ifndef NODEBUG /* The whole function makes no sense without it. */ struct avl_node *rt_tree_node; struct lqtextbuffer lqbuffer; OLSR_PRINTF(6, "ROUTING TABLE\n"); for (rt_tree_node = avl_walk_first(tree); rt_tree_node != NULL; rt_tree_node = avl_walk_next(rt_tree_node)) { struct avl_node *rtp_tree_node; struct ipaddr_str prefixstr, origstr, gwstr; struct rt_entry *rt = rt_tree2rt(rt_tree_node); /* first the route entry */ OLSR_PRINTF(6, "%s/%u, via %s, best-originator %s\n", olsr_ip_to_string(&prefixstr, &rt->rt_dst.prefix), rt->rt_dst.prefix_len, olsr_ip_to_string(&origstr, &rt->rt_nexthop.gateway), olsr_ip_to_string(&gwstr, &rt->rt_best->rtp_originator)); /* walk the per-originator path tree of routes */ for (rtp_tree_node = avl_walk_first(&rt->rt_path_tree); rtp_tree_node != NULL; rtp_tree_node = avl_walk_next(rtp_tree_node)) { struct rt_path *rtp = rtp_tree2rtp(rtp_tree_node); OLSR_PRINTF(6, "\tfrom %s, cost %s, metric %u, via %s, %s, v %u\n", olsr_ip_to_string(&origstr, &rtp->rtp_originator), get_linkcost_text(rtp->rtp_metric.cost, true, &lqbuffer), rtp->rtp_metric.hops, olsr_ip_to_string(&gwstr, &rtp-> rtp_nexthop. gateway), if_ifwithindex_name(rt->rt_nexthop.iif_index), rtp->rtp_version); } } #endif /* NODEBUG */ tree = NULL; /* squelch compiler warnings */ }
/** * Create a route entry for a given rt_path and * insert it into the global RIB tree. */ void olsr_insert_rt_path(struct rt_path *rtp, struct tc_entry *tc, struct link_entry *link) { struct rt_entry *rt; struct avl_node *node; /* * no unreachable routes please. */ if (tc->path_cost == ROUTE_COST_BROKEN) { return; } /* * No bogus prefix lengths. */ if (rtp->rtp_dst.prefix_len > olsr_cnf->maxplen) { return; } /* * first check if there is a route_entry for the prefix. */ node = avl_find(&routingtree, &rtp->rtp_dst); if (!node) { /* no route entry yet */ rt = olsr_alloc_rt_entry(&rtp->rtp_dst); if (!rt) { return; } } else { rt = rt_tree2rt(node); } /* Now insert the rt_path to the owning rt_entry tree */ rtp->rtp_originator = tc->addr; /* set key and backpointer prior to tree insertion */ rtp->rtp_tree_node.key = &rtp->rtp_originator; /* insert to the route entry originator tree */ avl_insert(&rt->rt_path_tree, &rtp->rtp_tree_node, AVL_DUP_NO); /* backlink to the owning route entry */ rtp->rtp_rt = rt; /* update the version field and relevant parameters */ olsr_update_rt_path(rtp, tc, link); }
void iterRouteTabInit(void) { struct avl_node *node; avl_init(&routingtree, avl_comp_prefix_default); routingtree_version = 0; node = avl_walk_first(&routingtree); iterRouteTab = node ? rt_tree2rt(node) : NULL; }
/** * Look up a maxplen entry (= /32 or /128) in the routing table. * * @param dst the address of the entry * * @return a pointer to a rt_entry struct * representing the route entry. */ struct rt_entry * olsr_lookup_routing_table(const union olsr_ip_addr *dst) { struct avl_node *rt_tree_node; struct olsr_ip_prefix prefix; prefix.prefix = *dst; prefix.prefix_len = olsr_cnf->maxplen; rt_tree_node = avl_find(&routingtree, &prefix); return rt_tree_node ? rt_tree2rt(rt_tree_node) : NULL; }
int iterRouteTabNext(char *buff, int len) { struct avl_node *rt_tree_node; if (iterRouteTab == NULL) return -1; snprintf(buff, len, "destination~%s~gateway~%s~interface~%s~metric~%d~", rawIpAddrToString(&iterRouteTab->rt_dst.prefix, ipAddrLen), rawIpAddrToString(&iterRouteTab->rt_best->rtp_nexthop.gateway, ipAddrLen), if_ifwithindex_name(iterRouteTab->rt_best->rtp_nexthop.iif_index), iterRouteTab->rt_best->rtp_metric.hops); rt_tree_node = avl_walk_next(&iterRouteTab->rt_tree_node); if (rt_tree_node) { iterRouteTab = rt_tree2rt(rt_tree_node); } else { iterRouteTab = NULL; } return 0; }