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.
This commit is contained in:
Ondrej Zajicek 2009-04-06 16:53:06 +02:00
parent 8298d780be
commit b722fe7ebd
3 changed files with 12 additions and 12 deletions

View file

@ -35,6 +35,7 @@ static void ospf_dump_dbdes(struct proto *p, struct ospf_dbdes_packet *pkt)
/** /**
* ospf_dbdes_send - transmit database description packet * ospf_dbdes_send - transmit database description packet
* @n: neighbor * @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. * 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. * 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. * of the buffer.
*/ */
void void
ospf_dbdes_send(struct ospf_neighbor *n) ospf_dbdes_send(struct ospf_neighbor *n, int next)
{ {
struct ospf_dbdes_packet *pkt; struct ospf_dbdes_packet *pkt;
struct ospf_packet *op; struct ospf_packet *op;
@ -77,10 +78,9 @@ ospf_dbdes_send(struct ospf_neighbor *n)
case NEIGHBOR_EXCHANGE: case NEIGHBOR_EXCHANGE:
n->myimms.bit.i = 0; n->myimms.bit.i = 0;
if (((n->myimms.bit.ms) && (n->dds == n->ddr + 1)) || if (next)
((!(n->myimms.bit.ms)) && (n->dds == n->ddr)))
{ {
snode *sn; /* Send next */ snode *sn;
struct ospf_lsa_header *lsa; struct ospf_lsa_header *lsa;
pkt = n->ldbdes; pkt = n->ldbdes;
@ -254,7 +254,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
n->imms.byte = ps->imms.byte; n->imms.byte = ps->imms.byte;
OSPF_TRACE(D_PACKETS, "I'm slave to %I.", n->ip); OSPF_TRACE(D_PACKETS, "I'm slave to %I.", n->ip);
ospf_neigh_sm(n, INM_NEGDONE); ospf_neigh_sm(n, INM_NEGDONE);
ospf_dbdes_send(n); ospf_dbdes_send(n, 1);
break; break;
} }
@ -283,7 +283,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
if (n->myimms.bit.ms == 0) if (n->myimms.bit.ms == 0)
{ {
/* Slave should retransmit dbdes packet */ /* Slave should retransmit dbdes packet */
ospf_dbdes_send(n); ospf_dbdes_send(n, 0);
} }
return; return;
} }
@ -334,7 +334,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
} }
else 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->ddr = ntohl(ps->ddseq);
n->dds = ntohl(ps->ddseq); n->dds = ntohl(ps->ddseq);
ospf_dbdes_reqladd(ps, n); ospf_dbdes_reqladd(ps, n);
ospf_dbdes_send(n); ospf_dbdes_send(n, 1);
} }
break; break;
@ -364,7 +364,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
if (n->myimms.bit.ms == 0) if (n->myimms.bit.ms == 0)
{ {
/* Slave should retransmit dbdes packet */ /* Slave should retransmit dbdes packet */
ospf_dbdes_send(n); ospf_dbdes_send(n, 0);
} }
return; return;
} }

View file

@ -10,7 +10,7 @@
#ifndef _BIRD_OSPF_DBDES_H_ #ifndef _BIRD_OSPF_DBDES_H_
#define _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, void ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n); struct ospf_iface *ifa, struct ospf_neighbor *n);

View file

@ -643,12 +643,12 @@ rxmt_timer_hook(timer * timer)
if (n->state == NEIGHBOR_EXSTART) if (n->state == NEIGHBOR_EXSTART)
{ {
ospf_dbdes_send(n); ospf_dbdes_send(n, 1);
return; return;
} }
if ((n->state == NEIGHBOR_EXCHANGE) && n->myimms.bit.ms) /* I'm master */ 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) if (n->state < NEIGHBOR_FULL)