One of four independent issues improving multi-node FIP failover speed
(BFD visibility/management, active drain handshake, standby pre-staging,
failover hot-path tightening). They can be implemented in any order.
Problem
A standby gateway node programs nothing — HasLocalRouters == false drives
removeAllRoutes in reconcile (agent.go:378). On failover the takeover
node must rebuild the kernel /32 routes, the OVS flows and the FRR/BGP
announcement, all on the critical path.
Proposal
Pre-program the data plane (kernel routes + OVS flows) for routers this
node is a standby for, without announcing them via BGP. Config-gated,
default off.
- New
StandbyRouters in OVNState. Routers for which this chassis has
a Gateway_Chassis row (priority ≥ 1) whose chassisredirect port is
bound elsewhere. refreshState already reads SB Port_Binding and NB
Gateway_Chassis (see ovn.go and EnsureActivePriorityLead,
ovn_gateway.go:112); extend it to populate StandbyRouters with the
same LocalRouterInfo shape.
- Two-tier
ensureRoutes. Split into a "data-plane" desired set (kernel
/32 + OVS flows; covers active and standby IPs) and an "announce"
desired set (FRR/BGP; active only). The stale-removal logic (isManaged)
must keep standby IPs in the kernel set so they are not torn down.
reconcile branch. When standby_prestage=true and StandbyRouters
is non-empty, install kernel routes + OVS MAC-tweak/hairpin flows for their
FIP/SNAT IPs. No FRR routes (no BGP announce) and no NB writes —
the default route, static MAC binding and priority are single shared
per-router objects owned by the active node.
- On failover the kernel route + OVS flow already exist; the takeover
reconcile only adds the FRR route + soft-refresh + NB writes.
Scope
ovn.go: OVNState.StandbyRouters; refreshState computes it.
agent.go: standby pre-staging branch in reconcile; two-tier desired
sets.
routing.go / routing_linux.go: split kernel-only vs full route
ensuring.
config.go: standby_prestage (default false).
Out of scope
- Pre-creating NB objects (default route / MAC binding) on the standby —
these are per-router singletons retagged by the active node and cannot be
pre-staged.
- Pre-announcing FIPs via BGP from the standby — that would attract traffic to
a node whose OVN chassisredirect is not active and blackhole it.
Acceptance criteria
Implementation hints
- Pre-staged kernel
/32 routes are SCOPE_LINK on br-ex and harmless
without a BGP announcement: no traffic reaches br-ex for that FIP until
the route is announced.
- Keep the active-vs-standby classification strictly OVN-derived (the
chassisredirect SB binding), never agent-guessed, to avoid two nodes both
pre-staging and announcing.
- This pairs with the failover hot-path tightening issue but does not depend
on it.
One of four independent issues improving multi-node FIP failover speed
(BFD visibility/management, active drain handshake, standby pre-staging,
failover hot-path tightening). They can be implemented in any order.
Problem
A standby gateway node programs nothing —
HasLocalRouters == falsedrivesremoveAllRoutesinreconcile(agent.go:378). On failover the takeovernode must rebuild the kernel
/32routes, the OVS flows and the FRR/BGPannouncement, all on the critical path.
Proposal
Pre-program the data plane (kernel routes + OVS flows) for routers this
node is a standby for, without announcing them via BGP. Config-gated,
default off.
StandbyRoutersinOVNState. Routers for which this chassis hasa
Gateway_Chassisrow (priority ≥ 1) whosechassisredirectport isbound elsewhere.
refreshStatealready reads SBPort_Bindingand NBGateway_Chassis(seeovn.goandEnsureActivePriorityLead,ovn_gateway.go:112); extend it to populateStandbyRouterswith thesame
LocalRouterInfoshape.ensureRoutes. Split into a "data-plane" desired set (kernel/32+ OVS flows; covers active and standby IPs) and an "announce"desired set (FRR/BGP; active only). The stale-removal logic (
isManaged)must keep standby IPs in the kernel set so they are not torn down.
reconcilebranch. Whenstandby_prestage=trueandStandbyRoutersis non-empty, install kernel routes + OVS MAC-tweak/hairpin flows for their
FIP/SNAT IPs. No FRR routes (no BGP announce) and no NB writes —
the default route, static MAC binding and priority are single shared
per-router objects owned by the active node.
reconcile only adds the FRR route + soft-refresh + NB writes.
Scope
ovn.go:OVNState.StandbyRouters;refreshStatecomputes it.agent.go: standby pre-staging branch inreconcile; two-tier desiredsets.
routing.go/routing_linux.go: split kernel-only vs full routeensuring.
config.go:standby_prestage(defaultfalse).Out of scope
these are per-router singletons retagged by the active node and cannot be
pre-staged.
a node whose OVN
chassisredirectis not active and blackhole it.Acceptance criteria
standby_prestage=false(default) behaviour is byte-for-byteunchanged.
standby_prestage=true, a standby node has kernel/32routes andOVS flows for its standby routers' FIPs but no FRR static route for
them (verified via
ListFRRRoutes).soft-refresh; the kernel route is already present.
routes/flows; pre-staged IPs are never withdrawn while still standby.
docs/explanation/documents the standby pre-staging model and itsdefault-off state.
Implementation hints
/32routes areSCOPE_LINKonbr-exand harmlesswithout a BGP announcement: no traffic reaches
br-exfor that FIP untilthe route is announced.
chassisredirectSB binding), never agent-guessed, to avoid two nodes bothpre-staging and announcing.
on it.