Skip to content

ospfd: add instance shutdown command - #21759

Merged
riw777 merged 4 commits into
FRRouting:masterfrom
opensourcerouting:ospf-shutdown-v2
May 5, 2026
Merged

ospfd: add instance shutdown command#21759
riw777 merged 4 commits into
FRRouting:masterfrom
opensourcerouting:ospf-shutdown-v2

Conversation

@rzalamena

Copy link
Copy Markdown
Member

Introduce the shutdown OSPFv2 instance command to temporally disable an instance and remove all state.

This new command also has the extended functionality when used with graceful restart: it sends grace LSAs to all OSPF enabled interfaces to enable non stop forwarding while the instance is shutdown.

@frrbot frrbot Bot added bugfix ospf tests Topotests, make check, etc labels Apr 23, 2026
@greptile-apps

greptile-apps Bot commented Apr 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces a shutdown VTY command for OSPFv2 instances that administratively disables the instance and clears all state, with optional graceful-restart support (grace LSAs sent before teardown to enable non-stop forwarding on helpers). The implementation is well-structured: it correctly guards ospf_if_up against re-entrancy during shutdown, blocks zebra route updates while shut down, adds an opaque-capability pre-check for the GR path, and includes a comprehensive topotest suite covering both plain and GR-assisted shutdown/restart cycles.

Confidence Score: 4/5

Mostly safe to merge; three P2 findings around ISM execution timing, GR timer/state interaction during shutdown, and excess AdjOK? events warrant review before landing.

All three findings are P2 (non-blocking style/correctness suggestions). The SCHEDULE→EXECUTE change in ospf_if_up is the most impactful as it affects all existing callers, not just the new shutdown path, and the interaction between the GR grace-period timer and the shutdown state could produce inelegant state-machine transitions. Score of 4 reflects that these are worth discussing before merge rather than hard blockers.

ospfd/ospf_interface.c (EXECUTE change scope), ospfd/ospfd.c (GR timer during shutdown), ospfd/ospf_ism.c (unconditional DR change during GR)

Important Files Changed

Filename Overview
ospfd/ospfd.c New ospf_shutdown() function: sets/clears OSPF_SHUTDOWN flag, tears down interfaces and LSDB on shutdown, spins up interfaces and reoriginates AS-external LSAs on restart. Grace-period timer interaction during extended shutdown is a concern.
ospfd/ospf_vty.c New ospf_instance_shutdown DEFPY with opaque-capability guard for GR path, config-write support for the shutdown keyword, and proper no shutdown path.
ospfd/ospf_interface.c Added OSPF_SHUTDOWN guard in ospf_if_up; also changed SCHEDULE→EXECUTE for ISM events, affecting all existing callers beyond the new shutdown feature.
ospfd/ospf_ism.c Modified ospf_dr_election to always call ospf_dr_change when restart_in_progress; may generate excess AdjOK? events on every DR election across all interface types.
ospfd/ospf_gr.c Extended ospf_gr_lsa_originate to treat OSPF_GR_SWITCH_CONTROL_PROCESSOR like OSPF_GR_UNKNOWN_RESTART for neighbor-count skip and unplanned flooding paths; correct per RFC 3623 Β§5.
ospfd/ospf_gr.h Renamed enum value OSPF_GR_SWITCH_REDUNDANT_CARD β†’ OSPF_GR_SWITCH_CONTROL_PROCESSOR; no remaining references to the old name were found in the codebase.
ospfd/ospf_asbr.c New ospf_asbr_reoriginate() correctly iterates all external routes and instances, checking connectivity before reoriginating on no shutdown.
ospfd/ospf_zebra.c Added OSPF_SHUTDOWN guard in ospf_zebra_read_route to suppress zebra route processing while the instance is shut down.
tests/topotests/ospf_shutdown/test_ospf_shutdown.py New topotest covering basic shutdown, shutdown+no-shutdown adjacency recovery, and GR-assisted shutdown with grace LSA verification.

Sequence Diagram

sequenceDiagram
    participant Operator
    participant ospf_vty
    participant ospf_gr
    participant ospfd
    participant ospf_interface
    participant Zebra

    Operator->>ospf_vty: shutdown (with GR)
    ospf_vty->>ospf_vty: check OSPF_OPAQUE_CAPABLE
    ospf_vty->>ospf_gr: ospf_gr_restart_enter(SWITCH_CONTROL_PROCESSOR, now+grace_period)
    ospf_gr->>ospf_gr: restart_in_progress=true, start grace timer
    ospf_vty->>ospf_gr: ospf_gr_unplanned_start_interface(oi) per interface
    ospf_gr-->>ospf_vty: Grace-LSAs flooded to all interfaces
    ospf_vty->>ospfd: ospf_shutdown(ospf, true)
    ospfd->>ospfd: SET_FLAG OSPF_SHUTDOWN
    ospfd->>ospf_interface: ospf_if_down(oi) per interface
    ospfd->>ospfd: ospf_area_lsdb_discard_delete + lsdb_delete_all
    Note over ospf_gr: Grace period timer running...
    Operator->>ospf_vty: no shutdown
    ospf_vty->>ospfd: ospf_shutdown(ospf, false)
    ospfd->>ospfd: UNSET_FLAG OSPF_SHUTDOWN
    ospfd->>ospf_interface: ospf_if_up(oi) per interface [EXECUTE]
    ospf_interface->>ospf_interface: ISM_InterfaceUp (synchronous)
    ospfd->>ospfd: ospf_asbr_reoriginate()
    ospfd-->>Zebra: AS-external LSAs re-flooded
    ospf_gr->>ospf_gr: GR completes when adjacencies restored or grace period expires
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: ospfd/ospf_interface.c
Line: 857-866

Comment:
**`OSPF_ISM_EVENT_EXECUTE` changes behavior for all existing callers**

The switch from `OSPF_ISM_EVENT_SCHEDULE` (`event_add_event`) to `OSPF_ISM_EVENT_EXECUTE` (`event_execute`) affects every call site of `ospf_if_up`, not just the new shutdown/restart path. Existing callers such as `ospf_router_id_update` (ospfd.c:1118) and the internal down→up cycle at ospf_interface.c:175 now run the ISM state machine synchronously and re-entrantly, whereas before each ISM transition was deferred to the next event-loop iteration. If any of those callers hold shared state that the ISM handler mutates (e.g., neighbor lists, adjacency state), the in-place execution could cause subtle ordering differences. The new `OSPF_SHUTDOWN` guard added on the same line is clearly necessary; the EXECUTE change should be split out and justified separately if intentional for all call sites.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ospfd/ospfd.c
Line: 2408-2425

Comment:
**Grace period timer can fire while OSPF instance is still shut down**

When `shutdown` is issued with GR enabled, `ospf_gr_restart_enter` starts a grace-period countdown timer (`t_grace_period`). If `no shutdown` is never issued (or is delayed beyond the grace period), `ospf_gr_grace_period_expired` fires while `OSPF_SHUTDOWN` is set and calls `ospf_gr_restart_exit`. That function calls `ospf_router_lsa_update_area` on every area (LSDB was just cleared) and schedules `ospf_spf_calculate_schedule(ospf, SPF_FLAG_GR_FINISH)` while setting `gr_info.finishing_restart = true`. If `no shutdown` is then issued after the timer has already fired, the instance starts with `restart_in_progress = false` and `finishing_restart` potentially still set, causing the GR-finish SPF to race with normal startup SPF runs. Adding a guard in `ospf_gr_grace_period_expired` (or `ospf_gr_restart_exit`) that skips the restart-exit logic when `OSPF_SHUTDOWN` is set would make the state machine cleaner.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ospfd/ospf_ism.c
Line: 232-234

Comment:
**`ospf_dr_change` triggered on every DR election during GR restart**

Adding `|| oi->ospf->gr_info.restart_in_progress` to the condition means `ospf_dr_change` (and consequently `ospf_nbr_adj_ok` for every neighbor) is called on every invocation of `ospf_dr_election` while the instance is in GR restart β€” even on point-to-point links or when there are no neighbors. On a busy topology this produces spurious AdjOK? events per DR election cycle until `restart_in_progress` is cleared. Consider narrowing the condition to broadcast/NBMA interfaces where DR election actually matters, or only triggering when neighbors are present (`ospf_interface_neighbor_count(oi) > 0`).

How can I resolve this? If you propose a fix, please make it concise.

Reviews (3): Last reviewed commit: "tests: topology test for OSPFv2 shutdown" | Re-trigger Greptile

Comment thread ospfd/ospfd.c Outdated
Comment thread ospfd/ospf_asbr.c
Comment thread ospfd/ospf_vty.c
@rzalamena

Copy link
Copy Markdown
Member Author

@greptileai

rwestphal and others added 4 commits April 23, 2026 21:34
Implement a shutdown command that stops the OSPFv2 instance and gets rid
of all state. It also triggers the OSPFv2 graceful restart if
configured.

Rename the definition `OSPF_GR_SWITCH_REDUNDANT_CARD` to
`OSPF_GR_SWITCH_CONTROL_PROCESSOR` to match the RFC 3623 specification.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Once an interface becomes ready to start, there's no need to
schedule the "LoopInd" and "InterfaceUp" events, they can be
triggered immediately.

This solves a race condition where an OSPF interface could start
after the OSPF instance was disabled with the "shutdown" command,
since the `ospf_shutdown()` function has no way to cancel scheduled
ISM events.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
When all neighbors in a broadcast segment have their router priority
set to zero, the restarting router won't detect any BDR change when
coming back up. It should also preserve its DR status, so it won't
detect any DR change.  Without detecting any DR/BDR change during the
DR election process, the router won't trigger the AdjOk event which
is necessary to move forward in the neighbor state machine.

To fix this problem, always trigger the AdjOk event at the end of
the DR election process when GR is in progress.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Test the new OSPFv2 shutdown feature. The topology tests the following
cases:
 1. Regular OSPFv2 instance shutdown
 2. OSPFv2 instance shutdown with graceful restart

The difference between the cases is that when graceful restart is
enabled the OSPFv2 instance sends a grace LSA in all OSPF enabled
interfaces so the helper routers keep the routes until the instance
is not shutdown anymore.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
@rzalamena

Copy link
Copy Markdown
Member Author

@greptileai

@riw777 riw777 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good

@riw777
riw777 merged commit e21ef8f into FRRouting:master May 5, 2026
24 checks passed
@rzalamena
rzalamena deleted the ospf-shutdown-v2 branch May 6, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants