Things I know about BGP

Full routes
Currently the IPv4 Internet is at about 515k prefixes and has been growing at about 15% each year for the last few years. That means in 5 years the IPv4 Internet may contain more than 1 million prefixes.

Currently the IPv6 Internet is at about 21k prefixes and has been growing at about 30% each year (on average). That means in 5 years the IPv6 Internet may contain more than 75k prefixes

Any router that receives full routes must hold them in memory, so if you want to accept full routes you have to watch your memory footprint to make sure that your platform can handle it.

Partial routes
are when you accepting a fraction of the full routing table. This can be some subnet of full routes, or just a default route. Your carrier can filter routes for you or you can filter them yourself.

When you’re using a default route your carrier can advertise this to you or you can just use a static route, but at least a carrier advertised default will disappear if the BGP session goes down.

Even with partial routes you can still control inbound and outbound traffic paths for your prefixes, but the limitation is that your router cannot make best path selection on prefixes that it doesn’t know about. This means that if your upstream carrier has a problem (maybe they lose their own upstream providers?) then your own routes may not reflect this and your traffic may get dropped.

Configuring Partial routes
This configuration shows how to limit learned prefixes to those on your upstream ASN +1. That means you’ll learn routes that are part of your upstream carrier’s ASN, plus any routes of their directly connected neighboring ASNs.

ip as-path access-list 1 permit ^65533_[0-9]*$
!
router bgp 65534
neighbor 10.3.128.1 filter-list 1 in

Before
sh ip bgp | begin Network
Network Next Hop Metric Weight Path
* 10.30.30.30/32 10.3.128.1 0 65533 65531 65530
*> 10.1.128.1 0 65532 65530 ?

After
sh ip bgp | begin Network
Network Next Hop Metric Weight Path
*> 10.30.30.30/32 10.1.128.1 0 65532 65530 ?

Why do we want to manipulate traffic?
Sometimes you may have circuits with a cost difference so load balancing isn’t sensible. Some networks have better peering so your customers are closer over that link. Some networks just have better performance or latency.

Or it might just be as simple as you want to push traffic to another circuit for maintenance – if you need to reload some hardware or if your carrier has a planned outage.

Controlling outbound traffic with local preference
Local preference is a blunt instrument, it simply alters the preference for all prefixes learned from a peer. The default local preference is 100, and the higher local preference wins. This is very useful for setting a backup peer.

route-map rm-bgp-localpref permit 10
set local-preference 500
!
router bgp 65534
Neighbor 10.1.128.1 route-map rm-bgp-localpref in

Verification
sh ip bgp | begin Network
Network Next Hop Metric LocPrf Path
* 10.31.31.31/32 10.3.128.1 65533 65531 ?
*> 10.1.128.1 0 500 65532 65531 ?

Controlling outbound traffic with weight
Weight is a fine tool as it can be applied per-prefix (with ACLs). The default weight is 0, and the higher weight wins. This is useful for directing particular flows of traffic over particular paths.

ip access-list standard acl-bgp-weight
permit 10.33.255.255
!
route-map rm-bgp-weight permit 10
match ip address acl-bgp-weight
set weight 100
continue
route-map rm-bgp-weight permit 20
!
router bgp 65534
neighbor 10.3.128.1 route-map rm-bgp-weight in

Verification
sh ip bgp | begin Network
Network Next Hop LocPrf Weight Path
*> 10.33.33.33/32 10.1.128.1 500 0 65532 65531 65533 ?
* 10.3.128.1 0 65533 ?
* 10.33.255.255/32 10.1.128.1 500 0 65532 65531 65533 ?
*> 10.3.128.1 100 65533 ?

Controlling inbound traffic with AS_PATH prepending

A blunt instrument, you make your advertisements look further away on one circuit compared to another. The effect is that routers that can see both paths will prefer the shorter one, encouraging traffic to use the shorter path. Even though this can be applied per-prefix, it is still a blunt too because sometimes the prepended path is still the best one.

ip prefix-list pfl-bgp-prepend seq 10 permit 10.34.255.255/32
!
route-map rm-bgp-prepend permit 10
match ip address prefix-list pfl-bgp-prepend
set as-path prepend 65534 65534 65534 65534 65534 65534 65534 65534 65534 65534
!
router bgp 65534
Neighbor 10.3.128.1 route-map rm-bgp-prepend out

There are no tools on the local router to show this, so you have to use a BGP looking glass to validate:
http://lg.peer1.net
http://lg.he.net
Note that looking glass sites far from you will probably not see your prepends, as BGP routers only share their best path with each other – so your prepended path probably won’t make it to the other side of the planet.

Controlling inbound traffic with MED (multi-exit discriminator)
A fine tool, very effective per-prefix control but it only applies when peering to a single AS with multiple circuits. This isn’t a very common configuration.

