BGP Route Reflectors

Written by jlgaddis on March 8, 2010 – 8:00 am -

Hopefully you recall that when running iBGP, a full mesh is required between all iBGP speaking peers within an autonomous system (AS). This can quickly lead to a huge number of peerings — and the associated management overhead — as we add more iBGP speakers. The total number of peerings needed to satisfy the full mesh requirement is illustrated by the following formula, where “n” is the number of iBGP speakers:

   n(n-1)/2

Thus:

  • 5 routers = 10 peerings
  • 10 routers = 45 peerings
  • 25 routers = 600 peerings

Would you want to manage all that? Me either. Enter route reflectors.

Route reflectors are one solution for keeping all of this under control. Route reflectors ease the full-mesh limitation and allows one router to advertise, or reflect, iBGP learned routes to other iBGP speakers. This has the end result of reducing the number of iBGP peers within our AS.

Here’s the topology we’ll be working with:

In this scenario, we’ll be running OSPF as our IGP and all routers will run iBGP and are members of AS 65000. R3 will serve as our route reflector, and all other routers only need to establish a BGP peering with R3. On R1 and R2 we’ll advertised the networks represented by the loopback0 interfaces as well.

Let’s get basic connectivity established.

R1# configure terminal
R1(config)# interface serial 0/1
R1(config-if)# ip address 198.18.13.1 255.255.255.0
R1(config-if)# no shutdown
R2# configure terminal
R2(config)# interface serial 0/1
R2(config-if)# ip address 198.18.23.2 255.255.255.0
R2(config-if)# no shutdown
R3# configure terminal
R3(config)# interface serial 1/2
R3(config-if)# clock rate 128000
R3(config-if)# ip address 198.18.13.3 255.255.255.0
R3(config-if)# no shutdown
R3(config-if)# interface serial 1/3
R3(config-if)# clock rate 128000
R3(config-if)# ip address 198.18.23.3 255.255.255.0
R3(config-if)# no shutdown
R3(config-if)# interface serial 1/0
R3(config-if)# encapsulation frame-relay
R3(config-if)# no shutdown
R3(config-if)# interface serial 1/0.34 point-to-point
R3(config-subif)# frame-relay interface-dlci 304
R3(config-fr-dlci)# ip address 198.18.34.3 255.255.255.0
R3(config-subif)# interface serial 1/0.35 point-to-point
R3(config-subif)# frame-relay interface-dlci 305
R3(config-fr-dlci)# ip address 198.18.35.3 255.255.255.0
R4# configure terminal
R4(config)# interface serial 0/0
R4(config-if)# encapsulation frame-relay
R4(config-if)# no shutdown
R4(config-if)# interface serial 0/0.34 point-to-point
R4(config-subif)# frame-relay interface-dlci 403
R4(config-fr-dlci)# ip address 198.18.34.4 255.255.255.0
R5# configure terminal
R5(config)# interface serial 0/0
R5(config-if)# encapsulation frame-relay
R5(config-if)# no shutdown
R5(config-if)# interface serial 0/0.35 point-to-point
R5(config-subif)# frame-relay interface-dlci 503
R5(config-fr-dlci)# ip address 198.18.35.5 255.255.255.0

At this point, make sure you can ping all routers from R3 and vice versa.

Go ahead and configure the loopback interfaces on R1 and R2.

R1(config-if)# interface loopback 0
R1(config-if)# ip address 198.18.111.1 255.255.255.255
R2(config-if)# interface loopback 0
R2(config-if)# ip address 198.18.222.2 255.255.255.255

Let’s configure our IGP, OSPF. We’ll keep it simple since our focus is on BGP. On R3, R4, and R5 configure OSPF process ID 1 and advertise all networks, e.g.:

! on R3, R4, and R5
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0

On R1 and R2, we’ll just run OSPF on the links to R3 (we’re “saving” our loopbacks for BGP).

R1(config-if)# router ospf 1
R1(config-router)# network 198.18.13.1 0.0.0.0 area 0
R2(config-if)# router ospf 1
R2(config-router)# network 198.18.23.2 0.0.0.0 area 0

Make sure you’re seeing all advertised routes on all routers.

When it comes to configuring BGP, the only place we have to do anything different is on the route reflector itself. Let’s go ahead and configure R1, R2, R4, and R5 for a BGP peering to R3. On R1 and R2, we’ll advertise the IP addresses of the loopback 0 interfaces into BGP as well.

