BGP – Route Manipulation via Communities

Laddat upp med en dubbel espresso för nu är det dags att gå över Communities. Vi har i tidigare poster gått igenom hur vi kan påverka routing-beslut i BGP via:

Gemensamt för både AS_PATH Prepending & MED är dock att din peer/ISP måste acceptera att du skickar dessa attribut, något som är långt ifrån varken best practice eller vanligt förekommande. Oftast väljer istället ISP:n att helt enkelt ignorera dessa attribut från dina routing-uppdateringar om du försöker lägga till detta.

dualhomed

Tänk dig följande exempel – du som kund har köpt en dual-homed uppkoppling med en primär länk på 100Mbit & backup på 20Mbit. Hur stor tror du risken är att Telia skulle gå in och manuellt modifiera Weight eller Local Preference för dina länkar (alt. låta dig använda MED)? Med 10,000+ kunder så skulle det bli en del route-maps att hålla reda på för dem.. 😉

Det är istället här användandet av Communities kommer in i bilden. BGP Communitys är ett 32bitars värde, där i det “nya formatet” (ip bgp-community new-format) delas upp i två 16bitars värde. Best practice är att använda sitt AS-nummer i det första 16bitars fältet, och sedan använda det sista fältet enligt eget önskemål för att skapa sina communitys.

Så för en ISP med AS 300 hade dess community-värden exempelvis kunnat vara:

  • 300:1
  • 300:10
  • 300:25000
  • 300:60000

Om du istället skulle vilja använda det “gamla formatet” så skrivs hela värdet ut i en och samma 32bitars sträng. 300:10 hade då blivit:

0000 0001 0010 1100 0000 0000 1010

Vilket omskrivet i decimalt blir – 1,228,810. Så vi kan antingen skicka community-taggen 300:10, eller använda oss av det gamla formatet och skicka taggen 1228810 för att få samma effekt- ganska lätt att se vad som är enklast! 🙂

Vi annonserar sedan community-taggen tillsammans med övriga BGP Attribut som Origin/Next hop/AS-Path etc, Community räknas förövrigt som du kanske kommer ihåg från posten “BGP Key Attributes”  tidigare i veckan som ett “Optional Attribute“. Alla routrar har med andra ord inte stöd för detta!

Genom communitys kan vi som kund “tagga” våra routing-uppdateringar enligt de värden som vår ISP tagit fram. ISPn kan i sin tur sedan använda en default route-map för alla sina kunder där de matchar Community-värden och ifrån det sätter exempelvis ett förutbestämt Weight eller Local Preference värde.

En vanlig lösning verkar vara att ISPn skickar ett excel-blad med alla sina förutbestämda communitys och dess “åtgärder”, något i stil med detta:

Community-excel

Om vi som kund sedan taggar vårat nät 200.0.0.0/24 med community 300:10 kommer då ISPn att ändra Local Preference till 10. Taggar vi med community 300:201 så kommer ISPn istället att använda AS_Path Prepend och lägga till ytterligare ett AS-hopp. Vi kan även kombinera flera communities om vi så önskar, taggar vi samma route med 300:50 OCH 300:202 så ändras både Local Preference & AS_Path Prepending!

Det är ganska lätt att se hur enormt mycket mer skalbart och lättanvänt detta är för vår ISP, alternativet hade ju varit att skapa individuella route-maps för varje kund som önskar någon form av routing-modifiering..

Labbexempel

MED

Vi tar och testar detta i praktiken med ovanstående topologi.

  • Länken mellan R1 & R3 är på 50M
  • Länken mellan R1 & R4 är på 2M
  • Länken mellan R2 & R4 är på 100M

Vi vill således att vår ISP använder länken via R2-R4 primärt för trafik som kommer från “the Internet”. Att modifiera Weight eller AS_Path-Prepending fungerar ej i detta fall, vår ISP måste istället använda Local Preference. Om du inte förstår varför så föreslår jag att du går tillbaka och läser posterna relaterat till detta länkat överst i dedå det är rätt basic vid det här laget. 😉

