BGP Conditional Advertisements
One of the seemingly complicated things to do in BGP is conditional advertisements. This can be used to apply policy to routes and only advertise specific routes when you (don’t) have another route. For example, you only advertise a default route when you have specific routes from a peer.
Another example is when you’re connected to two ISPs, but you prefer data to traverse just one of the two links. Maybe because one link is more expensive than the other or less reliable. Maybe you just like one more than the other. Whatever the reason, you want to perform traffic manipulation. Of course you could do something like as-path prepending, but you have no way to ensure this will be honored on the other side. They might have bgp bestpath as-path ignore enabled. The best way to force traffic to use a specific path is to have this path as the only path. However, just supressing the route isn’t smart in case of a failure somewhere. You could just advertise a summary to the other ISP (which would be an easier solution), but you need more granularity for some reason. In that case you can use Conditional Advertisements.
My example here is a simple topology of four routers in a diamond shape using very basic configuration.
R1:
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 unassigned YES unset administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/1.12 192.168.12.1 YES manual up up
GigabitEthernet0/1.13 192.168.13.1 YES manual up up
Loopback1 1.1.1.1 YES manual up up
Loopback11 11.11.11.1 YES manual up up
Loopback111 111.111.111.1 YES manual up up
router bgp 100
bgp log-neighbor-changes
network 1.1.1.1 mask 255.255.255.255
network 11.11.11.1 mask 255.255.255.255
network 111.111.111.1 mask 255.255.255.255
neighbor 192.168.12.2 remote-as 200
neighbor 192.168.13.3 remote-as 300
R2:
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 unassigned YES unset administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/1.12 192.168.12.2 YES manual up up
GigabitEthernet0/1.24 192.168.24.2 YES manual up up
router bgp 200
bgp log-neighbor-changes
neighbor 192.168.12.1 remote-as 100
neighbor 192.168.24.4 remote-as 400
R3:
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 unassigned YES unset administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/1.13 192.168.13.3 YES manual up up
GigabitEthernet0/1.34 192.168.34.3 YES manual up up
router bgp 300
bgp log-neighbor-changes
neighbor 192.168.13.1 remote-as 100
neighbor 192.168.34.4 remote-as 400
R4:
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 unassigned YES unset administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/1.24 192.168.24.4 YES manual up up
GigabitEthernet0/1.34 192.168.34.4 YES manual up up
Loopback1 4.4.4.4 YES manual up up
router bgp 400
bgp log-neighbor-changes
network 4.4.4.4 mask 255.255.255.255
neighbor 192.168.24.2 remote-as 200
neighbor 192.168.34.3 remote-as 300
So as a verification we perform a trace from R4 to each loopback address of R1
R4#trace 1.1.1.1 so lo1
Type escape sequence to abort.
Tracing the route to 1.1.1.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.24.2 2 msec 2 msec 4 msec
2 192.168.12.1 4 msec * 2 msec
R4#trace 11.11.11.1 so lo1
Type escape sequence to abort.
Tracing the route to 11.11.11.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.24.2 2 msec 2 msec 1 msec
2 192.168.12.1 2 msec * 2 msec
R4#trace 111.111.111.1 so lo1
Type escape sequence to abort.
Tracing the route to 111.111.111.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.24.2 3 msec 3 msec 1 msec
2 192.168.12.1 2 msec * 2 msec
So, for all routes the path via R2 is chosen. Now I need to influence incoming traffic. My business case states that traffic towards 1.1.1.1 and 111.111.111.1 should use R3, but 11.11.11.1 should enter through R2. This makes using summaries more difficult (not impossible, but I might not have control over 1.1.1.2 so it could be dangerous in real life). However, when the link to either router goes down all traffic should fail over to the other path.
This is where Conditional Advertisements come in. As long as both links exist I advertise 11.11.11.1 to R2 and 1.1.1.1 and 111.111.111.1 to R3.
The command we need to use for this is the neighbor x advertise-map command. The additional configuration on R1 looks like this:
ip prefix-list PL_R2_ADV_MAP permit 1.1.1.1/32
ip prefix-list PL_R2_ADV_MAP permit 111.111.111.1/32
!
ip prefix-list PL_R3_ADV_MAP permit 11.11.11.1/32
!
access-list 12 permit 192.168.12.0 0.0.0.255
access-list 13 permit 192.168.13.0 0.0.0.255
!
route-map R2_ADV_MAP permit 10
match ip add prefix-list PL_R2_ADV_MAP
!
route-map R3_ADV_MAP permit 10
match ip add prefix-list PL_R3_ADV_MAP
!
route-map R2_NON_EXIST permit 10
match ip add 12
!
route-map R3_NON_EXIST permit 10
match ip add 13
!
router bgp 100
net 192.168.12.0 m 255.255.255.0
net 192.168.13.0 m 255.255.255.0
neighbor 192.168.12.2 advertise-map R2_ADV_MAP non-exist-map R3_NON_EXIST
neighbor 192.168.13.3 advertise-map R3_ADV_MAP non-exist-map R2_NON_EXIST
This configuration is fairly simple. The basis is the neighbor 192.168.12.2 advertise-map R2_ADV_MAP non-exist-map R3_NON_EXIST
line. This line defines which routes to advertise (R2_ADV_MAP) and when to do so. In this case when the routes defined in R3_NON_EXIST do not exist. So the effect of this configuration in regard to R2 is that 1.1.1.1 /32 and 111.111.111.1 /32 won’t be advertised to R2 as long as the route to R3 exists.
A key point here is that the non-exist-map and the exist-map look at the BGP table, not the RIB. That’s why the networks 192.168.12.0 and 192.168.13.0 are added to BGP.
Before we applied this configuration to R1 the BGP tables on R2 and R3 looked as follows:
R2:
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 192.168.12.1 0 0 100 i
* 4.4.4.4/32 192.168.12.1 0 100 300 400 i
*> 192.168.24.4 0 0 400 i
*> 11.11.11.1/32 192.168.12.1 0 0 100 i
*> 111.111.111.1/32 192.168.12.1 0 0 100 i
R3:
Network Next Hop Metric LocPrf Weight Path
* 1.1.1.1/32 192.168.34.4 0 400 200 100 i
*> 192.168.13.1 0 0 100 i
*> 4.4.4.4/32 192.168.34.4 0 0 400 i
* 11.11.11.1/32 192.168.34.4 0 400 200 100 i
*> 192.168.13.1 0 0 100 i
* 111.111.111.1/32 192.168.34.4 0 400 200 100 i
*> 192.168.13.1 0 0 100 i
After the change it looks as follows:
R2:
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 192.168.24.4 0 400 300 100 i
* 4.4.4.4/32 192.168.12.1 0 100 300 400 i
*> 192.168.24.4 0 0 400 i
*> 11.11.11.1/32 192.168.12.1 0 0 100 i
*> 111.111.111.1/32 192.168.24.4 0 400 300 100 i
r> 192.168.12.0 192.168.12.1 0 0 100 i
*> 192.168.13.0 192.168.12.1 0 0 100 i
R3:
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 192.168.13.1 0 0 100 i
*> 4.4.4.4/32 192.168.34.4 0 0 400 i
*> 11.11.11.1/32 192.168.34.4 0 400 200 100 i
*> 111.111.111.1/32 192.168.13.1 0 0 100 i
* 192.168.12.0 192.168.34.4 0 400 200 100 i
*> 192.168.13.1 0 0 100 i
r 192.168.13.0 192.168.34.4 0 400 200 100 i
r> 192.168.13.1 0 0 100 i
The traceroutes reflect this behavior:
R4#trace 1.1.1.1 so lo1
Type escape sequence to abort.
Tracing the route to 1.1.1.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.34.3 2 msec 4 msec 1 msec
2 192.168.13.1 [AS 100] 1 msec * 5 msec
R4#trace 11.11.11.1 so lo1
Type escape sequence to abort.
Tracing the route to 11.11.11.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.24.2 2 msec 3 msec 6 msec
2 192.168.12.1 [AS 100] 3 msec * 3 msec
R4#trace 111.111.111.1 so lo1
Type escape sequence to abort.
Tracing the route to 111.111.111.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.34.3 3 msec 2 msec 2 msec
2 192.168.13.1 [AS 100] 2 msec * 2 msec
So that’s great right? If the link to R3 goes down everything will be routed via R2. So let’s test that case:
R1(config)#int g 0/1.13
R1(config-subif)#sh
R1(config-subif)#
R1(config-subif)#do sh ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 0.0.0.0 0 32768 i
*> 4.4.4.4/32 192.168.12.2 0 200 400 i
*> 11.11.11.1/32 0.0.0.0 0 32768 i
*> 111.111.111.1/32 0.0.0.0 0 32768 i
*> 192.168.12.0 0.0.0.0 0 32768 i
We can see that 192.168.13.0 has been removed from the BGP table. This should mean that R2 now has the BGP routes to 1.1.1.1 /32 and 111.111.111.1 /32 pointing directly to R1.
R2:
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 192.168.12.1 0 0 100 i
* 192.168.24.4 0 400 300 100 i
*> 4.4.4.4/32 192.168.24.4 0 0 400 i
*> 11.11.11.1/32 192.168.12.1 0 0 100 i
*> 111.111.111.1/32 192.168.12.1 0 0 100 i
* 192.168.24.4 0 400 300 100 i
r> 192.168.12.0 192.168.12.1 0 0 100 i
*> 192.168.13.0 192.168.24.4 0 400 300 100 i
Which is the case. The old BGP route however is still there. That’s because BGP is a slow protocol and R3 hasn’t removed the routes yet because it doesn’t know the neighbor is down for a long time. But after a few minutes R4 will use R2 as route to the destinations for which it used to use R3:
R4#trace 111.111.111.1 so lo1
Type escape sequence to abort.
Tracing the route to 111.111.111.1
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.24.2 3 msec 3 msec 5 msec
2 192.168.12.1 [AS 100] 3 msec * 2 msec
R4#
Keep in mind that BGP is a slow protocol and failover using this mechanism isn’t subsecond or even subminute. Especially when this information has to propagate the internet it can take a while. The other thing to keep in mind is that this solution only works when the link actually goes down and the route that is tracked is removed from the BGP table. In a soft failure scenario in which you can’t reach the neighbor, but the link stays up this doesn’t work. To work around that you can use an IP SLA using a tracked object on a dummy static route and redistribute that dummy route into BGP. Once the IP SLA goes down the tracked static will disappear from the routing table and therefor from the BGP table. This is a more reliable way of doing this.