From b1f384cd635db8124a9b778b4ed5c045c4331928 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Fri, 31 May 2013 11:32:13 +0930 Subject: [PATCH] Swap between broadcast & unicast links as they become available --- overlay_link.c | 6 +++++- route_link.c | 10 +++++++--- tests/routing | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/overlay_link.c b/overlay_link.c index 4d65bf9c..7fe8afe2 100644 --- a/overlay_link.c +++ b/overlay_link.c @@ -255,7 +255,11 @@ overlay_mdp_service_probe(overlay_mdp_frame *mdp) peer->address.sin_family = AF_INET; peer->address.sin_addr = probe.addr.sin_addr; peer->address.sin_port = probe.addr.sin_port; - set_reachable(peer, REACHABLE_UNICAST | (peer->reachable & REACHABLE_DIRECT)); + int r=REACHABLE_UNICAST; + // Don't turn assumed|broadcast into unicast|broadcast + if (!(peer->reachable & REACHABLE_ASSUMED)) + r |= (peer->reachable & REACHABLE_DIRECT); + set_reachable(peer, r); RETURN(0); OUT(); } diff --git a/route_link.c b/route_link.c index cb6709a5..33b77120 100644 --- a/route_link.c +++ b/route_link.c @@ -350,7 +350,7 @@ next: subscriber->last_probe=0; bzero(&subscriber->address, sizeof subscriber->address); } - reachable = REACHABLE_BROADCAST | (subscriber->reachable & REACHABLE_UNICAST); + reachable = REACHABLE_BROADCAST | (reachable & REACHABLE_UNICAST); next_hop = NULL; subscriber->interface = interface; } else { @@ -505,7 +505,6 @@ static void free_neighbour(struct neighbour **neighbour_ptr){ n->root=NULL; *neighbour_ptr = n->_next; free(n); - route_version++; } static void clean_neighbours(time_ms_t now) @@ -527,6 +526,10 @@ static void clean_neighbours(time_ms_t now) list = &link->_next; } } + // when all links to a neighbour that we are routing through expire, force a routing calculation update + struct link_state *state = get_link_state(n->subscriber); + if (state->next_hop == n->subscriber && (n->neighbour_link_timeout < now || !n->links) && state->route_version == route_version) + route_version++; if (!n->links){ free_neighbour(n_ptr); }else{ @@ -698,7 +701,8 @@ static void link_send(struct sched_ent *alarm) if (neighbours){ alarm->deadline = alarm->alarm; schedule(alarm); - } + }else + alarm->alarm=0; } static void update_alarm(time_ms_t limit){ diff --git a/tests/routing b/tests/routing index f8144f4b..8460d7ea 100755 --- a/tests/routing +++ b/tests/routing @@ -358,6 +358,26 @@ test_offline() { wait_until --timeout=30 instance_offline +C } +doc_lose_neighbours="Lose and regain neighbours" +setup_lose_neighbours() { + setup_servald + assert_no_servald_processes + foreach_instance +A +B +C create_single_identity + foreach_instance +A +B add_interface 1 + foreach_instance +B +C add_interface 2 + foreach_instance +A +B +C start_routing_instance +} +test_lose_neighbours() { + wait_until path_exists +A +B +C + wait_until path_exists +C +B +A + stop_servald_server +B + foreach_instance +A +C \ + wait_until --timeout=30 instance_offline +B + start_servald_server +B + wait_until path_exists +A +B +C + wait_until path_exists +C +B +A +} + setup_multi_interface() { setup_servald assert_no_servald_processes