R1(config-router)# router bgp 65000
R1(config-router)# neighbor 198.18.13.3 remote-as 65000
R1(config-router)# network 198.18.111.1 mask 255.255.255.255
R2(config-router)# router bgp 65000
R2(config-router)# neighbor 198.18.23.3 remote-as 65000
R2(config-router)# network 198.18.222.2 mask 255.255.255.255
R4(config-router)# router bgp 65000
R4(config-router)# neighbor 198.18.34.3 remote-as 65000
R5(config-router)# router bgp 65000
R5(config-router)# neighbor 198.18.35.3 remote-as 65000

Next, we simply have to configure BGP on R3. We’ll use the “route-reflector-client” option to the “neighbor” command to let R3 know that the other routers should be considered as route reflector clients (intuitive, huh!?). In this case, R3 will “reflect” advertisements from one client to the others. Hence, the advertisements from R1 and R2 (for their loopback 0 interfaces) will be reflected to the other routers. We’ll be able to verify this by looking at the BGP tables on R4 and R5.

R3(config-router)# router bgp 65000
R3(config-router)# neighbor 198.18.13.1 remote-as 65000
R3(config-router)# neighbor 198.18.13.1 route-reflector-client
R3(config-router)# neighbor 198.18.23.2 remote-as 65000
R3(config-router)# neighbor 198.18.23.2 route-reflector-client
R3(config-router)# neighbor 198.18.34.4 remote-as 65000
R3(config-router)# neighbor 198.18.34.4 route-reflector-client
R3(config-router)# neighbor 198.18.35.5 remote-as 65000
R3(config-router)# neighbor 198.18.35.5 route-reflector-client

Wait a moment for all the BGP sessions to come up (remember, BGP is sloooooow) then take a look at the BGP tables on R4 and R5.

R4(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*>i198.18.111.1/32  198.18.13.1              0    100      0 i
*>i198.18.222.2/32  198.18.23.2              0    100      0 i
R5(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*>i198.18.111.1/32  198.18.13.1              0    100      0 i
*>i198.18.222.2/32  198.18.23.2              0    100      0 i

That’s all there is to it! We’ve taken what normally would take a total of 10 BGP sessions and accomplished the same thing with just four. Later, we’ll talk about BGP confederations, another technique for reducing the iBGP mesh (mess).


Tags: , , , , | 1 Comment »

BGP Conditional Advertisements

Written by jlgaddis on March 5, 2010 – 5:39 pm -

When dealing with BGP, routes are normally advertised “unconditionally”. In other words, if a peering session with a neighbor is up, we’ll send them our routes. There may be times, however, when we want to refrain from advertising a prefix (or prefixes) to a neighbor. The conditional advertisement feature, says cisco.com, “is useful for multihomed networks, in which some prefixes are advertised to one of the providers only if information from the other provider is not present (this indicates a failure in the peering session or partial reachability)”.

To explain this a little better, take a look at the following topology and let’s go through a hypothetical scenario:

In this scenario, R4 (in AS 65100) represent us. We are multi-homed to R2 (AS 65002) and R5 (AS 65005), our service providers. Our connection to R5 is at 1544 Kbps (“T-1″), our connection to R2 is 128 Kbps over a frame-relay circuit, and both SPs will be sending us a default route via BGP. Normally, we would simply advertise all of our prefixes (we’ll have two) to both providers. With a little bit of AS prepending, it may even be possible to get most of our inbound traffic to flow over the R4-R5 link.

For our hypothetical situation, we’ll advertise 203.0.113.0/24, which represents the subnet our client PCs are on, to both providers and not attempt to do any manipulation of inbound traffic. Inbound traffic may come over either link. We want to ensure that traffic inbound to our server subnet (198.51.100.0/24), however, always take the faster (R4-R5) link. Even with a bit of manipulation (e.g. AS prepending), it may not be possible to ensure that 100% of inbound traffic comes over the faster link. Enter conditional advertisements.

How we’re going to handle this is to only advertise 198.51.100.0/24 to R5. R2 won’t be receiving an advertisement for that network directly from us, so it will send inbound traffic through its other connections, eventually transiting R5 and entering our network there. But, you might ask, what happens if our R4-R5 link goes down for whatever reason? At that point, there will be no routes for 198.51.100.0/24 advertised and inbound traffic won’t have any way to reach us. Within about 60 seconds, however, the BGP process on our router will notice that we have no longer have reachability to R5 and will begin advertising the 198.51.100.0/24 network to R2. At that point, inbound traffic will begin flowing again.

As mentioned, we’ll advertise 203.0.113.0/24 (our “clients” network) to both providers, all the time. We’ll advertise 198.51.100.0/24 to R5 (and only R5), as long as that link is up. If, for some reason, it goes down, then we’ll begin advertising 198.51.100.0/24 to R2, providing inbound traffic with an alternate, albeit slower, way of reaching us.

Let’s go ahead and get basic connectivity established:

R2# configure terminal
R2(config)# interface serial 0/0
R2(config-if)# encapsulation frame-relay
R2(config-if)# no shutdown
R2(config-if)# interface serial 0/0.24 point-to-point
R2(config-subif)# frame-relay interface-dlci 204
R2(config-fr-dlci)# ip address 172.16.24.1 255.255.255.252
R4# configure terminal
R4(config)# interface serial 0/0
R4(config-if)# encapsulation frame-relay
R4(config-if)# no shutdown
R4(config-if)# interface serial 0/0.24 point-to-point
R4(config-subif)# frame-relay interface-dlci 402
R4(config-fr-dlci)# ip address 172.16.24.2 255.255.255.252
R4(config-subif)# interface serial 0/1
R4(config-if)# no shutdown
R4(config-if)# ip address 172.16.14.2 255.255.255.252
R5# configure terminal
R5(config)# interface serial 0/1
R5(config-if)# clock rate 2000000
R5(config-if)# no shutdown
R5(config-if)# ip address 172.16.14.1 255.255.255.252

Make sure you can ping both R2 and R5 from R4. Now, let’s configure two loopback interfaces on R4 to represent our “servers” and “clients” subnets:

R4(config-if)# interface loopback 198
R4(config-if)# ip address 198.51.100.1 255.255.255.0
R4(config-if)# interface loopback 203
R4(config-if)# ip address 203.0.113.1 255.255.255.0

Configure the basic BGP session on our peers, R2 and R5. On both of these peers, we’ll send R4 a default route over BGP:

R2(config-subif)# router bgp 65002
R2(config-router)# neighbor 172.16.24.2 remote-as 65100
R2(config-router)# neighbor 172.16.24.2 default-originate
R5(config-if)# router bgp 65005
R5(config-router)# neighbor 172.16.14.2 remote-as 65100
R5(config-router)# neighbor 172.16.14.2 default-originate

On R4, we’ll do the same, with some other stuff added in. First, we need to ensure that we don’t act as a transit AS between our two providers. We’ll prevent this by creating an access list restricting what prefixes we advertise to our neighbors, and apply an outbound distribute-list to those peers. Let’s go ahead and begin advertising our two networks (to both peers, for now) as well:

R4(config-if)# access-list 25 permit 198.51.100.0
R4(config)# access-list 25 permit 203.0.113.0
R4(config)# router bgp 65100
R4(config-router)# neighbor 172.16.24.1 remote-as 65002
R4(config-router)# neighbor 172.16.24.1 distribute-list 25 out
R4(config-router)# neighbor 172.16.14.1 remote-as 65005
R4(config-router)# neighbor 172.16.14.1 distribute-list 25 out
R4(config-router)# network 198.51.100.0 mask 255.255.255.0
R4(config-router)# network 203.0.113.0 mask 255.255.255.0

On R4, we should now see routes for 172.16.24.1/30 and 172.16.14.1/30 (as well as our locally originated routes) in our BGP table:

R4(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
   Network          Next Hop            Metric LocPrf Weight Path
*  0.0.0.0          172.16.14.1              0             0 65005 i
*>                  172.16.24.1              0             0 65002 i
*> 198.51.100.0     0.0.0.0                  0         32768 i
*> 203.0.113.0      0.0.0.0                  0         32768 i

So far, so good.

Let’s make an AS path access list that defines an AS path that came directly from AS 65005

R4(config-router)# ip as-path access-list 1 permit ^65005$

Now, we need to create two more access lists. One will match the default route we receive from R5, the other will match the route we want to conditionally advertise to R2 (198.51.100.0/24).

R4(config)# access-list 5 permit 0.0.0.0 255.255.255.255
R4(config)# access-list 2 permit 198.51.100.0 0.0.0.255

Next up, we need to create two route maps (an “advertise-map” and a “non-exist-map”) and apply that config to our neighbor R2.

R4(config)# route-map ADVERTISE permit 10
R4(config-route-map)# match ip address 2
R4(config-route-map)# route-map NON-EXIST permit 10
R4(config-route-map)# match ip address 5
R4(config-route-map)# match as-path 1

Let’s go ahead and apply this to our neighbor R2 and clear the BGP process, then I’ll explain how it works.

R4(config-route-map)# router bgp 65100
R4(config-router)# neighbor 172.16.24.1 advertise-map ADVERTISE non-exist-map NON-EXIST
R4(config-router)# do clear ip bgp *

What we’ve done is told our BGP process that for our neighbor 172.16.24.1 (R2), advertise the routes described by the ADVERTISE route-map (thus, routes matching ACL 2) when the routes described by the NON-EXIST route-map (thus, routes matching ACL 5 with an AS Path as described by ACL 1). It seems like a lot to digest all at once, but if you break it down into its various parts, it becomes quite clear.

Let’s take a look at our BGP tables. On R4, we should see exactly what we saw earlier: the default routes from R2 and R5 and our two locally originated routes:

R4(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*  0.0.0.0          172.16.14.1              0             0 65005 i
*>                  172.16.24.1              0             0 65002 i
*> 198.51.100.0     0.0.0.0                  0         32768 i
*> 203.0.113.0      0.0.0.0                  0         32768 i

On R5, we should see routes to both of our networks 198.51.100.0/24 and 203.0.113.0/24:

R5(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 198.51.100.0     172.16.14.2              0             0 65100 i
*> 203.0.113.0      172.16.14.2              0             0 65100 i

Last, on R2, we should only see a route to 203.0.113.0/24, since the R4-R5 link is up:

R2(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 203.0.113.0      172.16.24.2              0             0 65100 i

Still, so far so good. Now, we test!

Let’s go to R5 and shut down the serial 0/1 interface that’s connected to R4. This will cause the BGP session to drop, which R4 will notice and, after a moment, begin advertising the 198.51.100.0/24 network to R2.

R5(config-router)# interface serial 0/1
R5(config-if)# shutdown

Wait a moment, then look at R2’s BGP table again:

R2(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
   Network          Next Hop            Metric LocPrf Weight Path
*> 198.51.100.0     172.16.24.2              0             0 65100 i
*> 203.0.113.0      172.16.24.2              0             0 65100 i

There’s the route to 198.51.100.0/24 from AS 65100, exactly what we wanted! Now, what happens when the connection between R4 and R5 comes back up?

R5(config-if)# no shutdown

The BGP session between R4 and R5 will come back up, R4 will receive the default route from R5, the BGP process will notice, and the route for 198.51.100.0/24 that is being advertised to R2 will be withdrawn:

R2(config-router)# do show ip bgp | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 203.0.113.0      172.16.24.2              0             0 65100 i

Success!


Tags: , , , , | No Comments »

Getting BGP routes into dynamips (with video)

Written by jlgaddis on August 21, 2009 – 5:24 am -

UPDATE: If you’re not interesting in doing this yourself and just want to see it in action, check out the video, “Dumping 265k BGP routes into dynamips”. When I went through these steps to document, I ended up with 298,870 prefixes in my dynamips router. When I did it the second time, to record the video, I only ended up with 265,857 prefixes. Not sure why the discrepancy, but at least you can see it works! YMMV!

After I posted “Dynamips, a 7200, and a full BGP table”, a number of you left comments asking how I got the BGP routes into dynamips… the answer is einval’s “bgpsimple”.

“This perl script allows to setup an BGP adjacency with a BGP peer, monitor the messages and updates received from that peer, and to send out updates from a predefined set of NLRIs/attributes. BGP session and message handling is done by Net::BGP.”

0. Pre-requisites

On Ubuntu, at least, you’re going to need to install some packages that likely aren’t already installed. We’re going to need these to be able to build bgpdump in step 2. Fortunately, the following command will install everything you need (well, except for Net::BGP and bgpsimple):

[root@stewie ~]# apt-get install build-essential zlib1g-dev libbz2-dev

1. Install Net::BGP

Before we can even think about doing this, we’re going to need to install the Net::BGP perl modules, most likely from CPAN (your distribution may provide it in a handy installable package, but I wouldn’t count on it). I’m using an Ubuntu 8.04 LTS Server installation — you can use whichever distribution (or BSD) that you like, but this is what I’m using.

Fire up the CPAN shell:

[root@stewie ~]# perl -MCPAN -e shell

cpan shell -- CPAN exploration and modules installation (v1.9402)
Enter 'h' for help.

cpan[1]>

If this is the first time you’ve done this, you’ll have to go through some configuration. That configuration is out of scope of this document. Google it.

Next, install Net::BGP and exit the CPAN shell:

cpan[1]> install Net::BGP
CPAN: Storable loaded ok (v2.15)
Going to read '/home/jlgaddis/.cpan/Metadata'
  Database was generated on Thu, 20 Aug 2009 22:27:00 GMT
Running install for module 'Net::BGP'
Running make for K/KB/KBRINT/Net-BGP-0.13.tar.gz

[snip]

Appending installation info to /usr/lib/perl/5.8/perllocal.pod
  KBRINT/Net-BGP-0.13.tar.gz
  /usr/bin/make install  -- OK

cpan[2]> exit
Lockfile removed.
[root@stewie ~]#

2. Install bgpdump

As mentioned in bgpsimple’s README, we’re going to use a RIB dump from a router in the default-free zone. Fortunately, RIPE makes this data available for download. Before we can use it, however, we need to convert it to a format that bgpsimple can use. We’re going to download and compile bgpdump which can do the conversion for us.

[root@stewie ~]# wget http://www.ris.ripe.net/source/libbgpdump-1.4.99.9.tar.gz
--22:00:48--  http://www.ris.ripe.net/source/libbgpdump-1.4.99.9.tar.gz
           => `libbgpdump-1.4.99.9.tar.gz'
Resolving www.ris.ripe.net... 193.0.19.19
Connecting to www.ris.ripe.net|193.0.19.19|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 82,909 (81K) [application/x-gzip]

100%[=====================================================>] 82,909       130.32K/s

22:00:49 (129.85 KB/s) - `libbgpdump-1.4.99.9.tar.gz' saved [82909/82909]

[root@stewie ~]#

Uncompress the tarball and change to the newly created directory:

[root@stewie ~]# tar zxf libbgpdump-1.4.99.9.tar.gz
[root@stewie ~]# cd libbgpdump-1.4.99.9/

Be sure to skim through the README file in this directory.

Now, we can begin to build bgpdump. I don’t need IPv6 support, so I’m going to leave it out.

[root@stewie ~/libbgpdump-1.4.99.9]# ./configure --disable-ipv6
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes

[snip]

checking for inet_ntoa... yes
checking for inet_ntop... yes
checking for IPv6 support... disabled
configure: creating ./config.status
config.status: creating Makefile
config.status: creating bgpdump-config.h
[root@stewie ~/libbgpdump-1.4.99.9]#

Once the configure script has completed (successfully!), we can build bgpdump:

[root@stewie ~/libbgpdump-1.4.99.9]# make

[snip]

[root@stewie ~/libbgpdump-1.4.99.9]# ls -l bgpdump
-rwxr-xr-x 1 root root 46540 2009-08-20 22:14 bgpdump

As you see, we end up with a binary named “bgpdump”, which I’m going to copy over to /usr/local/bin. I’m also going to create a directory named “bgp”, where I’ll store the files we’ll be working with:

[root@stewie ~/libbgpdump-1.4.99.9]# cp bgpdump /usr/local/bin
[root@stewie ~/libbgpdump-1.4.99.9]# mkdir ../bgp
[root@stewie ~/libbgpdump-1.4.99.9]# cd ../bgp

3. Get some route data

Before we can inject any routes into our router, we need some routes to inject! As mentioned, RIPE makes these available to us. Go to the “RIS Raw Data” page, pick a collector, then download a file containing the raw data:

[root@stewie ~/bgp]# wget http://data.ris.ripe.net/rrc16/2009.08/bview.20090820.2359.gz
--22:59:26--  http://data.ris.ripe.net/rrc16/2009.08/bview.20090820.2359.gz
           => `bview.20090820.2359.gz'
Resolving data.ris.ripe.net... 193.0.19.19
Connecting to data.ris.ripe.net|193.0.19.19|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3,108,638 (3.0M) [application/x-gzip]

100%[=====================================================>] 3,108,638    234.33K/s    ETA 00:00

22:59:40 (214.70 KB/s) - `bview.20090820.2359.gz' saved [3108638/3108638]

[root@stewie ~/bgp]#

Now that we have some routing data, we need to get it into a format that bgpsimple can work with. This is where bgpdump comes into play. Copying from bgpsimple’s README:

[root@stewie ~/bgp]# zcat bview.20090820.2359.gz | bgpdump -m - > myroutes
[root@stewie ~/bgp]#

4. Download bgpsimple

Download the code for bgpsimple:

[root@stewie ~/bgp]# wget http://bgpsimple.googlecode.com/files/bgp_simple.tgz
--23:11:17--  http://bgpsimple.googlecode.com/files/bgp_simple.tgz
           => `bgp_simple.tgz'
Resolving bgpsimple.googlecode.com... 209.85.225.82
Connecting to bgpsimple.googlecode.com|209.85.225.82|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9,324 (9.1K) [application/x-gzip]

100%[=====================================================>] 9,324         --.--K/s

23:11:17 (114.18 KB/s) - `bgp_simple.tgz' saved [9324/9324]

[root@stewie ~/bgp]#

Uncompress the tarball:

[root@stewie ~/bgp]# tar zxf bgp_simple.tgz

You should end up with a Perl script named “bgp_simple.pl”:

[root@stewie ~/bgp]# ls -l bgp_simple.pl
-rwxr-xr-x 1 jlgaddis jlgaddis 20388 2009-01-07 10:31 bgp_simple.pl

5. Start up your dynamips router

Now it’s time to fire up our virtual 7200 router. Here’s the .net file for dynagen that I used (don’t forget to change the filenames and paths, as appropriate).

Start up dynamips, start up dynagen, connect to the console, and do some initial configuration:

[jlgaddis@stewie ~]$ telnet 192.168.1.109 2000
Trying 192.168.1.109...
Connected to 192.168.1.109.
Escape character is '^]'.
Connected to Dynamips VM "R1" (ID 0, type c7200) - Console port


              Restricted Rights Legend

Use, duplication, or disclosure by the Government is
subject to restrictions as set forth in subparagraph
(c) of the Commercial Computer Software - Restricted
Rights clause at FAR sec. 52.227-19 and subparagraph
(c) (1) (ii) of the Rights in Technical Data and Computer
Software clause at DFARS sec. 252.227-7013.

[snip]

Router> enable
Router# configure terminal
Router(config)# no ip domain lookup
Router(config)# no ip http server
Router(config)# hostname c7200
c7200(config)# line con 0
c7200(config-line)# exec-timeout 0 0
c7200(config-line)# logging synchronous

6. Configure dynamips router’s network interface

We need to put an IP address on the router’s fastethernet 2/0 interface, then verify that we can ping the host that we’re going to run bgpsimple on:

c7200(config-line)# interface fastethernet 2/0
c7200(config-if)# ip address 192.168.1.99 255.255.255.0
c7200(config-if)# no shutdown
c7200(config-if)#
*Aug 20 23:23:26.167: %LINK-3-UPDOWN: Interface FastEthernet2/0, changed state to up
*Aug 20 23:23:27.167: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet2/0,
changed state to up
c7200(config-if)# do ping 192.168.1.104

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.104, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/8/12 ms

7. Configure the BGP session on your dynamips router

Next, we need to configure our dynamips router for a BGP session with bgpsimple. You will need to change IP address below (192.168.1.104) to the IP address of the box you are running bgpsimple on:

c7200(config-if)# router bgp 65000
c7200(config-router)# no synchronization
c7200(config-router)# no auto-summary
c7200(config-router)# neighbor 192.168.1.104 remote-as 65000

8. Test with a limited number of prefixes

Now that our dynamips router is configured for BGP, we’re ready for a quick test with a small number of prefixes (10, for now). Look at the README for what all these command-line options mean (I wrapped this for readability, you don’t have to):

[root@stewie ~/bgp]# ./bgp_simple.pl -myas 65000 -myip 192.168.1.104 \
> -peerip 192.168.1.99 -peeras 65000 -p myroutes -m 10 -n
---------------------------------------- CONFIG SUMMARY --------------------------------------------------
Configured for an iBGP session between me (ASN65000, 192.168.1.104) and peer (ASN65000, 192.168.1.99).
Will use prefixes from file myroutes.
Maximum number of prefixes to be advertised: 10.
Will spoof next hop address to 192.168.1.104.
----------------------------------------------------------------------------------------------------------
Sending full update.

[snip]

Looks like that worked, let’s take a look at the BGP table on our dynamips router:

*Aug 20 23:31:49.715: %BGP-5-ADJCHANGE: neighbor 192.168.1.104 Up
c7200# show ip bgp
BGP table version is 31, local router ID is 192.168.1.99
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i1.1.1.0/24       192.168.1.104                   0      0 25152 6939 3303 8300 i
*>i3.0.0.0          192.168.1.104                   0      0 25152 6939 15412 9304 80 i
*>i3.51.92.0/23     192.168.1.104                   0      0 25152 23148 7018 ?
*>i4.0.0.0/9        192.168.1.104                   0      0 25152 1273 3356 i
*>i4.0.0.0          192.168.1.104                   0      0 25152 1273 3356 i
*>i4.21.103.0/24    192.168.1.104                   0      0 25152 6939 3549 46133 i
*>i4.23.88.0/24     192.168.1.104                   0      0 25152 23148 7018 46164 i
*>i4.23.88.0/23     192.168.1.104                   0      0 25152 23148 7018 46164 i
*>i4.23.89.0/24     192.168.1.104                   0      0 25152 23148 7018 46164 i
*>i4.23.92.0/22     192.168.1.104                   0      0 25152 23148 7018 46164 i
c7200#

And there’s our 10 routes! w00t!

9. Advertise all the routes!

Now that we now we can get an adjacency up and exchange routes, let’s go for the gusto!

Kill bgp_simple.pl (CTRL-C works) and let’s take a quick look at how many routes are in the “myroutes” file.

[root@stewie ~/bgp]# wc -l myroutes
300035 myroutes

In my case, we have just over 300k. Your numbers may vary slightly — and there very well may be duplicate prefixes — depending on which dump you download from RIPE. In order to inject all the routes, we just run bgp_simple.pl as before, but without the “-m 10″ (maximum of 10 prefixes to advertise) option (again, wrapped for readability):

[root@stewie ~/bgp]# ./bgp_simple.pl -myas 65000 -myip 192.168.1.104 \
> -peerip 192.168.1.99 -peeras 65000 -p myroutes -n
---------------------------------------- CONFIG SUMMARY --------------------------------------------------
Configured for an iBGP session between me (ASN65000, 192.168.1.104) and peer (ASN65000, 192.168.1.99).
Will use prefixes from file myroutes.
Maximum number of prefixes to be advertised: 10.
Will spoof next hop address to 192.168.1.104.
----------------------------------------------------------------------------------------------------------
Sending full update.

[snip]

And now we just watch the number of prefixes received continually go up on our dynamips router:

c7200# show ip bgp summary | begin Neighbor
Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.1.104   4 65000   98425      21    98413    0    0 00:01:24    98237
c7200# show ip bgp summary | begin Neighbor
Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.1.104   4 65000  141060      23   141069    0    0 00:02:04   140849
c7200# show ip bgp summary | begin Neighbor
Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.1.104   4 65000  238966      25   238975    0    0 00:03:16   238739

We can take a quick look at a few of the prefixes in our BGP table:

c7200# show ip bgp 12.0.0.0/8 longer-prefixes | begin Network
   Network          Next Hop            Metric LocPrf Weight Path
*>i12.0.0.0/9       192.168.1.104                   0      0 25152 23148 7018 i
*>i12.0.0.0         192.168.1.104                   0      0 25152 23148 7018 i
*>i12.0.18.0/24     192.168.1.104                   0      0 25152 23148 7018 27585 i
*>i12.0.19.0/24     192.168.1.104                   0      0 25152 1273 3561 27487 i
*>i12.0.28.0/24     192.168.1.104                   0      0 25152 1273 4323 30050 i
*>i12.0.29.0/24     192.168.1.104                   0      0 25152 1273 174 30538 i
*>i12.0.33.0/24     192.168.1.104                   0      0 25152 1273 174 40544 i
*>i12.0.43.0/24     192.168.1.104                   0      0 25152 23148 7018 2386 i
*>i12.0.48.0/20     192.168.1.104                   0      0 25152 1273 174 1742 i
*>i12.0.153.0/24    192.168.1.104                   0      0 25152 23148 7018 6519 i
*>i12.0.170.0/24    192.168.1.104                   0      0 25152 23148 7018 22528 i
*>i12.0.239.0/24    192.168.1.104                   0      0 25152 19151 1239 33628 i
[snip]

That’s all there is to it!

10. All your routes are belong to us!

c7200# show ip bgp summary
BGP router identifier 192.168.1.99, local AS number 65000
BGP table version is 1038362, main routing table version 1038362
298870 network entries using 34967790 bytes of memory
298870 path entries using 15541240 bytes of memory
51910/51909 BGP path/bestpath attribute entries using 6436840 bytes of memory
47723 BGP AS-PATH entries using 1265376 bytes of memory
1 BGP community entries using 24 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 58211270 total bytes of memory
BGP activity 668359/369489 prefixes, 668359/369489 paths, scan interval 60 secs

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.1.104   4 65000  669061      20  1038362    0    0 00:04:16   298870
c7200#

OPTIONAL: If the BGP connection between bgpsimple and your dynamips router dies due to a hold timer expiring, you can get around this by doing two things:

  1. Editing bgp_simple.pl. At line 220, I added two lines:
        KeepAliveTime           => 600,
        HoldTime                => 1800,

That “section” of code (setting up the peer connection using Net::BGP::Peer) now reads like this:

my $bgp  = Net::BGP::Process->new();
my $peer = Net::BGP::Peer->new(
        Start                   => 0,
        ThisID                  => $myip,
        ThisAS                  => $myas,
        PeerID                  => $peerip,
        PeerAS                  => $peeras,
        KeepaliveCallback       => \&sub_keepalive_callback,
        UpdateCallback          => \&sub_update_callback,
        NotificationCallback    => \&sub_notification_callback,
        ErrorCallback           => \&sub_error_callback,
        OpenCallback            => \&sub_open_callback,
        ResetCallback           => \&sub_reset_callback,
        KeepAliveTime           => 600,
        HoldTime                => 1800,
);
  1. Adjusting the BGP timers on the dynamips router, like so:
c7200# configure terminal
c7200(config)# router bgp 65000
c7200(config-router)# timers bgp 600 1800
c7200(config-router)# end

We can then see those values reflected here:

c7200# show ip bgp neighbor 192.168.1.104 | in Last
  Last read 00:00:00, last write 00:00:56, hold time is 1800, keepalive interval is 600 seconds
c7200#

Note that it’s probably best to change both sides (bgp_simple.pl and your router’s config), since BGP will use the lowest of the values configured between peers.


Tags: , , , , , , , , , | 6 Comments »

Using BGP communities to influence routing, part 2

Written by jlgaddis on August 10, 2009 – 9:11 am -

I wanted to follow-up to an earlier post, “Using BGP communities to influence routing”, and show some more ways we can use BGP communities to influence routing on the Internet. What we’re going to see today is very common in the real world, although it does take the cooperation of your service provider.

If you’re lucky, your service provider will have already published a listing of communities that they accept and what effect they have. The ones we’ll be using today come from an old XO Communications document that I found.

Here’s the topology we’re going to be working with today:

We’re going to be the customer, in AS 65001. To keep things simple, we’ll configure a single connection on one service provider, XO Communications in AS 2828. As you can see, XO peers with a number of other providers. We have three loopback interfaces that we’re going to create, and the IP addresses we assign to those will be the ones we’re advertising into BGP.

Under normal circumstances, XO would simply pass along our advertisements to its peers. We’re going to see how we change that, however, by applying some communities to our routes as we send them to XO.

Here we have a small example of the communities a service provider might accept. By tagging our routes with these values, we can control how XO handles those routes. For example, if we send community 2828:1003, XO won’t advertise that route to Sprint. Likewise, if we send community 2828:1308, XO will prepend its own AS number three times. The possibilities are endless.

The bottom half of that diagram shows what we’ll actually accomplish when we’re done. When advertising our routes, we’ll use communities to tell XO:

  • don’t advertise 192.168.0.1/32 to Sprint (2828:1003),
  • prepend twice when advertising 192.168.0.1/32 to Level3 (2828:1207),
  • prepend once when advertising 192.168.0.1/32 to AT&T (2828:1108),
  • prepend thrice when advertising 192.168.1.1/32 to Sprint (2828:1303),
  • don’t advertise 192.168.1.1/32 to Level3 (2828:1007),
  • prepend twice when advertising 192.168.1.1/32 to AT&T (2828:1208), and
  • advertise 192.168.2.1 normally (no communities)

That’s a big list of demands, but it’s actually quite easy to do and — even better — it doesn’t require us to deal with another person at our service provider. By using these communities, we can do it ourselves (and change it whenever we want!).

For this lab, the XO, ATT, SPRINT, and LEVEL3 routers have already been configured. I’m intentionally not posting the configuration from XO, as it is out of the scope of this posting. While I may post it later, we’re only worried about how to configure things on the customer side.

Here we go…


Tags: , , , , | 1 Comment »

Dynamips, a 7200, and a full BGP table

Written by jlgaddis on August 7, 2009 – 5:15 am -

I’ve been using dynamips on and off for a while now and always knew it was cool as hell, but this just really impressed me:

c7200# show ip bgp summary
BGP router identifier 192.168.1.201, local AS number 65101
BGP table version is 593019, main routing table version 593019
297882 network entries using 34852194 bytes of memory
297882 path entries using 15489864 bytes of memory
56505/56484 BGP path/bestpath attribute entries using 7006620 bytes of memory
51421 BGP AS-PATH entries using 1620448 bytes of memory
1632 BGP community entries using 107766 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 59076892 total bytes of memory
BGP activity 298425/543 prefixes, 298425/543 paths, scan interval 60 secs

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.1.81    4 65001  592483     167   593019    0    0 01:19:55   297882

192.168.1.201 is a 7200 running under dynamips, and I just fed it a (nearly) full BGP table.

For the curious, that was the only router I had running under dynamips and the host is a MacBook (10.5.8), with a 2.2GHz Core2Duo and 4GB of RAM.

How fuckin’ cool is that!?


Tags: , , , , | 8 Comments »