The Hidden Mechanics of BGP UPDATE Message Handling
Introduction
I know, the title is quite provocative, but after reading this post I believe you will agree with me. Although the handling of BGP UPDATE messages, and in particular the announcement of the prefix selected as best path by the local peer, is a basic and seemingly straightforward topic in the BGP ecosystem, I recently stumbled upon an unusual behavior that I found worth investigating.
By default, unless additional configuration is applied, a BGP speaker receiving one or more UPDATE messages always executes the best path selection algorithm, selecting a single announcement and marking it as the best path. This announcement is then sent, via a BGP UPDATE message, to other peers following the rules briefly described below.
For eBGP sessions, the BGP UPDATE message containing the prefix classified as the best path is sent to all eBGP neighbors (except the one from which the announcement was received) and to iBGP neighbors.
For iBGP sessions, the split-horizon mechanism applies: the best path announcement is sent on all eBGP sessions but not on iBGP sessions (unless a route reflector is involved). In the route reflector case, beyond the standard rules, two fundamental rules apply:
- The announcement classified as the best path, if received from a client, is sent on all internal sessions (client and non-client) and external sessions
- The announcement classified as the best path, if received from a non-client, is sent only on iBGP sessions to clients
The behaviors previously described as "unusual" refer to two different scenarios: one involves external sessions, while the other involves internal sessions. In the eBGP case, the behavior is genuinely unexpected and undocumented in RFC specifications. In the iBGP case, the behavior is standards-compliant but often overlooked in practice. For completeness, the different behaviors are examined on two of the main Cisco platforms: IOS XE and IOS XR.
The following are some relevant references on BGP UPDATE message handling:
- RFC 4271: BGP-4 base protocol and UPDATE processing
- RFC 4456: route reflection as the standards-based method to relax full-mesh requirements
Test Scenario and Logical Topology
The following figure illustrates the logical diagram of the lab used throughout this post.

