Arista EOS BGP Configuration: Peers, Peer Groups and Verification - 夜莺博客

Arista EOS BGP Configuration: Peers, Peer Groups and Verification

Arista EOS speaks the same BGP dialect as Cisco IOS with a handful of differences that surprise experienced engineers: peer groups are almost mandatory in practice, address-family activation is explicit, and configuration sessions let you stage and diff a routing change before committing it. This guide builds an EOS BGP configuration from router-id to route policy, covers the address-family and next-hop details that break in multi-protocol designs, and finishes with the verification and session-management commands you will use during incidents.

EOS runs one multi-protocol BGP process that carries IPv4 unicast, IPv6 unicast, EVPN and labeled-unicast address families simultaneously. That single-process model is why the session-level configuration and the per-family configuration have to be reasoned about separately: the session commands define how a peering is established (remote-as, update-source, authentication, timers), while the address-family commands define what that session is allowed to carry. Almost every "the session is up but I get no routes" ticket on an Arista fabric comes down to that distinction.

Base session and peer group

switch# configure session BGP-2026-09
switch(config-sess-BGP-2026-09)# router bgp 65001
switch(config-router-bgp)# router-id 10.0.0.1
switch(config-router-bgp)# no bgp default ipv4-unicast
switch(config-router-bgp)# maximum-paths 4 ecmp 4
switch(config-router-bgp)# neighbor ISP peer group
switch(config-router-bgp)# neighbor ISP remote-as 65002
switch(config-router-bgp)# neighbor ISP description "Transit peers"
switch(config-router-bgp)# neighbor 203.0.113.1 peer group ISP
switch(config-router-bgp)# neighbor 203.0.113.5 peer group ISP
switch(config-router-bgp)# neighbor IBGP peer group
switch(config-router-bgp)# neighbor IBGP remote-as 65001
switch(config-router-bgp)# neighbor IBGP update-source Loopback0
switch(config-router-bgp)# neighbor 10.0.0.2 peer group IBGP
switch(config-router-bgp)# address-family ipv4
switch(config-af)# neighbor ISP activate
switch(config-af)# neighbor IBGP activate
switch(config-af)# network 10.0.0.0/24
switch(config-af)# exit
switch(config-router-bgp)# exit
switch(config-sess-BGP-2026-09)# show session-config named BGP-2026-09 diffs
switch(config-sess-BGP-2026-09)# commit

no bgp default ipv4-unicast disables the legacy behaviour of activating every new neighbour in the IPv4 unicast family implicitly. Using it forces you to activate families deliberately - the right choice for any modern design, and the reason a peer can be "up" with no routes if you forget the activation line. Configuration sessions add the same commit/diff safety that IOS XR engineers expect; EOS keeps a running history of session commits too.

A peer group in EOS is not a cosmetic grouping: members inherit every session-level attribute from the group at the moment they are attached, and an individual member can still override a specific attribute afterwards. The order of operations matters. If you place a neighbour into a group and then set neighbor 203.0.113.1 timers 30 90, the explicit line wins for that neighbour only. If you instead change the group's timers later, only members that have not overridden them follow along - which is exactly the behaviour you want for a transit group where one flaky ISP needs slower timers than the rest.

For route reflectors and large iBGP meshes, peer groups also collapse the update-group computation. EOS sorts neighbours into update groups based on their outbound policy; neighbours in the same update group share one generated update. Ten neighbours with identical outbound route-maps cost one update-generation pass, ten neighbours with ten slightly different maps cost ten. Audit with show ip bgp update-group summary before you blame the control plane for CPU spikes.

Finally, dynamic peer groups let an EOS switch accept inbound sessions from a range without listing every address. This is common in lab fabrics and in anycast route-reflector designs where a client addresses a VIP:

switch(config-router-bgp)# bgp listen range 10.10.0.0/16 peer-group IBGP
switch(config-router-bgp)# bgp listen limit 200
switch# show ip bgp peer-group IBGP
switch# show ip bgp neighbors | grep -i "dynamic"

Route policy, next-hop and BFD

switch(config)# ip prefix-list PL-DEFAULT seq 10 permit 0.0.0.0/0
switch(config)# route-map RM-IN permit 10
switch(config-route-map-RM-IN)# match ip address prefix-list PL-CUSTOMER
switch(config-route-map-RM-IN)# set local-preference 150
switch(config-route-map-RM-IN)# set community 65001:100 additive
switch(config-route-map-RM-IN)# exit