Vår ISP har skickat följande lista med communities vi kan använda oss av:

Community-excel.2png

Vi börjar med att konfigurera upp vår egen utrustning så kollar vi senare på hur ISPn hanterar detta.

Med ren grundkonfig kan vi se att ISP just nu föredrar den sämre länken via R1 på 50Mbit för att nå nätet 10.0.12.0/24.

bgp-community-default

Vi börjar med att konfigurera R1 – men vad är det vi vill åstadkomma? Kom ihåg att för Local Preference så är högst värde bäst (default 100), vi vill med andra ord att ISP ändrar Local Preference till <100 för länken mellan R1 – R3, och sedan sätter ett ännu lägre värde för länken mellan R1 – R4.  Enligt excel-listan behöver vi då sätta följande communities:

  • Länken mellan R1 – R3 – community 65000:50
  • Länken mellan R1 – R4 – community 65000:10

Vi börjar dock med en access-lista:

access-list 1 permit 10.0.12.0 0.0.0.255

Sedan en route-map:

route-map PeerToR3 permit 10
match ip address 1
 set community 65000:50
route-map PeerToR4 permit 10
match ip address 1
 set community 65000:10

Hur får vi då routern att skicka communities till sina peers? Vi måste först aktivera “bgp-community new format” då vi använt oss av det nya formatet att skriva communities:

ip bgp-community new-format

Vi behöver sedan bara konfigurera följande mot våra peers:

router bgp 500
neighbor 191.0.0.2 route-map PeerToR3 out
neighbor 191.0.0.2 send-community
neighbor 191.0.0.6 route-map PeerToR4 out
neighbor 191.0.0.6 send-community

Vi gör i princip samma sak för R2, men här behöver vi egentligen inte ändra LP då vi sänkt de andra länkarna till <100, men det är ju bra träning om inte annat.. 🙂

access-list 1 permit 10.0.12.0 0.0.0.255
route-map PeerToR4 permit 10
match ip address 1
 set community 65000:110
ip bgp-community new-format
router bgp 500
neighbor 191.0.0.10 route-map PeerToR4 out
neighbor 191.0.0.10 send-community

Svårare än så är det inte!

Hur har då vår ISP konfigurerat sitt nät?

Vi skapar först något som kallas “community-list”, här specificerar vi våra communities så vi sedan kan använda oss av dessa i route-maps:

ip community-list 1 permit 65000:10
ip community-list 2 permit 65000:50
ip community-list 3 permit 65000:110

Dessa fungerar precis som en access-lista och det finns möjlighet att göra både standard & extended-versioner:

R3(config)#ip community-list ?
 <1-99> Community list number (standard)
 <100-500> Community list number (expanded)
 expanded Add an expanded community-list entry
 standard Add a standard community-list entry

Vi skapar sedan en default route-map vi använder till alla våra kunder:

route-map CUSTOMER_DEFAULT permit 10
match community 1
 set local-preference 10
route-map CUSTOMER_DEFAULT permit 20
match community 2
 set local-preference 50
route-map CUSTOMER_DEFAULT permit  30
match community 3
 set local-preference 110
route-map CUSTOMER_DEFAULT permit 40

Inget konstigt direkt, istället för match ip address där vi sedan använt oss av en access-lista använder vi här istället match community, vilket hänvisar till den ip community-list vi tidigare skapat.

ip bgp-community new-format
router bgp 65000
neighbor x.x.x.x route-map CUSTOMER_DEFAULT in

Detta ger följande resultat:

R3

bgp-community-finalr3

R4

bgp-community-finalr4

R5

bgp-community-finalr5

Vackert! Vi behöver givetvis inte begränsa oss till endast ändra Weight/Local Preference, möjligheterna är rätt rejäla 😉

