示例#1
0
/**
 * 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 */
}
/**
 * Check the version number of all route paths hanging off a route entry.
 * If a route does not match the current routing tree number, remove it
 * from the global originator tree for that rt_entry.
 * Reset the best route pointer.
 */
static void
olsr_delete_outdated_routes(struct rt_entry *rt)
{
  struct rt_path *rtp;
  struct avl_node *rtp_tree_node, *next_rtp_tree_node;

  for (rtp_tree_node = avl_walk_first(&rt->rt_path_tree); rtp_tree_node != NULL; rtp_tree_node = next_rtp_tree_node) {
    /*
     * pre-fetch the next node before loosing context.
     */
    next_rtp_tree_node = avl_walk_next(rtp_tree_node);

    rtp = rtp_tree2rtp(rtp_tree_node);

    /*
     * check the version number which gets incremented on every SPF run.
     * comparing for unequalness avoids handling version number wraps.
     */
    if (routingtree_version != rtp->rtp_version) {
      /* remove from the originator tree */
      avl_delete(&rt->rt_path_tree, rtp_tree_node);
      rtp->rtp_rt = NULL;

      if (rt->rt_best == rtp) {
        rt->rt_best = NULL;
      }
    }
  }
}
示例#3
0
/**
 * run best route selection among a
 * set of identical prefixes.
 */
void
olsr_rt_best(struct rt_entry *rt)
{
  /* grab the first entry */
  struct avl_node *node = avl_walk_first(&rt->rt_path_tree);

  assert(node != 0);            /* should not happen */

  rt->rt_best = rtp_tree2rtp(node);

  /* walk all remaining originator entries */
  while ((node = avl_walk_next(node))) {
    struct rt_path *rtp = rtp_tree2rtp(node);

    if (olsr_cmp_rtp(rtp, rt->rt_best, current_inetgw)) {
      rt->rt_best = rtp;
    }
  }

  if (0 == rt->rt_dst.prefix_len) {
    current_inetgw = rt->rt_best;
  }
}
void
olsr_delete_interface_routes(int if_index) {
  struct rt_entry *rt;
  bool triggerUpdate = false;

  OLSR_FOR_ALL_RT_ENTRIES(rt) {
    bool mightTrigger = false;
    struct rt_path *rtp;
    struct avl_node *rtp_tree_node, *next_rtp_tree_node;

    /* run through all routing paths of route */
    for (rtp_tree_node = avl_walk_first(&rt->rt_path_tree); rtp_tree_node != NULL; rtp_tree_node = next_rtp_tree_node) {
      /*
       * pre-fetch the next node before loosing context.
       */
      next_rtp_tree_node = avl_walk_next(rtp_tree_node);

      rtp = rtp_tree2rtp(rtp_tree_node);

      /* nexthop use lost interface ? */
      if (rtp->rtp_nexthop.iif_index == if_index) {
        /* remove from the originator tree */
        avl_delete(&rt->rt_path_tree, rtp_tree_node);
        rtp->rtp_rt = NULL;

        if (rt->rt_best == rtp) {
          rt->rt_best = NULL;
          mightTrigger = true;
        }
      }
    }

    if (mightTrigger) {
      if (!rt->rt_path_tree.count) {
        /* oops, all routes are gone - flush the route head */
        avl_delete(&routingtree, rt_tree_node);

        /* do not dequeue route because they are already gone */
      }
      triggerUpdate = true;
    }
  } OLSR_FOR_ALL_RT_ENTRIES_END(rt)

  /* trigger route update if necessary */
  if (triggerUpdate) {
    olsr_update_rib_routes();
    olsr_update_kernel_routes();
  }
}