FortiOS: OSPF graceful restart#3529
Conversation
|
Rather than rejecting configuration that enables an unsupported combination, I would suggest a warning stating that FortiOS cannot enable one without the other We’re not talking about an operational commitment, most users are simply testing out capabilities and considering options Yes it’s important to make clear what works and what doesn’t, but I would prefer defaulting to “ok, but be aware that …” |
Sorry, I'm not sure if I understand. And then what? Which configuration would actually be deployed?
Which, in my opinion, does not reduce the need to fail fast and loudly.
I haven't seen any guidelines or built-in mechanism for handling unsupported configurations. So I'd make a judgment call based on the following loosely defined rules:
|
ipspace
left a comment
There was a problem hiding this comment.
The code has a distinct AI-generated feel to it. While it's technically correct, it's also unnecessarily verbose, and the same goes for caveats.
I've learned the hard way that I can't expect the code authors to take care of their code indefinitely, so I lean toward having code that's easier to understand for other humans.
Also, keep things simple. FortiOS cannot configure GR + GR helper functionality separately. No big deal (it's probably not the only device with that approach), but there's no need to make a detailed drama out of it.
| device cannot honour, leaving the restart role (which a helper rides along with) to render. | ||
| """ | ||
| for o_data,_,vname in _routing.rp_data(node,'ospf'): | ||
| gr = o_data.get('gr',None) |
There was a problem hiding this comment.
I would just continue to the next instance if "not gr"
| """ | ||
| for o_data,_,vname in _routing.rp_data(node,'ospf'): | ||
| gr = o_data.get('gr',None) | ||
| restart_on = isinstance(gr,dict) and 'restart' in gr # restart role explicitly enabled |
There was a problem hiding this comment.
Unnecessary, check it once and be done with it.
| gr = o_data.get('gr',None) | ||
| restart_on = isinstance(gr,dict) and 'restart' in gr # restart role explicitly enabled | ||
| helper_on = isinstance(gr,dict) and 'helper' in gr # helper role explicitly enabled | ||
| helper_off = removed_attributes(o_data,'gr.helper') # helper role explicitly disabled |
There was a problem hiding this comment.
After figuring out that the user wanted OSPF GR, I would just check if 'helper' and 'restart' are both present (and the validation code takes care of the details).
If one of them is missing, you have two options:
- Display an error saying "both have to be enabled for OSPF GR to work"
- Display a warning saying "we need both, so I have enabled one of them", enable it, and move on.
| * FortiOS accepts the graceful restart timers in the 1-3600 second range. A value of 0 (allowed by the _netlab_ schema) is rejected by the device during configuration deployment. | ||
| * Enabling graceful restart on any BGP neighbor also enables the global FortiOS **graceful-restart** switch, which preserves the forwarding state across a routing restart. Advertising the capability without it would announce forwarding-state preservation the device does not deliver. | ||
|
|
||
| OSPF graceful restart (**ospf.gr**): |
There was a problem hiding this comment.
We don't need to turn caveats into a novel. A simple bullet along the lines of "FortiOS enables OSPF Graceful Restart and helper functionality at the same time" would be enough.
We need to look at more platforms, but if it turns out that helper.grace_period is rare (although it makes sense from an implementation perspective, just like BGP weights do), then we have to document that in the OSPF document.
Imagine a user who configures I think the average user would be fine with enabling both in that situation. "unsupported" is too harsh in this situation, IMHO. Power users could still explicitly configure |
Not any longer, now it would be
I think it's important to let people know what's going on behind the scenes. If we can make things work without a major impact, then we should create a warning (which can be disabled). If a device has a limitation that would result in a configuration error or some such, then we should throw an error. However, while I think it's crucial we never do unexpected stuff behind the scenes, I wouldn't worry too much about generating just-the-right error message when a more generic one is understandable (and easier on us). In this example, "we have to enable GR and GR helper on FortiOS" is probably good enough, and we don't need "you enabled GR, but I enabled GR helper for you" together with "you enabled GR helper, but I can't do that without enabling GR, so I did that". |
Renders the OSPF graceful restart configuration introduced by the core ospf.gr attribute (ipspace#3490) on FortiOS, for both OSPFv2 and OSPFv3. FortiOS configures graceful restart with a single keyword, 'set restart-mode graceful-restart', in each of its two OSPF processes -- 'config router ospf' (OSPFv2) and 'config router ospf6' (OSPFv3), which netlab addresses as the IPv4 and IPv6 address families of its OSPF module. That one switch makes the device both a restarting router and a graceful-restart helper; the two roles cannot be configured independently. Because the roles are coupled, a device quirk rejects the two combinations FortiOS cannot honour: - helper enabled without restart: FortiOS would have to make the restart promise (preserve forwarding state across its own restart) that the user did not request. A helper is benign assistance to a neighbour, but restart is a commitment, so the helper role must not silently pull in restart. - restart enabled with helper explicitly disabled: the roles share one switch, so the request is unsatisfiable. A node that enables ospf.gr.restart therefore also acts as a helper. The quirk reads the explicit-disable intent through data.removed_attributes, since _remove_when_false records a cleared sub-key in _removed_attr rather than discarding it. ospf.gr.restart.grace_period maps to 'restart-period' (device range 1-3600, default 120), the grace period the restarting router advertises in its Grace-LSA. ospf.gr.helper.grace_period has no standard counterpart: RFC 3623 and RFC 5187 define only the restarting router's grace period, not a helper-side limit (that is an FRR-specific knob), so it is not rendered. restart-on-topology-change is left at the FortiOS default. The device feature ospf.gr is declared for both address families ([ ipv4, ipv6 ]) so the core check_gr validation admits FortiOS nodes, and docs/module/ospf.md marks FortiOS as supporting OSPF graceful restart. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
I replaced PR description, hope it is more readable. I made some changes through a separate commit, not sure if it is objectively better. I removed the new FortiOS OSPF graceful-restart caveat. The previous text tried to explain the restart/helper distinction, the FortiOS The essential FortiOS fact is already captured by the implementation and the PR |
Summary
Render OSPF graceful restart on Fortinet FortiOS for OSPFv2 and OSPFv3.
FortiOS uses one CLI switch,
set restart-mode graceful-restart, under bothconfig router ospfandconfig router ospf6. That switch enables theFortiOS graceful-restart behavior; FortiOS does not expose independent restart
and helper controls.
The netlab OSPF model is more explicit:
ospf.gr.restartandospf.gr.helperare separate attributes. The FortiOS quirk therefore appliesthis matrix:
restart\helperThe asymmetric handling is intentional. Enabling OSPF graceful restart on
FortiOS necessarily enables helper behavior, which is compatible with the RFC
model. The reverse is not safe: a helper-only request must not enable restart,
because restart requires the device to preserve forwarding state across its own
OSPF restart.
ospf.gr.restart.grace_periodmaps to FortiOSrestart-period.ospf.gr.helper.grace_periodis a helper-side local policy limit. RFC 3623allows such local policy, for example to "never allow the grace period to
exceed a Time T", but FortiOS has no corresponding configuration knob, so
netlab warns when this attribute is used on FortiOS.
Testing
combinations.
ospf.gr: Trueandospf.gr.restart: Truetransforminto
ospf.gr.restart: {}and are accepted by the FortiOS quirk.role because the shared upstream helper-only graceful-restart test is not
directly representable on FortiOS.