switch(config-router-bgp)# neighbor ISP route-map RM-IN in
switch(config-router-bgp)# neighbor IBGP next-hop-self
switch(config-router-bgp)# neighbor ISP bfd
switch(config-router-bgp)# neighbor ISP timers 10 30
switch(config-router-bgp)# address-family ipv4
switch(config-af)# neighbor ISP route-map RM-OUT out
switch(config-af)# redistribute connected route-map RM-CONNECTED

switch(config)# router bgp
switch(config-router-bgp)# address-family ipv6
switch(config-af)# neighbor IBGP6 activate
switch(config-af)# neighbor IBGP6 next-hop address-family ipv6 originate

Two gotchas live here. First, when a BGP session is established over IPv6 link-local addresses carrying IPv4 prefixes, EOS will not negotiate RFC 8950 IPv6 next hops unless you explicitly configure next-hop address-family ipv6 originate - without it the IPv4 prefixes get useless IPv4 next hops or are not advertised at all. Second, BFD brings sessions down far faster than BGP timers alone; enable it only where the peer supports it, otherwise you increase the chance of a false positive flap.

EOS route-maps are first-match-wins with an implicit deny at the end of the map, and the match clauses inside a single sequence are an AND, not an OR. That single sentence explains most "my prefix disappeared" incidents. When you want an OR, write two sequences. When you want to permit everything that is not explicitly filtered, terminate the map with route-map RM-IN permit 1000 and no match clause. A bare route-map RM-IN permit 10 with no matches at all matches everything, which is occasionally useful during debugging and dangerous in production.

Prefix-lists should carry sequence numbers from the first draft. EOS lets you insert seq 15 between two existing entries without rebuilding the list, which is what you want during an incident when you are tightening a filter at 03:00. Community manipulation deserves the same discipline: use well-known communities (no-export, no-advertise, internet) where they express the intent, and keep your own numbering scheme documented, because a stray set community ... additive that keeps appending on every re-advertisement inflates the community list until neighbours run out of update space.

On the next-hop side, remember that next-hop-self is a session-level command in EOS and applies per neighbour or per peer group, while next-hop address-family is a family-scoped refinement. In an EVPN or VXLAN fabric with an underlay iBGP, the route reflectors should not rewrite next hops - the whole point of the underlay is that the VTEP addresses are reachable. Blindly applying next-hop-self to a route-reflector peer group re-introduces an unnecessary extra hop lookup and can blackhole traffic if the reflector is not in the forwarding path.

Verification

switch# show ip bgp summary
switch# show ip bgp neighbors 203.0.113.1
switch# show ip bgp neighbors 203.0.113.1 advertised-routes
switch# show ip bgp neighbors 203.0.113.1 received-routes
switch# show ip bgp
switch# show ip bgp 10.0.0.0/24 detail
switch# show ip bgp regexp ^65002_
switch# show ip route bgp
switch# show ip bgp community 65001:100
switch# clear ip bgp 203.0.113.1 soft in
switch# clear ip bgp *

Read the summary table as three columns of truth: state (established), uptime, and prefix count. Established with zero prefixes narrows the fault to activation or an inbound filter; not established narrows it to reachability, timers or authentication. soft in is the safe way to re-apply inbound policy without dropping the session - practise using it instead of the reflexive clear ip bgp *.

Three more commands earn their place in the runbook. show ip bgp neighbors 203.0.113.1 routes shows the post-policy Adj-RIB-In, so you can prove whether a filter or the peer is responsible for missing prefixes; if the route is present there, the problem is inbound policy or RIB selection, and if it is absent, the peer never sent it. show ip bgp neighbors 203.0.113.1 policy prints the effective route-maps applied in each direction. show ip bgp update-group tells you whether a policy change forced every neighbour into its own update group, which is the usual cause of an unexpected CPU bump after a maintenance window.

For a path-selection question, always ask for the detail view rather than eyeballing show ip bgp: the detail output walks the tie-break criteria in order and stops at the one that decided the winner, which turns a twenty-minute argument into a ten-second answer. Pair it with the vendor-neutral explanation in our best path selection write-up when you need to explain the outcome to somebody who does not read Arista output.

Operating EOS BGP in production

Stage the change in a configuration session, review the diff, apply it on one route reflector or leaf first, verify the RIB and traffic, then roll forward. Keep policy in named route-maps and prefix-lists so an audit is possible, and remember that the fastest way to debug a fabric is often show ip bgp on the egress leaf rather than on the core. Related reading: EOS configuration sessions, BGP peering security, best path selection and BGP in EVPN fabrics.

