Route Object Correlation
Take a single installed route and trace it through the SAI object graph — route entry → next hop (or next-hop group) → router interface → neighbor → port — building a relationship graph that shows exactly what must exist for the route to forward.
Non-disruptive. Safe to run in the virtual lab.
Use SCAN with targeted MATCH patterns, never KEYS * on a busy system.
This lab is read-only; do not set/del any ASIC_DB keys — writing there does not 'fix' hardware and can desynchronize state.
Single node with one upstream route
SONiC-VS
├─ Ethernet0 ── (routed) ── next-hop 10.0.0.2 (neighbor MAC learned)
└─ route 10.20.0.0/24 ─→ next-hop ─→ RIF(Ethernet0) ─→ neighbor ─→ portObjective
- • Correlate one route across all the SAI-facing objects it depends on.
- • Distinguish human-readable application state (APPL_DB) from implementation-oriented objects (ASIC_DB).
- • Produce a relationship graph you can reuse as a routed-forwarding checklist.
Starting state
- • SONiC-VS up; one routed interface with a resolved neighbor.
- • At least one non-connected route (e.g., 10.20.0.0/24) installed and forwarding.
Prerequisites: Lessons 3.3, 3.4, and 3.5 complete. · A SONiC-VS instance with at least one routed interface and an installed route with a resolved next hop (reuse Module 2's adjacency, or add a static route with a reachable next hop). · A 'baseline' snapshot to revert to.
Tasks
- 1
Confirm the route in software (intent/applied)
Establish the human-readable view first: the route in FRR and in APPL_DB.
SONiC CLIshow ip route 10.20.0.0/24SONiC DBAPPL_DB is DB 0; SCAN, not KEYS *redis-cli -n 0 SCAN 0 MATCH 'ROUTE_TABLE:10.20.0.0/24' COUNT 100SONiC DBredis-cli -n 0 HGETALL 'ROUTE_TABLE:10.20.0.0/24'Expected:- FRR shows the route with a next-hop IP and egress interface.
- APPL_DB ROUTE_TABLE entry lists the nexthop and ifname in human-readable form.
What happened internally: APPL_DB holds application/desired state produced from FRR (via fpmsyncd) and managers. It is human-readable and references interfaces/IPs by name — the top of the correlation chain.
- 2
Find the route object in ASIC_DB and its next-hop reference
SONiC DBASIC_DB is DB 1redis-cli -n 1 SCAN 0 MATCH 'ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY*10.20.0.0/24*' COUNT 500SONiC DBread SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_IDredis-cli -n 1 HGETALL 'ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{...10.20.0.0/24...}'Expected:- A ROUTE_ENTRY object whose SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION is FORWARD and whose SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID is an oid: value (a VID).
What happened internally: This is the sync-path representation of the route. The next-hop attribute is an opaque VID — the first edge in the object graph. (This is a database record of the SAI request, not the silicon.)
- 3
Follow next hop → router interface → neighbor
SONiC DBreveals RIF oid + next-hop IPredis-cli -n 1 HGETALL 'ASIC_STATE:SAI_OBJECT_TYPE_NEXT_HOP:oid:0x...'SONiC DBRIF → port + src MAC + VRFredis-cli -n 1 HGETALL 'ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x...'SONiC DBneighbor keyed by (RIF, IP) → dst MACredis-cli -n 1 SCAN 0 MATCH 'ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY*' COUNT 500Expected:- The next hop references a router interface OID and a next-hop IP.
- The router interface references a port OID (and holds the source MAC / VRF).
- A neighbor entry for (that RIF, the next-hop IP) holds the destination MAC.
What happened internally: You are walking the reference graph: NEXT_HOP → ROUTER_INTERFACE → PORT, plus NEIGHBOR_ENTRY supplying the dst MAC. If the neighbor is missing, the route is 'inert' (Lesson 3.5).
- 4
Resolve the port OID to a front-panel port and translate a VID→RID
SONiC DBmap port name ↔ oid (COUNTERS_DB also maps these)redis-cli -n 1 HGET COUNTERS_PORT_NAME_MAP Ethernet0SONiC DBvirtual OID → real (vendor) OIDredis-cli -n 1 HGET VIDTORID oid:0x...Expected:- The port OID corresponds to a named front-panel port (e.g., Ethernet0).
- VIDTORID returns the implementation's real OID for a given virtual OID.
What happened internally: VIDTORID/RIDTOVID are maintained by syncd. This step shows that ASIC_DB uses virtual IDs that map to the vendor SAI's real handles — the abstraction boundary in action.
- 5
Draw the relationship graph
On paper or in a note, draw: route → next hop → RIF → (port) and RIF+IP → neighbor → dst MAC.
Mark which nodes came from human-readable APPL_DB and which from implementation-oriented ASIC_DB.
Expected:- A single-page graph you can reuse as a routed-forwarding checklist.
What happened internally: The graph is the mental model for Lesson 3.5's troubleshooting order: break any node and predict the failure signature.
Troubleshooting branches
If: No ROUTE_ENTRY in ASIC_DB though FRR shows the route
Then: Suspect a stall in the swss→syncd path or resource exhaustion; check orchagent/syncd logs and CRM (Lessons 3.4/3.8).
If: Route + next hop present but no matching neighbor entry
Then: Adjacency unresolved — the 'inert route' pattern. Verify ARP/ND for the next-hop IP.
If: SCAN returns nothing for your key pattern
Then: Key formats vary by version; widen the MATCH pattern, and confirm you're in the right DB (-n 0 APPL_DB, -n 1 ASIC_DB).
- None — read-only correlation. Revert to 'baseline' only if you added a temporary static route.
Lab evidence checklist
- ☐ APPL_DB ROUTE_TABLE entry captured (human-readable).
- ☐ ASIC_DB ROUTE_ENTRY with its NEXT_HOP_ID captured.
- ☐ Next hop → RIF → port chain captured.
- ☐ Neighbor entry (RIF, IP → MAC) captured.
- ☐ One VID→RID translation captured.
- ☐ Relationship graph drawn, nodes labeled by source DB.
Reflection
- Which objects were human-readable and which were implementation-oriented opaque OIDs — and why is that split useful?
- If the neighbor entry were missing, which of your captured objects would still be present, and would the route forward?
- Why is ASIC_DB the right place to confirm the request reached SAI, but still not proof the packet forwards?