dawno dawno temu, zabawa z BGP (samo nieco ironiczne tłumaczenie tego akronimu jako Bardzo Groźny Protokół zdaje się zdradzać w którą stronę podąża ten akapit) była zdecydowanie zarezerwowana dla wtajemniczonych tego świata, którzy nieco jak Lemowski Trurl i Klapaucjusz naśmiewali się z niewiedzy, ale z drugiej strony sami tą wiedzą się nie dzielili. potem zmieniło się wiele, opary w jaskiniach wiedzy nieco się rozrzedziły, pojawiły się kursy, certyfikacje, elitarne a potem masowe kursy - i nagle BGP ma w domu każda gospodyni domowa, gdyż bez niego nie wrzuci sobie via bluetooth nowego kontaktu do komórki.

fakt jednak faktem, że zadziwiająco mało osób realnie eksperymentuje z tym protokołem poza bardzo ograniczonym i jakże krótkim zderzeniem w momencie wdrożenia rozwiązania sieciowego. środowisko labowe na kursie było jakże oczywiste, a gdy ilość i złożoność prefiksów, ścieżek i atrybutów “pełnego” BGP wyląduje na naszym routerze, zwykle cichaczem stosujemy proste, wyuczone tricki - AS_PATH prepend, albo local-preference dla wszystkich prefiksów od sąsiada.

od czasu pojawienia się dynamipsa (w locie kompilującego binarne obrazy Cisco IOS) oraz wiedzy jak skonstruować Olive (czyli odpalić JunOS na PC/VMWare) eksperymenty mogłyby stać się ciekawsze, choć bardzo często brakuje ‘pełnej tablicy’.

kopia prawdziwej tablicy

można oczywiście poprosić o sesję BGP dobrego znajomego - po co jednak fizycznie zestawiać sesję z czymś na świecie, skoro można sobie bez łączności z Internetem odtworzyć kopię tej tablicy? możliwość taką udostępniają RIR i wykorzystanie jej jest banalnie proste.

skupię się poniżej na przewodniku po FreeBSD, choć w innych systemach może być to nawet prostsze. narzędzi i sposobu stworzenia tego typu sieci laboratoryjnej jest więcej, pozwolę sobie jedynie pokazać przykład tego, co działa dosyć szybko i wygodnie.

na początek należy doinstalować pakiet Net::BGP:

/usr/ports/net/p5-Net-BGP
make install clean

…oraz bibliotekę, która pozwoli nam przerobić format wejściowy w którym pozyskamy prefiksy do strawnego dla naszego skryptu:

wget http://www.ris.ripe.net/source/libbgpdump-latest.tgz
tar xvfz libbgpdump-latest.tgz
cd libbgpdump-1.4.99.13
./configure
make
cp bgpdump ../
cd ../

powinniśmy po komplikacji otrzymać binarkę bgpdump. następnie należy pobrać i skompilować bgp_simple:

wget http://bgpsimple.googlecode.com/files/bgp_simple.tgz
tar xvfz bgp_simple.tgz

w tym momencie warto od razu wykonać pewną modyfikację - demon Perlowy działa bardzo powoli ładując na nasze routery prefiksy - wrzucenie pełnej tablicy w formie pozyskanej z baz RIPE może zająć nawet 30 minut (nie badałem na razie czy to problem Net::BGP, samego skryptu Perlowego - router taką samą ilość prefiksów ładuje w czasie poniżej 10 sekund), a przez ten czas nie potrafi prawidłowo obsługiwać pakietów keepalive BGP co doprowadzi po 3 minutach (domyślna konfiguracja) do zerwania sesji. sugeruje zatem od razu od linijki 220 wprowadzić dwie linijki które wydłużą znacznie czas między pakietami hello i samą wartość licznika holdtime - do odpowiednio 60 minut i 180 minut:

KeepAliveTime           => 6000,
HoldTime                => 18000,

teraz należy wyposażyć się w tablicę - jesteśmy w Europie więc ściągnięcie obrazu z RR’a RIPE jest reprezentatywne dla naszej części Internetu:

wget http://data.ris.ripe.net/rrc00/2010.11/bview.20101121.1600.gz

i przerobić ją do formatu obsługiwanego przez bgp_simple.pl:

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

plik zawiera zrzut uaktualnień otrzymanych przez wskazany RR RIPE’a i jest dosyć obszerny - ten konkretny plik ma objętość 500MB i zawiera 3656255 linii. skąd taka ilość skoro pełna tablica zawiera jedynie ok 340,000 prefiksów? właśnie stąd, że przechowywane są wszystkie uaktualnienia związane z prefiksem a nie jeden. router BGP akceptując kolejne rozgłoszenia tego samego prefiksu sam zdecyduje, który według niego jest optymalny i proces zakończy się załadowaniem jedynie właśnie około 340,000 prefiksów IPv4.

pozostaje już tylko odpalić demona (będzie potrzebował uprawnień root’a aby zbindować się do portu 179/tcp):

./bgp_simple.pl -myas 65000 -myip 192.168.110.1 -peerip 192.168.110.10 -peeras 65100 -p bgp-ripe-feed.txt

powinien wystartować:

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

a po chwili powinien zacząć ładować do naszego routera prefiksy.

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 192.168.110.1 remote-as 65000

pozostaje jedynie cierpliwie poczekać na załadowanie się całej tablicy:

c1941w-lab#sh ip bgp summary
BGP router identifier 192.168.110.10, 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
192.168.110.1   4        65000 3252410       4 11665410    0    0 00:31:04   344999

po załadowaniu pełnej tablicy proces BGP zajmuje 212MB a tablica CEF pozwalająca routerom Cisco wykonywać routing w sposób optymalny około 64MB - innymi słowy, na pełną tablicę należy przygotować się z minimum 512MB RAMu:

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

podobne wyniki wskazuje oprogramowanie 12.2(33)SRE2 pracujące na platformie 7200:

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

rzeczony c1941W pracuje pod kontrolą oprogramowania 15.1(3)T i ma 1.5GB RAMu:

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 ma zestawiony peering z 7200 wyposażonym w kartę NPE-G1 i 1GB RAMu:

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.

pełna tablicy pomiędzy tymi dwoma routerami wymieniana jest w czasie poniżej 8 sekund. dla MTU typowego dla Ethernetu i włączonego PMTUD daje to MSS 1460 bajtów i jest dobrym wynikiem. lepsze można osiągnąć pracując w sieci z MTU ustawionym powyżej 4kB - co prawda protokół BGP wykorzysta tylko 4kB ale to i tak pozwala upakować więcej informacji w jednym segmencie, odciążając oba routery od pakowania i obierania danych BGP z segmentów TCP.

taka tablica różni się od tworzonej skryptami, syntetycznej swoją “żywą” zawartością - prefiksy pochodzą od faktycznych ASów w Internecie i posiadają ich pełne atrybuty - m.in. wartości community:

c1941w-lab#sh ip bgp 58.111.24.0
BGP routing table entry for 58.111.24.0/21, version 8576349
Paths: (1 available, best #1, table default)
 Advertised to update-groups:
    3
 65000 42109 41965 41877 3356 7473 4804
   192.168.110.1 from 192.168.110.1 (192.168.110.1)
     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 i bgp_simple obsługują jak na razie tylko 2B ASNy i IPv4. OpenBGPD potrafi wyeksportować do formatu MRT-MP (na razie niezgodnego z żadnym narzędziem) 4B ASNy i IPv6.

co dalej?

tak przygotowany router można wykorzystać do eksperymentów w labie - np. wzbogacenia rysowanych wykresów NetFlow o informacje o źródłowym i docelowym numerze AS, czy też eksperymentów z inżynierią ruchową. o tym czy ma to sens i co pozwala uzyskać, a także jak ciąć prefiksy z pełnej tablicy aby realizować routing na urządzeniach o ograniczonych zasobach sprzętowych na przechowywanie prefiksów - “wkrótce”.