The maintenance workflow that scales is boring by design: name the session after the change, not the date. configure session BGP-ADD-TRANSIT-PEER is still meaningful six months later; configure session 2026-09-14 is not. Before commit, run show session-config named NAME diffs and read the diff as text - EOS shows exactly which lines are being added and removed, which catches the classic mistake of pasting a whole router block and silently wiping a description or a password. After commit, compare the session with show session-config named NAME diffs again; an empty output is your proof that the running config matches the intent. If the change is wrong, configure session NAME followed by abort discards it without touching the running configuration, and rollback clean-config at the switch prompt restores the pre-session state entirely.

Convergence, timers and graceful restart

BGP's default keepalive/hold timers (60/180 seconds in EOS) are far too slow for a data-centre fabric, and too fast for a transit peering that must not flap on a single lost packet. Tune per neighbour rather than globally:

switch(config-router-bgp)# neighbor IBGP timers 3 9
switch(config-router-bgp)# neighbor ISP timers 10 30
switch(config-router-bgp)# neighbor IBGP bfd interval 300 min-rx 300 multiplier 3
switch(config-router-bgp)# neighbor IBGP graceful-restart
switch(config-router-bgp)# neighbor IBGP graceful-restart-helper
switch(config-router-bgp)# address-family ipv4
switch(config-af)# neighbor IBGP graceful-restart restart-time 300
switch(config-router-bgp)# bgp graceful-restart restart-time 300
switch# show ip bgp neighbors 10.0.0.2 | grep -i graceful

Sub-second detection is BFD's job, not BGP's. With a 300 ms interval and a multiplier of three you get roughly 900 ms detection, which is fast enough for a fabric where an ECMP path re-converges in tens of milliseconds but slow enough to survive a scheduling hiccup on a busy control plane. Do not set the multiplier to one in order to shave 600 ms off detection; you will lose sessions on routine CPU spikes and spend the next week explaining why throughput dipped every afternoon.

Graceful restart is the counterweight to aggressive timers. When a peer restarts, GR lets the adjacent router keep the pre-restart routes installed and marked stale, so forwarding continues while BGP reconverges. The helper role must be configured on the receiving side - graceful-restart-helper - and the restart-time on both sides should be agreed, because a restart-time mismatch is the difference between a seamless SSO event and a full-table reconvergence. Long-lived graceful restart (LLGR) extends the same idea to cover a control-plane restart that outlasts the restart-time, which matters for large EVPN fabrics where the full table can take minutes to re-advertise.

Failure modes and their signatures

Symptom Most likely cause First command
Session Established, zero prefixes received Address-family activation missing or inbound route-map denying everything show ip bgp neighbors X policy
Session stuck in Active/Idle Transport unreachable, wrong remote-as, or MD5 mismatch show ip bgp neighbors X | grep -i error
Routes present but traffic blackholed Next-hop unreachable, or next-hop-self applied where it should not be show ip bgp prefix detail
Periodic weekly flapping Timers too aggressive for a shared control plane, or a BFD false positive show logging | grep %BGP
Unexpected CPU rise after a policy push Update groups fragmented by per-neighbour outbound maps show ip bgp update-group

Log archaeology is the last resort but the fastest when you have timestamps: show logging | grep -i %BGP across a maintenance window tells you whether an outage began with a session reset, a route withdrawal or a scan. Combine it with a look at the forwarding layer when the symptom is partly forwarding rather than purely routing, because dual-primary and BGP next-hop problems look similar from a monitoring dashboard and completely different from the CLI.

Automating EOS BGP with eAPI and gNMI

curl -s -k -u admin:password https://switch/command-api \
  -d '{"jsonrpc":"2.0","method":"runCmds","params":{"version":1,"cmds":["show ip bgp summary"],"format":"json"},"id":1}'

curl -s -k -u admin:password https://switch/command-api \
  -d '{"jsonrpc":"2.0","method":"runCmds","params":{"version":1,"cmds":["enable","configure session AUTO-1","router bgp 65001","neighbor 203.0.113.9 peer group ISP","show session-config named AUTO-1 diffs"],"format":"json"},"id":2}'

eAPI exposes the same CLI you type, as JSON-RPC, which makes it ideal for change verification and terrible for configuration generation - you are still building strings for a CLI. Two habits keep it safe. First, run configuration through a named session and read the diff back in the same call, so the automation can refuse to commit an unexpected diff. Second, keep read-only polling on eAPI and move to gNMI/OpenConfig for state you intend to graph, because the command output format is versioned by the CLI and will change under you across EOS releases. Whether the BGP change is pushed by a script or by a template rendered from Ansible, the verification step is identical: show ip bgp summary, the expected prefix counts, and a diff of the running config against the intended config.

原文链接:https://www.arista.com/en/um-eos/eos-border-gateway-protocol-bgp