Commit b722fe7e authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

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.
parent 8298d780
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -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;
    }
+1 −1
Original line number Diff line number Diff line
@@ -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);

+2 −2
Original line number Diff line number Diff line
@@ -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)