R5(config-route-map)#set ?
 as-path Prepend string for a BGP AS-path attribute
 automatic-tag Automatically compute TAG value
 clns OSI summary address
 comm-list set BGP community list (for deletion)
 community BGP community attribute
 dampening Set BGP route flap dampening parameters
 default Set default information
 extcommunity BGP extended community attribute
 interface Output interface
 ip IP specific information
 ipv6 IPv6 specific information
 level Where to import route
 local-preference BGP local preference path attribute
 metric Metric value for destination routing protocol
 metric-type Type of metric for destination routing protocol
 mpls-label Set MPLS label for prefix
 nlri BGP NLRI type
 origin BGP origin code
 tag Tag value for destination routing protocol
 traffic-index BGP traffic classification number for accounting
 vrf Define VRF name
 weight BGP weight for routing table

Det får avsluta communities för den här gången, nästa post blir troligtvis om Route-Reflectors eller Confederations.

BGP – Local Preference & RIB-failures

Vi fortsätter på temat BGP Path Selection från föregående posten där vi kollade närmare på route manipulering via route-maps & weight-attributet.

Local Preference

  • Is a Path Attribute
  • Purpose – Identifies the best exit point from the AS to reach a given prefix
  • Scope – Throughout the AS in which it was set; not advertised to eBGP peers
  • Range – 0 through 4,294,967,295 (2^32 – 1)
  • Which is best? – Higher value is better
  • Default – 100
  • Changing the default – Using the bgp default local-preference n
  • Configuration – Via neighbor route-map; in option is required for updates from an eBGP peer

Efter Weight under BGP’s “best path selection”-process så hittar vi Local Preference, som tillskillnad från just Weight är det BGP Path Attribute. Detta betyder att det inte används endast lokalt av den routern vi konfigurerar det på utan att det annonseras vidare till andra. För Local Preference så är det dock endast till iBGP-neighbors vi annonserar detta!

Detta ger oss möjligheten att inom ett enskilt AS ge oss möjligheten att annonsera till alla iBGP-neighbors en önskad “exit point” för en specifik route vi lärt oss via eBGP. Själva utförandet görs genom en route-map på de inkommande routinguppdateringarna från vår eBGP-peer.

Om vi tittar närmare på ovanstående topologi så har vi ett full mesh-nät inom AS500 mellan R1,R2,R3 & R4. BGP table ser för tillfället ut enligt följande för R1:

bgp localpreference

Och R2:

bgp localpreference2

Du kanske redan har sett något som ser lite konstigt ut? För R2 så har vi default-värdet 100 på Local Preference för samtliga routes, men inte på R1? Vi har även routes markerade med r för R2, men mer om detta senare.

Detta beror på att som tidigare nämnt så används Local Preference endast inom iBGP, routes vi lärt oss från eBGP (R1) skickas endast med ett null värde och routern listar därför inget alls för dessa. R2, som inte har någon eBGP-neighbor utan lär sig alla routes via iBGP får dock default-värdet 100 för samtliga.

För att testa detta rent praktiskt – låt oss försöka konfigurera så att alla iBGP-peers i AS500 väljer omvägen via AS200 för att nå nätet 192.168.0.0/24, istället för direkt via R4 -> AS50.

Vilken router är det då vi ska utföra ändringen i? Om Local Preference justeras via en route-map på inkommande routing-uppdateringar från en eBGP-neighbor, så måste det ju vara i R3 vi ska ändra detta?

Vi börjar med att skapa en…. access-lista.

access-list 1 permit 192.168.0.0

Vi skapar sedan en route-map:

route-map LOCAL-PREF permit 10
match ip address 1
set local-preference 150
route-map LOCAL-PREF permit 20
router bgp 500
neighbor 172.16.36.6 route-map LOCAL-PREF in
do clear ip bgp *

Om allt fungerar som det ska så skall nu R3 annonsera detta till resterande iBGP-neighbors (R1,R2 & R4) som tack vare den högre Local pref. kommer välja att gå via R3(AS500) -> R6(AS200) -> R7(AS50) för att nå 192.168.0.0/24.

bgp localpref3

Sick! 🙂

