Hello list!
There is a "bug" in hello validation code causing neighbor to stuck in
"exstart" state forever in case of router id change.
RFC 2328 tells us to rely on neighbor source address for
Broadcast/PtMP/MBMA links (10.5).
No special checks are required for the router id (the same, 10.5).
So, the problem can easily be repeated with 2 bird instances:
B1 (rtr-id 1.2.3.22)
B2 (rtr-id 1.2.3.20)
Configure OSPFv2 on some shared medium, wait until they become adjacent
(actually, FULL)
Change B2 rtr-id to 1.2.3.200 and perform re-configure.
Bird then (like any other good implementation) will send new hello
without any neighbors in it,
so B1 changes its state to "Down".
When going to 'exstart' state the following problem occurs:
B1 "remembers" old rtr-id (which is smaller than B1's) so it assumes B2
to be the master.
B2 by the same rules assumes B1 is the master, so they start infinite
DBDES ping-pong every RxmitInterval seconds (10.8)
Patch to fix this behavior attached.
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index d5aa1b9..58e87bb 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -101,6 +101,17 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct
ospf_iface *ifa,
return;
}
+#ifdef OSPFv2
+ if (n && (n->rid != ntohl(ps_i->routerid)))
+ {
+ OSPF_TRACE(D_EVENTS,
+ "Neighbor %I has changed router id from %R to %R.",
+ n->ip, n->rid, ntohl(ps_i->routerid));
+ ospf_neigh_remove(n);
+ n = NULL;
+ }
+#endif
+
if (!n)
{
if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
@@ -132,7 +143,7 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct
ospf_iface *ifa,
n = ospf_neighbor_new(ifa);
- n->rid = ntohl(((struct ospf_packet *) ps)->routerid);
+ n->rid = ntohl(ps_i->routerid);
n->ip = faddr;
n->dr = ntohl(ps->dr);
n->bdr = ntohl(ps->bdr);