From b722fe7ebdf7e11f097ed0a85302769de2ac10fb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 6 Apr 2009 16:53:06 +0200 Subject: [PATCH] Fixes bug in OSPF packet retransmission. If a DBDES packet from a master to a slave is lost, then the old code does not retransmit it and instead send a next one with the same sequence number. That leads to silent desynchronization of LSA databases. --- proto/ospf/dbdes.c | 18 +++++++++--------- proto/ospf/dbdes.h | 2 +- proto/ospf/neighbor.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 4f7ebb7a..c190fe75 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -35,6 +35,7 @@ static void ospf_dump_dbdes(struct proto *p, struct ospf_dbdes_packet *pkt) /** * ospf_dbdes_send - transmit database description packet * @n: neighbor + * @next: whether to send a next packet in a sequence (1) or to retransmit the old one (0) * * Sending of a database description packet is described in 10.6 of RFC 2328. * Reception of each packet is acknowledged in the sequence number of another. @@ -43,7 +44,7 @@ static void ospf_dump_dbdes(struct proto *p, struct ospf_dbdes_packet *pkt) * of the buffer. */ void -ospf_dbdes_send(struct ospf_neighbor *n) +ospf_dbdes_send(struct ospf_neighbor *n, int next) { struct ospf_dbdes_packet *pkt; struct ospf_packet *op; @@ -77,10 +78,9 @@ ospf_dbdes_send(struct ospf_neighbor *n) case NEIGHBOR_EXCHANGE: n->myimms.bit.i = 0; - if (((n->myimms.bit.ms) && (n->dds == n->ddr + 1)) || - ((!(n->myimms.bit.ms)) && (n->dds == n->ddr))) + if (next) { - snode *sn; /* Send next */ + snode *sn; struct ospf_lsa_header *lsa; pkt = n->ldbdes; @@ -254,7 +254,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps, n->imms.byte = ps->imms.byte; OSPF_TRACE(D_PACKETS, "I'm slave to %I.", n->ip); ospf_neigh_sm(n, INM_NEGDONE); - ospf_dbdes_send(n); + ospf_dbdes_send(n, 1); break; } @@ -283,7 +283,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps, if (n->myimms.bit.ms == 0) { /* Slave should retransmit dbdes packet */ - ospf_dbdes_send(n); + ospf_dbdes_send(n, 0); } return; } @@ -334,7 +334,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps, } else { - ospf_dbdes_send(n); + ospf_dbdes_send(n, 1); } } @@ -350,7 +350,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps, n->ddr = ntohl(ps->ddseq); n->dds = ntohl(ps->ddseq); ospf_dbdes_reqladd(ps, n); - ospf_dbdes_send(n); + ospf_dbdes_send(n, 1); } break; @@ -364,7 +364,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps, if (n->myimms.bit.ms == 0) { /* Slave should retransmit dbdes packet */ - ospf_dbdes_send(n); + ospf_dbdes_send(n, 0); } return; } diff --git a/proto/ospf/dbdes.h b/proto/ospf/dbdes.h index c5ffe590..af962928 100644 --- a/proto/ospf/dbdes.h +++ b/proto/ospf/dbdes.h @@ -10,7 +10,7 @@ #ifndef _BIRD_OSPF_DBDES_H_ #define _BIRD_OSPF_DBDES_H_ -void ospf_dbdes_send(struct ospf_neighbor *n); +void ospf_dbdes_send(struct ospf_neighbor *n, int next); void ospf_dbdes_receive(struct ospf_dbdes_packet *ps, struct ospf_iface *ifa, struct ospf_neighbor *n); diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index d417ed08..6e72764e 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -643,12 +643,12 @@ rxmt_timer_hook(timer * timer) if (n->state == NEIGHBOR_EXSTART) { - ospf_dbdes_send(n); + ospf_dbdes_send(n, 1); return; } if ((n->state == NEIGHBOR_EXCHANGE) && n->myimms.bit.ms) /* I'm master */ - ospf_dbdes_send(n); + ospf_dbdes_send(n, 0); if (n->state < NEIGHBOR_FULL)