The table below provides the addressing details for each BGP peering session.
| Peer 1 | Peer 2 | BGP Session Type | Subnet |
|---|---|---|---|
| PE-AS-A-1 (.1) | PE-AS-B-1 (.2) | eBGP | 10.0.1.0/24 |
| PE-AS-A-1 (.1) | PE-AS-B-2 (.2) | eBGP | 10.0.2.0/24 |
| PE-AS-E-1 (.1) | PE-AS-B-1 (.2) | eBGP | 10.10.20.0/24 |
| PE-AS-C-1 (.2) | PE-AS-B-1 (.1) | eBGP | 10.34.0.0/24 |
| PE-AS-D-1 (.2) | PE-AS-B-2 (.1) | eBGP | 10.45.0.0/24 |
| PE-AS-F-1 (.2) | PE-AS-B-2 (.1) | eBGP | 10.20.20.0/24 |
| R1 (.10) | PE-AS-B-1 (.1) | iBGP | 192.168.100.0/24 |
| R1 (.10) | PE-AS-B-2 (.2) | iBGP | 192.168.100.0/24 |
| R1 (.1) | R2 (.200) | iBGP | 172.168.200.0/24 |
| R1 (.1) | R3 (.3) | iBGP | 10.13.0.0/24 |
With this topology, there are fundamentally six Autonomous Systems (AS):
- AS 65100: the AS from which the representative network 8.8.8.8/32 is announced
- AS 65101: the core of the test environment containing the two PE-AS-B routers (used for eBGP analysis) and R1 (Route Reflector) for examining iBGP session behavior
- AS 65134, 65145, 65200, 65300: additional ASs created to simulate multiple eBGP sessions for the PE-AS-B routers
The following sections show the BGP configuration for each node.
1PE-AS-A-1#show running-config | s r b
2router bgp 65100
3 bgp log-neighbor-changes
4 neighbor 10.0.1.2 remote-as 65101
5 neighbor 10.0.2.2 remote-as 65101
6 !
7 address-family ipv4
8 network 8.8.8.8 mask 255.255.255.255
9 neighbor 10.0.1.2 activate
10 neighbor 10.0.2.2 activate
11 exit-address-family1PE-AS-B-1#show running-config | s r b
2router bgp 65101
3 bgp log-neighbor-changes
4 neighbor 10.0.1.1 remote-as 65100
5 neighbor 10.10.20.1 remote-as 65200
6 neighbor 10.34.0.2 remote-as 65134
7 neighbor 192.168.100.10 remote-as 65101
8 neighbor 192.168.100.10 next-hop-self1RP/0/RP0/CPU0:PE-AS-B-2#show running-config router bgp
2Thu Jul 23 17:30:02.316 UTC
3router bgp 65101
4 bgp router-id 11.11.11.11
5 address-family ipv4 unicast
6 !
7 neighbor 10.0.2.1
8 remote-as 65100
9 address-family ipv4 unicast
10 route-policy PASS-ALL in
11 route-policy PASS-ALL out
12 !
13 !
14 neighbor 10.45.0.2
15 remote-as 65145
16 address-family ipv4 unicast
17 route-policy PASS-ALL in
18 route-policy PASS-ALL out
19 !
20 !
21 neighbor 10.20.20.2
22 remote-as 65300
23 address-family ipv4 unicast
24 route-policy PASS-ALL in
25 route-policy PASS-ALL out
26 !
27 !
28 neighbor 192.168.100.10
29 remote-as 65101
30 address-family ipv4 unicast
31 next-hop-self
32 route-policy PASS-ALL in
33 route-policy PASS-ALL out
34 !
35 !
36!1R1#show running-config | s r b
2router bgp 65101
3 bgp log-neighbor-changes
4 neighbor 10.13.0.3 remote-as 65101
5 neighbor 10.13.0.3 route-reflector-client
6 neighbor 172.168.200.200 remote-as 65101
7 neighbor 172.168.200.200 route-reflector-client
8 neighbor 192.168.100.1 remote-as 65101
9 neighbor 192.168.100.1 route-reflector-client
10 neighbor 192.168.100.2 remote-as 651011R2#show running-config | s r b
2router bgp 65101
3 bgp log-neighbor-changes
4 neighbor 172.168.200.1 remote-as 651011R3#show running-config | s r b
2router bgp 65101
3 bgp log-neighbor-changes
4 neighbor 10.13.0.1 remote-as 651011PE-AS-C-1#show running-config | s r b
2router bgp 65134
3 bgp log-neighbor-changes
4 neighbor 10.34.0.1 remote-as 651011PE-AS-E-1#show running-config | s r b
2router bgp 65200
3 bgp log-neighbor-changes
4 neighbor 10.10.20.2 remote-as 651011PE-AS-F-1#show running-config | s r b
2router bgp 65300
3 bgp log-neighbor-changes
4 neighbor 10.20.20.1 remote-as 651011PE-AS-D-1#show running-config | s r b
2router bgp 65145
3 bgp log-neighbor-changes
4 neighbor 10.45.0.1 remote-as 65101Cisco Dynamic Update Peer-Groups (aka Update Peer-Groups)
Before examining how individual announcements are handled, a brief overview of how Cisco platforms, specifically IOS XE and IOS XR, implement this management is necessary. On Cisco platforms, Update Peer-Groups are an internal optimization used to avoid building separate UPDATE messages for every neighbor when policy outcome is identical. An Update Peer-Group can be understood as a set of neighbors that receive equivalent outbound updates because they share the same effective advertisement policy.
Since this is a concept that tends to remain somewhat hidden in daily operations and may not receive much attention, the following clarification points are important:
- Update Peer-Groups are implementation-specific behavior: although the concept is similar, each platform implements them differently
- They are not defined as a protocol construct in any RFC
- They affect scale and update generation efficiency, not protocol correctness
When neighbors diverge in outbound policy or capability, platforms may split Update Peer-Groups and generate distinct UPDATE messages.
The BGP Dynamic Update Peer-Groups feature, documented by Cisco, was first introduced in Cisco IOS Release 12.0(24)S. This feature fundamentally changes the way BGP UPDATE messages are grouped and replicated to neighbors.
Legacy Peer-Group Model and Its Limitations
In earlier versions of Cisco IOS software, BGP UPDATE messages were grouped based on peer-group configurations. While this approach reduced the amount of system processing resources needed to generate updates, it imposed two significant constraints:
- All neighbors sharing the same peer-group configuration were required to share identical outbound routing policies
- All neighbors within a peer-group had to belong to the same address family, and neighbors in different peer-groups could not be associated with different address families independently
How Dynamic Update Peer-Groups Work
The BGP Dynamic Update Peer-Groups feature decouples update message generation from peer-group configuration entirely. An algorithm dynamically calculates Update Peer-Group membership based on outbound routing policies, grouping neighbors that share the same effective outbound policy into the same group regardless of their peer-group membership.
This mechanism operates automatically and requires no explicit configuration. When a change to outbound policy occurs, the router recalculates Update Peer-Group memberships and triggers an outbound soft reset after a one-minute timer expires. If immediate application is needed, the recalculation can be forced manually by issuing the clear ip bgp <neighbor-IP-address> soft out command.
For optimal performance, it is recommended to keep outbound routing policy identical for neighbors that share similar advertisement requirements. This allows the algorithm to group them efficiently, maximizing update message reuse. For those interested in further details, the reference section at the end of this post provides useful links.
Monitor Update Peer-Groups
Both IOS XE and IOS XR CLIs provide commands to display details about Update Peer-Groups. On IOS XE, the available commands are show bgp ipv4 unicast update-group and show bgp ipv4 unicast replication.
1PE-AS-B-1#show bgp ipv4 unicast update-group
2BGP version 4 update-group 8, internal, Address Family: IPv4 Unicast
3 BGP Update version : 2/0, messages 0, active RGs: 1
4 NEXT_HOP is always this router for eBGP paths
5 Topology: global, highest version: 2, tail marker: 2
6 Format state: Current working (OK, last not in list)
7 Refresh blocked (not in list, last not in list)
8 Update messages formatted 1, replicated 1, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
9 Number of NLRIs in the update sent: max 1, min 0
10 Minimum time between advertisement runs is 0 seconds
11 Has 1 member:
12 192.168.100.10
13
14BGP version 4 update-group 9, external, Address Family: IPv4 Unicast
15 BGP Update version : 2/0, messages 0, active RGs: 1
16 Topology: global, highest version: 2, tail marker: 2
17 Format state: Current working (OK, last minimum advertisement interval)
18 Refresh blocked (not in list, last not in list)
19 Update messages formatted 2, replicated 3, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
20 Number of NLRIs in the update sent: max 1, min 0
21 Minimum time between advertisement runs is 30 seconds
22 Has 3 members:
23 10.0.1.1 10.10.20.1 10.34.0.2 1PE-AS-B-1#show bgp ipv4 unicast replication
2
3 Current Next
4Index Members Leader MsgFmt MsgRepl Csize Version Version
5 8 1 192.168.100.10 1 1 0/1000 2/0
6 9 3 10.0.1.1 2 3 0/1000 2/0 Moving to IOS XR, the available commands are show bgp ipv4 unicast update-group and show bgp ipv4 unicast update-group performance-statistics. As in many other contexts, the information displayed on IOS XR is significantly more detailed compared to IOS XE. A specific reason why more group references appear on this platform is well illustrated on page 22 of this presentation.
1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast update-group
2Thu Jul 23 17:33:07.426 UTC
3
4Update group for IPv4 Unicast, index 0.1:
5 Attributes:
6 Outbound policy: PASS-ALL
7 First neighbor AS: 65145
8 4-byte AS capable
9 Advertise routes with local-label via Unicast SAFI
10 Minimum advertisement interval: 30 secs
11 Update group desynchronized: 0
12 Sub-groups merged: 5
13 Number of refresh subgroups: 0
14 Messages formatted: 10, replicated: 21
15 All neighbor are assigned to sub-group(s)
16 Neighbors in sub-group: 0.2, Filter-Groups num:1
17 Neighbors in filter-group: 0.2(RT num: 0)
18 10.0.2.1 10.20.20.2 10.45.0.2
19
20Update group for IPv4 Unicast, index 0.3:
21 Attributes:
22 Neighbor sessions are IPv4
23 Outbound policy: PASS-ALL
24 Internal
25 Common admin
26 First neighbor AS: 65101
27 Send communities
28 Send GSHUT community if originated
29 Send extended communities
30 Next-hop-self enabled
31 4-byte AS capable
32 Advertise routes with local-label via Unicast SAFI
33 Send AIGP
34 Send multicast attributes
35 Minimum advertisement interval: 0 secs
36 Update group desynchronized: 0
37 Sub-groups merged: 0
38 Number of refresh subgroups: 0
39 Messages formatted: 4, replicated: 4
40 All neighbor are assigned to sub-group(s)
41 Neighbors in sub-group: 0.4, Filter-Groups num:1
42 Neighbors in filter-group: 0.4(RT num: 0)
43 192.168.100.10 1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast update-group performance-statistics
2Thu Jul 23 17:35:10.690 UTC
3
4Update group for IPv4 Unicast, index 0.1:
5 Attributes:
6 Outbound policy: PASS-ALL
7 First neighbor AS: 65145
8 4-byte AS capable
9 Advertise routes with local-label via Unicast SAFI
10 Minimum advertisement interval: 30 secs
11 Update group desynchronized: 0
12 Sub-groups merged: 5
13 Number of refresh subgroups: 0
14 Messages formatted: 10, replicated: 21
15 All neighbor are assigned to sub-group(s)
16 Neighbors in sub-group: 0.2, Filter-Groups num:1
17 Neighbors in filter-group: 0.2(RT num: 0)
18 10.0.2.1 10.20.20.2 10.45.0.2
19
20 Updates generated for 0 prefixes in 20 calls(best-external:0) (time spent: 0.004 secs)
21 Update timer last started: Jul 23 17:32:26.781
22 Update timer last stopped: not set
23 Update timer last processed: Jul 23 17:32:26.790
24 Not-Advertised Stats:
25 Path Not Available : 14 Jul 23 17:31:56.790
26
27Update group for IPv4 Unicast, index 0.3:
28 Attributes:
29 Neighbor sessions are IPv4
30 Outbound policy: PASS-ALL
31 Internal
32 Common admin
33 First neighbor AS: 65101
34 Send communities
35 Send GSHUT community if originated
36 Send extended communities
37 Next-hop-self enabled
38 4-byte AS capable
39 Advertise routes with local-label via Unicast SAFI
40 Send AIGP
41 Send multicast attributes
42 Minimum advertisement interval: 0 secs
43 Update group desynchronized: 0
44 Sub-groups merged: 0
45 Number of refresh subgroups: 0
46 Messages formatted: 4, replicated: 4
47 All neighbor are assigned to sub-group(s)
48 Neighbors in sub-group: 0.4, Filter-Groups num:1
49 Neighbors in filter-group: 0.4(RT num: 0)
50 192.168.100.10
51
52 Updates generated for 0 prefixes in 13 calls(best-external:0) (time spent: 0.003 secs)
53 Update timer last started: Jul 23 17:31:56.907
54 Update timer last stopped: not set
55 Update timer last processed: Jul 23 17:31:56.913
56 Not-Advertised Stats:
57 Path Not Available : 8 Jul 23 17:31:56.787
58 Split Horizon Update : 2 Jul 23 17:29:28.161Additional variants of the commands mentioned above allow specifying the IP address of the session peer or the ASN.
BGP UPDATE Messages Over eBGP Sessions
Now that the mechanism behind announcement distribution is clearer, the next step is to verify the described behavior using the test environment introduced above. Starting from external session behavior, the analysis then moves to internal sessions.
Scenario One: Single eBGP Session per PE
In this first scenario, the default behavior described earlier is verified. To this end, on the border routers of AS 65101, all neighborship sessions (both internal and external) are shut down except those toward AS 65100 (PE-AS-A-1). This results in each PE-AS-B having only one active eBGP session.
1PE-AS-B-1#show bgp ipv4 unicast summary
2[OUTPUT OMITTED]
3
4Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
510.0.1.1 4 65100 5 4 2 0 0 00:00:25 1
610.10.20.1 4 65200 0 0 1 0 0 00:03:03 Idle (Admin)
710.34.0.2 4 65134 0 0 1 0 0 00:02:47 Idle (Admin)
8192.168.100.10 4 65101 0 0 1 0 0 00:02:28 Idle (Admin)1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast summary
2[OUTPUT OMITTED]
3
4Neighbor Spk AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down St/PfxRcd
510.0.2.1 0 65100 5564 5057 27 0 0 00:01:23 1
610.20.20.2 0 65300 5527 5038 0 0 0 00:01:36 Idle (Admin)
710.45.0.2 0 65145 5538 5039 0 0 0 00:01:36 Idle (Admin)
8192.168.100.10 0 65101 5528 5030 0 0 0 00:01:36 Idle (Admin)At this point, the behavior described at the beginning of the post can be verified. To do so, the debug command debug ip bgp ipv4 unicast updates in is enabled on PE-AS-A-1. The announcement of network 8.8.8.8/32, corresponding to the IP address assigned to Loopback 100 on PE-AS-A-1 itself, is then simulated toward the two eBGP neighbors PE-AS-B-1 and PE-AS-B-2. According to the expected behavior, only two outgoing BGP UPDATE messages should be observed, one directed to each neighbor.
1PE-AS-A-1(config)#interface lo1000
2PE-AS-A-1(config-if)#no shutdown
3PE-AS-A-1(config-if)#
4*Jul 23 19:40:29.020: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback100, changed state to up
5*Jul 23 19:40:29.021: %LINK-3-UPDOWN: Interface Loopback100, changed state to up
6*Jul 23 19:40:29.035: BGP(0): sourced route for 8.8.8.8/32 created
7*Jul 23 19:40:29.035: bgp_ipv4set_origin: redist 1, opaque 0x0, net 8.8.8.8
8*Jul 23 19:40:29.035: BGP(0): sourced route for 8.8.8.8/32 path 0x77248EF73F08 id 0 gw 0.0.0.0 created (weight 32768)
9*Jul 23 19:40:29.035: BGP(0): local route 8.8.8.8/32 added gw 0.0.0.0
10*Jul 23 19:40:29.035: BGP(0): redist event (1) request for 8.8.8.8/32
11*Jul 23 19:40:29.035: BGP(0) route 8.8.8.8/32 gw-1 0.0.0.0 src_proto (null) path-limit 1
12*Jul 23 19:40:29.035: BGP(0): route 8.8.8.8/32 up
13*Jul 23 19:40:29.035: BGP: topo global:IPv4 Unicast:base Remove_fwdroute for 8.8.8.8/32
14*Jul 23 19:40:29.035: bgp_ipv4update_origin: redist 0, opaque 0x0, net 8.8.8.8
15*Jul 23 19:40:29.035: BGP(0): local route 8.8.8.8/32 modified rib-gw 0.0.0.0 path-gw 0.0.0.0 [0x77248EF73F08:0]
16*Jul 23 19:40:29.035: BGP(0): redist event (4) request for 8.8.8.8/32
17*Jul 23 19:40:29.035: BGP(0) route 8.8.8.8/32 gw-1 0.0.0.0 src_proto (null) path-limit 1
18*Jul 23 19:40:29.035: bgp_ipv4update_origin: redist 1, opaque 0x0, net 8.8.8.8
19*Jul 23 19:40:29.035: BGP(0): redistributed local route 8.8.8.8/32 modified rib-gw 0.0.0.0 path-gw 0.0.0.0 [0x77248EF73F08:0]
20*Jul 23 19:40:38.979: BGP(0): (base) 10.0.1.2 send UPDATE (format) 8.8.8.8/32, next 10.0.1.1, metric 0, path Local
21*Jul 23 19:40:38.980: BGP(0): (base) 10.0.2.2 send UPDATE (format) 8.8.8.8/32, next 10.0.2.1, metric 0, path Local
22*Jul 23 19:40:38.995: BGP(0): 10.0.2.2 rcv UPDATE w/ attr: nexthop 10.0.2.2, origin i, originator 0.0.0.0, merged path 65101 65100, AS_PATH , community , large community , extended community , ipv6-extended community , SSA attribute
23*Jul 23 19:40:38.996: BGPSSA ssacount is 0, Tunnel attribute
24*Jul 23 19:40:38.996: Tunnel encap type: 0, encap size: 0, Link-state attribute: {}, PrefixSid attribute:
25*Jul 23 19:40:38.996: BGP(0): 10.0.2.2 rcv UPDATE about 8.8.8.8/32 -- DENIED due to: AS-PATH contains our own AS;This is where practice diverges from theory. Focusing on the last entry of the output, PE-AS-A-1 is discarding an announcement, specifically the one sent by PE-AS-B-2 (10.0.2.2), through AS_PATH attribute verification. Technically, searching through the RFCs that define network announcement handling, there is no mention of a mechanism preventing a prefix received via an eBGP session, once elected as best path, from being sent back to the same peer that originated it (a mechanism known as split-horizon, employed by EIGRP to prevent announcing a route to the neighbor from which it was learned).
However, this concept is implemented differently between IOS XE and IOS XR. While on IOS XE (PE-AS-B-1) there is no trace of a BGP UPDATE message being sent back, on IOS XR (PE-AS-B-2) there is. The reason PE-AS-B-2 sends the announcement back is attributable to the Update Peer-Group concept described previously. As soon as a BGP session is established, the PE creates a group, identified by an index 0.X, toward which best path announcements are replicated. Conversely, on IOS XE this concept is present but does not apply when only a single eBGP session is in the UP state. Its implementation ensures that, despite the Update Peer-Group being created, the BGP UPDATE message is not sent back.
The following outputs show the Update Peer-Group overview for both PE-AS-B routers.
1PE-AS-B-1#show bgp ipv4 uni update-group
2BGP version 4 update-group 18, external, Address Family: IPv4 Unicast
3 BGP Update version : 10/0, messages 0, active RGs: 1
4 Topology: global, highest version: 10, tail marker: 10
5 Format state: Current working (OK, last minimum advertisement interval)
6 Refresh blocked (not in list, last not in list)
7 Update messages formatted 0, replicated 0, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
8 Number of NLRIs in the update sent: max 0, min 0
9 Minimum time between advertisement runs is 30 seconds
10 Has 1 member:
11 10.0.1.1 1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast update-group
2Thu Jul 23 17:44:23.368 UTC
3
4Update group for IPv4 Unicast, index 0.1:
5 Attributes:
6 Outbound policy: PASS-ALL
7 First neighbor AS: 65145
8 4-byte AS capable
9 Advertise routes with local-label via Unicast SAFI
10 Minimum advertisement interval: 30 secs
11 Update group desynchronized: 0
12 Sub-groups merged: 7
13 Number of refresh subgroups: 0
14 Messages formatted: 34, replicated: 47
15 Neighbor not in any sub-group:
16 10.20.20.2 10.45.0.2
17 Neighbors in sub-group: 0.1, Filter-Groups num:1
18 Neighbors in filter-group: 0.1(RT num: 0)
19 10.0.2.1
20
21Update group for IPv4 Unicast, index 0.3:
22 Attributes:
23 Neighbor sessions are IPv4
24 Outbound policy: PASS-ALL
25 Internal
26 Common admin
27 First neighbor AS: 65101
28 Send communities
29 Send GSHUT community if originated
30 Send extended communities
31 Next-hop-self enabled
32 4-byte AS capable
33 Advertise routes with local-label via Unicast SAFI
34 Send AIGP
35 Send multicast attributes
36 Minimum advertisement interval: 0 secs
37 Update group desynchronized: 0
38 Sub-groups merged: 0
39 Number of refresh subgroups: 0
40 Messages formatted: 4, replicated: 4
41 Neighbor not in any sub-group:
42 192.168.100.10The result therefore reveals a behavior that may appear counterintuitive: a peer receives from its neighbor the same announcement it had sent moments earlier.
Scenario Two: Multiple eBGP Sessions
The second scenario enables, for each PE-AS-B, the eBGP sessions with its respective neighbors (refer to the topology diagram and addressing table for details).
1PE-AS-B-1#show bgp ipv4 unicast summary
2[OUTPUT OMITTED]
3
4Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
510.0.1.1 4 65100 11 11 4 0 0 00:07:00 1
610.10.20.1 4 65200 4 7 4 0 0 00:00:57 0
710.34.0.2 4 65134 4 6 4 0 0 00:00:46 0
8192.168.100.10 4 65101 0 0 1 0 0 1d12h Idle (Admin)1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast summary
2[OUTPUT OMITTED]
3
4Neighbor Spk AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down St/PfxRcd
510.0.2.1 0 65100 8012 7288 57 0 0 00:08:12 1
610.20.20.2 0 65300 5532 5043 57 0 0 00:01:16 0
710.45.0.2 0 65145 5543 5044 57 0 0 00:01:25 0
8192.168.100.10 0 65101 5528 5030 0 0 0 1d12h Idle (Admin)As soon as the additional external sessions reach the UP state on both platforms, they are associated with an Update Peer-Group. Since the outbound policies are identical for both routers (no policy on IOS XE, route-policy PASS-ALL on IOS XR), the neighbors are associated with the same group, as observable in the following outputs.
1PE-AS-B-1#show bgp ipv4 unicast update-group
2BGP version 4 update-group 18, external, Address Family: IPv4 Unicast
3 BGP Update version : 10/0, messages 0, active RGs: 1
4 Topology: global, highest version: 10, tail marker: 10
5 Format state: Current working (OK, last minimum advertisement interval)
6 Refresh blocked (not in list, last not in list)
7 Update messages formatted 2, replicated 2, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
8 Number of NLRIs in the update sent: max 1, min 0
9 Minimum time between advertisement runs is 30 seconds
10 Has 3 members:
11 10.0.1.1 10.10.20.1 10.34.0.2 1RP/0/RP0/CPU0:PE-AS-B-2#show bgp ipv4 unicast update-group
2Thu Jul 23 17:52:35.007 UTC
3
4Update group for IPv4 Unicast, index 0.1:
5 Attributes:
6 Outbound policy: PASS-ALL
7 First neighbor AS: 65145
8 4-byte AS capable
9 Advertise routes with local-label via Unicast SAFI
10 Minimum advertisement interval: 30 secs
11 Update group desynchronized: 0
12 Sub-groups merged: 9
13 Number of refresh subgroups: 0
14 Messages formatted: 36, replicated: 49
15 All neighbor are assigned to sub-group(s)
16 Neighbors in sub-group: 0.3, Filter-Groups num:1
17 Neighbors in filter-group: 0.1(RT num: 0)
18 10.0.2.1 10.20.20.2 10.45.0.2
19
20Update group for IPv4 Unicast, index 0.3:
21 Attributes:
22 Neighbor sessions are IPv4
23 Outbound policy: PASS-ALL
24 Internal
25 Common admin
26 First neighbor AS: 65101
27 Send communities
28 Send GSHUT community if originated
29 Send extended communities
30 Next-hop-self enabled
31 4-byte AS capable
32 Advertise routes with local-label via Unicast SAFI
33 Send AIGP
34 Send multicast attributes
35 Minimum advertisement interval: 0 secs
36 Update group desynchronized: 0
37 Sub-groups merged: 0
38 Number of refresh subgroups: 0
39 Messages formatted: 4, replicated: 4
40 Neighbor not in any sub-group:
41 192.168.100.10 The same procedure is now repeated. The announcement of network 8.8.8.8/32 from PE-AS-A-1 is simulated once again.
1PE-AS-A-1(config)#interface lo1000
2PE-AS-A-1(config-if)#no shutdown
3PE-AS-A-1(config-if)#
4*Jul 23 19:57:54.426: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback100, changed state to up
5*Jul 23 19:57:54.427: %LINK-3-UPDOWN: Interface Loopback100, changed state to up
6*Jul 23 19:57:54.445: bgp_ipv4set_origin: redist 1, opaque 0x0, net 8.8.8.8
7*Jul 23 19:57:54.445: BGP(0): sourced route for 8.8.8.8/32 path 0x77248EF73F08 id 0 gw 0.0.0.0 created (weight 32768)
8*Jul 23 19:57:54.446: BGP(0): local route 8.8.8.8/32 added gw 0.0.0.0
9*Jul 23 19:57:54.446: BGP(0): redist event (1) request for 8.8.8.8/32
10*Jul 23 19:57:54.446: BGP(0) route 8.8.8.8/32 gw-1 0.0.0.0 src_proto (null) path-limit 1
11*Jul 23 19:57:54.446: BGP(0): route 8.8.8.8/32 up
12*Jul 23 19:57:54.446: BGP: topo global:IPv4 Unicast:base Remove_fwdroute for 8.8.8.8/32
13*Jul 23 19:57:54.446: bgp_ipv4update_origin: redist 0, opaque 0x0, net 8.8.8.8
14*Jul 23 19:57:54.446: BGP(0): local route 8.8.8.8/32 modified rib-gw 0.0.0.0 path-gw 0.0.0.0 [0x77248EF73F08:0]
15*Jul 23 19:57:54.446: BGP(0): redist event (4) request for 8.8.8.8/32
16*Jul 23 19:57:54.446: BGP(0) route 8.8.8.8/32 gw-1 0.0.0.0 src_proto (null) path-limit 1
17*Jul 23 19:57:54.446: bgp_ipv4update_origin: redist 1, opaque 0x0, net 8.8.8.8
18*Jul 23 19:57:54.446: BGP(0): redistributed local route 8.8.8.8/32 modified rib-gw 0.0.0.0 path-gw 0.0.0.0 [0x77248EF73F08:0]
19*Jul 23 19:57:54.448: BGP(0): (base) 10.0.1.2 send UPDATE (format) 8.8.8.8/32, next 10.0.1.1, metric 0, path Local
20*Jul 23 19:57:54.448: BGP(0): (base) 10.0.2.2 send UPDATE (format) 8.8.8.8/32, next 10.0.2.1, metric 0, path Local
21*Jul 23 19:57:54.466: BGP: 10.0.1.2 Next hop is our own address 10.0.1.1
22*Jul 23 19:57:54.466: BGP(0): 10.0.1.2 rcv UPDATE w/ attr: nexthop 10.0.1.1, origin i, originator 0.0.0.0, merged path 65101 65100, AS_PATH , community , large community , extended community , ipv6-extended community , SSA attribute
23*Jul 23 19:57:54.466: BGPSSA ssacount is 0, Tunnel attribute
24*Jul 23 19:57:54.466: Tunnel encap type: 0, encap size: 0, Link-state attribute: {}, PrefixSid attribute:
25*Jul 23 19:57:54.467: BGP(0): 10.0.1.2 rcv UPDATE about 8.8.8.8/32 -- DENIED due to: AS-PATH contains our own AS; NEXTHOP is our own address;
26*Jul 23 19:57:54.467: BGP(0): 10.0.2.2 rcv UPDATE w/ attr: nexthop 10.0.2.2, origin i, originator 0.0.0.0, merged path 65101 65100, AS_PATH , community , large community , extended community , ipv6-extended community , SSA attribute
27*Jul 23 19:57:54.467: BGPSSA ssacount is 0, Tunnel attribute
28*Jul 23 19:57:54.467: Tunnel encap type: 0, encap size: 0, Link-state attribute: {}, PrefixSid attribute:
29*Jul 23 19:57:54.468: BGP(0): 10.0.2.2 rcv UPDATE about 8.8.8.8/32 -- DENIED due to: AS-PATH contains our own AS;Unlike the previous case, this time the return message is received from both PE-AS-B routers, as visible in entries #25 and #29. Looking more closely at the logs, another subtle difference emerges in how IOS XE and IOS XR handle UPDATE generation. The announcement sent by PE-AS-B-1 to PE-AS-A-1 has a next-hop attribute value of 10.0.1.1, which is the IP address used by PE-AS-A-1 to establish the eBGP session. In the IOS XR case, this behavior is not present because the next-hop attribute value is initialized with the local peer's IP address (PE-AS-B-2) used to establish the eBGP session. Despite this difference, the outcome remains the same: the received announcement is discarded.
For the curious, the opposite behavior is also shown below: when PE-AS-A-1 sends a BGP UPDATE to both neighbors to withdraw network 8.8.8.8/32. Similarly to what was just observed, the peer receives the message back from both PE-AS-B routers.
1PE-AS-A-1(config)#interface lo1000
2PE-AS-A-1(config-if)#shutdown
3*Jul 23 20:03:31.645: BGP(0): redist event (2) request for 8.8.8.8/32
4*Jul 23 20:03:31.645: BGP(0): route 8.8.8.8/32 down
5*Jul 23 20:03:31.645: BGP(0): no valid path for 8.8.8.8/32
6*Jul 23 20:03:31.646: BGP: topo global:IPv4 Unicast:base Remove_fwdroute for 8.8.8.8/32
7*Jul 23 20:03:31.646: BGP(0): (base) 10.0.1.2 send unreachable (format) 8.8.8.8/32
8*Jul 23 20:03:31.646: BGP(0): (base) 10.0.2.2 send unreachable (format) 8.8.8.8/32
9*Jul 23 20:03:31.653: BGP(0): 10.0.1.2 rcv UPDATE about 8.8.8.8/32 -- withdrawn
10*Jul 23 20:03:31.663: BGP(0): 10.0.2.2 rcv UPDATE about 8.8.8.8/32 -- withdrawn
11*Jul 23 20:03:33.639: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback100, changed state to down
12*Jul 23 20:03:33.642: %LINK-5-CHANGED: Interface Loopback100, changed state to administratively downDisabling the Default Behavior
As demonstrated above, in this scenario PE-AS-A-1 receives BGP UPDATE messages (announcement or withdrawal) from both PE-AS-B routers. But is it possible to disable this behavior and implement a split-horizon mechanism similar to EIGRP's? This is achievable on IOS XE through the command neighbor <neighbor-IP-address> as-override split-horizon. This command is, however, designed for MPLS L3VPN contexts. In essence, applying this command prevents the UPDATE from being sent back to the originating peer. The following output shows its usage and impact.
1PE-AS-B-1(config-router)#neighbor 10.0.1.1 as-override split-horizon
2PE-AS-B-1(config-router)#
3*Jul 23 20:09:54.406: %BGP-5-ADJCHANGE: neighbor 10.0.1.1 Down split-horizon config change
4*Jul 23 20:09:54.407: %BGP_SESSION-5-ADJCHANGE: neighbor 10.0.1.1 IPv4 Unicast topology base removed from session split-horizon config change
5*Jul 23 20:10:00.057: %BGP-5-ADJCHANGE: neighbor 10.0.1.1 UpApplying this command is disruptive as the existing session is reset (the local peer directly sends a TCP packet with the FIN flag set to 1). Once the command is applied, the output of show bgp ipv4 unicast neighbor <neighbor-IP-address> confirms that the split-horizon feature is currently enabled.
1PE-AS-B-1#show bgp ipv4 unicast neighbor 10.0.1.1 | in horizon
2 Split horizon processing before sending updates
3 Last reset 00:03:47, due to split-horizon config change of session 1In addition, verifying the Update Peer-Groups reveals a difference compared to what was shown at the beginning of this section. The session with neighbor PE-AS-A-1 (10.0.1.1) has been associated with a new Update Peer-Group. This output also includes a reference to the split-horizon feature.
1PE-AS-B-1(config-router)#do sh bgp ipv4 uni update-g
2BGP version 4 update-group 18, external, Address Family: IPv4 Unicast
3 BGP Update version : 28/0, messages 0, active RGs: 1
4 Topology: global, highest version: 28, tail marker: 28
5 Format state: Current working (OK, last minimum advertisement interval)
6 Refresh blocked (not in list, last not in list)
7 Update messages formatted 18, replicated 39, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
8 Number of NLRIs in the update sent: max 1, min 0
9 Minimum time between advertisement runs is 30 seconds
10 Has 2 members:
11 10.10.20.1 10.34.0.2
12
13BGP version 4 update-group 22, external, Address Family: IPv4 Unicast
14 BGP Update version : 28/0, messages 0, active RGs: 1
15 Overrides the neighbor AS 65100 with my AS before sending updates
16 Split horizon processing before sending updates
17 Topology: global, highest version: 28, tail marker: 28
18 Format state: Current working (OK, last minimum advertisement interval)
19 Refresh blocked (not in list, last not in list)
20 Update messages formatted 0, replicated 0, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
21 Number of NLRIs in the update sent: max 0, min 0
22 Minimum time between advertisement runs is 30 seconds
23 Has 1 member:
24 10.0.1.1 Regarding IOS XR, no equivalent command exists at the time of writing.
BGP UPDATE Messages Over iBGP Sessions
For iBGP peers, split-horizon applies by default as defined in RFC 4271. A route learned from one iBGP neighbor is not re-advertised to another iBGP neighbor unless route reflection or confederations are used. But what happens in a scenario involving a route reflector architecture? To answer this question, the following analysis focuses on AS 65101 and its iBGP sessions.
Scenario One: Route Reflection Back to the Originating Client
With reference to the initial statement that "the announcement classified as best path, if received from a client, is sent on all internal sessions (client and non-client) and external sessions," one might ask: in a route reflector client scenario, is the route sent back to the same client that originated it? In other words, when a route reflector receives a route from a client and selects it as best path, does it also forward it back to the same client peer from which it was received?
The answer is yes, it does come back. Directly from RFC 4456:
1) A route from a Non-Client IBGP peer: Reflect to all the Clients.
2) A route from a Client peer: Reflect to all the Non-Client peers and also to the Client peers. (Hence the Client peers are not required to be fully meshed.)
The key takeaway is in point 2: "Reflect to all." This means that in this case, the route reflector does not suppress the UPDATE toward the originating client. But a question naturally arises: how does the local peer (which, from the route reflector's perspective, is a route reflector client) discard such an announcement to avoid re-announcing it? From the same RFC, an additional attribute called ORIGINATOR_ID provides the answer. But how exactly does it contribute to the mechanism? The following is what the RFC states:
When an announcement is selected as best path and sent via an iBGP session from a route reflector client to a route reflector, it contains the standard attributes such as Origin, Next Hop, AS Path, and others. However, when the route reflector selects that announcement as best path and forwards it according to the rules described earlier, two fundamental attributes are added: ORIGINATOR_ID and CLUSTER_LIST. When the route reflector client receives an announcement whose ORIGINATOR_ID attribute value matches its own router-id, the announcement is discarded.
As an example, the following packet capture was performed between R1 (RR) and R3 (RR-client). From R3, the announcement of a new network (4.4.4.4/32) originates. As observable in the packet details, in addition to the same network being announced from R1 back to R3, the two new attributes mentioned above are present.
One might then ask: is the Update Peer-Group concept still preserved in this context? The answer is yes. Since Update Peer-Groups apply to both session types (internal and external), this mechanism remains active. The following output confirms this behavior.
1R1#show bgp ipv4 unicast update-group
2BGP version 4 update-group 16, internal, Address Family: IPv4 Unicast
3 BGP Update version : 1/0, messages 0, active RGs: 1
4 Route-Reflector Client
5 Topology: global, highest version: 1, tail marker: 1
6 Format state: Current working (OK, last not in list)
7 Refresh blocked (not in list, last not in list)
8 Update messages formatted 0, replicated 0, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
9 Number of NLRIs in the update sent: max 0, min 0
10 Minimum time between advertisement runs is 0 seconds
11 Has 3 members:
12 10.13.0.3 172.168.200.200 192.168.100.1
13
14BGP version 4 update-group 17, internal, Address Family: IPv4 Unicast
15 BGP Update version : 1/0, messages 0, active RGs: 1
16 Topology: global, highest version: 1, tail marker: 1
17 Format state: Current working (OK, last not in list)
18 Refresh blocked (not in list, last not in list)
19 Update messages formatted 0, replicated 0, current 0, refresh 0, limit 1000, mss 1460, SSO is disabled
20 Number of NLRIs in the update sent: max 0, min 0
21 Minimum time between advertisement runs is 0 seconds
22 Has 1 member:
23 192.168.100.2 Takeaways
Sometimes behaviors that make perfect theoretical sense are taken for granted. However, when moving to a real environment and confronting actual standard implementations, unexpected nuances can emerge. It is therefore fundamental to complement theoretical study with practical analysis that examines the details of actual implementations.
- A best-path UPDATE may be sent back to the originating eBGP peer depending on the platform's Update Peer-Group implementation
- IOS XE and IOS XR handle UPDATE generation differently, even when the protocol outcome is identical
- Update Peer-Groups are an implementation-specific optimization, not a protocol construct; they affect update replication scope
- In route reflector topologies, UPDATEs are reflected back to the originating client by design; loop prevention uses ORIGINATOR_ID and CLUSTER_LIST
- The receiving peer always discards the echoed route through standard loop detection mechanisms, so no routing loop occurs
I hope this post was an interesting read. As always, if you have comments or experiences to share on the topic, feel free to reach me through social channels. See you in the next post! 🚀