summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-04-06 16:53:06 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2009-04-06 16:53:06 +0200
commitb722fe7ebdf7e11f097ed0a85302769de2ac10fb (patch)
treee62efe0d3749bcc447981772eb71ba8c107b67c7
parent8298d780be5a5b00c31c10a37a5f3a1353d6e234 (diff)
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.
-rw-r--r--proto/ospf/dbdes.c18
-rw-r--r--proto/ospf/dbdes.h2
-rw-r--r--proto/ospf/neighbor.c4
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)