Skip to content

ospfd: fix DR stuck at 0.0.0.0 after a router ID change on a broadcast network#22625

Open
olasupo wants to merge 1 commit into
FRRouting:masterfrom
olasupo:ospf-ridchange-dr-election
Open

ospfd: fix DR stuck at 0.0.0.0 after a router ID change on a broadcast network#22625
olasupo wants to merge 1 commit into
FRRouting:masterfrom
olasupo:ospf-ridchange-dr-election

Conversation

@olasupo

@olasupo olasupo commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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.

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-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes OSPF DR state after a router ID change on a broadcast network. The main changes are:

  • Reset interface state on non-initial router-ID changes.
  • Keep startup router-ID assignment on the soft update path.
  • Add a topotest that changes r1's router ID and checks DR and Network-LSA state.
  • Add r1/r2 configs for the new broadcast LAN test.

Confidence Score: 5/5

This looks safe to merge after considering whether the reset should be narrower.

  • The main DR recovery path is addressed.
  • The new test covers the reported broadcast-network failure.
  • The only follow-up is possible extra interface churn on router-ID changes.

ospfd/ospfd.c

Important Files Changed

Filename Overview
ospfd/ospfd.c Changes router-ID refresh handling to run a full interface reset after non-initial router-ID changes.
tests/topotests/ospf_rid_change_dr/test_ospf_rid_change_dr.py Adds a focused topotest for DR re-election and Network-LSA validity after a zebra-driven router-ID change.
tests/topotests/ospf_rid_change_dr/r1/frr.conf Adds r1 OSPF configuration with higher priority so r1 becomes DR on the test LAN.
tests/topotests/ospf_rid_change_dr/r2/frr.conf Adds r2 OSPF configuration with priority 0 for the test LAN.
Prompt To Fix All With AI
Fix 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

Comment thread ospfd/ospfd.c
Comment on lines +262 to 265
if (reset
|| (rid_change
&& router_id_old.s_addr != INADDR_ANY))
ospf_if_reset(ifp);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] The DR/BDR of an interface is set to 0 after the OSPF router ID changes

1 participant