Commit 917ea3ee authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Move hello history into a separate structure.

parent 58673129
......@@ -1117,7 +1117,7 @@ dump_tables(FILE *out)
"rtt %s rttcost %d chan %d%s.\n",
format_address(neigh->address),
neigh->ifp->name,
neigh->reach,
neigh->hello.reach,
neighbour_rxcost(neigh),
neigh->txcost,
format_thousands(neigh->rtt),
......
......@@ -160,7 +160,7 @@ local_notify_neighbour_1(struct local_socket *s,
(unsigned long int)neigh,
format_address(neigh->address),
neigh->ifp->name,
neigh->reach,
neigh->hello.reach,
neighbour_rxcost(neigh),
neighbour_txcost(neigh),
rttbuf,
......
......@@ -441,7 +441,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
if(message[2] & 0x80)
/* Unicast, ignored for now. */
goto done;
changed = update_neighbour(neigh, seqno, interval);
changed = update_neighbour(neigh, &neigh->hello, seqno, interval);
update_neighbour_metric(neigh, changed);
if(interval > 0)
/* Multiply by 3/2 to allow hellos to expire. */
......@@ -1837,7 +1837,7 @@ send_marginal_ihu(struct interface *ifp)
FOR_ALL_NEIGHBOURS(neigh) {
if(ifp && neigh->ifp != ifp)
continue;
if(neigh->txcost >= 384 || (neigh->reach & 0xF000) != 0xF000)
if(neigh->txcost >= 384 || (neigh->hello.reach & 0xF000) != 0xF000)
send_ihu(neigh, ifp);
}
}
......
......@@ -90,11 +90,11 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
return NULL;
}
neigh->hello_seqno = -1;
neigh->hello.seqno = -1;
memcpy(neigh->address, address, 16);
neigh->txcost = INFINITY;
neigh->ihu_time = now;
neigh->hello_time = zero;
neigh->hello.time = zero;
neigh->hello_rtt_receive_time = zero;
neigh->rtt_time = zero;
neigh->ifp = ifp;
......@@ -108,33 +108,34 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
/* Recompute a neighbour's rxcost. Return true if anything changed.
This does not call local_notify_neighbour, see update_neighbour_metric. */
int
update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
update_neighbour(struct neighbour *neigh, struct hello_history *hist,
int hello, int hello_interval)
{
int missed_hellos;
int rc = 0;
if(hello < 0) {
if(neigh->hello_interval <= 0)
if(hist->interval <= 0)
return rc;
missed_hellos =
((int)timeval_minus_msec(&now, &neigh->hello_time) -
neigh->hello_interval * 7) /
(neigh->hello_interval * 10);
((int)timeval_minus_msec(&now, &hist->time) -
hist->interval * 7) /
(hist->interval * 10);
if(missed_hellos <= 0)
return rc;
timeval_add_msec(&neigh->hello_time, &neigh->hello_time,
missed_hellos * neigh->hello_interval * 10);
timeval_add_msec(&hist->time, &hist->time,
missed_hellos * hist->interval * 10);
} else {
if(neigh->hello_seqno >= 0 && neigh->reach > 0) {
missed_hellos = seqno_minus(hello, neigh->hello_seqno) - 1;
if(hist->seqno >= 0 && hist->reach > 0) {
missed_hellos = seqno_minus(hello, hist->seqno) - 1;
if(missed_hellos < -8) {
/* Probably a neighbour that rebooted and lost its seqno.
Reboot the universe. */
neigh->reach = 0;
hist->reach = 0;
missed_hellos = 0;
rc = 1;
} else if(missed_hellos < 0) {
neigh->reach <<= -missed_hellos;
hist->reach <<= -missed_hellos;
missed_hellos = 0;
rc = 1;
}
......@@ -142,41 +143,41 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
missed_hellos = 0;
}
if(hello_interval != 0) {
neigh->hello_time = now;
neigh->hello_interval = hello_interval;
hist->time = now;
hist->interval = hello_interval;
}
}
if(missed_hellos > 0) {
neigh->reach >>= missed_hellos;
neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos);
hist->reach >>= missed_hellos;
hist->seqno = seqno_plus(hist->seqno, missed_hellos);
missed_hellos = 0;
rc = 1;
}
if(hello >= 0) {
neigh->hello_seqno = hello;
neigh->reach >>= 1;
neigh->reach |= 0x8000;
if((neigh->reach & 0xFC00) != 0xFC00)
hist->seqno = hello;
hist->reach >>= 1;
hist->reach |= 0x8000;
if((hist->reach & 0xFC00) != 0xFC00)
rc = 1;
}
/* Make sure to give neighbours some feedback early after association */
if((neigh->reach & 0xBF00) == 0x8000) {
if((hist->reach & 0xBF00) == 0x8000) {
/* A new neighbour */
send_hello(neigh->ifp);
} else {
/* Don't send hellos, in order to avoid a positive feedback loop. */
int a = (neigh->reach & 0xC000);
int b = (neigh->reach & 0x3000);
int a = (hist->reach & 0xC000);
int b = (hist->reach & 0x3000);
if((a == 0xC000 && b == 0) || (a == 0 && b == 0x3000)) {
/* Reachability is either 1100 or 0011 */
send_self_update(neigh->ifp);
}
}
if((neigh->reach & 0xFC00) == 0xC000) {
if((hist->reach & 0xFC00) == 0xC000) {
/* This is a newish neighbour, let's request a full route dump.
We ought to avoid this when the network is dense */
send_unicast_request(neigh, NULL, 0, NULL, 0);
......@@ -196,7 +197,7 @@ reset_txcost(struct neighbour *neigh)
return 0;
/* If we're losing a lot of packets, we probably lost an IHU too */
if(delay >= 180000 || (neigh->reach & 0xFFF0) == 0 ||
if(delay >= 180000 || (neigh->hello.reach & 0xFFF0) == 0 ||
(neigh->ihu_interval > 0 &&
delay >= neigh->ihu_interval * 10 * 10)) {
neigh->txcost = INFINITY;
......@@ -224,11 +225,11 @@ check_neighbours()
neigh = neighs;
while(neigh) {
changed = update_neighbour(neigh, -1, 0);
changed = update_neighbour(neigh, &neigh->hello, -1, 0);
if(neigh->reach == 0 ||
neigh->hello_time.tv_sec > now.tv_sec || /* clock stepped */
timeval_minus_msec(&now, &neigh->hello_time) > 300000) {
if(neigh->hello.reach == 0 ||
neigh->hello.time.tv_sec > now.tv_sec || /* clock stepped */
timeval_minus_msec(&now, &neigh->hello.time) > 300000) {
struct neighbour *old = neigh;
neigh = neigh->next;
flush_neighbour(old);
......@@ -240,8 +241,8 @@ check_neighbours()
update_neighbour_metric(neigh, changed);
if(neigh->hello_interval > 0)
msecs = MIN(msecs, neigh->hello_interval * 10);
if(neigh->hello.interval > 0)
msecs = MIN(msecs, neigh->hello.interval * 10);
if(neigh->ihu_interval > 0)
msecs = MIN(msecs, neigh->ihu_interval * 10);
neigh = neigh->next;
......@@ -254,9 +255,9 @@ unsigned
neighbour_rxcost(struct neighbour *neigh)
{
unsigned delay;
unsigned short reach = neigh->reach;
unsigned short reach = neigh->hello.reach;
delay = timeval_minus_msec(&now, &neigh->hello_time);
delay = timeval_minus_msec(&now, &neigh->hello.time);
if((reach & 0xFFF0) == 0 || delay >= 180000) {
return INFINITY;
......
......@@ -20,16 +20,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct hello_history {
unsigned short reach;
unsigned short interval; /* in centiseconds */
int seqno;
struct timeval time;
};
struct neighbour {
struct neighbour *next;
/* This is -1 when unknown, so don't make it unsigned */
int hello_seqno;
unsigned char address[16];
unsigned short reach;
struct hello_history hello;
unsigned short txcost;
struct timeval hello_time;
struct timeval ihu_time;
unsigned short hello_interval; /* in centiseconds */
unsigned short ihu_interval; /* in centiseconds */
/* Used for RTT estimation. */
/* Absolute time (modulo 2^32) at which the Hello was sent,
......@@ -50,7 +54,8 @@ int neighbour_valid(struct neighbour *neigh);
void flush_neighbour(struct neighbour *neigh);
struct neighbour *find_neighbour(const unsigned char *address,
struct interface *ifp);
int update_neighbour(struct neighbour *neigh, int hello, int hello_interval);
int update_neighbour(struct neighbour *neigh, struct hello_history *hist,
int hello, int hello_interval);
unsigned check_neighbours(void);
unsigned neighbour_txcost(struct neighbour *neigh);
unsigned neighbour_rxcost(struct neighbour *neigh);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment