bgp in the lab

long, long time ago, playing with BGP was reserved for secret group of people, that somewhat alike Lems Trurl and Klapaucjusz were laughing from mere mortals but didn’t share the knowledge. then, a lot of things changed, trainings, certifications appeared, and then bootcamps and finally massive, open-for-all intro courses. and now, BGP is everywhere and is configured by anyone - you’ll find typical home wives running it as well, as without it they couldn’t upload new contact via bluetooth it seems.

fact is however, that real-life experience is still limited, and one of the reasons is limited availability of full table views in BGP. lab networks are usually small and even if they offer ‘hundreds’ of prefixes, it’s hardly real setup and real problems. now, if you haven’t tried it in the lab, as soon as you’ll need to work with real table and big iron, you may not feel comfortable and confident anymore as in the lab. and so, we tend to use easiest tricks, almost muscle memory - things like AS_PATH prepend, local-preference and that’s about it.

once dynamips was released (doing on-the-fly binary interpretation of Cisco IOS), and it’s well known how to build Olive (JunOS on PC/VMware), all that labbing could be easily more interesting by injecting full, real table view of global BGP.

real table copy

of course you can ask your friend for feed - why would you need to do to that extremes, if you can simply load existing full view, even without being connected to internet? RIRs are publishing them and it’s very easy.

i’ll focus on FreeBSD tutorial, but with other OSes this may be even simpler. you can also use a number of tools - and again, i’ll use simplest and shortest way to get the job done.

first of all, we’ll need Net::BGP package:

make install clean

and then lib that will enable us to translate one format to the one accepted by script:

tar xvfz libbgpdump-latest.tgz
cd libbgpdump-
cp bgpdump ../
cd ../

once this is done, you should have bgpdump binary. then, let’s get and build bgp_simple binary:

tar xvfz bgp_simple.tgz

it’s wise to do one small modification right now - Perl daemon works very slowly. getting full feed over it make take even 30 minutes, and in the meantime, it won’t properly process BGP keepalives (i haven’t checked if thats because of Net::BGP or anything else). after three minutes this will lead to BGP session disconnection. i suggest to modify both keep alive timer and hold timer up to 60 and 180 minutes (just for sakes of lab operation):

KeepAliveTime           => 6000,
HoldTime                => 18000,

now we need to get the table itself. i’m in Europe, so getting one from RIPEs RR should give me representative view of Internet:


once we have it, we need to modify it to format supported by

zcat bview.20101121.1600.gz | bgpdump -m - > bgp-ripe-feed.txt

this file is essentially a dump of RIPE RR announcements and it’s quite big - it’s over 500MB big and has 3656255 lines. why so much if global routing table has around 340 thousands of prexies? well, it contains all announcements so before BGP process decides which of those are best paths.

the only thing left is to start daemon (it will need root access rights to bind to 179/tcp):

./ -myas 65000 -myip -peerip -peeras 65100 -p bgp-ripe-feed.txt

it should start:

-------- CONFIG SUMMARY ---------------------------------------------
Configured for an eBGP session between me (ASN65000, and peer (ASN65100,
Will use prefixes from file bgp-ripe-feed.txt.
Will set next hop address to because of eBGP peering.

and then moment later, start feeding our router with prefixes.

konfiguracja routera Cisco (fizycznego lub wirtualnego - dynamips działa doskonale, podobnie zresztą jak i Olive czy OpenBGPD/Quagga) powinna oczywiście wyglądać dla tego przykładu następująco:

router bgp 65100
  timers bgp 6000 18000
  neighbor remote-as 65000

only thing left is to wait until whole table loads:

c1941w-lab#sh ip bgp summary
BGP router identifier, local AS number 65100
BGP table version is 11665410, main routing table version 11665410
344999 network entries using 46919864 bytes of memory
344999 path entries using 17939948 bytes of memory
67835/64064 BGP path/bestpath attribute entries using 8411540 bytes of memory
62048 BGP AS-PATH entries using 2683072 bytes of memory
1773 BGP community entries using 80882 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
3970 BGP filter-list cache entries using 47640 bytes of memory
BGP using 76082946 total bytes of memory
BGP activity 1643781/1298782 prefixes, 1644641/1299642 paths, scan interval 60 secs

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd   4        65000 3252410       4 11665410    0    0 00:31:04   344999

full BGP table takes around 212MB, and CEF table around 64MB. you should have 512MB memory in your router as a minimum to support full feed:

c1941w-lab#sh proc mem sorted | i BGP R|IP RIB
199   0 1055328372 2141416984  212593604          0          0 BGP Router
163   0  308598780  500553552   64461732          0          0 IP RIB Update

you can get similar results on 7200 running with 12.2(33)SRE2:

c7200-03#sh proc mem sorted | i BGP R|IP RIB
234   0  602783840  183179128  206642228          0          0 BGP Router
150   0  189090980  254981544   64440236          0          0 IP RIB Update

my lab Cisco 1941W has 1.5GB of RAM and is running 15.1(3)T:

c1941w-lab#sh ver | i IOS|mem
Cisco IOS Software, C1900 Software (C1900-UNIVERSALK9-M), Version 15.1(3)T, RELEASE SOFTWARE (fc1)
Cisco CISCO1941W-E/K9 (revision 1.0) with 1531872K/40960K bytes of memory.

router is connected to 7200 with NPE-G1 and 1GB of RAM:

Cisco IOS Software, 7200 Software (C7200-ADVIPSERVICESK9-M), Version 12.2(33)SRE2, RELEASE SOFTWARE (fc1)
Cisco 7206VXR (NPE-G1) processor (revision B) with 983040K/65536K bytes of memory.

full table in such situation is exchanged below 8 seconds - that’s for default MTU on Ethernet and MSS set at 1460 bytes. if you care, you can increase MTU to 4k or 9k (BGP will anyway use only up to 4kB), which may speed up a bit the whole process and lessen load of the CPU (that needs to prepare less number of BGP messages).

so, such real life table will show full richness vs synthetic tables built using scripts - it will have corrent AS_PATHs, origin AS, communities etc:

c1941w-lab#sh ip bgp
BGP routing table entry for, version 8576349
Paths: (1 available, best #1, table default)
 Advertised to update-groups:
 65000 42109 41965 41877 3356 7473 4804 from (
     Origin EGP, localpref 100, valid, external, best
     Community: 3356:3 3356:22 3356:100 3356:123 3356:575 3356:2003 7473:10000 7473:12156
     7473:12168 7473:12178 7473:12187 7473:12208 7473:12218 7473:12226 7473:12237 7473:20000
     7473:21009 7473:21079 7473:31009 7473:31209 7473:33919 7473:42105 65002:1668 65002:13680

bgpdump and bgp_simple support only 2-byte ASNs and IPv4. OpenBGPd can dump 4-byte ASNs and IPv6 into MRT-MP format, but this one lacks tools to process infortmation as of yet.

what’s next?

once you have the full feed in your lab, you can experiment with a lot of stuff. BGP traffic engineering, NetFlow reporting (even ‘off-path’) and many other things. we’ll cover that soon with some tips and tricks how to customize your BGP configurations.