+
+ /* Begin with myself */
+
+ myself->status.visited = 1;
+ myself->nexthop = myself;
+ myself->via = myself;
+ node = avl_alloc_node();
+ node->data = myself;
+ avl_insert_top(todo_tree, node);
+
+ /* Loop while todo_tree is filled */
+
+ while(todo_tree->head)
+ {
+ for(from = todo_tree->head; from; from = next)
+ {
+ next = from->next;
+ n = (node_t *)from->data;
+
+ for(to = n->edge_tree->head; to; to = to->next)
+ {
+ e = (edge_t *)to->data;
+
+ if(e->from == n)
+ check = e->to;
+ else
+ check = e->from;
+
+ if(!check->status.visited)
+ {
+ check->status.visited = 1;
+ check->nexthop = (n->nexthop == myself) ? check : n->nexthop;
+ check->via = (e->options & OPTION_INDIRECT || n->via != n) ? n->via : check;
+ node = avl_alloc_node();
+ node->data = check;
+ avl_insert_before(todo_tree, from, node);
+ }
+ }
+
+ avl_delete_node(todo_tree, from);
+ }
+ }
+
+ avl_free_tree(todo_tree);
+
+ /* Nodes we haven't visited are unreachable, prune them. */
+
+ if(prune)
+ for(node = node_tree->head; node; node = next)
+ {
+ next = node->next;
+ n = (node_t *)node->data;
+
+ if(n->status.visited == 0)
+ node_del(n);
+ }