Don't override subscriber interface due to unicast probe packets

This commit is contained in:
Jeremy Lakeman 2013-05-01 16:20:04 +09:30
parent dd03014b44
commit a29c1d3468
3 changed files with 28 additions and 12 deletions

View File

@ -236,6 +236,12 @@ overlay_mdp_service_probe(overlay_mdp_frame *mdp)
if (probe.addr.sin_family!=AF_INET)
RETURN(WHY("Unsupported address family"));
struct overlay_interface *interface = &overlay_interfaces[probe.interface];
// if a peer is already reachable, and this probe would change the interface, ignore it
// TODO track unicast links better in route_link.c
if (peer->reachable & REACHABLE_DIRECT && peer->interface && peer->interface != interface)
RETURN(0);
peer->last_probe_response = gettime_ms();
peer->interface = &overlay_interfaces[probe.interface];
peer->address.sin_family = AF_INET;
@ -256,14 +262,18 @@ int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay
if (interface->state!=INTERFACE_STATE_UP)
return WHY("I can't send a probe if the interface is down.");
// don't send a unicast probe unless its on the same interface that is already known to be reachable
if (peer->reachable & REACHABLE_DIRECT && peer->interface && peer->interface != interface)
return -1;
if (addr.sin_addr.s_addr==0) {
if (config.debug.overlayinterfaces)
WHY("I can't send a probe to address 0.0.0.0");
DEBUG("I can't send a probe to address 0.0.0.0");
return -1;
}
if (addr.sin_port==0) {
if (config.debug.overlayinterfaces)
WHY("I can't send a probe to port 0");
DEBUG("I can't send a probe to port 0");
return -1;
}

View File

@ -303,6 +303,12 @@ next:
if (!(subscriber->reachable & REACHABLE_ASSUMED))
reachable = REACHABLE_NONE;
} else if (next_hop == subscriber){
// reset the state of any unicast probe's if the interface has changed
if (subscriber->interface != interface){
reachable = 0;
subscriber->last_probe=0;
bzero(&subscriber->address, sizeof subscriber->address);
}
reachable = REACHABLE_BROADCAST | (subscriber->reachable & REACHABLE_UNICAST);
subscriber->interface = interface;
} else {

View File

@ -45,6 +45,7 @@ start_routing_instance() {
set debug.mdprequests yes \
set debug.linkstate yes \
set debug.verbose yes \
set debug.overlayrouting yes \
set rhizome.enable no
start_servald_server
wait_until interface_up
@ -318,26 +319,25 @@ setup_multi_interface() {
set interfaces.1.dummy_address 127.0.1.$instance_number \
set interfaces.1.dummy_netmask 255.255.255.224 \
set interfaces.1.type wifi \
set interfaces.1.drop_unicasts on \
set interfaces.2.file dummyeth \
set interfaces.2.dummy_address 127.0.2.$instance_number \
set interfaces.2.dummy_netmask 255.255.255.224 \
set interfaces.2.type ethernet \
set interfaces.2.drop_unicasts on
set interfaces.2.type ethernet
foreach_instance +A +B start_routing_instance
}
multi_has_link() {
executeOk_servald route print
grep "^$1:BROADCAST UNICAST :dummyeth" $_tfw_tmp/stdout || return 1
return 0
}
doc_multi_interface="Multiple links of different types to the same neighbour"
test_multi_interface() {
foreach_instance +A +B \
wait_until has_seen_instances +A +B
sleep 5
set_instance +A
executeOk_servald route print
assertStdoutGrep --matches=1 "^$SIDB:BROADCAST :dummyeth"
wait_until multi_has_link $SIDB
set_instance +B
executeOk_servald route print
assertStdoutGrep --matches=1 "^$SIDA:BROADCAST :dummyeth"
wait_until multi_has_link $SIDA
}
setup_circle() {