mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-11 09:07:44 +00:00
proto/stp: hoist the parent flap/hold-down veto to the shell for a clock-free classify core
evaluate_parent no longer reads the injected clock: it returns a ParentEval of Mandatory, Discretionary, or None, and the flap/hold-down veto is applied at the edge via a new TreeState::is_switch_suppressed(now_ms), gating only the discretionary arm. classify_announce/classify_periodic take the pre-computed switch_suppressed bool instead of now_ms, so the whole classify ladder is clock-free; the shell callers (tree announce/periodic re-eval, MMP first-RTT re-eval, handle_parent_lost) compute the veto verdict. The no-coords parent case stays discretionary (veto-gated) exactly as before. Behavior unchanged; the veto tests now assert the moved responsibility.
This commit is contained in:
@@ -13,6 +13,7 @@ use crate::proto::mmp::{
|
||||
LinkReportKind, LinkReportSnapshot, MmpAction, PeerLivenessSnapshot, ReceiverReport, RrLog,
|
||||
SenderReport,
|
||||
};
|
||||
use crate::proto::stp::ParentEval;
|
||||
use std::time::{Duration, Instant};
|
||||
use tracing::{debug, info, trace, warn};
|
||||
|
||||
@@ -198,11 +199,18 @@ impl Node {
|
||||
.map(|d| d.as_secs())
|
||||
.unwrap_or(0);
|
||||
let mono_now_ms = crate::time::mono_ms();
|
||||
if let Some(new_parent) = self.tree_state.evaluate_parent(
|
||||
&peer_costs,
|
||||
&std::collections::BTreeSet::new(),
|
||||
mono_now_ms,
|
||||
) {
|
||||
// Compute the flap-dampening / hold-down veto at the edge; a mandatory
|
||||
// switch bypasses it, a discretionary one is taken only if not suppressed.
|
||||
let switch_suppressed = self.tree_state.is_switch_suppressed(mono_now_ms);
|
||||
let new_parent = match self
|
||||
.tree_state
|
||||
.evaluate_parent(&peer_costs, &std::collections::BTreeSet::new())
|
||||
{
|
||||
ParentEval::Mandatory(p) => Some(p),
|
||||
ParentEval::Discretionary(p) if !switch_suppressed => Some(p),
|
||||
ParentEval::Discretionary(_) | ParentEval::None => None,
|
||||
};
|
||||
if let Some(new_parent) = new_parent {
|
||||
let new_seq = self.tree_state.my_declaration().sequence() + 1;
|
||||
let flap_dampened =
|
||||
self.tree_state
|
||||
|
||||
+14
-2
@@ -329,8 +329,17 @@ impl Node {
|
||||
// the wall-clock `now_ms` above used for the peer's tree position). Read
|
||||
// once and threaded into classify + the state mutators.
|
||||
let mono_now_ms = crate::time::mono_ms();
|
||||
// Compute the flap-dampening / hold-down veto at the edge; the classify core
|
||||
// is clock-free and consumes only this pre-computed verdict.
|
||||
let switch_suppressed = self.tree_state.is_switch_suppressed(mono_now_ms);
|
||||
|
||||
match Stp::classify_announce(&self.tree_state, *from, &peer_costs, &skip, mono_now_ms) {
|
||||
match Stp::classify_announce(
|
||||
&self.tree_state,
|
||||
*from,
|
||||
&peer_costs,
|
||||
&skip,
|
||||
switch_suppressed,
|
||||
) {
|
||||
TreeDecision::Switch {
|
||||
new_parent,
|
||||
new_seq,
|
||||
@@ -583,8 +592,11 @@ impl Node {
|
||||
// Monotonic ms for the flap-dampening / hold-down timers, read once and
|
||||
// threaded into classify + the state mutators.
|
||||
let mono_now_ms = crate::time::mono_ms();
|
||||
// Compute the flap-dampening / hold-down veto at the edge; the classify core
|
||||
// is clock-free and consumes only this pre-computed verdict.
|
||||
let switch_suppressed = self.tree_state.is_switch_suppressed(mono_now_ms);
|
||||
|
||||
match Stp::classify_periodic(&self.tree_state, &peer_costs, &skip, mono_now_ms) {
|
||||
match Stp::classify_periodic(&self.tree_state, &peer_costs, &skip, switch_suppressed) {
|
||||
TreeDecision::Switch {
|
||||
new_parent,
|
||||
new_seq,
|
||||
|
||||
Reference in New Issue
Block a user