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:
parent
8298d780be
commit
b722fe7ebd
3 changed files with 12 additions and 12 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue