Proving the Path Part 3: Policy Route and Routing
Part 2 established that the choppy Teams call’s session predates the SLA breach on the HUB-1 path: it’s been running on whatever decision it made minutes before the incident started, untouched since. Stage 3 and 4 of the chain, policy route and routing, ask a different question that’s easy to conflate with the first one: not what did this session decide, but what would a new flow to the same destination decide right now.
Policy route: does a rule even match?
On FortiOS, an SD-WAN service rule behaves as an implicit policy route ahead of the standard routing table lookup. diagnose firewall proute list shows both explicit PBR and SD-WAN-generated entries in one place:
diagnose firewall proute list
list route policy info(vf=root):
id=131073 vwl_service=1 vwl_mbr_seq=1 2 dscp_tag=0xff 0xff
flags=0x0 tos=0x00 tos_mask=0x00 protocol=0 sport=0-65535
iif=0 dport=0-65535 path(2): oif=6(to-hub1) oif=7(to-hub2)
source(1): 0.0.0.0-255.255.255.255
destination(1): Microsoft_Teams gwy=0.0.0.0
That entry is the Teams/M365 service rule from the SD-WAN configuration, matched against the Internet Service DB object rather than a static address, with both overlay members listed as eligible paths. The 5-tuple for the live call (UDP, destination port 3478, destination address in the Microsoft Teams ISDB range) matches this rule cleanly. There’s nothing ambiguous or stale about which rule applies; a new flow to this destination hits exactly the rule I’d expect.
Routing: does the FIB actually resolve it?
A matched service rule still needs a usable route behind it. get router info routing-table details against a representative Teams destination confirms the recursive resolution through the SD-WAN zone:
get router info routing-table details 52.x.x.x
Routing entry for 52.x.x.0/24
Known via "sdwan", distance 1, metric 0, best
Last update 00:02:14 ago
* <hub egress>, via to-hub1
The route is valid, recursively resolves through the currently-selected overlay member, and was last updated a couple of minutes ago, after the failover-and-recovery cycle, which is a preview of Part 4’s finding that the rule has already settled back onto HUB-1.
Applying it to the fault
Running both checks against the same destination the live call is using confirms something specific: right now, a brand-new Teams call from SPOKE-14 would match the correct service rule and resolve to a healthy path. Policy route and routing, evaluated against the current state of the network, are not the problem. That’s a genuinely useful negative result: it rules out an entire category of explanation (“the routing config is wrong” or “the service rule stopped matching”) and narrows the question to something that only makes sense in light of Part 2’s finding: the live call isn’t evaluating any of this. It made its policy-route and routing decision once, at creation, and it’s been coasting on that decision ever since.
False conclusion checkpoint: the route exists, so traffic must use it
This is worth stating plainly because it’s the most common shortcut I see: seeing a correct entry in proute list or the routing table proves what a new flow will do, not what an existing one is doing. A policy route or SD-WAN decision only applies to a session at the moment that session is evaluated, which for TCP and UDP flows is once, at creation. An already-established session ignores config changes made after that point entirely, which is exactly consistent with what Part 2’s session table entry showed.
Where this leaves us
Policy route and routing are both healthy and would send a fresh call down the right path today. That rules out routing as the ongoing cause and pushes the real question fully onto the SD-WAN layer’s history: was the failover itself somehow the source of degradation, or did the SD-WAN and SLA mechanism work exactly as designed, while the persisting problem is something else entirely? Part 4 goes to the health-check history to settle that.