subnet-up/down hooks, use list_t for the todo list.

This commit is contained in:
Guus Sliepen 2004-12-01 20:06:39 +00:00
parent c46f56a8b8
commit 40b1692940

View file

@ -54,6 +54,7 @@
#include "netutl.h" #include "netutl.h"
#include "node.h" #include "node.h"
#include "process.h" #include "process.h"
#include "subnet.h"
#include "utils.h" #include "utils.h"
/* Implementation of Kruskal's algorithm. /* Implementation of Kruskal's algorithm.
@ -141,10 +142,11 @@ void mst_kruskal(void)
void sssp_bfs(void) void sssp_bfs(void)
{ {
avl_node_t *node, *from, *next, *to; avl_node_t *node, *next, *to;
edge_t *e; edge_t *e;
node_t *n; node_t *n;
avl_tree_t *todo_tree; list_t *todo_list;
list_node_t *from, *todonext;
bool indirect; bool indirect;
char *name; char *name;
char *address, *port; char *address, *port;
@ -153,7 +155,7 @@ void sssp_bfs(void)
cp(); cp();
todo_tree = avl_alloc_tree(NULL, NULL); todo_list = list_alloc(NULL);
/* Clear visited status on nodes */ /* Clear visited status on nodes */
@ -169,86 +171,80 @@ void sssp_bfs(void)
myself->status.indirect = false; myself->status.indirect = false;
myself->nexthop = myself; myself->nexthop = myself;
myself->via = myself; myself->via = myself;
node = avl_alloc_node(); list_insert_head(todo_list, myself);
node->data = myself;
avl_insert_top(todo_tree, node);
/* Loop while todo_tree is filled */ /* Loop while todo_list is filled */
while(todo_tree->head) { for(from = todo_list->head; from; from = todonext) { /* "from" is the node from which we start */
for(from = todo_tree->head; from; from = next) { /* "from" is the node from which we start */ n = from->data;
next = from->next;
n = from->data;
for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */ for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */
e = to->data; e = to->data;
if(!e->reverse) if(!e->reverse)
continue; continue;
/* Situation: /* Situation:
/ /
/ /
----->(n)---e-->(e->to) ----->(n)---e-->(e->to)
\ \
\ \
Where e is an edge, (n) and (e->to) are nodes. Where e is an edge, (n) and (e->to) are nodes.
n->address is set to the e->address of the edge left of n to n. n->address is set to the e->address of the edge left of n to n.
We are currently examining the edge e right of n from n: We are currently examining the edge e right of n from n:
- If e->reverse->address != n->address, then e->to is probably - If e->reverse->address != n->address, then e->to is probably
not reachable for the nodes left of n. We do as if the indirectdata not reachable for the nodes left of n. We do as if the indirectdata
flag is set on edge e. flag is set on edge e.
- If edge e provides for better reachability of e->to, update - If edge e provides for better reachability of e->to, update
e->to and (re)add it to the todo_tree to (re)examine the reachability e->to and (re)add it to the todo_list to (re)examine the reachability
of nodes behind it. of nodes behind it.
*/ */
indirect = n->status.indirect || e->options & OPTION_INDIRECT indirect = n->status.indirect || e->options & OPTION_INDIRECT
|| ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address)); || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address));
if(e->to->status.visited if(e->to->status.visited
&& (!e->to->status.indirect || indirect)) && (!e->to->status.indirect || indirect))
continue; continue;
e->to->status.visited = true; e->to->status.visited = true;
e->to->status.indirect = indirect; e->to->status.indirect = indirect;
e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
e->to->via = indirect ? n->via : e->to; e->to->via = indirect ? n->via : e->to;
e->to->options = e->options; e->to->options = e->options;
if(sockaddrcmp(&e->to->address, &e->address)) { if(sockaddrcmp(&e->to->address, &e->address)) {
node = avl_unlink(node_udp_tree, e->to); node = avl_unlink(node_udp_tree, e->to);
sockaddrfree(&e->to->address); sockaddrfree(&e->to->address);
sockaddrcpy(&e->to->address, &e->address); sockaddrcpy(&e->to->address, &e->address);
if(e->to->hostname) if(e->to->hostname)
free(e->to->hostname); free(e->to->hostname);
e->to->hostname = sockaddr2hostname(&e->to->address); e->to->hostname = sockaddr2hostname(&e->to->address);
avl_insert_node(node_udp_tree, node); avl_insert_node(node_udp_tree, node);
if(e->to->options & OPTION_PMTU_DISCOVERY) { if(e->to->options & OPTION_PMTU_DISCOVERY) {
e->to->mtuprobes = 0; e->to->mtuprobes = 0;
e->to->minmtu = 0; e->to->minmtu = 0;
e->to->maxmtu = MTU; e->to->maxmtu = MTU;
if(e->to->status.validkey) if(e->to->status.validkey)
send_mtu_probe(e->to); send_mtu_probe(e->to);
}
} }
node = avl_alloc_node();
node->data = e->to;
avl_insert_before(todo_tree, from, node);
} }
avl_delete_node(todo_tree, from); list_insert_tail(todo_list, e->to);
} }
todonext = from->next;
list_delete_node(todo_list, from);
} }
avl_free_tree(todo_tree); list_free(todo_list);
/* Check reachability status. */ /* Check reachability status. */
@ -292,8 +288,10 @@ void sssp_bfs(void)
free(address); free(address);
free(port); free(port);
for(i = 0; i < 7; i++) for(i = 0; i < 6; i++)
free(envp[i]); free(envp[i]);
subnet_update(n, NULL, n->status.reachable);
} }
} }
} }