bgp-troubleshooting
BGP session state, missing routes, prefix policy, default-originate, next-hop-self, route reflector — decision trees and checklists
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
BGP session state, missing routes, prefix policy, default-originate, next-hop-self, route reflector — decision trees and checklists
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SLA path failure workflow — read sla_paths.json, traceroute-first localization, ECMP handling, protocol triage
OSPF adjacency, LSDB, area types, authentication, route filtering, and redistribution — symptom-first decision trees with lookup tables
Cross-protocol redistribution (OSPF↔EIGRP) — seed metrics, subnets keyword, loop risk, route-map filtering
Path selection investigation — PBR, route-map and prefix-list policy influence, ECMP behavior, routing table verification
| name | BGP Troubleshooting |
| description | BGP session state, missing routes, prefix policy, default-originate, next-hop-self, route reflector — decision trees and checklists |
PREREQUISITE: Before using this skill, you MUST have already run
get_interfaces(device)andget_bgp(device, "summary")on the target device. If sessions are not Established, go directly to the Session Checklist below — do not read the full skill from the top. If all sessions are Established, proceed with the relevant symptom section.
BGP session state, missing routes, prefix policy, default-originate, next-hop-self, route reflector. Covers: AS1010 (E1C, E2C), AS2020 (X1C), AS4040 (IAN), AS5050 (IBN).
All BGP sessions in the current topology are eBGP. The iBGP/Route Reflector section below is included as generic troubleshooting guidance for completeness.
Defaults: Keepalive 60s · Hold 180s · AD 20 (eBGP) / 200 (iBGP) · Weight 0 (received routes) / 32768 (locally originated)
When a BGP neighbor is not Established:
get_bgp(device, "summary")
| State | Root Cause | Fix |
|---|---|---|
| Established + count | Healthy | — |
| Idle | TCP failing or admin shutdown | Check reachability, check neighbor X shutdown |
| Connect | TCP SYN in progress | Reachability issue — peer unreachable or TCP 179 filtered |
| Active | TCP connect failed, retrying / listening for incoming | Check ACL on TCP 179, check update-source, ebgp-multihop for non-direct eBGP |
| OpenSent | OPEN sent, waiting reply | Usually transient, else hold-timer mismatch |
| OpenConfirm | OPEN exchanged, awaiting KEEPALIVE | Usually transient — if stuck, check hold-timer or capability negotiation failure |
| Idle (Admin) | neighbor X shutdown configured | Remove shutdown |
Run get_bgp(device, "config") and verify in order. Stop at the first mismatch — fix it first, then re-verify. If the issue persists after the fix, start a new investigation cycle for any remaining problems.
If config output is ambiguous (e.g., no explicit timers shown but sessions are flapping), run get_bgp(device, "neighbors", neighbor=<ip>) to see negotiated timers directly.
Note: This checklist checks AS numbers before timers, which differs from CLAUDE.md Principle 6's generic ordering (timers before AS). In BGP, AS mismatch causes immediate OPEN rejection — it is more fundamental than a timer mismatch, which is negotiated after OPEN exchange.
local-as on each side matches the peer's remote-as)neighbors shows actual negotiated values — if they differ from defaults, check config for explicit timers statements on the local device. Trust the operational data; do not dismiss non-default negotiated values as parser artifacts.ping(device, neighbor_ip, source=update_source_ip) from the configured source address.update-source set correctly? Required for iBGP sessions using Loopback addresses — verify both sides agree on source IP. (Not applicable in current topology — all sessions are eBGP with physical interface peering.)ebgp-multihop configured? Required for non-directly-connected eBGP peers. Missing → stuck in Active.| Query | Returns | When to use |
|---|---|---|
summary | Neighbor list, state, uptime, prefixes received | First check — verify all sessions are Established and prefix counts non-zero |
table | Full BGP table with path attributes (next-hop, AS-path, local-pref, MED, origin, weight) | Route missing, wrong best path selected, or next-hop investigation |
config | BGP process config, neighbors, route-maps, prefix-lists, address-family, RR config | Verify neighbor config, policies, route-reflector-client, update-source |
neighbors | Per-neighbor detail: negotiated timers, capabilities, address families, reset reasons | Timer mismatch diagnosis, capability issues, session flapping investigation. Use neighbor=<ip> on IOS to scope to a single peer. |
When get_bgp(device, "summary") shows a session as Established but with 0 prefixes received:
get_bgp(device, "config") for neighbor <ip> activate under address-family ipv4 unicast. On IOS-XE, neighbors defined under the global router bgp process need explicit activation under the address-family to exchange IPv4 prefixes.get_routing_policies(peer_device, "route_maps") on the sending side.network statements or redistribution config. Check get_bgp(peer_device, "config") and get_bgp(peer_device, "table").When get_bgp(device, "neighbors", neighbor=<ip>) shows repeated resets:
| Reset Reason | Root Cause | Action |
|---|---|---|
| Hold Timer Expired | Keepalives not arriving in time — aggressive timers, congested link, or CPU overload | Check timers in config — non-default values (e.g., keepalive 3 / hold 9) make sessions fragile on any jitter |
| Notification received (cease) | Peer sent administrative notification | Check peer for neighbor X shutdown or max-prefix limit reached |
| Peer closed session | TCP reset from peer | Check peer's BGP process health and interface stability |
| No route to peer | IGP route to peer's update-source lost | Check IGP adjacencies and get_routing(device, prefix=<peer_ip>) |
Key diagnostic: Compare "hold time" (negotiated) vs "Configured hold time" in neighbors output. If the negotiated hold time is under 30 seconds, any network jitter will cause flapping. Restore to defaults (keepalive 60 / hold 180) on the non-standard side.
When a route should be in the BGP table but isn't:
get_bgp(device, "table")
get_bgp(device, "config")
> = best, * = valid, = not valid/no best path)get_bgp(device, "table") — inspect the next-hop field. If the next-hop is an eBGP peer's IP (external address), iBGP peers may have no IGP route to it. Fix: apply neighbor X next-hop-self on the eBGP edge router so it rewrites the next-hop to its own interface before advertising to iBGP peers. Verify reachability: get_routing(peer_device, prefix=<next_hop_ip>).get_routing_policies(device, "route_maps") and get_routing_policies(device, "prefix_lists") — check for deny clauses on the sending device. Remember: route-maps have an implicit deny at the end — any prefix not explicitly permitted is dropped.network statement matching exact route in RIB? (must be exact — not aggregate unless aggregate-address is configured)redistribute configured? Check metric-type and route-map filters* missing from table output)get_bgp(device, "table") for the prefix; if absent, confirm via the peer that its path does not traverse your AS.NO_EXPORT (0xFFFFFF01) MUST NOT be advertised outside the AS; NO_ADVERTISE (0xFFFFFF02) MUST NOT be advertised to any peer. Either community causes a route to be silently withheld from outbound updates — route is present locally but invisible to peers. Check communities in get_bgp(device, "table") output for the affected prefix (RFC 1997 §3).When ISP should be sending default but it's missing:
get_bgp(device, "table") → look for 0.0.0.0/0 with a valid best path (>)
get_bgp(device, "summary") → confirm session to ISP peer is Established
default-originate only conditionally (e.g., default-originate route-map) — check ISP configINTENT.json → each edge router has different ISP-facing IPsGeneric guidance — not applicable to the current topology (all sessions are eBGP).
When iBGP routes are missing on a peer:
get_bgp(device, "summary") → verify iBGP session to RR is Established
get_bgp(rr_device, "config") → verify peer has route-reflector-client configured
get_bgp(device, "table") → check if route exists but isn't best path
neighbor X route-reflector-client for all clientsnext-hop-self or IGP must reach originatorWhen a route exists but the wrong next-hop is being used:
get_bgp(device, "table") → see all paths for a prefix
get_bgp(device, "config") → check for weight, local-pref, or AS-path manipulation
bgp always-compare-med is configured)get_bgp(device, "summary") shows all neighbors as Establishedget_bgp(device, "table") shows expected prefixes with > (best path)0.0.0.0/0 present from all ISP peers on each customer edge router (E1C, E2C, X1C)get_routing(device) shows BGP default route in RIBclear ip bgp command is in the FORBIDDEN set and cannot be executed via MCP tools — advise the operator to run clear ip bgp <neighbor> soft in or clear ip bgp <neighbor> soft out manually on the device.References: RFC 4271 (BGP-4, FSM §8, best path §9.1.2, NEXT_HOP §5.1.3, MED scope §9.1.2) · RFC 4456 (BGP Route Reflection, cluster-id §8) · RFC 4760 (Multiprotocol Extensions) · RFC 1997 (BGP Communities, well-known §3)