ospfd: fix DR stuck at 0.0.0.0 after a router ID change on a broadcast network#22625
ospfd: fix DR stuck at 0.0.0.0 after a router ID change on a broadcast network#22625olasupo wants to merge 1 commit into
Conversation
When the OSPF router-id changes, ospf_process_refresh_data() resets each interface self neighbor via ospf_nbr_self_reset(), which clears the cached DR/BDR. On a multi-access (broadcast/NBMA) network the change was then applied with a soft interface update (ospf_if_update()) that does not re-run the interface state machine, so the DR/BDR stayed 0.0.0.0 and the router originated a Network-LSA with a Link State ID of 0.0.0.0, breaking SPF. Reset the interface state machine, as is already done for "clear ip ospf process", on a genuine router-id change so the DR is re-elected and the Network-LSA re-originated. The initial router-id assignment (from INADDR_ANY) is unaffected. Add a topotest that changes a broadcast DR router-id and checks the interface DR and Network-LSA remain valid. Signed-off-by: Olasupo Okunaiya <olasupo.o@gmail.com>
Greptile SummaryThis PR fixes OSPF DR state after a router ID change on a broadcast network. The main changes are:
Confidence Score: 5/5This looks safe to merge after considering whether the reset should be narrower.
ospfd/ospfd.c Important Files Changed
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
ospfd/ospfd.c:262-265
**Router-ID Change Flaps All Interfaces**
When zebra reports a non-initial router-ID change, this condition now runs a full down/up reset for every OSPF interface in the VRF. The reported failure only needs the interface state machine to re-run where DR/BDR state matters, but this also tears down point-to-point, passive, and other unaffected interfaces, which can drop adjacencies or abort graceful-restart helper state during an otherwise soft router-ID refresh.
Reviews (1): Last reviewed commit: "ospfd: re-elect DR after a router-id cha..." | Re-trigger Greptile |
| if (reset | ||
| || (rid_change | ||
| && router_id_old.s_addr != INADDR_ANY)) | ||
| ospf_if_reset(ifp); |
There was a problem hiding this comment.
Router-ID Change Flaps All Interfaces
When zebra reports a non-initial router-ID change, this condition now runs a full down/up reset for every OSPF interface in the VRF. The reported failure only needs the interface state machine to re-run where DR/BDR state matters, but this also tears down point-to-point, passive, and other unaffected interfaces, which can drop adjacencies or abort graceful-restart helper state during an otherwise soft router-ID refresh.
Prompt To Fix With AI
This is a comment left during a code review.
Path: ospfd/ospfd.c
Line: 262-265
Comment:
**Router-ID Change Flaps All Interfaces**
When zebra reports a non-initial router-ID change, this condition now runs a full down/up reset for every OSPF interface in the VRF. The reported failure only needs the interface state machine to re-run where DR/BDR state matters, but this also tears down point-to-point, passive, and other unaffected interfaces, which can drop adjacencies or abort graceful-restart helper state during an otherwise soft router-ID refresh.
How can I resolve this? If you propose a fix, please make it concise.
Fixes #22250
The issue report already traces this to the self neighbor reset, and that matches what I found when I walked through the code.
When the OSPF router ID changes, ospf_process_refresh_data() calls ospf_nbr_self_reset() on every interface. That rebuilds the self neighbor and clears the cached DR and BDR. On a broadcast or NBMA network the change is then applied with a soft interface update, ospf_if_update(), which does not run the interface state machine again. So the DR and BDR stay at 0.0.0.0, and the router goes on to originate a Network LSA with a Link State ID of 0.0.0.0, which breaks SPF on that segment. Running "clear ip ospf process" recovers it, because that path does reset the interfaces.
The fix resets the interface state machine on a genuine router ID change, the same thing "clear ip ospf process" already does, so the DR is elected again and the Network LSA is originated again. The first assignment of the router ID, which comes from INADDR_ANY, still uses the soft update, so startup is left alone.
Testing
I added a topotest under tests/topotests/ospf_rid_change_dr. Two routers sit on a broadcast LAN, one becomes the DR, and then its router ID is changed by adding a loopback address so that zebra hands OSPF a new ID while the adjacency is up. The test then checks that the interface DR and the Network LSA are still valid.
With the fix the topotest passes. Reverting only the fix makes it fail with the interface DR left at 0.0.0.0, which is the reported symptom. I also ran ospf_single_switch, ospf_basic_functionality/test_ospf_lan, the flood reduction test that changes the router ID at runtime, and ospf_multi_instance, and they all pass. checkpatch is clean.