On Fri, Feb 09, 2018 at 03:39:43AM +0100, Claudio Jeker wrote: > On netsplits it can happen that on join multiple ospfd end up as DR. > In my case with 3 routers the one cut off stays DR even though the rest of > the network already has a DR and BDR. > > Looking into this it seems that in some cases we don't issue an > IF_EVT_NBR_CHNG and so the re-evaluation of DR/BDR does not happen. > Looking at hello.c and the rfc seems to suggest that the following case is > currently not handled: > > o Bidirectional communication has been established to a > neighbor. In other words, the state of the neighbor has > transitioned to 2-Way or higher. > > The other cases in the RFC seem to be covered. > The following diff fixes this and seems to solve the problem I'm seeing. > > Since this is one of those bits that always caused trouble I would like > more tests and maybe someone is brave enough to OK the diff. > -- > :wq Claudio
I reproduced the issue you describe with VMs in vmm. To simulate a netsplit I just removed the tap interface from the bridge. The vio in the VM then still has link but can obviously not reach the others anymore. I verified that with your patch applied this problem is solved. No unwanted side effects happened in my testing setup. OK remi@ > > Index: hello.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ospfd/hello.c,v > retrieving revision 1.21 > diff -u -p -r1.21 hello.c > --- hello.c 18 Nov 2014 20:54:29 -0000 1.21 > +++ hello.c 9 Feb 2018 02:11:55 -0000 > @@ -188,7 +188,6 @@ recv_hello(struct iface *iface, struct i > nbr->dr.s_addr = hello.d_rtr; > nbr->bdr.s_addr = hello.bd_rtr; > nbr->priority = hello.rtr_priority; > - nbr_change = 1; > } > > /* actually the neighbor address shouldn't be stored on virtual links */ > @@ -201,8 +200,10 @@ recv_hello(struct iface *iface, struct i > memcpy(&nbr_id, buf, sizeof(nbr_id)); > if (nbr_id == ospfe_router_id()) { > /* seen myself */ > - if (nbr->state & NBR_STA_PRELIM) > + if (nbr->state & NBR_STA_PRELIM) { > nbr_fsm(nbr, NBR_EVT_2_WAY_RCVD); > + nbr_change = 1; > + } > break; > } > buf += sizeof(nbr_id);