MED a peer to use a particular circuit for some (or all) of your advertised prefixes, but sometimes metrics are filtered by peers so you must work with them to make sure it is supported.

ip access-list standard acl-bgp-med
permit 10.10.10.0 0.0.0.255
!
route-map rm-bgp-med permit 10
match ip address name acl-bgp-med
set metric 200
!
router bgp 65534
neighbor 192.0.2.1 route-map rm-bgp-med out

There are no tools on the local router to show this, so you have to work with your peer to validate this.

Blackhole incoming DDoS using BGP
This is a local administrator activated mechanism, whereby you can use BGP to indicate to your upstream provider to null route traffic for a particular prefix of yours. This ensures the DDoS target is offline but saves the rest of the network, and you don’t pay for bandwidth for incoming DDoS. This must be arranged with your upstream provider.

ip route 10.34.254.254 255.255.255.255 Null0 tag 111
!
route-map rm-bgp-blackhole permit 10
match tag 111
set community 65534:666
!
router bgp 65534
redistribute static route-map rm-bgp-blackhole
neighbor 10.1.128.1 send-community
neighbor 10.3.128.1 send-community
!
ip bgp new-format

Verification
show ip bgp community | begin Network
Network Next Hop Metric LocPrf Weight Path
*> 10.34.255.255/32 0.0.0.0 0 32768 ?

Cisco CLI Shortcuts

Some of these shortcuts I’ve used for a long time, and a couple of them I learned today. I can’t believe I’ve gone so long without knowing how to go to the beginning of a line. My left arrow key is going to miss me.

CTRL-A will take you to the beginning of a line. Very handy for negating a configuration item like this:
no ip route 10.10.10.10 255.255.255.0 20.20.20.20
CTRL-E will take you to the end of the line. Not as handy but at least you know how to move around now.

The default command will set an interface (and many other configuration items) to their default settings. This is very handy if you have complex interface configurations and you want to start from scratch without removing the configuration line by line.
default interface Fa0/0

Learn the short-hand available on your platform. I didn’t realize the time-savings of this method until I saw a TAC engineer do this, and now I am addicted to it. If you look at this configuration:
configuration terminal
interface FastEthernet0/0
switchport
switchport trunk encapsulation dot1q
switchport mode trunk
switchport trunk allowed vlan 10,100,2000-2010
switchport nonegotiate
exit
exit
copy running-config startup-config

You can do the same thing with a lot less typing, and you don’t have to tab-complete all the time either:
conf t
int fa0/0
sw
sw tr en do
sw mo tr
sw tr al vl 10,100,2000-2010
sw no
end
cop ru st

This saves time, and whether you’re designing, testing, configuring or troubleshooting it pays to get more work done in less time.

You can add or remove VLANs from a trunk without having to type the whole line:
interface FastEthernet0/0
switchport trunk allowed vlan remove 100
switchport trunk allowed vlan add 200
end

On all platforms you can use the | include command to match basic text searches on any show command:
show run | include username
This command easily shows the usernames and privilege levels of those users in the configuration.

This handy command shows only CPU processes that are actually using CPU cycles, and it illustrates the | exclude command to filter out text:
show proc cpu | exclude 0.00

I often want to see configuration that I know starts somewhere in the middle, or bottom of the config. On simple router configs it isn’t a big deal to page through the data, but complex switches like the 6500 series can easily get to be thousands of lines long and paging through all that can get tiring (and boring). Use the | begin command to match text and start showing the configuration there:
show run | begin vty
This will start displaying the configuration at the first line that matches “vty” and now you can review your remote access configuration without having to hit the space bar a few hundred times.

On router platforms you can use the | section command to match entire sections of the configuration:
show run | section router
This will list the full configuration of any dynamic routing protocols you have configured. Try this on a CME router and you’ll really be happy when you can list all the configured ephones and ephone-dns:
show run | section ephone-dn

If you’re testing the bandwidth of a link you might want to get interface statistics:
show interface Gi0/8 | i rate
Queueing strategy: fifo
5 minute input rate 3000 bits/sec, 3 packets/sec
5 minute output rate 4000 bits/sec, 4 packets/sec

But you’ll notice this is a 5 minute statistic, which means you’ll have to be loading this interface for at least 5 minutes before you get a true reading. For the impatient there is a solution, we can set the statistical interval to 30 seconds (the minimum):
conf t
interface Gi0/8
load-interval 30
end
sh int gi 0/8 | i rate
Queueing strategy: fifo
30 second input rate 1000 bits/sec, 1 packets/sec
30 second output rate 1000 bits/sec, 1 packets/sec

That’s better – now you only have to load the interface for 30 seconds to figure out the utilization. As far as data-rate analysis goes it is as close as you need to get most of the time; you’ll have to use different methods to get more granular than this.