Vi hade givetvis även kunnat ändra detta i R4 också, men då istället sänkt Local Preference <100 för att få samma effekt.

RIB-Failure

När BGP är klar med sin “BGP best path”-algoritm och har valt vilken väg som är bäst för en specifikt destination, har jag tidigare skrivit att detta skickas vidare till routerns routing table, detta är dock en sanning med modifikation..

BGP skickar nämligen den bästa routen till en annan process vid namnet “IOS Routing Table Manager” (RTM). IOS RTM väljer sedan den bästa routen för en destination mellan flera olika konkurrerande källor. En route kan ju som du bör veta vid det här laget även läras via IGP/BGP/Connected/Static route. IOS samlar den bästa routen från varje process och skickar detta vidare till RTM som sedan i sin tur väljer vilken route som är bäst. För att lyckas med detta används “Administrative Distance” (detta borde du verkligen kunna om du läst CCNA ;)..)

  • Connected – AD 0
  • Static – AD 1
  • EIGRP Summary route – AD 5
  • BGP – AD 20
  • EIGRP (internal) – AD 90
  • IGRP – AD 100
  • OSPF – AD 110
  • ISIS – AD 115
  • RIP – AD 120
  • ODR (On-Demand Routing) – AD 160
  • EIGRP (External) – AD 170
  • iBGP – AD 200
  • Unreachable – AD 255

I de flesta fall borde vi aldrig se en route vi lärt oss via BGP även finns i vår IGP-process eller som Connected (detta blir mer ett problem när vi senare börjar grotta ner oss i MPLS VPNs med BGP/IGP-redistribution). Men hur som helst, OM det skulle hända så finns det ett inbyggt kommando som kan vara bra att känna till – sh ip bgp rib-failures.

Om vi går tillbaka och kollar R2’s BGP-table igen från föregående exempel:

bgp localpreference2

En sh ip bgp rib-failures visar följande:

R2#sh ip bgp rib-failure 
Network Next Hop RIB-failure RIB-NH Matches
200.0.0.0 1.1.1.1 Higher admin distance n/a
200.0.1.0 1.1.1.1 Higher admin distance n/a
200.0.2.0 1.1.1.1 Higher admin distance n/a
200.0.3.0 1.1.1.1 Higher admin distance n/a

Detta listar routes som BGP anser vara bäst, men som RTM valt att ej lägga till i routing table – anledningen är tydlig här, iBGP har en AD på 200, och routern har valt att lägga till routes från en annan “källa” med lägre AD.

show ip route visar boven:

R2#sh ip route | i O E2 
O E2 200.0.0.0/24 [110/1] via 172.16.12.1, 00:03:47, Serial0/0
O E2 200.0.1.0/24 [110/1] via 172.16.12.1, 00:03:47, Serial0/0
O E2 200.0.2.0/24 [110/1] via 172.16.12.1, 00:03:47, Serial0/0
O E2 200.0.3.0/24 [110/1] via 172.16.12.1, 00:03:47, Serial0/0

RTM har fått information om samma routes från OSPF-processen med en AD på 110 och därför valt detta istället.

Detta orsakades på grund av ett konfigurationsfel i R1 där vi redistributade klassfulla BGP-nät in till OSPF-processen, efter att ha tagit bort detta försvann även rib-failure:

R2#sh ip bgp 
BGP table version is 86, local router ID is 2.2.2.2
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
*>i5.5.5.0/24 1.1.1.1 0 100 0 100 i
*>i6.6.6.0/24 3.3.3.3 0 100 0 200 i
*>i10.0.0.0/16 1.1.1.1 0 100 0 100 i
*>i192.168.0.0 3.3.3.3 0 150 0 200 50 i
*>i200.0.0.0 1.1.1.1 0 100 0 100 i
*>i200.0.1.0 1.1.1.1 0 100 0 100 i
*>i200.0.2.0 1.1.1.1 0 100 0 100 i
*>i200.0.3.0 1.1.1.1 0 100 0 100 i

Vackert!