1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302 |
- /* BGP routing information
- Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
- This file is part of GNU Zebra.
- GNU Zebra is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
- GNU Zebra is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Zebra; see the file COPYING. If not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
- #include <zebra.h>
- #include "prefix.h"
- #include "linklist.h"
- #include "memory.h"
- #include "command.h"
- #include "stream.h"
- #include "filter.h"
- #include "str.h"
- #include "log.h"
- #include "routemap.h"
- #include "buffer.h"
- #include "sockunion.h"
- #include "plist.h"
- #include "thread.h"
- #include "workqueue.h"
- #include "bgpd/bgpd.h"
- #include "bgpd/bgp_table.h"
- #include "bgpd/bgp_route.h"
- #include "bgpd/bgp_attr.h"
- #include "bgpd/bgp_debug.h"
- #include "bgpd/bgp_aspath.h"
- #include "bgpd/bgp_regex.h"
- #include "bgpd/bgp_community.h"
- #include "bgpd/bgp_ecommunity.h"
- #include "bgpd/bgp_clist.h"
- #include "bgpd/bgp_packet.h"
- #include "bgpd/bgp_filter.h"
- #include "bgpd/bgp_fsm.h"
- #include "bgpd/bgp_mplsvpn.h"
- #include "bgpd/bgp_nexthop.h"
- #include "bgpd/bgp_damp.h"
- #include "bgpd/bgp_advertise.h"
- #include "bgpd/bgp_zebra.h"
- #include "bgpd/bgp_vty.h"
- /* Extern from bgp_dump.c */
- extern const char *bgp_origin_str[];
- extern const char *bgp_origin_long_str[];
- static struct bgp_node *
- bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
- struct prefix_rd *prd)
- {
- struct bgp_node *rn;
- struct bgp_node *prn = NULL;
-
- assert (table);
- if (!table)
- return NULL;
-
- if (safi == SAFI_MPLS_VPN)
- {
- prn = bgp_node_get (table, (struct prefix *) prd);
- if (prn->info == NULL)
- prn->info = bgp_table_init (afi, safi);
- else
- bgp_unlock_node (prn);
- table = prn->info;
- }
- rn = bgp_node_get (table, p);
- if (safi == SAFI_MPLS_VPN)
- rn->prn = prn;
- return rn;
- }
- /* Allocate bgp_info_extra */
- static struct bgp_info_extra *
- bgp_info_extra_new (void)
- {
- struct bgp_info_extra *new;
- new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra));
- return new;
- }
- static void
- bgp_info_extra_free (struct bgp_info_extra **extra)
- {
- if (extra && *extra)
- {
- if ((*extra)->damp_info)
- bgp_damp_info_free ((*extra)->damp_info, 0);
-
- (*extra)->damp_info = NULL;
-
- XFREE (MTYPE_BGP_ROUTE_EXTRA, *extra);
-
- *extra = NULL;
- }
- }
- /* Get bgp_info extra information for the given bgp_info, lazy allocated
- * if required.
- */
- struct bgp_info_extra *
- bgp_info_extra_get (struct bgp_info *ri)
- {
- if (!ri->extra)
- ri->extra = bgp_info_extra_new();
- return ri->extra;
- }
- /* Allocate new bgp info structure. */
- static struct bgp_info *
- bgp_info_new (void)
- {
- return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
- }
- /* Free bgp route information. */
- static void
- bgp_info_free (struct bgp_info *binfo)
- {
- if (binfo->attr)
- bgp_attr_unintern (binfo->attr);
-
- bgp_info_extra_free (&binfo->extra);
- peer_unlock (binfo->peer); /* bgp_info peer reference */
- XFREE (MTYPE_BGP_ROUTE, binfo);
- }
- struct bgp_info *
- bgp_info_lock (struct bgp_info *binfo)
- {
- binfo->lock++;
- return binfo;
- }
- struct bgp_info *
- bgp_info_unlock (struct bgp_info *binfo)
- {
- assert (binfo && binfo->lock > 0);
- binfo->lock--;
-
- if (binfo->lock == 0)
- {
- #if 0
- zlog_debug ("%s: unlocked and freeing", __func__);
- zlog_backtrace (LOG_DEBUG);
- #endif
- bgp_info_free (binfo);
- return NULL;
- }
- #if 0
- if (binfo->lock == 1)
- {
- zlog_debug ("%s: unlocked to 1", __func__);
- zlog_backtrace (LOG_DEBUG);
- }
- #endif
-
- return binfo;
- }
- void
- bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
- {
- struct bgp_info *top;
- top = rn->info;
-
- ri->next = rn->info;
- ri->prev = NULL;
- if (top)
- top->prev = ri;
- rn->info = ri;
-
- bgp_info_lock (ri);
- bgp_lock_node (rn);
- peer_lock (ri->peer); /* bgp_info peer reference */
- }
- /* Do the actual removal of info from RIB, for use by bgp_process
- completion callback *only* */
- static void
- bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri)
- {
- if (ri->next)
- ri->next->prev = ri->prev;
- if (ri->prev)
- ri->prev->next = ri->next;
- else
- rn->info = ri->next;
-
- bgp_info_unlock (ri);
- bgp_unlock_node (rn);
- }
- void
- bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
- {
- bgp_info_set_flag (rn, ri, BGP_INFO_REMOVED);
- /* set of previous already took care of pcount */
- UNSET_FLAG (ri->flags, BGP_INFO_VALID);
- }
- /* undo the effects of a previous call to bgp_info_delete; typically
- called when a route is deleted and then quickly re-added before the
- deletion has been processed */
- static void
- bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
- /* unset of previous already took care of pcount */
- SET_FLAG (ri->flags, BGP_INFO_VALID);
- }
- /* Adjust pcount as required */
- static void
- bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
- {
- assert (rn && rn->table);
- assert (ri && ri->peer && ri->peer->bgp);
- /* Ignore 'pcount' for RS-client tables */
- if (rn->table->type != BGP_TABLE_MAIN
- || ri->peer == ri->peer->bgp->peer_self)
- return;
-
- if (BGP_INFO_HOLDDOWN (ri)
- && CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
-
- UNSET_FLAG (ri->flags, BGP_INFO_COUNTED);
-
- /* slight hack, but more robust against errors. */
- if (ri->peer->pcount[rn->table->afi][rn->table->safi])
- ri->peer->pcount[rn->table->afi][rn->table->safi]--;
- else
- {
- zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
- __func__, ri->peer->host);
- zlog_backtrace (LOG_WARNING);
- zlog_warn ("%s: Please report to Quagga bugzilla", __func__);
- }
- }
- else if (!BGP_INFO_HOLDDOWN (ri)
- && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
- SET_FLAG (ri->flags, BGP_INFO_COUNTED);
- ri->peer->pcount[rn->table->afi][rn->table->safi]++;
- }
- }
- /* Set/unset bgp_info flags, adjusting any other state as needed.
- * This is here primarily to keep prefix-count in check.
- */
- void
- bgp_info_set_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
- {
- SET_FLAG (ri->flags, flag);
-
- /* early bath if we know it's not a flag that changes useability state */
- if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
- return;
-
- bgp_pcount_adjust (rn, ri);
- }
- void
- bgp_info_unset_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
- {
- UNSET_FLAG (ri->flags, flag);
-
- /* early bath if we know it's not a flag that changes useability state */
- if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
- return;
-
- bgp_pcount_adjust (rn, ri);
- }
- /* Get MED value. If MED value is missing and "bgp bestpath
- missing-as-worst" is specified, treat it as the worst value. */
- static u_int32_t
- bgp_med_value (struct attr *attr, struct bgp *bgp)
- {
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- return attr->med;
- else
- {
- if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
- return BGP_MED_MAX;
- else
- return 0;
- }
- }
- /* Compare two bgp route entity. br is preferable then return 1. */
- static int
- bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
- {
- u_int32_t new_pref;
- u_int32_t exist_pref;
- u_int32_t new_med;
- u_int32_t exist_med;
- u_int32_t new_weight = 0;
- u_int32_t exist_weight = 0;
- struct in_addr new_id;
- struct in_addr exist_id;
- int new_cluster;
- int exist_cluster;
- int internal_as_route = 0;
- int confed_as_route = 0;
- int ret;
- /* 0. Null check. */
- if (new == NULL)
- return 0;
- if (exist == NULL)
- return 1;
- /* 1. Weight check. */
- if (new->attr->extra)
- new_weight = new->attr->extra->weight;
- if (exist->attr->extra)
- exist_weight = exist->attr->extra->weight;
- if (new_weight > exist_weight)
- return 1;
- if (new_weight < exist_weight)
- return 0;
- /* 2. Local preference check. */
- if (new->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- new_pref = new->attr->local_pref;
- else
- new_pref = bgp->default_local_pref;
- if (exist->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- exist_pref = exist->attr->local_pref;
- else
- exist_pref = bgp->default_local_pref;
-
- if (new_pref > exist_pref)
- return 1;
- if (new_pref < exist_pref)
- return 0;
- /* 3. Local route check. */
- if (new->sub_type == BGP_ROUTE_STATIC)
- return 1;
- if (exist->sub_type == BGP_ROUTE_STATIC)
- return 0;
- if (new->sub_type == BGP_ROUTE_REDISTRIBUTE)
- return 1;
- if (exist->sub_type == BGP_ROUTE_REDISTRIBUTE)
- return 0;
- if (new->sub_type == BGP_ROUTE_AGGREGATE)
- return 1;
- if (exist->sub_type == BGP_ROUTE_AGGREGATE)
- return 0;
- /* 4. AS path length check. */
- if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
- {
- int exist_hops = aspath_count_hops (exist->attr->aspath);
- int exist_confeds = aspath_count_confeds (exist->attr->aspath);
-
- if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
- {
- int aspath_hops;
-
- aspath_hops = aspath_count_hops (new->attr->aspath);
- aspath_hops += aspath_count_confeds (new->attr->aspath);
-
- if ( aspath_hops < (exist_hops + exist_confeds))
- return 1;
- if ( aspath_hops > (exist_hops + exist_confeds))
- return 0;
- }
- else
- {
- int newhops = aspath_count_hops (new->attr->aspath);
-
- if (newhops < exist_hops)
- return 1;
- if (newhops > exist_hops)
- return 0;
- }
- }
- /* 5. Origin check. */
- if (new->attr->origin < exist->attr->origin)
- return 1;
- if (new->attr->origin > exist->attr->origin)
- return 0;
- /* 6. MED check. */
- internal_as_route = (aspath_count_hops (new->attr->aspath) == 0
- && aspath_count_hops (exist->attr->aspath) == 0);
- confed_as_route = (aspath_count_confeds (new->attr->aspath) > 0
- && aspath_count_confeds (exist->attr->aspath) > 0
- && aspath_count_hops (new->attr->aspath) == 0
- && aspath_count_hops (exist->attr->aspath) == 0);
-
- if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
- || (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
- && confed_as_route)
- || aspath_cmp_left (new->attr->aspath, exist->attr->aspath)
- || aspath_cmp_left_confed (new->attr->aspath, exist->attr->aspath)
- || internal_as_route)
- {
- new_med = bgp_med_value (new->attr, bgp);
- exist_med = bgp_med_value (exist->attr, bgp);
- if (new_med < exist_med)
- return 1;
- if (new_med > exist_med)
- return 0;
- }
- /* 7. Peer type check. */
- if (peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_IBGP)
- return 1;
- if (peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_CONFED)
- return 1;
- if (peer_sort (new->peer) == BGP_PEER_IBGP
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
- return 0;
- if (peer_sort (new->peer) == BGP_PEER_CONFED
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
- return 0;
- /* 8. IGP metric check. */
- if (new->extra || exist->extra)
- {
- uint32_t newm = (new->extra ? new->extra->igpmetric : 0);
- uint32_t existm = (exist->extra ? exist->extra->igpmetric : 0);
-
- if (newm < existm)
- return 1;
- if (newm > existm)
- return 0;
- }
- /* 9. Maximum path check. */
- /* 10. If both paths are external, prefer the path that was received
- first (the oldest one). This step minimizes route-flap, since a
- newer path won't displace an older one, even if it was the
- preferred route based on the additional decision criteria below. */
- if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
- && peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
- {
- if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
- return 1;
- if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED))
- return 0;
- }
- /* 11. Rourter-ID comparision. */
- if (new->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- new_id.s_addr = new->attr->extra->originator_id.s_addr;
- else
- new_id.s_addr = new->peer->remote_id.s_addr;
- if (exist->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- exist_id.s_addr = exist->attr->extra->originator_id.s_addr;
- else
- exist_id.s_addr = exist->peer->remote_id.s_addr;
- if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr))
- return 1;
- if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr))
- return 0;
- /* 12. Cluster length comparision. */
- if (new->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
- new_cluster = new->attr->extra->cluster->length;
- else
- new_cluster = 0;
- if (exist->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
- exist_cluster = exist->attr->extra->cluster->length;
- else
- exist_cluster = 0;
- if (new_cluster < exist_cluster)
- return 1;
- if (new_cluster > exist_cluster)
- return 0;
- /* 13. Neighbor address comparision. */
- ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote);
- if (ret == 1)
- return 0;
- if (ret == -1)
- return 1;
- return 1;
- }
- static enum filter_type
- bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi)
- {
- struct bgp_filter *filter;
- filter = &peer->filter[afi][safi];
- #define FILTER_EXIST_WARN(F,f,filter) \
- if (BGP_DEBUG (update, UPDATE_IN) \
- && !(F ## _IN (filter))) \
- plog_warn (peer->log, "%s: Could not find configured input %s-list %s!", \
- peer->host, #f, F ## _IN_NAME(filter));
-
- if (DISTRIBUTE_IN_NAME (filter)) {
- FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
-
- if (access_list_apply (DISTRIBUTE_IN (filter), p) == FILTER_DENY)
- return FILTER_DENY;
- }
- if (PREFIX_LIST_IN_NAME (filter)) {
- FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
-
- if (prefix_list_apply (PREFIX_LIST_IN (filter), p) == PREFIX_DENY)
- return FILTER_DENY;
- }
-
- if (FILTER_LIST_IN_NAME (filter)) {
- FILTER_EXIST_WARN(FILTER_LIST, as, filter);
-
- if (as_list_apply (FILTER_LIST_IN (filter), attr->aspath)== AS_FILTER_DENY)
- return FILTER_DENY;
- }
-
- return FILTER_PERMIT;
- #undef FILTER_EXIST_WARN
- }
- static enum filter_type
- bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi)
- {
- struct bgp_filter *filter;
- filter = &peer->filter[afi][safi];
- #define FILTER_EXIST_WARN(F,f,filter) \
- if (BGP_DEBUG (update, UPDATE_OUT) \
- && !(F ## _OUT (filter))) \
- plog_warn (peer->log, "%s: Could not find configured output %s-list %s!", \
- peer->host, #f, F ## _OUT_NAME(filter));
- if (DISTRIBUTE_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
-
- if (access_list_apply (DISTRIBUTE_OUT (filter), p) == FILTER_DENY)
- return FILTER_DENY;
- }
- if (PREFIX_LIST_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
-
- if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
- return FILTER_DENY;
- }
- if (FILTER_LIST_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(FILTER_LIST, as, filter);
-
- if (as_list_apply (FILTER_LIST_OUT (filter), attr->aspath) == AS_FILTER_DENY)
- return FILTER_DENY;
- }
- return FILTER_PERMIT;
- #undef FILTER_EXIST_WARN
- }
- /* If community attribute includes no_export then return 1. */
- static int
- bgp_community_filter (struct peer *peer, struct attr *attr)
- {
- if (attr->community)
- {
- /* NO_ADVERTISE check. */
- if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
- return 1;
- /* NO_EXPORT check. */
- if (peer_sort (peer) == BGP_PEER_EBGP &&
- community_include (attr->community, COMMUNITY_NO_EXPORT))
- return 1;
- /* NO_EXPORT_SUBCONFED check. */
- if (peer_sort (peer) == BGP_PEER_EBGP
- || peer_sort (peer) == BGP_PEER_CONFED)
- if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
- return 1;
- }
- return 0;
- }
- /* Route reflection loop check. */
- static int
- bgp_cluster_filter (struct peer *peer, struct attr *attr)
- {
- struct in_addr cluster_id;
- if (attr->extra && attr->extra->cluster)
- {
- if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
- cluster_id = peer->bgp->cluster_id;
- else
- cluster_id = peer->bgp->router_id;
-
- if (cluster_loop_check (attr->extra->cluster, cluster_id))
- return 1;
- }
- return 0;
- }
- static int
- bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi)
- {
- struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- filter = &peer->filter[afi][safi];
- /* Apply default weight value. */
- if (peer->weight)
- (bgp_attr_extra_get (attr))->weight = peer->weight;
- /* Route map apply. */
- if (ROUTE_MAP_IN_NAME (filter))
- {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info);
- peer->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free newly generated AS path and community by route-map. */
- bgp_attr_flush (attr);
- return RMAP_DENY;
- }
- }
- return RMAP_PERMIT;
- }
- static int
- bgp_export_modifier (struct peer *rsclient, struct peer *peer,
- struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
- {
- struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- filter = &peer->filter[afi][safi];
- /* Route map apply. */
- if (ROUTE_MAP_EXPORT_NAME (filter))
- {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = rsclient;
- info.attr = attr;
- SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_EXPORT (filter), p, RMAP_BGP, &info);
- rsclient->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free newly generated AS path and community by route-map. */
- bgp_attr_flush (attr);
- return RMAP_DENY;
- }
- }
- return RMAP_PERMIT;
- }
- static int
- bgp_import_modifier (struct peer *rsclient, struct peer *peer,
- struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
- {
- struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- filter = &rsclient->filter[afi][safi];
- /* Apply default weight value. */
- if (peer->weight)
- (bgp_attr_extra_get (attr))->weight = peer->weight;
- /* Route map apply. */
- if (ROUTE_MAP_IMPORT_NAME (filter))
- {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_IMPORT (filter), p, RMAP_BGP, &info);
- peer->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free newly generated AS path and community by route-map. */
- bgp_attr_flush (attr);
- return RMAP_DENY;
- }
- }
- return RMAP_PERMIT;
- }
- static int
- bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
- struct attr *attr, afi_t afi, safi_t safi)
- {
- int ret;
- char buf[SU_ADDRSTRLEN];
- struct bgp_filter *filter;
- struct peer *from;
- struct bgp *bgp;
- int transparent;
- int reflect;
- from = ri->peer;
- filter = &peer->filter[afi][safi];
- bgp = peer->bgp;
-
- if (DISABLE_BGP_ANNOUNCE)
- return 0;
- /* Do not send announces to RS-clients from the 'normal' bgp_table. */
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- return 0;
- /* Do not send back route to sender. */
- if (from == peer)
- return 0;
- /* If peer's id and route's nexthop are same. draft-ietf-idr-bgp4-23 5.1.3 */
- if (p->family == AF_INET
- && IPV4_ADDR_SAME(&peer->remote_id, &ri->attr->nexthop))
- return 0;
- #ifdef HAVE_IPV6
- if (p->family == AF_INET6
- && IPV6_ADDR_SAME(&peer->remote_id, &ri->attr->nexthop))
- return 0;
- #endif
- /* Aggregate-address suppress check. */
- if (ri->extra && ri->extra->suppress)
- if (! UNSUPPRESS_MAP_NAME (filter))
- return 0;
- /* Default route check. */
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
- {
- if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
- return 0;
- #ifdef HAVE_IPV6
- else if (p->family == AF_INET6 && p->prefixlen == 0)
- return 0;
- #endif /* HAVE_IPV6 */
- }
- /* Transparency check. */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
- && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- transparent = 1;
- else
- transparent = 0;
- /* If community is not disabled check the no-export and local. */
- if (! transparent && bgp_community_filter (peer, ri->attr))
- return 0;
- /* If the attribute has originator-id and it is same as remote
- peer's id. */
- if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
- {
- if (IPV4_ADDR_SAME (&peer->remote_id, &ri->attr->extra->originator_id))
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
- "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- return 0;
- }
- }
-
- /* ORF prefix-list filter check */
- if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
- && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
- || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
- if (peer->orf_plist[afi][safi])
- {
- if (prefix_list_apply (peer->orf_plist[afi][safi], p) == PREFIX_DENY)
- return 0;
- }
- /* Output filter check. */
- if (bgp_output_filter (peer, p, ri->attr, afi, safi) == FILTER_DENY)
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
- "%s [Update:SEND] %s/%d is filtered",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- return 0;
- }
- #ifdef BGP_SEND_ASPATH_CHECK
- /* AS path loop check. */
- if (aspath_loop_check (ri->attr->aspath, peer->as))
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
- "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
- peer->host, peer->as);
- return 0;
- }
- #endif /* BGP_SEND_ASPATH_CHECK */
- /* If we're a CONFED we need to loop check the CONFED ID too */
- if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
- {
- if (aspath_loop_check(ri->attr->aspath, bgp->confed_id))
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
- "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
- peer->host,
- bgp->confed_id);
- return 0;
- }
- }
- /* Route-Reflect check. */
- if (peer_sort (from) == BGP_PEER_IBGP && peer_sort (peer) == BGP_PEER_IBGP)
- reflect = 1;
- else
- reflect = 0;
- /* IBGP reflection check. */
- if (reflect)
- {
- /* A route from a Client peer. */
- if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- {
- /* Reflect to all the Non-Client peers and also to the
- Client peers other than the originator. Originator check
- is already done. So there is noting to do. */
- /* no bgp client-to-client reflection check. */
- if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- return 0;
- }
- else
- {
- /* A route from a Non-client peer. Reflect to all other
- clients. */
- if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- return 0;
- }
- }
-
- /* AS-Pathlimit check */
- if (ri->attr->pathlimit.ttl && peer_sort (peer) == BGP_PEER_EBGP)
- /* Our ASN has not yet been pre-pended, that's done in packet_attribute
- * on output. Hence the test here is for >=.
- */
- if (aspath_count_hops (ri->attr->aspath) >= ri->attr->pathlimit.ttl)
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog_info ("%s [Update:SEND] suppressed, AS-Pathlimit TTL %u exceeded",
- peer->host, ri->attr->pathlimit.ttl);
- return 0;
- }
-
- /* For modify attribute, copy it to temporary structure. */
- bgp_attr_dup (attr, ri->attr);
-
- /* If local-preference is not set. */
- if ((peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED)
- && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
- {
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
- attr->local_pref = bgp->default_local_pref;
- }
- /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
- if (peer_sort (peer) == BGP_PEER_EBGP
- && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- {
- if (ri->peer != bgp->peer_self && ! transparent
- && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
- attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC));
- }
- /* next-hop-set */
- if (transparent || reflect
- || (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
- && ((p->family == AF_INET && attr->nexthop.s_addr)
- #ifdef HAVE_IPV6
- || (p->family == AF_INET6 &&
- ! IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
- #endif /* HAVE_IPV6 */
- )))
- {
- /* NEXT-HOP Unchanged. */
- }
- else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF)
- || (p->family == AF_INET && attr->nexthop.s_addr == 0)
- #ifdef HAVE_IPV6
- || (p->family == AF_INET6 &&
- IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
- #endif /* HAVE_IPV6 */
- || (peer_sort (peer) == BGP_PEER_EBGP
- && bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
- {
- /* Set IPv4 nexthop. */
- if (p->family == AF_INET)
- {
- if (safi == SAFI_MPLS_VPN)
- memcpy (&attr->extra->mp_nexthop_global_in, &peer->nexthop.v4,
- IPV4_MAX_BYTELEN);
- else
- memcpy (&attr->nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
- }
- #ifdef HAVE_IPV6
- /* Set IPv6 nexthop. */
- if (p->family == AF_INET6)
- {
- /* IPv6 global nexthop must be included. */
- memcpy (&attr->extra->mp_nexthop_global, &peer->nexthop.v6_global,
- IPV6_MAX_BYTELEN);
- attr->extra->mp_nexthop_len = 16;
- }
- #endif /* HAVE_IPV6 */
- }
- #ifdef HAVE_IPV6
- if (p->family == AF_INET6)
- {
- /* Left nexthop_local unchanged if so configured. */
- if ( CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
- {
- if ( IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_local) )
- attr->extra->mp_nexthop_len=32;
- else
- attr->extra->mp_nexthop_len=16;
- }
- /* Default nexthop_local treatment for non-RS-Clients */
- else
- {
- /* Link-local address should not be transit to different peer. */
- attr->extra->mp_nexthop_len = 16;
- /* Set link-local address for shared network peer. */
- if (peer->shared_network
- && ! IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
- {
- memcpy (&attr->extra->mp_nexthop_local, &peer->nexthop.v6_local,
- IPV6_MAX_BYTELEN);
- attr->extra->mp_nexthop_len = 32;
- }
- /* If bgpd act as BGP-4+ route-reflector, do not send link-local
- address.*/
- if (reflect)
- attr->extra->mp_nexthop_len = 16;
- /* If BGP-4+ link-local nexthop is not link-local nexthop. */
- if (! IN6_IS_ADDR_LINKLOCAL (&peer->nexthop.v6_local))
- attr->extra->mp_nexthop_len = 16;
- }
- }
- #endif /* HAVE_IPV6 */
- /* AS-Pathlimit: Check ASN for private/confed */
- if (attr->pathlimit.ttl)
- {
- /* locally originated update */
- if (!attr->pathlimit.as)
- attr->pathlimit.as = peer->local_as;
-
- /* if the AS_PATHLIMIT attribute is attached to a prefix by a
- member of a confederation, then when the prefix is advertised outside
- of the confederation boundary, then the AS number of the
- confederation member inside of the AS_PATHLIMIT attribute should be
- replaced by the confederation's AS number. */
- if (peer_sort (from) == BGP_PEER_CONFED
- && peer_sort (peer) != BGP_PEER_CONFED)
- attr->pathlimit.as = peer->local_as;
- /* Private ASN should be updated whenever announcement leaves
- * private space. This is deliberately done after simple confed
- * based update..
- */
- if (attr->pathlimit.as >= BGP_PRIVATE_AS_MIN
- && attr->pathlimit.as <= BGP_PRIVATE_AS_MAX)
- {
- if (peer->local_as < BGP_PRIVATE_AS_MIN
- || peer->local_as > BGP_PRIVATE_AS_MAX)
- attr->pathlimit.as = peer->local_as;
- /* Ours is private, try using theirs.. */
- else if (peer->as < BGP_PRIVATE_AS_MIN
- || peer->local_as > BGP_PRIVATE_AS_MAX)
- attr->pathlimit.as = peer->as;
- }
- }
-
- /* If this is EBGP peer and remove-private-AS is set. */
- if (peer_sort (peer) == BGP_PEER_EBGP
- && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && aspath_private_as_check (attr->aspath))
- attr->aspath = aspath_empty_get ();
- /* Route map & unsuppress-map apply. */
- if (ROUTE_MAP_OUT_NAME (filter)
- || (ri->extra && ri->extra->suppress) )
- {
- struct bgp_info info;
- struct attr dummy_attr = { 0 };
-
- info.peer = peer;
- info.attr = attr;
- /* The route reflector is not allowed to modify the attributes
- of the reflected IBGP routes. */
- if (peer_sort (from) == BGP_PEER_IBGP
- && peer_sort (peer) == BGP_PEER_IBGP)
- {
- bgp_attr_dup (&dummy_attr, attr);
- info.attr = &dummy_attr;
- }
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
- if (ri->extra && ri->extra->suppress)
- ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
- else
- ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
- peer->rmap_type = 0;
-
- if (dummy_attr.extra)
- bgp_attr_extra_free (&dummy_attr);
-
- if (ret == RMAP_DENYMATCH)
- {
- bgp_attr_flush (attr);
- return 0;
- }
- }
- return 1;
- }
- static int
- bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
- struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
- {
- int ret;
- char buf[SU_ADDRSTRLEN];
- struct bgp_filter *filter;
- struct bgp_info info;
- struct peer *from;
- struct bgp *bgp;
- from = ri->peer;
- filter = &rsclient->filter[afi][safi];
- bgp = rsclient->bgp;
- if (DISABLE_BGP_ANNOUNCE)
- return 0;
- /* Do not send back route to sender. */
- if (from == rsclient)
- return 0;
- /* Aggregate-address suppress check. */
- if (ri->extra && ri->extra->suppress)
- if (! UNSUPPRESS_MAP_NAME (filter))
- return 0;
- /* Default route check. */
- if (CHECK_FLAG (rsclient->af_sflags[afi][safi],
- PEER_STATUS_DEFAULT_ORIGINATE))
- {
- if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
- return 0;
- #ifdef HAVE_IPV6
- else if (p->family == AF_INET6 && p->prefixlen == 0)
- return 0;
- #endif /* HAVE_IPV6 */
- }
- /* If the attribute has originator-id and it is same as remote
- peer's id. */
- if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
- {
- if (IPV4_ADDR_SAME (&rsclient->remote_id,
- &ri->attr->extra->originator_id))
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (rsclient->log, LOG_DEBUG,
- "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
- rsclient->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- return 0;
- }
- }
- /* ORF prefix-list filter check */
- if (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
- && (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
- || CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
- if (rsclient->orf_plist[afi][safi])
- {
- if (prefix_list_apply (rsclient->orf_plist[afi][safi], p) == PREFIX_DENY)
- return 0;
- }
- /* Output filter check. */
- if (bgp_output_filter (rsclient, p, ri->attr, afi, safi) == FILTER_DENY)
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (rsclient->log, LOG_DEBUG,
- "%s [Update:SEND] %s/%d is filtered",
- rsclient->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- return 0;
- }
- #ifdef BGP_SEND_ASPATH_CHECK
- /* AS path loop check. */
- if (aspath_loop_check (ri->attr->aspath, rsclient->as))
- {
- if (BGP_DEBUG (filter, FILTER))
- zlog (rsclient->log, LOG_DEBUG,
- "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
- rsclient->host, rsclient->as);
- return 0;
- }
- #endif /* BGP_SEND_ASPATH_CHECK */
- /* For modify attribute, copy it to temporary structure. */
- bgp_attr_dup (attr, ri->attr);
- /* next-hop-set */
- if ((p->family == AF_INET && attr->nexthop.s_addr == 0)
- #ifdef HAVE_IPV6
- || (p->family == AF_INET6 &&
- IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
- #endif /* HAVE_IPV6 */
- )
- {
- /* Set IPv4 nexthop. */
- if (p->family == AF_INET)
- {
- if (safi == SAFI_MPLS_VPN)
- memcpy (&attr->extra->mp_nexthop_global_in, &rsclient->nexthop.v4,
- IPV4_MAX_BYTELEN);
- else
- memcpy (&attr->nexthop, &rsclient->nexthop.v4, IPV4_MAX_BYTELEN);
- }
- #ifdef HAVE_IPV6
- /* Set IPv6 nexthop. */
- if (p->family == AF_INET6)
- {
- /* IPv6 global nexthop must be included. */
- memcpy (&attr->extra->mp_nexthop_global, &rsclient->nexthop.v6_global,
- IPV6_MAX_BYTELEN);
- attr->extra->mp_nexthop_len = 16;
- }
- #endif /* HAVE_IPV6 */
- }
- #ifdef HAVE_IPV6
- if (p->family == AF_INET6)
- {
- struct attr_extra *attre = attr->extra;
-
- assert (attr->extra);
-
- /* Left nexthop_local unchanged if so configured. */
- if ( CHECK_FLAG (rsclient->af_flags[afi][safi],
- PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
- {
- if ( IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local) )
- attre->mp_nexthop_len=32;
- else
- attre->mp_nexthop_len=16;
- }
-
- /* Default nexthop_local treatment for RS-Clients */
- else
- {
- /* Announcer and RS-Client are both in the same network */
- if (rsclient->shared_network && from->shared_network &&
- (rsclient->ifindex == from->ifindex))
- {
- if ( IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local) )
- attre->mp_nexthop_len=32;
- else
- attre->mp_nexthop_len=16;
- }
- /* Set link-local address for shared network peer. */
- else if (rsclient->shared_network
- && IN6_IS_ADDR_LINKLOCAL (&rsclient->nexthop.v6_local))
- {
- memcpy (&attre->mp_nexthop_local, &rsclient->nexthop.v6_local,
- IPV6_MAX_BYTELEN);
- attre->mp_nexthop_len = 32;
- }
- else
- attre->mp_nexthop_len = 16;
- }
- }
- #endif /* HAVE_IPV6 */
- /* If this is EBGP peer and remove-private-AS is set. */
- if (peer_sort (rsclient) == BGP_PEER_EBGP
- && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && aspath_private_as_check (attr->aspath))
- attr->aspath = aspath_empty_get ();
- /* Route map & unsuppress-map apply. */
- if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
- {
- info.peer = rsclient;
- info.attr = attr;
- SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_OUT);
- if (ri->extra && ri->extra->suppress)
- ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
- else
- ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
- rsclient->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- bgp_attr_flush (attr);
- return 0;
- }
- }
- return 1;
- }
- struct bgp_info_pair
- {
- struct bgp_info *old;
- struct bgp_info *new;
- };
- static void
- bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *result)
- {
- struct bgp_info *new_select;
- struct bgp_info *old_select;
- struct bgp_info *ri;
- struct bgp_info *ri1;
- struct bgp_info *ri2;
- struct bgp_info *nextri = NULL;
-
- /* bgp deterministic-med */
- new_select = NULL;
- if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
- for (ri1 = rn->info; ri1; ri1 = ri1->next)
- {
- if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
- continue;
- if (BGP_INFO_HOLDDOWN (ri1))
- continue;
- new_select = ri1;
- if (ri1->next)
- for (ri2 = ri1->next; ri2; ri2 = ri2->next)
- {
- if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
- continue;
- if (BGP_INFO_HOLDDOWN (ri2))
- continue;
- if (aspath_cmp_left (ri1->attr->aspath, ri2->attr->aspath)
- || aspath_cmp_left_confed (ri1->attr->aspath,
- ri2->attr->aspath))
- {
- if (bgp_info_cmp (bgp, ri2, new_select))
- {
- bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
- new_select = ri2;
- }
- bgp_info_set_flag (rn, ri2, BGP_INFO_DMED_CHECK);
- }
- }
- bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_CHECK);
- bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
- }
- /* Check old selected route and new selected route. */
- old_select = NULL;
- new_select = NULL;
- for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- old_select = ri;
- if (BGP_INFO_HOLDDOWN (ri))
- {
- /* reap REMOVED routes, if needs be
- * selected route must stay for a while longer though
- */
- if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
- && (ri != old_select))
- bgp_info_reap (rn, ri);
-
- continue;
- }
- if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)
- && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED)))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
- continue;
- }
- bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
- bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_SELECTED);
- if (bgp_info_cmp (bgp, ri, new_select))
- new_select = ri;
- }
-
- result->old = old_select;
- result->new = new_select;
- return;
- }
- static int
- bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
- struct bgp_node *rn, afi_t afi, safi_t safi)
- {
- struct prefix *p;
- struct attr attr = { 0 };
- p = &rn->p;
- /* Announce route to Established peer. */
- if (peer->status != Established)
- return 0;
- /* Address family configuration check. */
- if (! peer->afc_nego[afi][safi])
- return 0;
- /* First update is deferred until ORF or ROUTE-REFRESH is received */
- if (CHECK_FLAG (peer->af_sflags[afi][safi],
- PEER_STATUS_ORF_WAIT_REFRESH))
- return 0;
- switch (rn->table->type)
- {
- case BGP_TABLE_MAIN:
- /* Announcement to peer->conf. If the route is filtered,
- withdraw it. */
- if (selected && bgp_announce_check (selected, peer, p, &attr, afi, safi))
- bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
- else
- bgp_adj_out_unset (rn, peer, p, afi, safi);
- break;
- case BGP_TABLE_RSCLIENT:
- /* Announcement to peer->conf. If the route is filtered,
- withdraw it. */
- if (selected &&
- bgp_announce_check_rsclient (selected, peer, p, &attr, afi, safi))
- bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
- else
- bgp_adj_out_unset (rn, peer, p, afi, safi);
- break;
- }
-
- bgp_attr_extra_free (&attr);
-
- return 0;
- }
- struct bgp_process_queue
- {
- struct bgp *bgp;
- struct bgp_node *rn;
- afi_t afi;
- safi_t safi;
- };
- static wq_item_status
- bgp_process_rsclient (struct work_queue *wq, void *data)
- {
- struct bgp_process_queue *pq = data;
- struct bgp *bgp = pq->bgp;
- struct bgp_node *rn = pq->rn;
- afi_t afi = pq->afi;
- safi_t safi = pq->safi;
- struct bgp_info *new_select;
- struct bgp_info *old_select;
- struct bgp_info_pair old_and_new;
- struct listnode *node, *nnode;
- struct peer *rsclient = rn->table->owner;
-
- /* Best path selection. */
- bgp_best_selection (bgp, rn, &old_and_new);
- new_select = old_and_new.new;
- old_select = old_and_new.old;
- if (CHECK_FLAG (rsclient->sflags, PEER_STATUS_GROUP))
- {
- if (rsclient->group)
- for (ALL_LIST_ELEMENTS (rsclient->group->peer, node, nnode, rsclient))
- {
- /* Nothing to do. */
- if (old_select && old_select == new_select)
- if (!CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
- continue;
- if (old_select)
- bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
- if (new_select)
- {
- bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
- bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- }
- bgp_process_announce_selected (rsclient, new_select, rn,
- afi, safi);
- }
- }
- else
- {
- if (old_select)
- bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
- if (new_select)
- {
- bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
- bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- }
- bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
- }
- if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
- bgp_info_reap (rn, old_select);
-
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
- }
- static wq_item_status
- bgp_process_main (struct work_queue *wq, void *data)
- {
- struct bgp_process_queue *pq = data;
- struct bgp *bgp = pq->bgp;
- struct bgp_node *rn = pq->rn;
- afi_t afi = pq->afi;
- safi_t safi = pq->safi;
- struct prefix *p = &rn->p;
- struct bgp_info *new_select;
- struct bgp_info *old_select;
- struct bgp_info_pair old_and_new;
- struct listnode *node, *nnode;
- struct peer *peer;
-
- /* Best path selection. */
- bgp_best_selection (bgp, rn, &old_and_new);
- old_select = old_and_new.old;
- new_select = old_and_new.new;
- /* Nothing to do. */
- if (old_select && old_select == new_select)
- {
- if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
- {
- if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED))
- bgp_zebra_announce (p, old_select, bgp);
-
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
- }
- }
- if (old_select)
- bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
- if (new_select)
- {
- bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
- bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- }
- /* Check each BGP peer. */
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- {
- bgp_process_announce_selected (peer, new_select, rn, afi, safi);
- }
- /* FIB update. */
- if (safi == SAFI_UNICAST && ! bgp->name &&
- ! bgp_option_check (BGP_OPT_NO_FIB))
- {
- if (new_select
- && new_select->type == ZEBRA_ROUTE_BGP
- && new_select->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_announce (p, new_select, bgp);
- else
- {
- /* Withdraw the route from the kernel. */
- if (old_select
- && old_select->type == ZEBRA_ROUTE_BGP
- && old_select->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_withdraw (p, old_select);
- }
- }
-
- /* Reap old select bgp_info, it it has been removed */
- if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
- bgp_info_reap (rn, old_select);
-
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
- }
- static void
- bgp_processq_del (struct work_queue *wq, void *data)
- {
- struct bgp_process_queue *pq = data;
- struct bgp_table *table = pq->rn->table;
-
- bgp_unlock (pq->bgp);
- bgp_unlock_node (pq->rn);
- bgp_table_unlock (table);
- XFREE (MTYPE_BGP_PROCESS_QUEUE, pq);
- }
- static void
- bgp_process_queue_init (void)
- {
- bm->process_main_queue
- = work_queue_new (bm->master, "process_main_queue");
- bm->process_rsclient_queue
- = work_queue_new (bm->master, "process_rsclient_queue");
-
- if ( !(bm->process_main_queue && bm->process_rsclient_queue) )
- {
- zlog_err ("%s: Failed to allocate work queue", __func__);
- exit (1);
- }
-
- bm->process_main_queue->spec.workfunc = &bgp_process_main;
- bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
- bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
- bm->process_rsclient_queue->spec.del_item_data
- = bm->process_main_queue->spec.del_item_data;
- bm->process_main_queue->spec.max_retries
- = bm->process_main_queue->spec.max_retries = 0;
- bm->process_rsclient_queue->spec.hold
- = bm->process_main_queue->spec.hold = 50;
- }
- void
- bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
- {
- struct bgp_process_queue *pqnode;
-
- /* already scheduled for processing? */
- if (CHECK_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED))
- return;
-
- if ( (bm->process_main_queue == NULL) ||
- (bm->process_rsclient_queue == NULL) )
- bgp_process_queue_init ();
-
- pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
- sizeof (struct bgp_process_queue));
- if (!pqnode)
- return;
- /* all unlocked in bgp_processq_del */
- bgp_table_lock (rn->table);
- pqnode->rn = bgp_lock_node (rn);
- pqnode->bgp = bgp;
- bgp_lock (bgp);
- pqnode->afi = afi;
- pqnode->safi = safi;
-
- switch (rn->table->type)
- {
- case BGP_TABLE_MAIN:
- work_queue_add (bm->process_main_queue, pqnode);
- break;
- case BGP_TABLE_RSCLIENT:
- work_queue_add (bm->process_rsclient_queue, pqnode);
- break;
- }
-
- return;
- }
- static int
- bgp_maximum_prefix_restart_timer (struct thread *thread)
- {
- struct peer *peer;
- peer = THREAD_ARG (thread);
- peer->t_pmax_restart = NULL;
- if (BGP_DEBUG (events, EVENTS))
- zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
- peer->host);
- peer_clear (peer);
- return 0;
- }
- int
- bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
- safi_t safi, int always)
- {
- if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
- return 0;
- if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
- {
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT)
- && ! always)
- return 0;
- zlog (peer->log, LOG_INFO,
- "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
- "limit %ld", afi_safi_print (afi, safi), peer->host,
- peer->pcount[afi][safi], peer->pmax[afi][safi]);
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
- return 0;
- {
- u_int8_t ndata[7];
- if (safi == SAFI_MPLS_VPN)
- safi = BGP_SAFI_VPNV4;
-
- ndata[0] = (afi >> 8);
- ndata[1] = afi;
- ndata[2] = safi;
- ndata[3] = (peer->pmax[afi][safi] >> 24);
- ndata[4] = (peer->pmax[afi][safi] >> 16);
- ndata[5] = (peer->pmax[afi][safi] >> 8);
- ndata[6] = (peer->pmax[afi][safi]);
- SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
- bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
- }
- /* restart timer start */
- if (peer->pmax_restart[afi][safi])
- {
- peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
- if (BGP_DEBUG (events, EVENTS))
- zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
- peer->host, peer->v_pmax_restart);
- BGP_TIMER_ON (peer->t_pmax_restart, bgp_maximum_prefix_restart_timer,
- peer->v_pmax_restart);
- }
- return 1;
- }
- else
- UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
- if (peer->pcount[afi][safi] > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100))
- {
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD)
- && ! always)
- return 0;
- zlog (peer->log, LOG_INFO,
- "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
- afi_safi_print (afi, safi), peer->host, peer->pcount[afi][safi],
- peer->pmax[afi][safi]);
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
- }
- else
- UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
- return 0;
- }
- /* Unconditionally remove the route from the RIB, without taking
- * damping into consideration (eg, because the session went down)
- */
- static void
- bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
- afi_t afi, safi_t safi)
- {
- bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
-
- if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_info_delete (rn, ri); /* keep historical info */
-
- bgp_process (peer->bgp, rn, afi, safi);
- }
- static void
- bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
- afi_t afi, safi_t safi)
- {
- int status = BGP_DAMP_NONE;
- /* apply dampening, if result is suppressed, we'll be retaining
- * the bgp_info in the RIB for historical reference.
- */
- if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP)
- if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0))
- == BGP_DAMP_SUPPRESSED)
- {
- bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
- return;
- }
-
- bgp_rib_remove (rn, ri, peer, afi, safi);
- }
- static void
- bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
- struct attr *attr, struct peer *peer, struct prefix *p, int type,
- int sub_type, struct prefix_rd *prd, u_char *tag)
- {
- struct bgp_node *rn;
- struct bgp *bgp;
- struct attr new_attr = { 0 };
- struct attr *attr_new;
- struct attr *attr_new2;
- struct bgp_info *ri;
- struct bgp_info *new;
- const char *reason;
- char buf[SU_ADDRSTRLEN];
- /* Do not insert announces from a rsclient into its own 'bgp_table'. */
- if (peer == rsclient)
- return;
- bgp = peer->bgp;
- rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
- /* Check previously received route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
- break;
- /* AS path loop check. */
- if (aspath_loop_check (attr->aspath, rsclient->as) > peer->allowas_in[afi][safi])
- {
- reason = "as-path contains our own AS;";
- goto filtered;
- }
- /* Route reflector originator ID check. */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
- && IPV4_ADDR_SAME (&rsclient->remote_id, &attr->extra->originator_id))
- {
- reason = "originator is us;";
- goto filtered;
- }
-
- bgp_attr_dup (&new_attr, attr);
- /* Apply export policy. */
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) &&
- bgp_export_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
- {
- reason = "export-policy;";
- goto filtered;
- }
- attr_new2 = bgp_attr_intern (&new_attr);
-
- /* Apply import policy. */
- if (bgp_import_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
- {
- bgp_attr_unintern (attr_new2);
- reason = "import-policy;";
- goto filtered;
- }
- attr_new = bgp_attr_intern (&new_attr);
- bgp_attr_unintern (attr_new2);
- /* IPv4 unicast next hop check. */
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- {
- /* Next hop must not be 0.0.0.0 nor Class E address. */
- if (new_attr.nexthop.s_addr == 0
- || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
- {
- bgp_attr_unintern (attr_new);
- reason = "martian next-hop;";
- goto filtered;
- }
- }
-
- /* new_attr isn't passed to any functions after here */
- bgp_attr_extra_free (&new_attr);
-
- /* If the update is implicit withdraw. */
- if (ri)
- {
- ri->uptime = bgp_clock ();
- /* Same attribute comes in. */
- if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
- && attrhash_cmp (ri->attr, attr_new))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s rcvd %s/%d for RS-client %s...duplicate ignored",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- bgp_unlock_node (rn);
- bgp_attr_unintern (attr_new);
- return;
- }
- /* Withdraw/Announce before we fully processed the withdraw */
- if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- bgp_info_restore (rn, ri);
-
- /* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- /* The attribute is changed. */
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- /* Update to new attribute. */
- bgp_attr_unintern (ri->attr);
- ri->attr = attr_new;
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN)
- memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
- return;
- }
- /* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- {
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- }
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = type;
- new->sub_type = sub_type;
- new->peer = peer;
- new->attr = attr_new;
- new->uptime = bgp_clock ();
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN)
- memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
-
- bgp_attr_extra_free (&new_attr);
-
- return;
- filtered:
- /* This BGP update is filtered. Log the reason then update BGP entry. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s rcvd UPDATE about %s/%d -- DENIED for RS-client %s due to: %s",
- peer->host,
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host, reason);
- if (ri)
- bgp_rib_remove (rn, ri, peer, afi, safi);
- bgp_unlock_node (rn);
-
- if (new_attr.extra)
- bgp_attr_extra_free (&new_attr);
-
- return;
- }
- static void
- bgp_withdraw_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
- struct peer *peer, struct prefix *p, int type, int sub_type,
- struct prefix_rd *prd, u_char *tag)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- char buf[SU_ADDRSTRLEN];
- if (rsclient == peer)
- return;
- rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
- /* Lookup withdrawn route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
- break;
- /* Withdraw specified route from routing table. */
- if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_rib_withdraw (rn, ri, peer, afi, safi);
- else if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s Can't find the route %s/%d", peer->host,
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- /* Unlock bgp_node_get() lock. */
- bgp_unlock_node (rn);
- }
- static int
- bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, int type, int sub_type,
- struct prefix_rd *prd, u_char *tag, int soft_reconfig)
- {
- int ret;
- int aspath_loop_count = 0;
- struct bgp_node *rn;
- struct bgp *bgp;
- struct attr new_attr = { 0 };
- struct attr *attr_new;
- struct bgp_info *ri;
- struct bgp_info *new;
- const char *reason;
- char buf[SU_ADDRSTRLEN];
- bgp = peer->bgp;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
- /* When peer's soft reconfiguration enabled. Record input packet in
- Adj-RIBs-In. */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
- && peer != bgp->peer_self && ! soft_reconfig)
- bgp_adj_in_set (rn, peer, attr);
- /* Check previously received route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
- break;
- /* AS path local-as loop check. */
- if (peer->change_local_as)
- {
- if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
- aspath_loop_count = 1;
- if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count)
- {
- reason = "as-path contains our own AS;";
- goto filtered;
- }
- }
- /* AS path loop check. */
- if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
- || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
- && aspath_loop_check(attr->aspath, bgp->confed_id)
- > peer->allowas_in[afi][safi]))
- {
- reason = "as-path contains our own AS;";
- goto filtered;
- }
- /* Route reflector originator ID check. */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
- && IPV4_ADDR_SAME (&bgp->router_id, &attr->extra->originator_id))
- {
- reason = "originator is us;";
- goto filtered;
- }
- /* Route reflector cluster ID check. */
- if (bgp_cluster_filter (peer, attr))
- {
- reason = "reflected from the same cluster;";
- goto filtered;
- }
- /* Apply incoming filter. */
- if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)
- {
- reason = "filter;";
- goto filtered;
- }
- /* Apply incoming route-map. */
- bgp_attr_dup (&new_attr, attr);
- if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)
- {
- reason = "route-map;";
- goto filtered;
- }
- /* IPv4 unicast next hop check. */
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- {
- /* If the peer is EBGP and nexthop is not on connected route,
- discard it. */
- if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1
- && ! bgp_nexthop_check_ebgp (afi, &new_attr)
- && ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
- {
- reason = "non-connected next-hop;";
- goto filtered;
- }
- /* Next hop must not be 0.0.0.0 nor Class E address. Next hop
- must not be my own address. */
- if (bgp_nexthop_self (afi, &new_attr)
- || new_attr.nexthop.s_addr == 0
- || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
- {
- reason = "martian next-hop;";
- goto filtered;
- }
- }
- attr_new = bgp_attr_intern (&new_attr);
- /* If the update is implicit withdraw. */
- if (ri)
- {
- ri->uptime = bgp_clock ();
- /* Same attribute comes in. */
- if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
- && attrhash_cmp (ri->attr, attr_new))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP
- && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- {
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
- {
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- }
- }
- else /* Duplicate - odd */
- {
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s rcvd %s/%d...duplicate ignored",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- /* graceful restart STALE flag unset. */
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
- bgp_process (bgp, rn, afi, safi);
- }
- }
- bgp_unlock_node (rn);
- bgp_attr_unintern (attr_new);
- bgp_attr_extra_free (&new_attr);
-
- return 0;
- }
- /* Withdraw/Announce before we fully processed the withdraw */
- if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- {
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d, flapped quicker than processing",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- bgp_info_restore (rn, ri);
- }
- /* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- /* graceful restart STALE flag unset. */
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
- /* The attribute is changed. */
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
-
- /* implicit withdraw, decrement aggregate and pcount here.
- * only if update is accepted, they'll increment below.
- */
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
-
- /* Update bgp route dampening information. */
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP)
- {
- /* This is implicit withdraw so we should update dampening
- information. */
- if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_damp_withdraw (ri, rn, afi, safi, 1);
- }
-
- /* Update to new attribute. */
- bgp_attr_unintern (ri->attr);
- ri->attr = attr_new;
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN)
- memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
- /* Update bgp route dampening information. */
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP)
- {
- /* Now we do normal update dampening. */
- ret = bgp_damp_update (ri, rn, afi, safi);
- if (ret == BGP_DAMP_SUPPRESSED)
- {
- bgp_unlock_node (rn);
- bgp_attr_extra_free (&new_attr);
- return 0;
- }
- }
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6)
- && safi == SAFI_UNICAST
- && (peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED
- || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
- || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
- {
- if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- else
- bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
- }
- else
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- /* Process change. */
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
- bgp_attr_extra_free (&new_attr);
-
- return 0;
- }
- /* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- {
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- }
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = type;
- new->sub_type = sub_type;
- new->peer = peer;
- new->attr = attr_new;
- new->uptime = bgp_clock ();
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN)
- memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6)
- && safi == SAFI_UNICAST
- && (peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED
- || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
- || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
- {
- if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- else
- bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
- }
- else
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- /* Increment prefix */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- bgp_attr_extra_free (&new_attr);
-
- /* If maximum prefix count is configured and current prefix
- count exeed it. */
- if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
- return -1;
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- return 0;
- /* This BGP update is filtered. Log the reason then update BGP
- entry. */
- filtered:
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s rcvd UPDATE about %s/%d -- DENIED due to: %s",
- peer->host,
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, reason);
- if (ri)
- bgp_rib_remove (rn, ri, peer, afi, safi);
- bgp_unlock_node (rn);
-
- bgp_attr_extra_free (&new_attr);
-
- return 0;
- }
- int
- bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, int type, int sub_type,
- struct prefix_rd *prd, u_char *tag, int soft_reconfig)
- {
- struct peer *rsclient;
- struct listnode *node, *nnode;
- struct bgp *bgp;
- int ret;
- ret = bgp_update_main (peer, p, attr, afi, safi, type, sub_type, prd, tag,
- soft_reconfig);
- bgp = peer->bgp;
- /* Process the update for each RS-client. */
- for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
- {
- if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- bgp_update_rsclient (rsclient, afi, safi, attr, peer, p, type,
- sub_type, prd, tag);
- }
- return ret;
- }
- int
- bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, int type, int sub_type,
- struct prefix_rd *prd, u_char *tag)
- {
- struct bgp *bgp;
- char buf[SU_ADDRSTRLEN];
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct peer *rsclient;
- struct listnode *node, *nnode;
- bgp = peer->bgp;
- /* Process the withdraw for each RS-client. */
- for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
- {
- if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- bgp_withdraw_rsclient (rsclient, afi, safi, peer, p, type, sub_type, prd, tag);
- }
- /* Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE about %s/%d -- withdrawn",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- /* Lookup node. */
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
- /* If peer is soft reconfiguration enabled. Record input packet for
- further calculation. */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
- && peer != bgp->peer_self)
- bgp_adj_in_unset (rn, peer);
- /* Lookup withdrawn route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
- break;
- /* Withdraw specified route from routing table. */
- if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_rib_withdraw (rn, ri, peer, afi, safi);
- else if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
- "%s Can't find the route %s/%d", peer->host,
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- /* Unlock bgp_node_get() lock. */
- bgp_unlock_node (rn);
- return 0;
- }
- void
- bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
- {
- struct bgp *bgp;
- struct attr attr = { 0 };
- struct aspath *aspath = { 0 };
- struct prefix p;
- struct bgp_info binfo;
- struct peer *from;
- int ret = RMAP_DENYMATCH;
-
- if (!(afi == AFI_IP || afi == AFI_IP6))
- return;
-
- bgp = peer->bgp;
- from = bgp->peer_self;
-
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
- aspath = attr.aspath;
- attr.local_pref = bgp->default_local_pref;
- memcpy (&attr.nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
- if (afi == AFI_IP)
- str2prefix ("0.0.0.0/0", &p);
- #ifdef HAVE_IPV6
- else if (afi == AFI_IP6)
- {
- struct attr_extra *ae;
- attr.extra = NULL;
-
- ae = bgp_attr_extra_get (&attr);
- attr.extra = ae;
-
- str2prefix ("::/0", &p);
- /* IPv6 global nexthop must be included. */
- memcpy (&ae->mp_nexthop_global, &peer->nexthop.v6_global,
- IPV6_MAX_BYTELEN);
- ae->mp_nexthop_len = 16;
-
- /* If the peer is on shared nextwork and we have link-local
- nexthop set it. */
- if (peer->shared_network
- && !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
- {
- memcpy (&ae->mp_nexthop_local, &peer->nexthop.v6_local,
- IPV6_MAX_BYTELEN);
- ae->mp_nexthop_len = 32;
- }
- }
- #endif /* HAVE_IPV6 */
- if (peer->default_rmap[afi][safi].name)
- {
- binfo.peer = bgp->peer_self;
- binfo.attr = &attr;
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
- ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
- RMAP_BGP, &binfo);
- bgp->peer_self->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- bgp_attr_flush (&attr);
- withdraw = 1;
- }
- }
- if (withdraw)
- {
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
- bgp_default_withdraw_send (peer, afi, safi);
- UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
- }
- else
- {
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
- bgp_default_update_send (peer, &attr, afi, safi, from);
- }
-
- bgp_attr_extra_free (&attr);
- aspath_unintern (aspath);
- }
- static void
- bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table, int rsclient)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct attr attr = { 0 };
-
- if (! table)
- table = (rsclient) ? peer->rib[afi][safi] : peer->bgp->rib[afi][safi];
- if (safi != SAFI_MPLS_VPN
- && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
- bgp_default_originate (peer, afi, safi, 0);
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next(rn))
- for (ri = rn->info; ri; ri = ri->next)
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
- {
- if ( (rsclient) ?
- (bgp_announce_check_rsclient (ri, peer, &rn->p, &attr, afi, safi))
- : (bgp_announce_check (ri, peer, &rn->p, &attr, afi, safi)))
- bgp_adj_out_set (rn, peer, &rn->p, &attr, afi, safi, ri);
- else
- bgp_adj_out_unset (rn, peer, &rn->p, afi, safi);
-
- bgp_attr_extra_free (&attr);
- }
- }
- void
- bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_table *table;
- if (peer->status != Established)
- return;
- if (! peer->afc_nego[afi][safi])
- return;
- /* First update is deferred until ORF or ROUTE-REFRESH is received */
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
- return;
- if (safi != SAFI_MPLS_VPN)
- bgp_announce_table (peer, afi, safi, NULL, 0);
- else
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next(rn))
- if ((table = (rn->info)) != NULL)
- bgp_announce_table (peer, afi, safi, table, 0);
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- bgp_announce_table (peer, afi, safi, NULL, 1);
- }
- void
- bgp_announce_route_all (struct peer *peer)
- {
- afi_t afi;
- safi_t safi;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_announce_route (peer, afi, safi);
- }
- static void
- bgp_soft_reconfig_table_rsclient (struct peer *rsclient, afi_t afi,
- safi_t safi, struct bgp_table *table)
- {
- struct bgp_node *rn;
- struct bgp_adj_in *ain;
- if (! table)
- table = rsclient->bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ain = rn->adj_in; ain; ain = ain->next)
- {
- bgp_update_rsclient (rsclient, afi, safi, ain->attr, ain->peer,
- &rn->p, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
- }
- }
- void
- bgp_soft_reconfig_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
- {
- struct bgp_table *table;
- struct bgp_node *rn;
-
- if (safi != SAFI_MPLS_VPN)
- bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, NULL);
- else
- for (rn = bgp_table_top (rsclient->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((table = rn->info) != NULL)
- bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, table);
- }
- static void
- bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table)
- {
- int ret;
- struct bgp_node *rn;
- struct bgp_adj_in *ain;
- if (! table)
- table = peer->bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ain = rn->adj_in; ain; ain = ain->next)
- {
- if (ain->peer == peer)
- {
- ret = bgp_update (peer, &rn->p, ain->attr, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
- NULL, NULL, 1);
- if (ret < 0)
- {
- bgp_unlock_node (rn);
- return;
- }
- continue;
- }
- }
- }
- void
- bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_table *table;
- if (peer->status != Established)
- return;
- if (safi != SAFI_MPLS_VPN)
- bgp_soft_reconfig_table (peer, afi, safi, NULL);
- else
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((table = rn->info) != NULL)
- bgp_soft_reconfig_table (peer, afi, safi, table);
- }
- struct bgp_clear_node_queue
- {
- struct bgp_node *rn;
- enum bgp_clear_route_type purpose;
- };
- static wq_item_status
- bgp_clear_route_node (struct work_queue *wq, void *data)
- {
- struct bgp_clear_node_queue *cnq = data;
- struct bgp_node *rn = cnq->rn;
- struct peer *peer = wq->spec.data;
- struct bgp_info *ri;
- afi_t afi = rn->table->afi;
- safi_t safi = rn->table->safi;
-
- assert (rn && peer);
-
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer || cnq->purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- /* graceful restart STALE flag set. */
- if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)
- && peer->nsf[afi][safi]
- && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
- && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
- else
- bgp_rib_remove (rn, ri, peer, afi, safi);
- break;
- }
- return WQ_SUCCESS;
- }
- static void
- bgp_clear_node_queue_del (struct work_queue *wq, void *data)
- {
- struct bgp_clear_node_queue *cnq = data;
- struct bgp_node *rn = cnq->rn;
- struct bgp_table *table = rn->table;
-
- bgp_unlock_node (rn);
- bgp_table_unlock (table);
- XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
- }
- static void
- bgp_clear_node_complete (struct work_queue *wq)
- {
- struct peer *peer = wq->spec.data;
-
- /* Tickle FSM to start moving again */
- BGP_EVENT_ADD (peer, Clearing_Completed);
- peer_unlock (peer); /* bgp_clear_route */
- }
- static void
- bgp_clear_node_queue_init (struct peer *peer)
- {
- char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
-
- snprintf (wname, sizeof(wname), "clear %s", peer->host);
- #undef CLEAR_QUEUE_NAME_LEN
- if ( (peer->clear_node_queue = work_queue_new (bm->master, wname)) == NULL)
- {
- zlog_err ("%s: Failed to allocate work queue", __func__);
- exit (1);
- }
- peer->clear_node_queue->spec.hold = 10;
- peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
- peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
- peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
- peer->clear_node_queue->spec.max_retries = 0;
-
- /* we only 'lock' this peer reference when the queue is actually active */
- peer->clear_node_queue->spec.data = peer;
- }
- static void
- bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table, struct peer *rsclient,
- enum bgp_clear_route_type purpose)
- {
- struct bgp_node *rn;
-
-
- if (! table)
- table = (rsclient) ? rsclient->rib[afi][safi] : peer->bgp->rib[afi][safi];
-
- /* If still no table => afi/safi isn't configured at all or smth. */
- if (! table)
- return;
-
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- struct bgp_info *ri;
- struct bgp_adj_in *ain;
- struct bgp_adj_out *aout;
-
- if (rn->info == NULL)
- continue;
- /* XXX:TODO: This is suboptimal, every non-empty route_node is
- * queued for every clearing peer, regardless of whether it is
- * relevant to the peer at hand.
- *
- * Overview: There are 3 different indices which need to be
- * scrubbed, potentially, when a peer is removed:
- *
- * 1 peer's routes visible via the RIB (ie accepted routes)
- * 2 peer's routes visible by the (optional) peer's adj-in index
- * 3 other routes visible by the peer's adj-out index
- *
- * 3 there is no hurry in scrubbing, once the struct peer is
- * removed from bgp->peer, we could just GC such deleted peer's
- * adj-outs at our leisure.
- *
- * 1 and 2 must be 'scrubbed' in some way, at least made
- * invisible via RIB index before peer session is allowed to be
- * brought back up. So one needs to know when such a 'search' is
- * complete.
- *
- * Ideally:
- *
- * - there'd be a single global queue or a single RIB walker
- * - rather than tracking which route_nodes still need to be
- * examined on a peer basis, we'd track which peers still
- * aren't cleared
- *
- * Given that our per-peer prefix-counts now should be reliable,
- * this may actually be achievable. It doesn't seem to be a huge
- * problem at this time,
- */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- struct bgp_clear_node_queue *cnq;
- /* both unlocked in bgp_clear_node_queue_del */
- bgp_table_lock (rn->table);
- bgp_lock_node (rn);
- cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
- sizeof (struct bgp_clear_node_queue));
- cnq->rn = rn;
- cnq->purpose = purpose;
- work_queue_add (peer->clear_node_queue, cnq);
- break;
- }
- for (ain = rn->adj_in; ain; ain = ain->next)
- if (ain->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- break;
- }
- for (aout = rn->adj_out; aout; aout = aout->next)
- if (aout->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- bgp_adj_out_remove (rn, aout, peer, afi, safi);
- bgp_unlock_node (rn);
- break;
- }
- }
- return;
- }
- void
- bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi,
- enum bgp_clear_route_type purpose)
- {
- struct bgp_node *rn;
- struct bgp_table *table;
- struct peer *rsclient;
- struct listnode *node, *nnode;
- if (peer->clear_node_queue == NULL)
- bgp_clear_node_queue_init (peer);
-
- /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
- * Idle until it receives a Clearing_Completed event. This protects
- * against peers which flap faster than we can we clear, which could
- * lead to:
- *
- * a) race with routes from the new session being installed before
- * clear_route_node visits the node (to delete the route of that
- * peer)
- * b) resource exhaustion, clear_route_node likely leads to an entry
- * on the process_main queue. Fast-flapping could cause that queue
- * to grow and grow.
- */
- if (!peer->clear_node_queue->thread)
- peer_lock (peer); /* bgp_clear_node_complete */
- switch (purpose)
- {
- case BGP_CLEAR_ROUTE_NORMAL:
- if (safi != SAFI_MPLS_VPN)
- bgp_clear_route_table (peer, afi, safi, NULL, NULL, purpose);
- else
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((table = rn->info) != NULL)
- bgp_clear_route_table (peer, afi, safi, table, NULL, purpose);
- for (ALL_LIST_ELEMENTS (peer->bgp->rsclient, node, nnode, rsclient))
- if (CHECK_FLAG(rsclient->af_flags[afi][safi],
- PEER_FLAG_RSERVER_CLIENT))
- bgp_clear_route_table (peer, afi, safi, NULL, rsclient, purpose);
- break;
- case BGP_CLEAR_ROUTE_MY_RSCLIENT:
- bgp_clear_route_table (peer, afi, safi, NULL, peer, purpose);
- break;
- default:
- assert (0);
- break;
- }
-
- /* If no routes were cleared, nothing was added to workqueue, the
- * completion function won't be run by workqueue code - call it here.
- * XXX: Actually, this assumption doesn't hold, see
- * bgp_clear_route_table(), we queue all non-empty nodes.
- *
- * Additionally, there is a presumption in FSM that clearing is only
- * really needed if peer state is Established - peers in
- * pre-Established states shouldn't have any route-update state
- * associated with them (in or out).
- *
- * We still can get here in pre-Established though, through
- * peer_delete -> bgp_fsm_change_status, so this is a useful sanity
- * check to ensure the assumption above holds.
- *
- * At some future point, this check could be move to the top of the
- * function, and do a quick early-return when state is
- * pre-Established, avoiding above list and table scans. Once we're
- * sure it is safe..
- */
- if (!peer->clear_node_queue->thread)
- bgp_clear_node_complete (peer->clear_node_queue);
- }
-
- void
- bgp_clear_route_all (struct peer *peer)
- {
- afi_t afi;
- safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
- }
- void
- bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
- {
- struct bgp_table *table;
- struct bgp_node *rn;
- struct bgp_adj_in *ain;
- table = peer->bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ain = rn->adj_in; ain ; ain = ain->next)
- if (ain->peer == peer)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- break;
- }
- }
- void
- bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_table *table;
- table = peer->bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_rib_remove (rn, ri, peer, afi, safi);
- break;
- }
- }
- }
- /* Delete all kernel routes. */
- void
- bgp_cleanup_routes (void)
- {
- struct bgp *bgp;
- struct listnode *node, *nnode;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct bgp_info *ri;
- for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
- {
- table = bgp->rib[AFI_IP][SAFI_UNICAST];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = ri->next)
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_withdraw (&rn->p, ri);
- table = bgp->rib[AFI_IP6][SAFI_UNICAST];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = ri->next)
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_NORMAL)
- bgp_zebra_withdraw (&rn->p, ri);
- }
- }
- void
- bgp_reset (void)
- {
- vty_reset ();
- bgp_zclient_reset ();
- access_list_reset ();
- prefix_list_reset ();
- }
- /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
- value. */
- int
- bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
- {
- u_char *pnt;
- u_char *lim;
- struct prefix p;
- int psize;
- int ret;
- /* Check peer status. */
- if (peer->status != Established)
- return 0;
-
- pnt = packet->nlri;
- lim = pnt + packet->length;
- for (; pnt < lim; pnt += psize)
- {
- /* Clear prefix structure. */
- memset (&p, 0, sizeof (struct prefix));
- /* Fetch prefix length. */
- p.prefixlen = *pnt++;
- p.family = afi2family (packet->afi);
-
- /* Already checked in nlri_sanity_check(). We do double check
- here. */
- if ((packet->afi == AFI_IP && p.prefixlen > 32)
- || (packet->afi == AFI_IP6 && p.prefixlen > 128))
- return -1;
- /* Packet size overflow check. */
- psize = PSIZE (p.prefixlen);
- /* When packet overflow occur return immediately. */
- if (pnt + psize > lim)
- return -1;
- /* Fetch prefix from NLRI packet. */
- memcpy (&p.u.prefix, pnt, psize);
- /* Check address. */
- if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST)
- {
- if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
- {
- /*
- * From draft-ietf-idr-bgp4-22, Section 6.3:
- * If a BGP router receives an UPDATE message with a
- * semantically incorrect NLRI field, in which a prefix is
- * semantically incorrect (eg. an unexpected multicast IP
- * address), it should ignore the prefix.
- */
- zlog (peer->log, LOG_ERR,
- "IPv4 unicast NLRI is multicast address %s",
- inet_ntoa (p.u.prefix4));
- return -1;
- }
- }
- #ifdef HAVE_IPV6
- /* Check address. */
- if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST)
- {
- if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- char buf[BUFSIZ];
- zlog (peer->log, LOG_WARNING,
- "IPv6 link-local NLRI received %s ignore this NLRI",
- inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
- continue;
- }
- }
- #endif /* HAVE_IPV6 */
- /* Normal process. */
- if (attr)
- ret = bgp_update (peer, &p, attr, packet->afi, packet->safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
- else
- ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
- /* Address family configuration mismatch or maximum-prefix count
- overflow. */
- if (ret < 0)
- return -1;
- }
- /* Packet length consistency check. */
- if (pnt != lim)
- return -1;
- return 0;
- }
- /* NLRI encode syntax check routine. */
- int
- bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
- bgp_size_t length)
- {
- u_char *end;
- u_char prefixlen;
- int psize;
- end = pnt + length;
- /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for
- syntactic validity. If the field is syntactically incorrect,
- then the Error Subcode is set to Invalid Network Field. */
- while (pnt < end)
- {
- prefixlen = *pnt++;
-
- /* Prefix length check. */
- if ((afi == AFI_IP && prefixlen > 32)
- || (afi == AFI_IP6 && prefixlen > 128))
- {
- plog_err (peer->log,
- "%s [Error] Update packet error (wrong prefix length %d)",
- peer->host, prefixlen);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
- return -1;
- }
- /* Packet size overflow check. */
- psize = PSIZE (prefixlen);
- if (pnt + psize > end)
- {
- plog_err (peer->log,
- "%s [Error] Update packet error"
- " (prefix data overflow prefix size is %d)",
- peer->host, psize);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
- return -1;
- }
- pnt += psize;
- }
- /* Packet length consistency check. */
- if (pnt != end)
- {
- plog_err (peer->log,
- "%s [Error] Update packet error"
- " (prefix length mismatch with total length)",
- peer->host);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
- return -1;
- }
- return 0;
- }
- static struct bgp_static *
- bgp_static_new (void)
- {
- return XCALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));
- }
- static void
- bgp_static_free (struct bgp_static *bgp_static)
- {
- if (bgp_static->rmap.name)
- free (bgp_static->rmap.name);
- XFREE (MTYPE_BGP_STATIC, bgp_static);
- }
- static void
- bgp_static_withdraw_rsclient (struct bgp *bgp, struct peer *rsclient,
- struct prefix *p, afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
- /* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
- }
- static void
- bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
- struct bgp_static *bgp_static,
- afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_info *new;
- struct bgp_info info;
- struct attr *attr_new;
- struct attr attr = {0 };
- struct attr new_attr = { .extra = 0 };
- struct bgp *bgp;
- int ret;
- char buf[SU_ADDRSTRLEN];
- bgp = rsclient->bgp;
- assert (bgp_static);
- if (!bgp_static)
- return;
- rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
- attr.nexthop = bgp_static->igpnexthop;
- attr.med = bgp_static->igpmetric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
-
- if (bgp_static->ttl)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
- attr.pathlimit.as = 0;
- attr.pathlimit.ttl = bgp_static->ttl;
- }
-
- if (bgp_static->atomic)
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
-
- /* Apply network route-map for export to this rsclient. */
- if (bgp_static->rmap.name)
- {
- struct attr attr_tmp = attr;
- info.peer = rsclient;
- info.attr = &attr_tmp;
-
- SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
- SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
- rsclient->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_tmp);
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
- bgp_attr_extra_free (&attr);
-
- return;
- }
- attr_new = bgp_attr_intern (&attr_tmp);
- }
- else
- attr_new = bgp_attr_intern (&attr);
-
- new_attr = *attr_new;
-
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- if (bgp_import_modifier (rsclient, bgp->peer_self, p, &new_attr, afi, safi)
- == RMAP_DENY)
- {
- /* This BGP update is filtered. Log the reason then update BGP entry. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (rsclient->log, LOG_DEBUG,
- "Static UPDATE about %s/%d -- DENIED for RS-client %s due to: import-policy",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- bgp->peer_self->rmap_type = 0;
- bgp_attr_unintern (attr_new);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
-
- return;
- }
- bgp->peer_self->rmap_type = 0;
- bgp_attr_unintern (attr_new);
- attr_new = bgp_attr_intern (&new_attr);
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
- if (ri)
- {
- if (attrhash_cmp (ri->attr, attr_new) &&
- !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- {
- bgp_unlock_node (rn);
- bgp_attr_unintern (attr_new);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- else
- {
- /* The attribute is changed. */
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- /* Rewrite BGP route information. */
- if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- bgp_info_restore(rn, ri);
- bgp_attr_unintern (ri->attr);
- ri->attr = attr_new;
- ri->uptime = bgp_clock ();
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- }
-
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_STATIC;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = attr_new;
- new->uptime = bgp_clock ();
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- }
- static void
- bgp_static_update_main (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_info *new;
- struct bgp_info info;
- struct attr attr = { 0 };
- struct attr *attr_new;
- int ret;
- assert (bgp_static);
- if (!bgp_static)
- return;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
-
- attr.nexthop = bgp_static->igpnexthop;
- attr.med = bgp_static->igpmetric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- if (bgp_static->ttl)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
- attr.pathlimit.as = 0;
- attr.pathlimit.ttl = bgp_static->ttl;
- }
- if (bgp_static->atomic)
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
- /* Apply route-map. */
- if (bgp_static->rmap.name)
- {
- struct attr attr_tmp = attr;
- info.peer = bgp->peer_self;
- info.attr = &attr_tmp;
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
- bgp->peer_self->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_tmp);
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_static_withdraw (bgp, p, afi, safi);
- return;
- }
- attr_new = bgp_attr_intern (&attr_tmp);
- }
- else
- attr_new = bgp_attr_intern (&attr);
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
- if (ri)
- {
- if (attrhash_cmp (ri->attr, attr_new) &&
- !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- {
- bgp_unlock_node (rn);
- bgp_attr_unintern (attr_new);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- else
- {
- /* The attribute is changed. */
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- /* Rewrite BGP route information. */
- if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- bgp_info_restore(rn, ri);
- else
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_attr_unintern (ri->attr);
- ri->attr = attr_new;
- ri->uptime = bgp_clock ();
- /* Process change. */
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- }
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_STATIC;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = attr_new;
- new->uptime = bgp_clock ();
- /* Aggregate address increment. */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- }
- void
- bgp_static_update (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
- {
- struct peer *rsclient;
- struct listnode *node, *nnode;
- bgp_static_update_main (bgp, p, bgp_static, afi, safi);
- for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
- {
- if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- bgp_static_update_rsclient (rsclient, p, bgp_static, afi, safi);
- }
- }
- static void
- bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
- u_char safi, struct prefix_rd *prd, u_char *tag)
- {
- struct bgp_node *rn;
- struct bgp_info *new;
-
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_STATIC;
- new->peer = bgp->peer_self;
- new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP);
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->uptime = bgp_clock ();
- new->extra = bgp_info_extra_new();
- memcpy (new->extra->tag, tag, 3);
- /* Aggregate address increment. */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- }
- void
- bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
- safi_t safi)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
- /* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
- }
- void
- bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
- {
- struct bgp_static *bgp_static;
- struct bgp *bgp;
- struct bgp_node *rn;
- struct prefix *p;
- bgp = rsclient->bgp;
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if ((bgp_static = rn->info) != NULL)
- {
- p = &rn->p;
- bgp_static_update_rsclient (rsclient, p, bgp_static,
- afi, safi);
- }
- }
- static void
- bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
- u_char safi, struct prefix_rd *prd, u_char *tag)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
- /* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
- }
- static void
- bgp_pathlimit_update_parents (struct bgp *bgp, struct bgp_node *rn,
- int ttl_edge)
- {
- struct bgp_node *parent = rn;
- struct bgp_static *sp;
-
- /* Existing static changed TTL, search parents and adjust their atomic */
- while ((parent = parent->parent))
- if ((sp = parent->info))
- {
- int sp_level = (sp->atomic ? 1 : 0);
- ttl_edge ? sp->atomic++ : sp->atomic--;
-
- /* did we change state of parent whether atomic is set or not? */
- if (sp_level != (sp->atomic ? 1 : 0))
- {
- bgp_static_update (bgp, &parent->p, sp,
- rn->table->afi, rn->table->safi);
- }
- }
- }
- /* Configure static BGP network. When user don't run zebra, static
- route should be installed as valid. */
- static int
- bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
- u_int16_t afi, u_char safi, const char *rmap, int backdoor,
- u_char ttl)
- {
- int ret;
- struct prefix p;
- struct bgp_static *bgp_static;
- struct bgp_node *rn;
- u_char need_update = 0;
- u_char ttl_change = 0;
- u_char ttl_edge = (ttl ? 1 : 0);
- u_char new = 0;
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- #ifdef HAVE_IPV6
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- vty_out (vty, "%% Malformed prefix (link-local address)%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- #endif /* HAVE_IPV6 */
- apply_mask (&p);
- /* Set BGP static route configuration. */
- rn = bgp_node_get (bgp->route[afi][safi], &p);
- if (rn->info)
- {
- /* Configuration change. */
- bgp_static = rn->info;
- /* Check previous routes are installed into BGP. */
- if (bgp_static->valid)
- {
- if (bgp_static->backdoor != backdoor
- || bgp_static->ttl != ttl)
- need_update = 1;
- }
-
- /* need to catch TTL set/unset transitions for handling of
- * ATOMIC_AGGREGATE
- */
- if ((bgp_static->ttl ? 1 : 0) != ttl_edge)
- ttl_change = 1;
-
- bgp_static->backdoor = backdoor;
- bgp_static->ttl = ttl;
-
- if (rmap)
- {
- if (bgp_static->rmap.name)
- free (bgp_static->rmap.name);
- bgp_static->rmap.name = strdup (rmap);
- bgp_static->rmap.map = route_map_lookup_by_name (rmap);
- }
- else
- {
- if (bgp_static->rmap.name)
- free (bgp_static->rmap.name);
- bgp_static->rmap.name = NULL;
- bgp_static->rmap.map = NULL;
- bgp_static->valid = 0;
- }
- bgp_unlock_node (rn);
- }
- else
- {
- /* New configuration. */
- bgp_static = bgp_static_new ();
- bgp_static->backdoor = backdoor;
- bgp_static->valid = 0;
- bgp_static->igpmetric = 0;
- bgp_static->igpnexthop.s_addr = 0;
- bgp_static->ttl = ttl;
- ttl_change = ttl_edge;
- new = 1;
-
- if (rmap)
- {
- if (bgp_static->rmap.name)
- free (bgp_static->rmap.name);
- bgp_static->rmap.name = strdup (rmap);
- bgp_static->rmap.map = route_map_lookup_by_name (rmap);
- }
- rn->info = bgp_static;
- }
- /* ".. sites that choose to advertise the
- * AS_PATHLIMIT path attribute SHOULD advertise the ATOMIC_AGGREGATE on
- * all less specific covering prefixes as well as the more specific
- * prefixes."
- *
- * So:
- * Prefix that has just had pathlimit set/unset:
- * - Must bump ATOMIC refcount on all parents.
- *
- * To catch less specific prefixes:
- * - Must search children for ones with TTL, bump atomic refcount
- * (we dont care if we're deleting a less specific prefix..)
- */
- if (ttl_change)
- {
- /* Existing static changed TTL, search parents and adjust their atomic */
- bgp_pathlimit_update_parents (bgp, rn, ttl_edge);
- }
-
- if (new)
- {
- struct bgp_node *child;
- struct bgp_static *sc;
-
- /* New static, search children and bump this statics atomic.. */
- child = bgp_lock_node (rn); /* route_next_until unlocks it.. */
- while ((child = bgp_route_next_until (child, rn)))
- {
- if ((sc = child->info) && sc->ttl)
- bgp_static->atomic++;
- }
- }
-
- /* If BGP scan is not enabled, we should install this route here. */
- if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
- {
- bgp_static->valid = 1;
- if (need_update)
- bgp_static_withdraw (bgp, &p, afi, safi);
- if (! bgp_static->backdoor)
- bgp_static_update (bgp, &p, bgp_static, afi, safi);
- }
- return CMD_SUCCESS;
- }
- /* Configure static BGP network. */
- static int
- bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
- u_int16_t afi, u_char safi)
- {
- int ret;
- struct prefix p;
- struct bgp_static *bgp_static;
- struct bgp_node *rn;
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- #ifdef HAVE_IPV6
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- vty_out (vty, "%% Malformed prefix (link-local address)%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- #endif /* HAVE_IPV6 */
- apply_mask (&p);
- rn = bgp_node_lookup (bgp->route[afi][safi], &p);
- if (! rn)
- {
- vty_out (vty, "%% Can't find specified static route configuration.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- bgp_static = rn->info;
-
- /* decrement atomic in parents, see bgp_static_set */
- bgp_pathlimit_update_parents (bgp, rn, 0);
-
- /* Update BGP RIB. */
- if (! bgp_static->backdoor)
- bgp_static_withdraw (bgp, &p, afi, safi);
- /* Clear configuration. */
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
- return CMD_SUCCESS;
- }
- /* Called from bgp_delete(). Delete all static routes from the BGP
- instance. */
- void
- bgp_static_delete (struct bgp *bgp)
- {
- afi_t afi;
- safi_t safi;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- if (safi == SAFI_MPLS_VPN)
- {
- table = rn->info;
- for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
- {
- bgp_static = rn->info;
- bgp_static_withdraw_vpnv4 (bgp, &rm->p,
- AFI_IP, SAFI_MPLS_VPN,
- (struct prefix_rd *)&rn->p,
- bgp_static->tag);
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- }
- }
- else
- {
- bgp_static = rn->info;
- bgp_static_withdraw (bgp, &rn->p, afi, safi);
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- }
- }
- }
- int
- bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
- const char *tag_str)
- {
- int ret;
- struct prefix p;
- struct prefix_rd prd;
- struct bgp *bgp;
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
- u_char tag[3];
- bgp = vty->index;
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- ret = str2prefix_rd (rd_str, &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2tag (tag_str, tag);
- if (! ret)
- {
- vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
- (struct prefix *)&prd);
- if (prn->info == NULL)
- prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
- else
- bgp_unlock_node (prn);
- table = prn->info;
- rn = bgp_node_get (table, &p);
- if (rn->info)
- {
- vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
- bgp_unlock_node (rn);
- }
- else
- {
- /* New configuration. */
- bgp_static = bgp_static_new ();
- bgp_static->valid = 1;
- memcpy (bgp_static->tag, tag, 3);
- rn->info = bgp_static;
- bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
- }
- return CMD_SUCCESS;
- }
- /* Configure static BGP network. */
- int
- bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
- const char *rd_str, const char *tag_str)
- {
- int ret;
- struct bgp *bgp;
- struct prefix p;
- struct prefix_rd prd;
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
- u_char tag[3];
- bgp = vty->index;
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- ret = str2prefix_rd (rd_str, &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2tag (tag_str, tag);
- if (! ret)
- {
- vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
- (struct prefix *)&prd);
- if (prn->info == NULL)
- prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
- else
- bgp_unlock_node (prn);
- table = prn->info;
- rn = bgp_node_lookup (table, &p);
- if (rn)
- {
- bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
- bgp_static = rn->info;
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
- }
- else
- vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- DEFUN (bgp_network,
- bgp_network_cmd,
- "network A.B.C.D/M",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
- return bgp_static_set (vty, vty->index, argv[0],
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
- }
- ALIAS (bgp_network,
- bgp_network_ttl_cmd,
- "network A.B.C.D/M pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (bgp_network_route_map,
- bgp_network_route_map_cmd,
- "network A.B.C.D/M route-map WORD",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- {
- return bgp_static_set (vty, vty->index, argv[0],
- AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
- }
- DEFUN (bgp_network_backdoor,
- bgp_network_backdoor_cmd,
- "network A.B.C.D/M backdoor",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n")
- {
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
- }
- ALIAS (bgp_network_backdoor,
- bgp_network_backdoor_ttl_cmd,
- "network A.B.C.D/M backdoor pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (bgp_network_mask,
- bgp_network_mask_cmd,
- "network A.B.C.D mask A.B.C.D",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 3)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
-
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
- }
- ALIAS (bgp_network_mask,
- bgp_network_mask_ttl_cmd,
- "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (bgp_network_mask_route_map,
- bgp_network_mask_route_map_cmd,
- "network A.B.C.D mask A.B.C.D route-map WORD",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[2], 0, 0);
- }
- DEFUN (bgp_network_mask_backdoor,
- bgp_network_mask_backdoor_cmd,
- "network A.B.C.D mask A.B.C.D backdoor",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 3)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
- }
- ALIAS (bgp_network_mask_backdoor,
- bgp_network_mask_backdoor_ttl_cmd,
- "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (bgp_network_mask_natural,
- bgp_network_mask_natural_cmd,
- "network A.B.C.D",
- "Specify a network to announce via BGP\n"
- "Network number\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
- }
- ALIAS (bgp_network_mask_natural,
- bgp_network_mask_natural_ttl_cmd,
- "network A.B.C.D pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (bgp_network_mask_natural_route_map,
- bgp_network_mask_natural_route_map_cmd,
- "network A.B.C.D route-map WORD",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
- }
- DEFUN (bgp_network_mask_natural_backdoor,
- bgp_network_mask_natural_backdoor_cmd,
- "network A.B.C.D backdoor",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1, ttl);
- }
- ALIAS (bgp_network_mask_natural_backdoor,
- bgp_network_mask_natural_backdoor_ttl_cmd,
- "network A.B.C.D backdoor pathlimit (1-255>",
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (no_bgp_network,
- no_bgp_network_cmd,
- "no network A.B.C.D/M",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- return bgp_static_unset (vty, vty->index, argv[0], AFI_IP,
- bgp_node_safi (vty));
- }
- ALIAS (no_bgp_network,
- no_bgp_network_ttl_cmd,
- "no network A.B.C.D/M pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- ALIAS (no_bgp_network,
- no_bgp_network_route_map_cmd,
- "no network A.B.C.D/M route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- ALIAS (no_bgp_network,
- no_bgp_network_backdoor_cmd,
- "no network A.B.C.D/M backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n")
- ALIAS (no_bgp_network,
- no_bgp_network_backdoor_ttl_cmd,
- "no network A.B.C.D/M backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (no_bgp_network_mask,
- no_bgp_network_mask_cmd,
- "no network A.B.C.D mask A.B.C.D",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
- bgp_node_safi (vty));
- }
- ALIAS (no_bgp_network,
- no_bgp_network_mask_ttl_cmd,
- "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_route_map_cmd,
- "no network A.B.C.D mask A.B.C.D route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_backdoor_cmd,
- "no network A.B.C.D mask A.B.C.D backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n")
- ALIAS (no_bgp_network_mask,
- no_bgp_network_mask_backdoor_ttl_cmd,
- "no network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Network mask\n"
- "Network mask\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_cmd,
- "no network A.B.C.D",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
- bgp_node_safi (vty));
- }
- ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_route_map_cmd,
- "no network A.B.C.D route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_backdoor_cmd,
- "no network A.B.C.D backdoor",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n")
- ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_ttl_cmd,
- "no network A.B.C.D pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- ALIAS (no_bgp_network_mask_natural,
- no_bgp_network_mask_natural_backdoor_ttl_cmd,
- "no network A.B.C.D backdoor pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "Network number\n"
- "Specify a BGP backdoor route\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- #ifdef HAVE_IPV6
- DEFUN (ipv6_bgp_network,
- ipv6_bgp_network_cmd,
- "network X:X::X:X/M",
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n")
- {
- u_char ttl = 0;
-
- if (argc == 2)
- VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST,
- NULL, 0, ttl);
- }
- ALIAS (ipv6_bgp_network,
- ipv6_bgp_network_ttl_cmd,
- "network X:X::X:X/M pathlimit <0-255>",
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- DEFUN (ipv6_bgp_network_route_map,
- ipv6_bgp_network_route_map_cmd,
- "network X:X::X:X/M route-map WORD",
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- {
- return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
- bgp_node_safi (vty), argv[1], 0, 0);
- }
- DEFUN (no_ipv6_bgp_network,
- no_ipv6_bgp_network_cmd,
- "no network X:X::X:X/M",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n")
- {
- return bgp_static_unset (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (no_ipv6_bgp_network,
- no_ipv6_bgp_network_route_map_cmd,
- "no network X:X::X:X/M route-map WORD",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "Route-map to modify the attributes\n"
- "Name of the route map\n")
- ALIAS (no_ipv6_bgp_network,
- no_ipv6_bgp_network_ttl_cmd,
- "no network X:X::X:X/M pathlimit <0-255>",
- NO_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>\n"
- "AS-Path hopcount limit attribute\n"
- "AS-Pathlimit TTL, in number of AS-Path hops\n")
- ALIAS (ipv6_bgp_network,
- old_ipv6_bgp_network_cmd,
- "ipv6 bgp network X:X::X:X/M",
- IPV6_STR
- BGP_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
- ALIAS (no_ipv6_bgp_network,
- old_no_ipv6_bgp_network_cmd,
- "no ipv6 bgp network X:X::X:X/M",
- NO_STR
- IPV6_STR
- BGP_STR
- "Specify a network to announce via BGP\n"
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
- #endif /* HAVE_IPV6 */
- /* Aggreagete address:
- advertise-map Set condition to advertise attribute
- as-set Generate AS set path information
- attribute-map Set attributes of aggregate
- route-map Set parameters of aggregate
- summary-only Filter more specific routes from updates
- suppress-map Conditionally filter more specific routes from updates
- <cr>
- */
- struct bgp_aggregate
- {
- /* Summary-only flag. */
- u_char summary_only;
- /* AS set generation. */
- u_char as_set;
- /* Route-map for aggregated route. */
- struct route_map *map;
- /* Suppress-count. */
- unsigned long count;
- /* SAFI configuration. */
- safi_t safi;
- };
- static struct bgp_aggregate *
- bgp_aggregate_new (void)
- {
- return XCALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
- }
- static void
- bgp_aggregate_free (struct bgp_aggregate *aggregate)
- {
- XFREE (MTYPE_BGP_AGGREGATE, aggregate);
- }
- static void
- bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
- afi_t afi, safi_t safi, struct bgp_info *del,
- struct bgp_aggregate *aggregate)
- {
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- u_char origin;
- struct aspath *aspath = NULL;
- struct aspath *asmerge = NULL;
- struct community *community = NULL;
- struct community *commerge = NULL;
- struct in_addr nexthop;
- u_int32_t med = 0;
- struct bgp_info *ri;
- struct bgp_info *new;
- int first = 1;
- unsigned long match = 0;
- /* Record adding route's nexthop and med. */
- if (rinew)
- {
- nexthop = rinew->attr->nexthop;
- med = rinew->attr->med;
- }
- /* ORIGIN attribute: If at least one route among routes that are
- aggregated has ORIGIN with the value INCOMPLETE, then the
- aggregated route must have the ORIGIN attribute with the value
- INCOMPLETE. Otherwise, if at least one route among routes that
- are aggregated has ORIGIN with the value EGP, then the aggregated
- route must have the origin attribute with the value EGP. In all
- other case the value of the ORIGIN attribute of the aggregated
- route is INTERNAL. */
- origin = BGP_ORIGIN_IGP;
- table = bgp->rib[afi][safi];
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
- if (del && ri == del)
- continue;
- if (! rinew && first)
- {
- nexthop = ri->attr->nexthop;
- med = ri->attr->med;
- first = 0;
- }
- #ifdef AGGREGATE_NEXTHOP_CHECK
- if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
- || ri->attr->med != med)
- {
- if (aspath)
- aspath_free (aspath);
- if (community)
- community_free (community);
- bgp_unlock_node (rn);
- bgp_unlock_node (top);
- return;
- }
- #endif /* AGGREGATE_NEXTHOP_CHECK */
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- if (aggregate->summary_only)
- {
- (bgp_info_extra_get (ri))->suppress++;
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
- aggregate->count++;
- if (aggregate->as_set)
- {
- if (origin < ri->attr->origin)
- origin = ri->attr->origin;
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, ri->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (ri->attr->aspath);
- if (ri->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- ri->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
- }
- else
- community = community_dup (ri->attr->community);
- }
- }
- }
- }
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
- if (rinew)
- {
- aggregate->count++;
-
- if (aggregate->summary_only)
- (bgp_info_extra_get (rinew))->suppress++;
- if (aggregate->as_set)
- {
- if (origin < rinew->attr->origin)
- origin = rinew->attr->origin;
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (rinew->attr->aspath);
- if (rinew->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- rinew->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
- }
- else
- community = community_dup (rinew->attr->community);
- }
- }
- }
- if (aggregate->count > 0)
- {
- rn = bgp_node_get (table, p);
- new = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_AGGREGATE;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
- new->uptime = bgp_clock ();
- bgp_info_add (rn, new);
- bgp_unlock_node (rn);
- bgp_process (bgp, rn, afi, safi);
- }
- else
- {
- if (aspath)
- aspath_free (aspath);
- if (community)
- community_free (community);
- }
- }
- void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
- struct bgp_aggregate *);
- void
- bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
- struct bgp_info *ri, afi_t afi, safi_t safi)
- {
- struct bgp_node *child;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
- /* MPLS-VPN aggregation is not yet supported. */
- if (safi == SAFI_MPLS_VPN)
- return;
- if (p->prefixlen == 0)
- return;
- if (BGP_INFO_HOLDDOWN (ri))
- return;
- child = bgp_node_get (bgp->aggregate[afi][safi], p);
- /* Aggregate address configuration check. */
- for (rn = child; rn; rn = rn->parent)
- if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
- {
- bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route (bgp, &rn->p, ri, afi, safi, NULL, aggregate);
- }
- bgp_unlock_node (child);
- }
- void
- bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
- struct bgp_info *del, afi_t afi, safi_t safi)
- {
- struct bgp_node *child;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
- /* MPLS-VPN aggregation is not yet supported. */
- if (safi == SAFI_MPLS_VPN)
- return;
- if (p->prefixlen == 0)
- return;
- child = bgp_node_get (bgp->aggregate[afi][safi], p);
- /* Aggregate address configuration check. */
- for (rn = child; rn; rn = rn->parent)
- if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
- {
- bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route (bgp, &rn->p, NULL, afi, safi, del, aggregate);
- }
- bgp_unlock_node (child);
- }
- static void
- bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
- struct bgp_aggregate *aggregate)
- {
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- struct bgp_info *new;
- struct bgp_info *ri;
- unsigned long match;
- u_char origin = BGP_ORIGIN_IGP;
- struct aspath *aspath = NULL;
- struct aspath *asmerge = NULL;
- struct community *community = NULL;
- struct community *commerge = NULL;
- table = bgp->rib[afi][safi];
- /* Sanity check. */
- if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
- return;
- if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
- return;
-
- /* If routes exists below this node, generate aggregate routes. */
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- /* summary-only aggregate route suppress aggregated
- route announcement. */
- if (aggregate->summary_only)
- {
- (bgp_info_extra_get (ri))->suppress++;
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
- /* as-set aggregate route generate origin, as path,
- community aggregation. */
- if (aggregate->as_set)
- {
- if (origin < ri->attr->origin)
- origin = ri->attr->origin;
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, ri->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (ri->attr->aspath);
- if (ri->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- ri->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
- }
- else
- community = community_dup (ri->attr->community);
- }
- }
- aggregate->count++;
- }
- }
-
- /* If this node is suppressed, process the change. */
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
- /* Add aggregate route to BGP table. */
- if (aggregate->count)
- {
- rn = bgp_node_get (table, p);
- new = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_AGGREGATE;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
- new->uptime = bgp_clock ();
- bgp_info_add (rn, new);
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- }
- }
- void
- bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
- safi_t safi, struct bgp_aggregate *aggregate)
- {
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- struct bgp_info *ri;
- unsigned long match;
- table = bgp->rib[afi][safi];
- if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
- return;
- if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
- return;
- /* If routes exists below this node, generate aggregate routes. */
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- if (aggregate->summary_only && ri->extra)
- {
- ri->extra->suppress--;
- if (ri->extra->suppress == 0)
- {
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
- }
- aggregate->count--;
- }
- }
- /* If this node was suppressed, process the change. */
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
- /* Delete aggregate route from BGP table. */
- rn = bgp_node_get (table, p);
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_AGGREGATE)
- break;
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
- }
- /* Aggregate route attribute. */
- #define AGGREGATE_SUMMARY_ONLY 1
- #define AGGREGATE_AS_SET 1
- static int
- bgp_aggregate_set (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi,
- u_char summary_only, u_char as_set)
- {
- int ret;
- struct prefix p;
- struct bgp_node *rn;
- struct bgp *bgp;
- struct bgp_aggregate *aggregate;
- /* Convert string to prefix structure. */
- ret = str2prefix (prefix_str, &p);
- if (!ret)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- /* Get BGP structure. */
- bgp = vty->index;
- /* Old configuration check. */
- rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
- if (rn->info)
- {
- vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
- bgp_unlock_node (rn);
- return CMD_WARNING;
- }
- /* Make aggregate address structure. */
- aggregate = bgp_aggregate_new ();
- aggregate->summary_only = summary_only;
- aggregate->as_set = as_set;
- aggregate->safi = safi;
- rn->info = aggregate;
- /* Aggregate address insert into BGP routing table. */
- if (safi & SAFI_UNICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (safi & SAFI_MULTICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
- return CMD_SUCCESS;
- }
- static int
- bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi)
- {
- int ret;
- struct prefix p;
- struct bgp_node *rn;
- struct bgp *bgp;
- struct bgp_aggregate *aggregate;
- /* Convert string to prefix structure. */
- ret = str2prefix (prefix_str, &p);
- if (!ret)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- /* Get BGP structure. */
- bgp = vty->index;
- /* Old configuration check. */
- rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
- if (! rn)
- {
- vty_out (vty, "%% There is no aggregate-address configuration.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- aggregate = rn->info;
- if (aggregate->safi & SAFI_UNICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (aggregate->safi & SAFI_MULTICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
- /* Unlock aggregate address configuration. */
- rn->info = NULL;
- bgp_aggregate_free (aggregate);
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
- return CMD_SUCCESS;
- }
- DEFUN (aggregate_address,
- aggregate_address_cmd,
- "aggregate-address A.B.C.D/M",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty), 0, 0);
- }
- DEFUN (aggregate_address_mask,
- aggregate_address_mask_cmd,
- "aggregate-address A.B.C.D A.B.C.D",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- 0, 0);
- }
- DEFUN (aggregate_address_summary_only,
- aggregate_address_summary_only_cmd,
- "aggregate-address A.B.C.D/M summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, 0);
- }
- DEFUN (aggregate_address_mask_summary_only,
- aggregate_address_mask_summary_only_cmd,
- "aggregate-address A.B.C.D A.B.C.D summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, 0);
- }
- DEFUN (aggregate_address_as_set,
- aggregate_address_as_set_cmd,
- "aggregate-address A.B.C.D/M as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- 0, AGGREGATE_AS_SET);
- }
- DEFUN (aggregate_address_mask_as_set,
- aggregate_address_mask_as_set_cmd,
- "aggregate-address A.B.C.D A.B.C.D as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- 0, AGGREGATE_AS_SET);
- }
- DEFUN (aggregate_address_as_set_summary,
- aggregate_address_as_set_summary_cmd,
- "aggregate-address A.B.C.D/M as-set summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
- }
- ALIAS (aggregate_address_as_set_summary,
- aggregate_address_summary_as_set_cmd,
- "aggregate-address A.B.C.D/M summary-only as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
- DEFUN (aggregate_address_mask_as_set_summary,
- aggregate_address_mask_as_set_summary_cmd,
- "aggregate-address A.B.C.D A.B.C.D as-set summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
- AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
- }
- ALIAS (aggregate_address_mask_as_set_summary,
- aggregate_address_mask_summary_as_set_cmd,
- "aggregate-address A.B.C.D A.B.C.D summary-only as-set",
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
- DEFUN (no_aggregate_address,
- no_aggregate_address_cmd,
- "no aggregate-address A.B.C.D/M",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- {
- return bgp_aggregate_unset (vty, argv[0], AFI_IP, bgp_node_safi (vty));
- }
- ALIAS (no_aggregate_address,
- no_aggregate_address_summary_only_cmd,
- "no aggregate-address A.B.C.D/M summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- ALIAS (no_aggregate_address,
- no_aggregate_address_as_set_cmd,
- "no aggregate-address A.B.C.D/M as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n")
- ALIAS (no_aggregate_address,
- no_aggregate_address_as_set_summary_cmd,
- "no aggregate-address A.B.C.D/M as-set summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
- ALIAS (no_aggregate_address,
- no_aggregate_address_summary_as_set_cmd,
- "no aggregate-address A.B.C.D/M summary-only as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
- DEFUN (no_aggregate_address_mask,
- no_aggregate_address_mask_cmd,
- "no aggregate-address A.B.C.D A.B.C.D",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n")
- {
- int ret;
- char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
- }
- ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_summary_only_cmd,
- "no aggregate-address A.B.C.D A.B.C.D summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n")
- ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_as_set_cmd,
- "no aggregate-address A.B.C.D A.B.C.D as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n")
- ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_as_set_summary_cmd,
- "no aggregate-address A.B.C.D A.B.C.D as-set summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Generate AS set path information\n"
- "Filter more specific routes from updates\n")
- ALIAS (no_aggregate_address_mask,
- no_aggregate_address_mask_summary_as_set_cmd,
- "no aggregate-address A.B.C.D A.B.C.D summary-only as-set",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate address\n"
- "Aggregate mask\n"
- "Filter more specific routes from updates\n"
- "Generate AS set path information\n")
- #ifdef HAVE_IPV6
- DEFUN (ipv6_aggregate_address,
- ipv6_aggregate_address_cmd,
- "aggregate-address X:X::X:X/M",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0, 0);
- }
- DEFUN (ipv6_aggregate_address_summary_only,
- ipv6_aggregate_address_summary_only_cmd,
- "aggregate-address X:X::X:X/M summary-only",
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- {
- return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- AGGREGATE_SUMMARY_ONLY, 0);
- }
- DEFUN (no_ipv6_aggregate_address,
- no_ipv6_aggregate_address_cmd,
- "no aggregate-address X:X::X:X/M",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- {
- return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
- }
- DEFUN (no_ipv6_aggregate_address_summary_only,
- no_ipv6_aggregate_address_summary_only_cmd,
- "no aggregate-address X:X::X:X/M summary-only",
- NO_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- {
- return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (ipv6_aggregate_address,
- old_ipv6_aggregate_address_cmd,
- "ipv6 bgp aggregate-address X:X::X:X/M",
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- ALIAS (ipv6_aggregate_address_summary_only,
- old_ipv6_aggregate_address_summary_only_cmd,
- "ipv6 bgp aggregate-address X:X::X:X/M summary-only",
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- ALIAS (no_ipv6_aggregate_address,
- old_no_ipv6_aggregate_address_cmd,
- "no ipv6 bgp aggregate-address X:X::X:X/M",
- NO_STR
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n")
- ALIAS (no_ipv6_aggregate_address_summary_only,
- old_no_ipv6_aggregate_address_summary_only_cmd,
- "no ipv6 bgp aggregate-address X:X::X:X/M summary-only",
- NO_STR
- IPV6_STR
- BGP_STR
- "Configure BGP aggregate entries\n"
- "Aggregate prefix\n"
- "Filter more specific routes from updates\n")
- #endif /* HAVE_IPV6 */
- /* Redistribute route treatment. */
- void
- bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
- u_int32_t metric, u_char type)
- {
- struct bgp *bgp;
- struct listnode *node, *nnode;
- struct bgp_info *new;
- struct bgp_info *bi;
- struct bgp_info info;
- struct bgp_node *bn;
- struct attr attr = { 0 };
- struct attr attr_new = { 0 };
- struct attr *new_attr;
- afi_t afi;
- int ret;
- /* Make default attribute. */
- bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
- if (nexthop)
- attr.nexthop = *nexthop;
- attr.med = metric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
- {
- afi = family2afi (p->family);
- if (bgp->redist[afi][type])
- {
- /* Copy attribute for modification. */
- bgp_attr_dup (&attr_new, &attr);
- if (bgp->redist_metric_flag[afi][type])
- attr_new.med = bgp->redist_metric[afi][type];
- /* Apply route-map. */
- if (bgp->rmap[afi][type].map)
- {
- info.peer = bgp->peer_self;
- info.attr = &attr_new;
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
- ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
- &info);
- bgp->peer_self->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_new);
- bgp_attr_extra_free (&attr_new);
-
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_redistribute_delete (p, type);
- return;
- }
- }
- bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
- afi, SAFI_UNICAST, p, NULL);
-
- new_attr = bgp_attr_intern (&attr_new);
- bgp_attr_extra_free (&attr_new);
-
- for (bi = bn->info; bi; bi = bi->next)
- if (bi->peer == bgp->peer_self
- && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
- break;
-
- if (bi)
- {
- if (attrhash_cmp (bi->attr, new_attr) &&
- !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
- {
- bgp_attr_unintern (new_attr);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_unlock_node (bn);
- return;
- }
- else
- {
- /* The attribute is changed. */
- bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
-
- /* Rewrite BGP route information. */
- if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
- bgp_info_restore(bn, bi);
- else
- bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
- bgp_attr_unintern (bi->attr);
- bi->attr = new_attr;
- bi->uptime = bgp_clock ();
-
- /* Process change. */
- bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
- bgp_process (bgp, bn, afi, SAFI_UNICAST);
- bgp_unlock_node (bn);
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- }
- new = bgp_info_new ();
- new->type = type;
- new->sub_type = BGP_ROUTE_REDISTRIBUTE;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = new_attr;
- new->uptime = bgp_clock ();
- bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
- bgp_info_add (bn, new);
- bgp_unlock_node (bn);
- bgp_process (bgp, bn, afi, SAFI_UNICAST);
- }
- }
- /* Unintern original. */
- aspath_unintern (attr.aspath);
- bgp_attr_extra_free (&attr);
- }
- void
- bgp_redistribute_delete (struct prefix *p, u_char type)
- {
- struct bgp *bgp;
- struct listnode *node, *nnode;
- afi_t afi;
- struct bgp_node *rn;
- struct bgp_info *ri;
- for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
- {
- afi = family2afi (p->family);
- if (bgp->redist[afi][type])
- {
- rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == type)
- break;
- if (ri)
- {
- bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, SAFI_UNICAST);
- }
- bgp_unlock_node (rn);
- }
- }
- }
- /* Withdraw specified route type's route. */
- void
- bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
- {
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_table *table;
- table = bgp->rib[afi][SAFI_UNICAST];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == type)
- break;
- if (ri)
- {
- bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, SAFI_UNICAST);
- }
- }
- }
- /* Static function to display route. */
- static void
- route_vty_out_route (struct prefix *p, struct vty *vty)
- {
- int len;
- u_int32_t destination;
- char buf[BUFSIZ];
- if (p->family == AF_INET)
- {
- len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
- destination = ntohl (p->u.prefix4.s_addr);
- if ((IN_CLASSC (destination) && p->prefixlen == 24)
- || (IN_CLASSB (destination) && p->prefixlen == 16)
- || (IN_CLASSA (destination) && p->prefixlen == 8)
- || p->u.prefix4.s_addr == 0)
- {
- /* When mask is natural, mask is not displayed. */
- }
- else
- len += vty_out (vty, "/%d", p->prefixlen);
- }
- else
- len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
- p->prefixlen);
- len = 17 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- enum bgp_display_type
- {
- normal_list,
- };
- /* Print the short form route status for a bgp_info */
- static void
- route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo)
- {
- /* Route status display. */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
- vty_out (vty, "R");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
- vty_out (vty, "S");
- else if (binfo->extra && binfo->extra->suppress)
- vty_out (vty, "s");
- else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, "*");
- else
- vty_out (vty, " ");
- /* Selected */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, "h");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
- vty_out (vty, "d");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
- vty_out (vty, ">");
- else
- vty_out (vty, " ");
- /* Internal route. */
- if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
- vty_out (vty, "i");
- else
- vty_out (vty, " ");
- }
- /* called from terminal list command */
- void
- route_vty_out (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi)
- {
- struct attr *attr;
-
- /* short status lead text */
- route_vty_short_status_out (vty, binfo);
-
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- if (p->family == AF_INET)
- {
- if (safi == SAFI_MPLS_VPN)
- vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- #ifdef HAVE_IPV6
- else if (p->family == AF_INET6)
- {
- int len;
- char buf[BUFSIZ];
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- len = 16 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- #endif /* HAVE_IPV6 */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, "%10d", attr->med);
- else
- vty_out (vty, " ");
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- vty_out (vty, "%7d", attr->local_pref);
- else
- vty_out (vty, " ");
- vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
-
- /* Print aspath */
- if (attr->aspath)
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- /* Print origin */
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- /* called from terminal list command */
- void
- route_vty_out_tmp (struct vty *vty, struct prefix *p,
- struct attr *attr, safi_t safi)
- {
- /* Route status display. */
- vty_out (vty, "*");
- vty_out (vty, ">");
- vty_out (vty, " ");
- /* print prefix and mask */
- route_vty_out_route (p, vty);
- /* Print attribute */
- if (attr)
- {
- if (p->family == AF_INET)
- {
- if (safi == SAFI_MPLS_VPN)
- vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- #ifdef HAVE_IPV6
- else if (p->family == AF_INET6)
- {
- int len;
- char buf[BUFSIZ];
-
- assert (attr->extra);
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- len = 16 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- #endif /* HAVE_IPV6 */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, "%10d", attr->med);
- else
- vty_out (vty, " ");
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- vty_out (vty, "%7d", attr->local_pref);
- else
- vty_out (vty, " ");
-
- vty_out (vty, "%7d ", (attr->extra ? attr->extra->weight : 0));
-
- /* Print aspath */
- if (attr->aspath)
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- /* Print origin */
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- void
- route_vty_out_tag (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi)
- {
- struct attr *attr;
- u_int32_t label = 0;
-
- if (!binfo->extra)
- return;
-
- /* short status lead text */
- route_vty_short_status_out (vty, binfo);
-
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- if (p->family == AF_INET)
- {
- if (safi == SAFI_MPLS_VPN)
- vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- #ifdef HAVE_IPV6
- else if (p->family == AF_INET6)
- {
- assert (attr->extra);
- char buf[BUFSIZ];
- char buf1[BUFSIZ];
- if (attr->extra->mp_nexthop_len == 16)
- vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- else if (attr->extra->mp_nexthop_len == 32)
- vty_out (vty, "%s(%s)",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ),
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf1, BUFSIZ));
-
- }
- #endif /* HAVE_IPV6 */
- }
- label = decode_label (binfo->extra->tag);
- vty_out (vty, "notag/%d", label);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- /* dampening route */
- static void
- damp_route_vty_out (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi)
- {
- struct attr *attr;
- int len;
- char timebuf[BGP_UPTIME_LEN];
- /* short status lead text */
- route_vty_short_status_out (vty, binfo);
-
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- len = vty_out (vty, "%s", binfo->peer->host);
- len = 17 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
- else
- vty_out (vty, "%*s", len, " ");
- vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN));
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- /* Print aspath */
- if (attr->aspath)
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- /* Print origin */
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- /* flap route */
- static void
- flap_route_vty_out (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi)
- {
- struct attr *attr;
- struct bgp_damp_info *bdi;
- char timebuf[BGP_UPTIME_LEN];
- int len;
-
- if (!binfo->extra)
- return;
-
- bdi = binfo->extra->damp_info;
- /* short status lead text */
- route_vty_short_status_out (vty, binfo);
-
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- len = vty_out (vty, "%s", binfo->peer->host);
- len = 16 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
- else
- vty_out (vty, "%*s", len, " ");
- len = vty_out (vty, "%d", bdi->flap);
- len = 5 - len;
- if (len < 1)
- vty_out (vty, " ");
- else
- vty_out (vty, "%*s ", len, " ");
-
- vty_out (vty, "%s ", peer_uptime (bdi->start_time,
- timebuf, BGP_UPTIME_LEN));
- if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
- && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN));
- else
- vty_out (vty, "%*s ", 8, " ");
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- /* Print aspath */
- if (attr->aspath)
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- /* Print origin */
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- static void
- route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
- struct bgp_info *binfo, afi_t afi, safi_t safi)
- {
- char buf[INET6_ADDRSTRLEN];
- char buf1[BUFSIZ];
- struct attr *attr;
- int sockunion_vty_out (struct vty *, union sockunion *);
-
- attr = binfo->attr;
- if (attr)
- {
- /* Line1 display AS-path, Aggregator */
- if (attr->aspath)
- {
- vty_out (vty, " ");
- if (aspath_count_hops (attr->aspath) == 0)
- vty_out (vty, "Local");
- else
- aspath_print_vty (vty, "%s", attr->aspath, "");
- }
- if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
- vty_out (vty, ", (removed)");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
- vty_out (vty, ", (stale)");
- if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
- vty_out (vty, ", (aggregated by %u %s)",
- attr->extra->aggregator_as,
- inet_ntoa (attr->extra->aggregator_addr));
- if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- vty_out (vty, ", (Received from a RR-client)");
- if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- vty_out (vty, ", (Received from a RS-client)");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, ", (history entry)");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
- vty_out (vty, ", (suppressed due to dampening)");
- vty_out (vty, "%s", VTY_NEWLINE);
-
- /* Line2 display Next-hop, Neighbor, Router-id */
- if (p->family == AF_INET)
- {
- vty_out (vty, " %s", safi == SAFI_MPLS_VPN ?
- inet_ntoa (attr->extra->mp_nexthop_global_in) :
- inet_ntoa (attr->nexthop));
- }
- #ifdef HAVE_IPV6
- else
- {
- assert (attr->extra);
- vty_out (vty, " %s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, INET6_ADDRSTRLEN));
- }
- #endif /* HAVE_IPV6 */
- if (binfo->peer == bgp->peer_self)
- {
- vty_out (vty, " from %s ",
- p->family == AF_INET ? "0.0.0.0" : "::");
- vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
- }
- else
- {
- if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
- vty_out (vty, " (inaccessible)");
- else if (binfo->extra && binfo->extra->igpmetric)
- vty_out (vty, " (metric %d)", binfo->extra->igpmetric);
- vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
- else
- vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- #ifdef HAVE_IPV6
- /* display nexthop local */
- if (attr->extra && attr->extra->mp_nexthop_len == 32)
- {
- vty_out (vty, " (%s)%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf, INET6_ADDRSTRLEN),
- VTY_NEWLINE);
- }
- #endif /* HAVE_IPV6 */
- /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
- vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, ", metric %d", attr->med);
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
- vty_out (vty, ", localpref %d", attr->local_pref);
- else
- vty_out (vty, ", localpref %d", bgp->default_local_pref);
- if (attr->extra && attr->extra->weight != 0)
- vty_out (vty, ", weight %d", attr->extra->weight);
-
- if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, ", valid");
- if (binfo->peer != bgp->peer_self)
- {
- if (binfo->peer->as == binfo->peer->local_as)
- vty_out (vty, ", internal");
- else
- vty_out (vty, ", %s",
- (bgp_confederation_peers_check(bgp, binfo->peer->as) ? "confed-external" : "external"));
- }
- else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
- vty_out (vty, ", aggregated, local");
- else if (binfo->type != ZEBRA_ROUTE_BGP)
- vty_out (vty, ", sourced");
- else
- vty_out (vty, ", sourced, local");
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
- vty_out (vty, ", atomic-aggregate");
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
- vty_out (vty, ", best");
- vty_out (vty, "%s", VTY_NEWLINE);
-
- /* Line 4 display Community */
- if (attr->community)
- vty_out (vty, " Community: %s%s", attr->community->str,
- VTY_NEWLINE);
-
- /* Line 5 display Extended-community */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
- vty_out (vty, " Extended Community: %s%s",
- attr->extra->ecommunity->str, VTY_NEWLINE);
-
- /* Line 6 display Originator, Cluster-id */
- if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
- (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
- {
- assert (attr->extra);
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- vty_out (vty, " Originator: %s",
- inet_ntoa (attr->extra->originator_id));
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
- {
- int i;
- vty_out (vty, ", Cluster list: ");
- for (i = 0; i < attr->extra->cluster->length / 4; i++)
- vty_out (vty, "%s ",
- inet_ntoa (attr->extra->cluster->list[i]));
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- /* 7: AS Pathlimit */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATHLIMIT))
- {
-
- vty_out (vty, " AS-Pathlimit: %u",
- attr->pathlimit.ttl);
- if (attr->pathlimit.as)
- vty_out (vty, " (%u)", attr->pathlimit.as);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- if (binfo->extra && binfo->extra->damp_info)
- bgp_damp_info_vty (vty, binfo);
- /* Line 7 display Uptime */
- vty_out (vty, " Last update: %s", ctime (&binfo->uptime));
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- #define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale, R Removed%s"
- #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
- #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s"
- #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
- #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
- enum bgp_show_type
- {
- bgp_show_type_normal,
- bgp_show_type_regexp,
- bgp_show_type_prefix_list,
- bgp_show_type_filter_list,
- bgp_show_type_route_map,
- bgp_show_type_neighbor,
- bgp_show_type_cidr_only,
- bgp_show_type_prefix_longer,
- bgp_show_type_community_all,
- bgp_show_type_community,
- bgp_show_type_community_exact,
- bgp_show_type_community_list,
- bgp_show_type_community_list_exact,
- bgp_show_type_flap_statistics,
- bgp_show_type_flap_address,
- bgp_show_type_flap_prefix,
- bgp_show_type_flap_cidr_only,
- bgp_show_type_flap_regexp,
- bgp_show_type_flap_filter_list,
- bgp_show_type_flap_prefix_list,
- bgp_show_type_flap_prefix_longer,
- bgp_show_type_flap_route_map,
- bgp_show_type_flap_neighbor,
- bgp_show_type_dampend_paths,
- bgp_show_type_damp_neighbor
- };
- static int
- bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router_id,
- enum bgp_show_type type, void *output_arg)
- {
- struct bgp_info *ri;
- struct bgp_node *rn;
- int header = 1;
- int display;
- unsigned long output_count;
- /* This is first entry point, so reset total line. */
- output_count = 0;
- /* Start processing of routes. */
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- display = 0;
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- {
- if (!(ri->extra && ri->extra->damp_info))
- continue;
- }
- if (type == bgp_show_type_regexp
- || type == bgp_show_type_flap_regexp)
- {
- regex_t *regex = output_arg;
-
- if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
- continue;
- }
- if (type == bgp_show_type_prefix_list
- || type == bgp_show_type_flap_prefix_list)
- {
- struct prefix_list *plist = output_arg;
-
- if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
- continue;
- }
- if (type == bgp_show_type_filter_list
- || type == bgp_show_type_flap_filter_list)
- {
- struct as_list *as_list = output_arg;
- if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
- continue;
- }
- if (type == bgp_show_type_route_map
- || type == bgp_show_type_flap_route_map)
- {
- struct route_map *rmap = output_arg;
- struct bgp_info binfo;
- struct attr dummy_attr = { 0 };
- int ret;
- bgp_attr_dup (&dummy_attr, ri->attr);
- binfo.peer = ri->peer;
- binfo.attr = &dummy_attr;
- ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
-
- bgp_attr_extra_free (&dummy_attr);
-
- if (ret == RMAP_DENYMATCH)
- continue;
- }
- if (type == bgp_show_type_neighbor
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_damp_neighbor)
- {
- union sockunion *su = output_arg;
- if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
- continue;
- }
- if (type == bgp_show_type_cidr_only
- || type == bgp_show_type_flap_cidr_only)
- {
- u_int32_t destination;
- destination = ntohl (rn->p.u.prefix4.s_addr);
- if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
- continue;
- if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
- continue;
- if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
- continue;
- }
- if (type == bgp_show_type_prefix_longer
- || type == bgp_show_type_flap_prefix_longer)
- {
- struct prefix *p = output_arg;
- if (! prefix_match (p, &rn->p))
- continue;
- }
- if (type == bgp_show_type_community_all)
- {
- if (! ri->attr->community)
- continue;
- }
- if (type == bgp_show_type_community)
- {
- struct community *com = output_arg;
- if (! ri->attr->community ||
- ! community_match (ri->attr->community, com))
- continue;
- }
- if (type == bgp_show_type_community_exact)
- {
- struct community *com = output_arg;
- if (! ri->attr->community ||
- ! community_cmp (ri->attr->community, com))
- continue;
- }
- if (type == bgp_show_type_community_list)
- {
- struct community_list *list = output_arg;
- if (! community_list_match (ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_community_list_exact)
- {
- struct community_list *list = output_arg;
- if (! community_list_exact_match (ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix)
- {
- struct prefix *p = output_arg;
- if (! prefix_match (&rn->p, p))
- continue;
- if (type == bgp_show_type_flap_prefix)
- if (p->prefixlen != rn->p.prefixlen)
- continue;
- }
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- {
- if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
- || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- continue;
- }
- if (header)
- {
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
- || type == bgp_show_type_flap_neighbor)
- vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
- else
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header = 0;
- }
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_address
- || type == bgp_show_type_flap_prefix
- || type == bgp_show_type_flap_cidr_only
- || type == bgp_show_type_flap_regexp
- || type == bgp_show_type_flap_filter_list
- || type == bgp_show_type_flap_prefix_list
- || type == bgp_show_type_flap_prefix_longer
- || type == bgp_show_type_flap_route_map
- || type == bgp_show_type_flap_neighbor)
- flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
- else
- route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
- display++;
- }
- if (display)
- output_count++;
- }
- /* No route is displayed */
- if (output_count == 0)
- {
- if (type == bgp_show_type_normal)
- vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
- }
- else
- vty_out (vty, "%sTotal number of prefixes %ld%s",
- VTY_NEWLINE, output_count, VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- static int
- bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
- enum bgp_show_type type, void *output_arg)
- {
- struct bgp_table *table;
- if (bgp == NULL) {
- bgp = bgp_get_default ();
- }
- if (bgp == NULL)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- table = bgp->rib[afi][safi];
- return bgp_show_table (vty, table, &bgp->router_id, type, output_arg);
- }
- /* Header of detailed BGP route information */
- static void
- route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
- struct bgp_node *rn,
- struct prefix_rd *prd, afi_t afi, safi_t safi)
- {
- struct bgp_info *ri;
- struct prefix *p;
- struct peer *peer;
- struct listnode *node, *nnode;
- char buf1[INET6_ADDRSTRLEN];
- char buf2[INET6_ADDRSTRLEN];
- int count = 0;
- int best = 0;
- int suppress = 0;
- int no_export = 0;
- int no_advertise = 0;
- int local_as = 0;
- int first = 0;
- p = &rn->p;
- vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
- (safi == SAFI_MPLS_VPN ?
- prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
- safi == SAFI_MPLS_VPN ? ":" : "",
- inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
- p->prefixlen, VTY_NEWLINE);
- for (ri = rn->info; ri; ri = ri->next)
- {
- count++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- {
- best = count;
- if (ri->extra && ri->extra->suppress)
- suppress = 1;
- if (ri->attr->community != NULL)
- {
- if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
- no_advertise = 1;
- if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
- no_export = 1;
- if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
- local_as = 1;
- }
- }
- }
- vty_out (vty, "Paths: (%d available", count);
- if (best)
- {
- vty_out (vty, ", best #%d", best);
- if (safi == SAFI_UNICAST)
- vty_out (vty, ", table Default-IP-Routing-Table");
- }
- else
- vty_out (vty, ", no best path");
- if (no_advertise)
- vty_out (vty, ", not advertised to any peer");
- else if (no_export)
- vty_out (vty, ", not advertised to EBGP peer");
- else if (local_as)
- vty_out (vty, ", not advertised outside local AS");
- if (suppress)
- vty_out (vty, ", Advertisements suppressed by an aggregate.");
- vty_out (vty, ")%s", VTY_NEWLINE);
- /* advertised peer */
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- {
- if (bgp_adj_out_lookup (peer, p, afi, safi, rn))
- {
- if (! first)
- vty_out (vty, " Advertised to non peer-group peers:%s ", VTY_NEWLINE);
- vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
- first = 1;
- }
- }
- if (! first)
- vty_out (vty, " Not advertised to any peer");
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- /* Display specified route of BGP table. */
- static int
- bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
- struct bgp_table *rib, const char *ip_str,
- afi_t afi, safi_t safi, struct prefix_rd *prd,
- int prefix_check)
- {
- int ret;
- int header;
- int display = 0;
- struct prefix match;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_info *ri;
- struct bgp_table *table;
- /* Check IP address argument. */
- ret = str2prefix (ip_str, &match);
- if (! ret)
- {
- vty_out (vty, "address is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- match.family = afi2family (afi);
- if (safi == SAFI_MPLS_VPN)
- {
- for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
- {
- if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
- continue;
- if ((table = rn->info) != NULL)
- {
- header = 1;
- if ((rm = bgp_node_match (table, &match)) != NULL)
- {
- if (prefix_check && rm->p.prefixlen != match.prefixlen)
- continue;
- for (ri = rm->info; ri; ri = ri->next)
- {
- if (header)
- {
- route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
- AFI_IP, SAFI_MPLS_VPN);
- header = 0;
- }
- display++;
- route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
- }
- }
- }
- }
- }
- else
- {
- header = 1;
- if ((rn = bgp_node_match (rib, &match)) != NULL)
- {
- if (! prefix_check || rn->p.prefixlen == match.prefixlen)
- {
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (header)
- {
- route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi);
- header = 0;
- }
- display++;
- route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
- }
- }
- }
- }
- if (! display)
- {
- vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
- }
- /* Display specified route of Main RIB */
- static int
- bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
- afi_t afi, safi_t safi, struct prefix_rd *prd,
- int prefix_check)
- {
- struct bgp *bgp;
- /* BGP structure lookup. */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (bgp == NULL)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
- afi, safi, prd, prefix_check);
- }
- /* BGP route print out function. */
- DEFUN (show_ip_bgp,
- show_ip_bgp_cmd,
- "show ip bgp",
- SHOW_STR
- IP_STR
- BGP_STR)
- {
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
- }
- DEFUN (show_ip_bgp_ipv4,
- show_ip_bgp_ipv4_cmd,
- "show ip bgp ipv4 (unicast|multicast)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal,
- NULL);
-
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
- }
- DEFUN (show_ip_bgp_route,
- show_ip_bgp_route_cmd,
- "show ip bgp A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0);
- }
- DEFUN (show_ip_bgp_ipv4_route,
- show_ip_bgp_ipv4_route_cmd,
- "show ip bgp ipv4 (unicast|multicast) A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Network in the BGP routing table to display\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0);
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
- }
- DEFUN (show_ip_bgp_vpnv4_all_route,
- show_ip_bgp_vpnv4_all_route_cmd,
- "show ip bgp vpnv4 all A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display VPNv4 NLRI specific information\n"
- "Display information about all VPNv4 NLRIs\n"
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0);
- }
- DEFUN (show_ip_bgp_vpnv4_rd_route,
- show_ip_bgp_vpnv4_rd_route_cmd,
- "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display VPNv4 NLRI specific information\n"
- "Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n"
- "Network in the BGP routing table to display\n")
- {
- int ret;
- struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0);
- }
- DEFUN (show_ip_bgp_prefix,
- show_ip_bgp_prefix_cmd,
- "show ip bgp A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1);
- }
- DEFUN (show_ip_bgp_ipv4_prefix,
- show_ip_bgp_ipv4_prefix_cmd,
- "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1);
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
- }
- DEFUN (show_ip_bgp_vpnv4_all_prefix,
- show_ip_bgp_vpnv4_all_prefix_cmd,
- "show ip bgp vpnv4 all A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display VPNv4 NLRI specific information\n"
- "Display information about all VPNv4 NLRIs\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 1);
- }
- DEFUN (show_ip_bgp_vpnv4_rd_prefix,
- show_ip_bgp_vpnv4_rd_prefix_cmd,
- "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display VPNv4 NLRI specific information\n"
- "Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- int ret;
- struct prefix_rd prd;
- ret = str2prefix_rd (argv[0], &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 1);
- }
- DEFUN (show_ip_bgp_view,
- show_ip_bgp_view_cmd,
- "show ip bgp view WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "BGP view name\n")
- {
- struct bgp *bgp;
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[0]);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, bgp, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
- }
- DEFUN (show_ip_bgp_view_route,
- show_ip_bgp_view_route_cmd,
- "show ip bgp view WORD A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "BGP view name\n"
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
- }
- DEFUN (show_ip_bgp_view_prefix,
- show_ip_bgp_view_prefix_cmd,
- "show ip bgp view WORD A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "BGP view name\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp,
- show_bgp_cmd,
- "show bgp",
- SHOW_STR
- BGP_STR)
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
- NULL);
- }
- ALIAS (show_bgp,
- show_bgp_ipv6_cmd,
- "show bgp ipv6",
- SHOW_STR
- BGP_STR
- "Address family\n")
- /* old command */
- DEFUN (show_ipv6_bgp,
- show_ipv6_bgp_cmd,
- "show ipv6 bgp",
- SHOW_STR
- IP_STR
- BGP_STR)
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
- NULL);
- }
- DEFUN (show_bgp_route,
- show_bgp_route_cmd,
- "show bgp X:X::X:X",
- SHOW_STR
- BGP_STR
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
- }
- ALIAS (show_bgp_route,
- show_bgp_ipv6_route_cmd,
- "show bgp ipv6 X:X::X:X",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Network in the BGP routing table to display\n")
- /* old command */
- DEFUN (show_ipv6_bgp_route,
- show_ipv6_bgp_route_cmd,
- "show ipv6 bgp X:X::X:X",
- SHOW_STR
- IP_STR
- BGP_STR
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
- }
- DEFUN (show_bgp_prefix,
- show_bgp_prefix_cmd,
- "show bgp X:X::X:X/M",
- SHOW_STR
- BGP_STR
- "IPv6 prefix <network>/<length>\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
- }
- ALIAS (show_bgp_prefix,
- show_bgp_ipv6_prefix_cmd,
- "show bgp ipv6 X:X::X:X/M",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n")
- /* old command */
- DEFUN (show_ipv6_bgp_prefix,
- show_ipv6_bgp_prefix_cmd,
- "show ipv6 bgp X:X::X:X/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
- }
- DEFUN (show_bgp_view,
- show_bgp_view_cmd,
- "show bgp view WORD",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n")
- {
- struct bgp *bgp;
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[0]);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_show (vty, bgp, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
- }
- ALIAS (show_bgp_view,
- show_bgp_view_ipv6_cmd,
- "show bgp view WORD ipv6",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n")
-
- DEFUN (show_bgp_view_route,
- show_bgp_view_route_cmd,
- "show bgp view WORD X:X::X:X",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0);
- }
- ALIAS (show_bgp_view_route,
- show_bgp_view_ipv6_route_cmd,
- "show bgp view WORD ipv6 X:X::X:X",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- "Network in the BGP routing table to display\n")
- DEFUN (show_bgp_view_prefix,
- show_bgp_view_prefix_cmd,
- "show bgp view WORD X:X::X:X/M",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "IPv6 prefix <network>/<length>\n")
- {
- return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
- }
- ALIAS (show_bgp_view_prefix,
- show_bgp_view_ipv6_prefix_cmd,
- "show bgp view WORD ipv6 X:X::X:X/M",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- "IPv6 prefix <network>/<length>\n")
- /* old command */
- DEFUN (show_ipv6_mbgp,
- show_ipv6_mbgp_cmd,
- "show ipv6 mbgp",
- SHOW_STR
- IP_STR
- MBGP_STR)
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
- NULL);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_route,
- show_ipv6_mbgp_route_cmd,
- "show ipv6 mbgp X:X::X:X",
- SHOW_STR
- IP_STR
- MBGP_STR
- "Network in the MBGP routing table to display\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 0);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_prefix,
- show_ipv6_mbgp_prefix_cmd,
- "show ipv6 mbgp X:X::X:X/M",
- SHOW_STR
- IP_STR
- MBGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
- {
- return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1);
- }
- #endif
- static int
- bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- int i;
- struct buffer *b;
- char *regstr;
- int first;
- regex_t *regex;
- int rc;
-
- first = 0;
- b = buffer_new (1024);
- for (i = 0; i < argc; i++)
- {
- if (first)
- buffer_putc (b, ' ');
- else
- {
- if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
- continue;
- first = 1;
- }
- buffer_putstr (b, argv[i]);
- }
- buffer_putc (b, '\0');
- regstr = buffer_getstr (b);
- buffer_free (b);
- regex = bgp_regcomp (regstr);
- XFREE(MTYPE_TMP, regstr);
- if (! regex)
- {
- vty_out (vty, "Can't compile regexp %s%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- rc = bgp_show (vty, NULL, afi, safi, type, regex);
- bgp_regex_free (regex);
- return rc;
- }
- DEFUN (show_ip_bgp_regexp,
- show_ip_bgp_regexp_cmd,
- "show ip bgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- {
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
- bgp_show_type_regexp);
- }
- DEFUN (show_ip_bgp_flap_regexp,
- show_ip_bgp_flap_regexp_cmd,
- "show ip bgp flap-statistics regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- {
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_regexp);
- }
- DEFUN (show_ip_bgp_ipv4_regexp,
- show_ip_bgp_ipv4_regexp_cmd,
- "show ip bgp ipv4 (unicast|multicast) regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_MULTICAST,
- bgp_show_type_regexp);
- return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
- bgp_show_type_regexp);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_regexp,
- show_bgp_regexp_cmd,
- "show bgp regexp .LINE",
- SHOW_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- {
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_regexp);
- }
- ALIAS (show_bgp_regexp,
- show_bgp_ipv6_regexp_cmd,
- "show bgp ipv6 regexp .LINE",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- /* old command */
- DEFUN (show_ipv6_bgp_regexp,
- show_ipv6_bgp_regexp_cmd,
- "show ipv6 bgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the BGP AS paths\n")
- {
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_regexp);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_regexp,
- show_ipv6_mbgp_regexp_cmd,
- "show ipv6 mbgp regexp .LINE",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the AS path regular expression\n"
- "A regular-expression to match the MBGP AS paths\n")
- {
- return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_regexp);
- }
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_prefix_list (struct vty *vty, const char *prefix_list_str, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- struct prefix_list *plist;
- plist = prefix_list_lookup (afi, prefix_list_str);
- if (plist == NULL)
- {
- vty_out (vty, "%% %s is not a valid prefix-list name%s",
- prefix_list_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, NULL, afi, safi, type, plist);
- }
- DEFUN (show_ip_bgp_prefix_list,
- show_ip_bgp_prefix_list_cmd,
- "show ip bgp prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
- {
- return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_list);
- }
- DEFUN (show_ip_bgp_flap_prefix_list,
- show_ip_bgp_flap_prefix_list_cmd,
- "show ip bgp flap-statistics prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
- {
- return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix_list);
- }
- DEFUN (show_ip_bgp_ipv4_prefix_list,
- show_ip_bgp_ipv4_prefix_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes conforming to the prefix-list\n"
- "IP prefix-list name\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
- bgp_show_type_prefix_list);
- return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_list);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_prefix_list,
- show_bgp_prefix_list_cmd,
- "show bgp prefix-list WORD",
- SHOW_STR
- BGP_STR
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
- {
- return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_list);
- }
- ALIAS (show_bgp_prefix_list,
- show_bgp_ipv6_prefix_list_cmd,
- "show bgp ipv6 prefix-list WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes conforming to the prefix-list\n"
- "IPv6 prefix-list name\n")
- /* old command */
- DEFUN (show_ipv6_bgp_prefix_list,
- show_ipv6_bgp_prefix_list_cmd,
- "show ipv6 bgp prefix-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the prefix-list\n"
- "IPv6 prefix-list name\n")
- {
- return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_list);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_prefix_list,
- show_ipv6_mbgp_prefix_list_cmd,
- "show ipv6 mbgp prefix-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the prefix-list\n"
- "IPv6 prefix-list name\n")
- {
- return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_prefix_list);
- }
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_filter_list (struct vty *vty, const char *filter, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- struct as_list *as_list;
- as_list = as_list_lookup (filter);
- if (as_list == NULL)
- {
- vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, NULL, afi, safi, type, as_list);
- }
- DEFUN (show_ip_bgp_filter_list,
- show_ip_bgp_filter_list_cmd,
- "show ip bgp filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_filter_list);
- }
- DEFUN (show_ip_bgp_flap_filter_list,
- show_ip_bgp_flap_filter_list_cmd,
- "show ip bgp flap-statistics filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_filter_list);
- }
- DEFUN (show_ip_bgp_ipv4_filter_list,
- show_ip_bgp_ipv4_filter_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) filter-list WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
- bgp_show_type_filter_list);
-
- return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
- bgp_show_type_filter_list);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_filter_list,
- show_bgp_filter_list_cmd,
- "show bgp filter-list WORD",
- SHOW_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_filter_list);
- }
- ALIAS (show_bgp_filter_list,
- show_bgp_ipv6_filter_list_cmd,
- "show bgp ipv6 filter-list WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- /* old command */
- DEFUN (show_ipv6_bgp_filter_list,
- show_ipv6_bgp_filter_list_cmd,
- "show ipv6 bgp filter-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_filter_list);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_filter_list,
- show_ipv6_mbgp_filter_list_cmd,
- "show ipv6 mbgp filter-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes conforming to the filter-list\n"
- "Regular expression access list name\n")
- {
- return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_filter_list);
- }
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_route_map (struct vty *vty, const char *rmap_str, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- struct route_map *rmap;
- rmap = route_map_lookup_by_name (rmap_str);
- if (! rmap)
- {
- vty_out (vty, "%% %s is not a valid route-map name%s",
- rmap_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, NULL, afi, safi, type, rmap);
- }
- DEFUN (show_ip_bgp_route_map,
- show_ip_bgp_route_map_cmd,
- "show ip bgp route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
- {
- return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_route_map);
- }
- DEFUN (show_ip_bgp_flap_route_map,
- show_ip_bgp_flap_route_map_cmd,
- "show ip bgp flap-statistics route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
- {
- return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_route_map);
- }
- DEFUN (show_ip_bgp_ipv4_route_map,
- show_ip_bgp_ipv4_route_map_cmd,
- "show ip bgp ipv4 (unicast|multicast) route-map WORD",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_MULTICAST,
- bgp_show_type_route_map);
- return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_UNICAST,
- bgp_show_type_route_map);
- }
- DEFUN (show_bgp_route_map,
- show_bgp_route_map_cmd,
- "show bgp route-map WORD",
- SHOW_STR
- BGP_STR
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
- {
- return bgp_show_route_map (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_route_map);
- }
- ALIAS (show_bgp_route_map,
- show_bgp_ipv6_route_map_cmd,
- "show bgp ipv6 route-map WORD",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the route-map\n"
- "A route-map to match on\n")
- DEFUN (show_ip_bgp_cidr_only,
- show_ip_bgp_cidr_only_cmd,
- "show ip bgp cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display only routes with non-natural netmasks\n")
- {
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_cidr_only, NULL);
- }
- DEFUN (show_ip_bgp_flap_cidr_only,
- show_ip_bgp_flap_cidr_only_cmd,
- "show ip bgp flap-statistics cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Display only routes with non-natural netmasks\n")
- {
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_cidr_only, NULL);
- }
- DEFUN (show_ip_bgp_ipv4_cidr_only,
- show_ip_bgp_ipv4_cidr_only_cmd,
- "show ip bgp ipv4 (unicast|multicast) cidr-only",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display only routes with non-natural netmasks\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
- bgp_show_type_cidr_only, NULL);
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_cidr_only, NULL);
- }
- DEFUN (show_ip_bgp_community_all,
- show_ip_bgp_community_all_cmd,
- "show ip bgp community",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n")
- {
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_community_all, NULL);
- }
- DEFUN (show_ip_bgp_ipv4_community_all,
- show_ip_bgp_ipv4_community_all_cmd,
- "show ip bgp ipv4 (unicast|multicast) community",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
- bgp_show_type_community_all, NULL);
-
- return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
- bgp_show_type_community_all, NULL);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_community_all,
- show_bgp_community_all_cmd,
- "show bgp community",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n")
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_community_all, NULL);
- }
- ALIAS (show_bgp_community_all,
- show_bgp_ipv6_community_all_cmd,
- "show bgp ipv6 community",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n")
- /* old command */
- DEFUN (show_ipv6_bgp_community_all,
- show_ipv6_bgp_community_all_cmd,
- "show ipv6 bgp community",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n")
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
- bgp_show_type_community_all, NULL);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_community_all,
- show_ipv6_mbgp_community_all_cmd,
- "show ipv6 mbgp community",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n")
- {
- return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_community_all, NULL);
- }
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_community (struct vty *vty, int argc, const char **argv, int exact,
- u_int16_t afi, u_char safi)
- {
- struct community *com;
- struct buffer *b;
- int i;
- char *str;
- int first = 0;
- b = buffer_new (1024);
- for (i = 0; i < argc; i++)
- {
- if (first)
- buffer_putc (b, ' ');
- else
- {
- if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
- continue;
- first = 1;
- }
-
- buffer_putstr (b, argv[i]);
- }
- buffer_putc (b, '\0');
- str = buffer_getstr (b);
- buffer_free (b);
- com = community_str2com (str);
- XFREE (MTYPE_TMP, str);
- if (! com)
- {
- vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, NULL, afi, safi,
- (exact ? bgp_show_type_community_exact :
- bgp_show_type_community), com);
- }
- DEFUN (show_ip_bgp_community,
- show_ip_bgp_community_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- {
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
- }
- ALIAS (show_ip_bgp_community,
- show_ip_bgp_community2_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
- ALIAS (show_ip_bgp_community,
- show_ip_bgp_community3_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
- ALIAS (show_ip_bgp_community,
- show_ip_bgp_community4_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- DEFUN (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
- }
- ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community2_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
- ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community3_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
- ALIAS (show_ip_bgp_ipv4_community,
- show_ip_bgp_ipv4_community4_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- DEFUN (show_ip_bgp_community_exact,
- show_ip_bgp_community_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- {
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
- }
- ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community2_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community3_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_ip_bgp_community_exact,
- show_ip_bgp_community4_exact_cmd,
- "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- DEFUN (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
- }
- ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community2_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community3_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
- ALIAS (show_ip_bgp_ipv4_community_exact,
- show_ip_bgp_ipv4_community4_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_community,
- show_bgp_community_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- {
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (show_bgp_community,
- show_bgp_ipv6_community_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- ALIAS (show_bgp_community,
- show_bgp_community2_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- ALIAS (show_bgp_community,
- show_bgp_ipv6_community2_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
-
- ALIAS (show_bgp_community,
- show_bgp_community3_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- ALIAS (show_bgp_community,
- show_bgp_ipv6_community3_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- ALIAS (show_bgp_community,
- show_bgp_community4_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- ALIAS (show_bgp_community,
- show_bgp_ipv6_community4_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- DEFUN (show_ipv6_bgp_community,
- show_ipv6_bgp_community_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- {
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
- }
- /* old command */
- ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community2_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community3_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- ALIAS (show_ipv6_bgp_community,
- show_ipv6_bgp_community4_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- DEFUN (show_bgp_community_exact,
- show_bgp_community_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- {
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_bgp_community_exact,
- show_bgp_community2_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community2_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_bgp_community_exact,
- show_bgp_community3_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community3_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- ALIAS (show_bgp_community_exact,
- show_bgp_community4_exact_cmd,
- "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
- ALIAS (show_bgp_community_exact,
- show_bgp_ipv6_community4_exact_cmd,
- "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- /* old command */
- DEFUN (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- {
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
- }
- /* old command */
- ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community2_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- /* old command */
- ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community3_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- /* old command */
- ALIAS (show_ipv6_bgp_community_exact,
- show_ipv6_bgp_community4_exact_cmd,
- "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
-
- /* old command */
- DEFUN (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- {
- return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
- }
- /* old command */
- ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community2_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community3_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- ALIAS (show_ipv6_mbgp_community,
- show_ipv6_mbgp_community4_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n")
- /* old command */
- DEFUN (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- {
- return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
- }
- /* old command */
- ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community2_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- /* old command */
- ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community3_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- /* old command */
- ALIAS (show_ipv6_mbgp_community_exact,
- show_ipv6_mbgp_community4_exact_cmd,
- "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the communities\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "community number\n"
- "Do not send outside local AS (well-known community)\n"
- "Do not advertise to any peer (well-known community)\n"
- "Do not export to next AS (well-known community)\n"
- "Exact match of the communities")
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_community_list (struct vty *vty, const char *com, int exact,
- u_int16_t afi, u_char safi)
- {
- struct community_list *list;
- list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
- if (list == NULL)
- {
- vty_out (vty, "%% %s is not a valid community-list name%s", com,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show (vty, NULL, afi, safi,
- (exact ? bgp_show_type_community_list_exact :
- bgp_show_type_community_list), list);
- }
- DEFUN (show_ip_bgp_community_list,
- show_ip_bgp_community_list_cmd,
- "show ip bgp community-list (<1-500>|WORD)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
- {
- return bgp_show_community_list (vty, argv[0], 0, AFI_IP, SAFI_UNICAST);
- }
- DEFUN (show_ip_bgp_ipv4_community_list,
- show_ip_bgp_ipv4_community_list_cmd,
- "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD)",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_UNICAST);
- }
- DEFUN (show_ip_bgp_community_list_exact,
- show_ip_bgp_community_list_exact_cmd,
- "show ip bgp community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
- {
- return bgp_show_community_list (vty, argv[0], 1, AFI_IP, SAFI_UNICAST);
- }
- DEFUN (show_ip_bgp_ipv4_community_list_exact,
- show_ip_bgp_ipv4_community_list_exact_cmd,
- "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_UNICAST);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_community_list,
- show_bgp_community_list_cmd,
- "show bgp community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
- {
- return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (show_bgp_community_list,
- show_bgp_ipv6_community_list_cmd,
- "show bgp ipv6 community-list (<1-500>|WORD)",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n")
- /* old command */
- DEFUN (show_ipv6_bgp_community_list,
- show_ipv6_bgp_community_list_cmd,
- "show ipv6 bgp community-list WORD",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n")
- {
- return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_community_list,
- show_ipv6_mbgp_community_list_cmd,
- "show ipv6 mbgp community-list WORD",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n")
- {
- return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_MULTICAST);
- }
- DEFUN (show_bgp_community_list_exact,
- show_bgp_community_list_exact_cmd,
- "show bgp community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
- {
- return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
- }
- ALIAS (show_bgp_community_list_exact,
- show_bgp_ipv6_community_list_exact_cmd,
- "show bgp ipv6 community-list (<1-500>|WORD) exact-match",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Display routes matching the community-list\n"
- "community-list number\n"
- "community-list name\n"
- "Exact match of the communities\n")
- /* old command */
- DEFUN (show_ipv6_bgp_community_list_exact,
- show_ipv6_bgp_community_list_exact_cmd,
- "show ipv6 bgp community-list WORD exact-match",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n"
- "Exact match of the communities\n")
- {
- return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_community_list_exact,
- show_ipv6_mbgp_community_list_exact_cmd,
- "show ipv6 mbgp community-list WORD exact-match",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Display routes matching the community-list\n"
- "community-list name\n"
- "Exact match of the communities\n")
- {
- return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_MULTICAST);
- }
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_prefix_longer (struct vty *vty, const char *prefix, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- int ret;
- struct prefix *p;
- p = prefix_new();
- ret = str2prefix (prefix, p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = bgp_show (vty, NULL, afi, safi, type, p);
- prefix_free(p);
- return ret;
- }
- DEFUN (show_ip_bgp_prefix_longer,
- show_ip_bgp_prefix_longer_cmd,
- "show ip bgp A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
- }
- DEFUN (show_ip_bgp_flap_prefix_longer,
- show_ip_bgp_flap_prefix_longer_cmd,
- "show ip bgp flap-statistics A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix_longer);
- }
- DEFUN (show_ip_bgp_ipv4_prefix_longer,
- show_ip_bgp_ipv4_prefix_longer_cmd,
- "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
- "Display route and more specific routes\n")
- {
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_MULTICAST,
- bgp_show_type_prefix_longer);
- return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
- }
- DEFUN (show_ip_bgp_flap_address,
- show_ip_bgp_flap_address_cmd,
- "show ip bgp flap-statistics A.B.C.D",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "Network in the BGP routing table to display\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_address);
- }
- DEFUN (show_ip_bgp_flap_prefix,
- show_ip_bgp_flap_prefix_cmd,
- "show ip bgp flap-statistics A.B.C.D/M",
- SHOW_STR
- IP_STR
- BGP_STR
- "Display flap statistics of routes\n"
- "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_prefix);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_prefix_longer,
- show_bgp_prefix_longer_cmd,
- "show bgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- BGP_STR
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
- }
- ALIAS (show_bgp_prefix_longer,
- show_bgp_ipv6_prefix_longer_cmd,
- "show bgp ipv6 X:X::X:X/M longer-prefixes",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "IPv6 prefix <network>/<length>\n"
- "Display route and more specific routes\n")
- /* old command */
- DEFUN (show_ipv6_bgp_prefix_longer,
- show_ipv6_bgp_prefix_longer_cmd,
- "show ipv6 bgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "Display route and more specific routes\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
- bgp_show_type_prefix_longer);
- }
- /* old command */
- DEFUN (show_ipv6_mbgp_prefix_longer,
- show_ipv6_mbgp_prefix_longer_cmd,
- "show ipv6 mbgp X:X::X:X/M longer-prefixes",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
- "Display route and more specific routes\n")
- {
- return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
- bgp_show_type_prefix_longer);
- }
- #endif /* HAVE_IPV6 */
- static struct peer *
- peer_lookup_in_view (struct vty *vty, const char *view_name,
- const char *ip_str)
- {
- int ret;
- struct bgp *bgp;
- struct peer *peer;
- union sockunion su;
- /* BGP structure lookup. */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (! bgp)
- {
- vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
- return NULL;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (! bgp)
- {
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return NULL;
- }
- }
- /* Get peer sockunion. */
- ret = str2sockunion (ip_str, &su);
- if (ret < 0)
- {
- vty_out (vty, "Malformed address: %s%s", ip_str, VTY_NEWLINE);
- return NULL;
- }
- /* Peer structure lookup. */
- peer = peer_lookup (bgp, &su);
- if (! peer)
- {
- vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
- return NULL;
- }
-
- return peer;
- }
- enum bgp_stats
- {
- BGP_STATS_MAXBITLEN = 0,
- BGP_STATS_RIB,
- BGP_STATS_PREFIXES,
- BGP_STATS_TOTPLEN,
- BGP_STATS_UNAGGREGATEABLE,
- BGP_STATS_MAX_AGGREGATEABLE,
- BGP_STATS_AGGREGATES,
- BGP_STATS_SPACE,
- BGP_STATS_ASPATH_COUNT,
- BGP_STATS_ASPATH_MAXHOPS,
- BGP_STATS_ASPATH_TOTHOPS,
- BGP_STATS_ASPATH_MAXSIZE,
- BGP_STATS_ASPATH_TOTSIZE,
- BGP_STATS_ASN_HIGHEST,
- BGP_STATS_MAX,
- };
- static const char *table_stats_strs[] =
- {
- [BGP_STATS_PREFIXES] = "Total Prefixes",
- [BGP_STATS_TOTPLEN] = "Average prefix length",
- [BGP_STATS_RIB] = "Total Advertisements",
- [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
- [BGP_STATS_MAX_AGGREGATEABLE] = "Maximum aggregateable prefixes",
- [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
- [BGP_STATS_SPACE] = "Address space advertised",
- [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
- [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
- [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
- [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
- [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
- [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
- [BGP_STATS_MAX] = NULL,
- };
- struct bgp_table_stats
- {
- struct bgp_table *table;
- unsigned long long counts[BGP_STATS_MAX];
- };
- #if 0
- #define TALLY_SIGFIG 100000
- static unsigned long
- ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
- {
- unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
- unsigned long res = (newtot * TALLY_SIGFIG) / count;
- unsigned long ret = newtot / count;
-
- if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
- return ret + 1;
- else
- return ret;
- }
- #endif
- static int
- bgp_table_stats_walker (struct thread *t)
- {
- struct bgp_node *rn;
- struct bgp_node *top;
- struct bgp_table_stats *ts = THREAD_ARG (t);
- unsigned int space = 0;
-
- if (!(top = bgp_table_top (ts->table)))
- return 0;
- switch (top->p.family)
- {
- case AF_INET:
- space = IPV4_MAX_BITLEN;
- break;
- case AF_INET6:
- space = IPV6_MAX_BITLEN;
- break;
- }
-
- ts->counts[BGP_STATS_MAXBITLEN] = space;
- for (rn = top; rn; rn = bgp_route_next (rn))
- {
- struct bgp_info *ri;
- struct bgp_node *prn = rn->parent;
- unsigned int rinum = 0;
-
- if (rn == top)
- continue;
-
- if (!rn->info)
- continue;
-
- ts->counts[BGP_STATS_PREFIXES]++;
- ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
- #if 0
- ts->counts[BGP_STATS_AVGPLEN]
- = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
- ts->counts[BGP_STATS_AVGPLEN],
- rn->p.prefixlen);
- #endif
-
- /* check if the prefix is included by any other announcements */
- while (prn && !prn->info)
- prn = prn->parent;
-
- if (prn == NULL || prn == top)
- {
- ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
- /* announced address space */
- if (space)
- ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen);
- }
- else if (prn->info)
- ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
-
- for (ri = rn->info; ri; ri = ri->next)
- {
- rinum++;
- ts->counts[BGP_STATS_RIB]++;
-
- if (ri->attr &&
- (CHECK_FLAG (ri->attr->flag,
- ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))))
- ts->counts[BGP_STATS_AGGREGATES]++;
-
- /* as-path stats */
- if (ri->attr && ri->attr->aspath)
- {
- unsigned int hops = aspath_count_hops (ri->attr->aspath);
- unsigned int size = aspath_size (ri->attr->aspath);
- as_t highest = aspath_highest (ri->attr->aspath);
-
- ts->counts[BGP_STATS_ASPATH_COUNT]++;
-
- if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
- ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
-
- if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
- ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
-
- ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
- ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
- #if 0
- ts->counts[BGP_STATS_ASPATH_AVGHOPS]
- = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
- ts->counts[BGP_STATS_ASPATH_AVGHOPS],
- hops);
- ts->counts[BGP_STATS_ASPATH_AVGSIZE]
- = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
- ts->counts[BGP_STATS_ASPATH_AVGSIZE],
- size);
- #endif
- if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
- ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
- }
- }
- }
- return 0;
- }
- static int
- bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
- {
- struct bgp_table_stats ts;
- unsigned int i;
-
- if (!bgp->rib[afi][safi])
- {
- vty_out (vty, "%% No RIB exist for the AFI/SAFI%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- memset (&ts, 0, sizeof (ts));
- ts.table = bgp->rib[afi][safi];
- thread_execute (bm->master, bgp_table_stats_walker, &ts, 0);
- vty_out (vty, "BGP %s RIB statistics%s%s",
- afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE);
-
- for (i = 0; i < BGP_STATS_MAX; i++)
- {
- if (!table_stats_strs[i])
- continue;
-
- switch (i)
- {
- #if 0
- case BGP_STATS_ASPATH_AVGHOPS:
- case BGP_STATS_ASPATH_AVGSIZE:
- case BGP_STATS_AVGPLEN:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12.2f",
- (float)ts.counts[i] / (float)TALLY_SIGFIG);
- break;
- #endif
- case BGP_STATS_ASPATH_TOTHOPS:
- case BGP_STATS_ASPATH_TOTSIZE:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12.2f",
- ts.counts[i] ?
- (float)ts.counts[i] /
- (float)ts.counts[BGP_STATS_ASPATH_COUNT]
- : 0);
- break;
- case BGP_STATS_TOTPLEN:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12.2f",
- ts.counts[i] ?
- (float)ts.counts[i] /
- (float)ts.counts[BGP_STATS_PREFIXES]
- : 0);
- break;
- case BGP_STATS_SPACE:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
- if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
- break;
- vty_out (vty, "%30s: ", "%% announced ");
- vty_out (vty, "%12.2f%s",
- 100 * (float)ts.counts[BGP_STATS_SPACE] /
- (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]),
- VTY_NEWLINE);
- vty_out (vty, "%30s: ", "/8 equivalent ");
- vty_out (vty, "%12.2f%s",
- (float)ts.counts[BGP_STATS_SPACE] /
- (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)),
- VTY_NEWLINE);
- if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
- break;
- vty_out (vty, "%30s: ", "/24 equivalent ");
- vty_out (vty, "%12.2f",
- (float)ts.counts[BGP_STATS_SPACE] /
- (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24)));
- break;
- default:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12llu", ts.counts[i]);
- }
-
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- return CMD_SUCCESS;
- }
- static int
- bgp_table_stats_vty (struct vty *vty, const char *name,
- const char *afi_str, const char *safi_str)
- {
- struct bgp *bgp;
- afi_t afi;
- safi_t safi;
-
- if (name)
- bgp = bgp_lookup_by_name (name);
- else
- bgp = bgp_get_default ();
- if (!bgp)
- {
- vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (strncmp (afi_str, "ipv", 3) == 0)
- {
- if (strncmp (afi_str, "ipv4", 4) == 0)
- afi = AFI_IP;
- else if (strncmp (afi_str, "ipv6", 4) == 0)
- afi = AFI_IP6;
- else
- {
- vty_out (vty, "%% Invalid address family %s%s",
- afi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (strncmp (safi_str, "m", 1) == 0)
- safi = SAFI_MULTICAST;
- else if (strncmp (safi_str, "u", 1) == 0)
- safi = SAFI_UNICAST;
- else if (strncmp (safi_str, "vpnv4", 5) == 0)
- safi = BGP_SAFI_VPNV4;
- else if (strncmp (safi_str, "vpnv6", 6) == 0)
- safi = BGP_SAFI_VPNV6;
- else
- {
- vty_out (vty, "%% Invalid subsequent address family %s%s",
- safi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- vty_out (vty, "%% Invalid address family %s%s",
- afi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- if ((afi == AFI_IP && safi == BGP_SAFI_VPNV6)
- || (afi == AFI_IP6 && safi == BGP_SAFI_VPNV4))
- {
- vty_out (vty, "%% Invalid subsequent address family %s for %s%s",
- afi_str, safi_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_table_stats (vty, bgp, afi, safi);
- }
- DEFUN (show_bgp_statistics,
- show_bgp_statistics_cmd,
- "show bgp (ipv4|ipv6) (unicast|multicast) statistics",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "BGP RIB advertisement statistics\n")
- {
- return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
- }
- ALIAS (show_bgp_statistics,
- show_bgp_statistics_vpnv4_cmd,
- "show bgp (ipv4) (vpnv4) statistics",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "BGP RIB advertisement statistics\n")
- DEFUN (show_bgp_statistics_view,
- show_bgp_statistics_view_cmd,
- "show bgp view WORD (ipv4|ipv6) (unicast|multicast) statistics",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "Address family\n"
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "BGP RIB advertisement statistics\n")
- {
- return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
- }
- ALIAS (show_bgp_statistics_view,
- show_bgp_statistics_view_vpnv4_cmd,
- "show bgp view WORD (ipv4) (vpnv4) statistics",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "Address family\n"
- "Address Family modifier\n"
- "BGP RIB advertisement statistics\n")
- enum bgp_pcounts
- {
- PCOUNT_ADJ_IN = 0,
- PCOUNT_DAMPED,
- PCOUNT_REMOVED,
- PCOUNT_HISTORY,
- PCOUNT_STALE,
- PCOUNT_VALID,
- PCOUNT_ALL,
- PCOUNT_COUNTED,
- PCOUNT_PFCNT, /* the figure we display to users */
- PCOUNT_MAX,
- };
- static const char *pcount_strs[] =
- {
- [PCOUNT_ADJ_IN] = "Adj-in",
- [PCOUNT_DAMPED] = "Damped",
- [PCOUNT_REMOVED] = "Removed",
- [PCOUNT_HISTORY] = "History",
- [PCOUNT_STALE] = "Stale",
- [PCOUNT_VALID] = "Valid",
- [PCOUNT_ALL] = "All RIB",
- [PCOUNT_COUNTED] = "PfxCt counted",
- [PCOUNT_PFCNT] = "Useable",
- [PCOUNT_MAX] = NULL,
- };
- struct peer_pcounts
- {
- unsigned int count[PCOUNT_MAX];
- const struct peer *peer;
- const struct bgp_table *table;
- };
- static int
- bgp_peer_count_walker (struct thread *t)
- {
- struct bgp_node *rn;
- struct peer_pcounts *pc = THREAD_ARG (t);
- const struct peer *peer = pc->peer;
-
- for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn))
- {
- struct bgp_adj_in *ain;
- struct bgp_info *ri;
-
- for (ain = rn->adj_in; ain; ain = ain->next)
- if (ain->peer == peer)
- pc->count[PCOUNT_ADJ_IN]++;
- for (ri = rn->info; ri; ri = ri->next)
- {
- char buf[SU_ADDRSTRLEN];
-
- if (ri->peer != peer)
- continue;
-
- pc->count[PCOUNT_ALL]++;
-
- if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
- pc->count[PCOUNT_DAMPED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- pc->count[PCOUNT_HISTORY]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
- pc->count[PCOUNT_REMOVED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- pc->count[PCOUNT_STALE]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_VALID))
- pc->count[PCOUNT_VALID]++;
- if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- pc->count[PCOUNT_PFCNT]++;
-
- if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
- pc->count[PCOUNT_COUNTED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- plog_warn (peer->log,
- "%s [pcount] %s/%d is counted but flags 0x%x",
- peer->host,
- inet_ntop(rn->p.family, &rn->p.u.prefix,
- buf, SU_ADDRSTRLEN),
- rn->p.prefixlen,
- ri->flags);
- }
- else
- {
- if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- plog_warn (peer->log,
- "%s [pcount] %s/%d not counted but flags 0x%x",
- peer->host,
- inet_ntop(rn->p.family, &rn->p.u.prefix,
- buf, SU_ADDRSTRLEN),
- rn->p.prefixlen,
- ri->flags);
- }
- }
- }
- return 0;
- }
- static int
- bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi)
- {
- struct peer_pcounts pcounts = { .peer = peer };
- unsigned int i;
-
- if (!peer || !peer->bgp || !peer->afc[afi][safi]
- || !peer->bgp->rib[afi][safi])
- {
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- memset (&pcounts, 0, sizeof(pcounts));
- pcounts.peer = peer;
- pcounts.table = peer->bgp->rib[afi][safi];
-
- /* in-place call via thread subsystem so as to record execution time
- * stats for the thread-walk (i.e. ensure this can't be blamed on
- * on just vty_read()).
- */
- thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
-
- vty_out (vty, "Prefix counts for %s, %s%s",
- peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
- vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
- vty_out (vty, "%sCounts from RIB table walk:%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
- for (i = 0; i < PCOUNT_MAX; i++)
- vty_out (vty, "%20s: %-10d%s",
- pcount_strs[i], pcounts.count[i], VTY_NEWLINE);
- if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
- {
- vty_out (vty, "%s [pcount] PfxCt drift!%s",
- peer->host, VTY_NEWLINE);
- vty_out (vty, "Please report this bug, with the above command output%s",
- VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
- }
- DEFUN (show_ip_bgp_neighbor_prefix_counts,
- show_ip_bgp_neighbor_prefix_counts_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) prefix-counts",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display detailed prefix count information\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST);
- }
- DEFUN (show_bgp_ipv6_neighbor_prefix_counts,
- show_bgp_ipv6_neighbor_prefix_counts_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) prefix-counts",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display detailed prefix count information\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST);
- }
- DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts,
- show_ip_bgp_ipv4_neighbor_prefix_counts_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) prefix-counts",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display detailed prefix count information\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[1]);
- if (! peer)
- return CMD_WARNING;
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST);
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST);
- }
- DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
- show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd,
- "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X) prefix-counts",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display detailed prefix count information\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN);
- }
- static void
- show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
- int in)
- {
- struct bgp_table *table;
- struct bgp_adj_in *ain;
- struct bgp_adj_out *adj;
- unsigned long output_count;
- struct bgp_node *rn;
- int header1 = 1;
- struct bgp *bgp;
- int header2 = 1;
- bgp = peer->bgp;
- if (! bgp)
- return;
- table = bgp->rib[afi][safi];
- output_count = 0;
-
- if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
- PEER_STATUS_DEFAULT_ORIGINATE))
- {
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, "Originating default network 0.0.0.0%s%s",
- VTY_NEWLINE, VTY_NEWLINE);
- header1 = 0;
- }
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- if (in)
- {
- for (ain = rn->adj_in; ain; ain = ain->next)
- if (ain->peer == peer)
- {
- if (header1)
- {
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- header1 = 0;
- }
- if (header2)
- {
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header2 = 0;
- }
- if (ain->attr)
- {
- route_vty_out_tmp (vty, &rn->p, ain->attr, safi);
- output_count++;
- }
- }
- }
- else
- {
- for (adj = rn->adj_out; adj; adj = adj->next)
- if (adj->peer == peer)
- {
- if (header1)
- {
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- header1 = 0;
- }
- if (header2)
- {
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header2 = 0;
- }
- if (adj->attr)
- {
- route_vty_out_tmp (vty, &rn->p, adj->attr, safi);
- output_count++;
- }
- }
- }
-
- if (output_count != 0)
- vty_out (vty, "%sTotal number of prefixes %ld%s",
- VTY_NEWLINE, output_count, VTY_NEWLINE);
- }
- static int
- peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, int in)
- {
- if (! peer || ! peer->afc[afi][safi])
- {
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (in && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
- {
- vty_out (vty, "%% Inbound soft reconfiguration not enabled%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- show_adj_route (vty, peer, afi, safi, in);
- return CMD_SUCCESS;
- }
- DEFUN (show_ip_bgp_view_neighbor_advertised_route,
- show_ip_bgp_view_neighbor_advertised_route_cmd,
- "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- {
- struct peer *peer;
- if (argc == 2)
- peer = peer_lookup_in_view (vty, argv[0], argv[1]);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0);
- }
- ALIAS (show_ip_bgp_view_neighbor_advertised_route,
- show_ip_bgp_neighbor_advertised_route_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
- show_ip_bgp_ipv4_neighbor_advertised_route_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[1]);
- if (! peer)
- return CMD_WARNING;
- if (strncmp (argv[0], "m", 1) == 0)
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 0);
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0);
- }
- #ifdef HAVE_IPV6
- DEFUN (show_bgp_view_neighbor_advertised_route,
- show_bgp_view_neighbor_advertised_route_cmd,
- "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- {
- struct peer *peer;
- if (argc == 2)
- peer = peer_lookup_in_view (vty, argv[0], argv[1]);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0);
- }
- ALIAS (show_bgp_view_neighbor_advertised_route,
- show_bgp_view_ipv6_neighbor_advertised_route_cmd,
- "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- DEFUN (show_bgp_view_neighbor_received_routes,
- show_bgp_view_neighbor_received_routes_cmd,
- "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- {
- struct peer *peer;
- if (argc == 2)
- peer = peer_lookup_in_view (vty, argv[0], argv[1]);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1);
- }
- ALIAS (show_bgp_view_neighbor_received_routes,
- show_bgp_view_ipv6_neighbor_received_routes_cmd,
- "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- ALIAS (show_bgp_view_neighbor_advertised_route,
- show_bgp_neighbor_advertised_route_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
-
- ALIAS (show_bgp_view_neighbor_advertised_route,
- show_bgp_ipv6_neighbor_advertised_route_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- /* old command */
- ALIAS (show_bgp_view_neighbor_advertised_route,
- ipv6_bgp_neighbor_advertised_route_cmd,
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
-
- /* old command */
- DEFUN (ipv6_mbgp_neighbor_advertised_route,
- ipv6_mbgp_neighbor_advertised_route_cmd,
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the routes advertised to a BGP neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0);
- }
- #endif /* HAVE_IPV6 */
- DEFUN (show_ip_bgp_view_neighbor_received_routes,
- show_ip_bgp_view_neighbor_received_routes_cmd,
- "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- {
- struct peer *peer;
- if (argc == 2)
- peer = peer_lookup_in_view (vty, argv[0], argv[1]);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
- }
- ALIAS (show_ip_bgp_view_neighbor_received_routes,
- show_ip_bgp_neighbor_received_routes_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
- show_ip_bgp_ipv4_neighbor_received_routes_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[1]);
- if (! peer)
- return CMD_WARNING;
-
- if (strncmp (argv[0], "m", 1) == 0)
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1);
- return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
- }
- DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
- show_ip_bgp_neighbor_received_prefix_filter_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- {
- char name[BUFSIZ];
- union sockunion *su;
- struct peer *peer;
- int count;
- su = sockunion_str2su (argv[0]);
- if (su == NULL)
- return CMD_WARNING;
- peer = peer_lookup (NULL, su);
- if (! peer)
- return CMD_WARNING;
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
- if (count)
- {
- vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP, name);
- }
- return CMD_SUCCESS;
- }
- DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
- show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- {
- char name[BUFSIZ];
- union sockunion *su;
- struct peer *peer;
- int count;
- su = sockunion_str2su (argv[1]);
- if (su == NULL)
- return CMD_WARNING;
- peer = peer_lookup (NULL, su);
- if (! peer)
- return CMD_WARNING;
- if (strncmp (argv[0], "m", 1) == 0)
- {
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_MULTICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
- if (count)
- {
- vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP, name);
- }
- }
- else
- {
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
- if (count)
- {
- vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP, name);
- }
- }
- return CMD_SUCCESS;
- }
- #ifdef HAVE_IPV6
- ALIAS (show_bgp_view_neighbor_received_routes,
- show_bgp_neighbor_received_routes_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- ALIAS (show_bgp_view_neighbor_received_routes,
- show_bgp_ipv6_neighbor_received_routes_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- DEFUN (show_bgp_neighbor_received_prefix_filter,
- show_bgp_neighbor_received_prefix_filter_cmd,
- "show bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- {
- char name[BUFSIZ];
- union sockunion *su;
- struct peer *peer;
- int count;
- su = sockunion_str2su (argv[0]);
- if (su == NULL)
- return CMD_WARNING;
- peer = peer_lookup (NULL, su);
- if (! peer)
- return CMD_WARNING;
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name);
- if (count)
- {
- vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP6, name);
- }
- return CMD_SUCCESS;
- }
- ALIAS (show_bgp_neighbor_received_prefix_filter,
- show_bgp_ipv6_neighbor_received_prefix_filter_cmd,
- "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- BGP_STR
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- /* old command */
- ALIAS (show_bgp_view_neighbor_received_routes,
- ipv6_bgp_neighbor_received_routes_cmd,
- "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- IPV6_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- /* old command */
- DEFUN (ipv6_mbgp_neighbor_received_routes,
- ipv6_mbgp_neighbor_received_routes_cmd,
- "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) received-routes",
- SHOW_STR
- IPV6_STR
- MBGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the received routes from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 1);
- }
- DEFUN (show_bgp_view_neighbor_received_prefix_filter,
- show_bgp_view_neighbor_received_prefix_filter_cmd,
- "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- {
- char name[BUFSIZ];
- union sockunion *su;
- struct peer *peer;
- struct bgp *bgp;
- int count;
- /* BGP structure lookup. */
- bgp = bgp_lookup_by_name (argv[0]);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- su = sockunion_str2su (argv[1]);
- if (su == NULL)
- return CMD_WARNING;
- peer = peer_lookup (bgp, su);
- if (! peer)
- return CMD_WARNING;
- sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
- count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name);
- if (count)
- {
- vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, AFI_IP6, name);
- }
- return CMD_SUCCESS;
- }
- ALIAS (show_bgp_view_neighbor_received_prefix_filter,
- show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd,
- "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
- SHOW_STR
- BGP_STR
- "BGP view\n"
- "View name\n"
- "Address family\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display information received from a BGP neighbor\n"
- "Display the prefixlist filter\n")
- #endif /* HAVE_IPV6 */
- static int
- bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
- safi_t safi, enum bgp_show_type type)
- {
- if (! peer || ! peer->afc[afi][safi])
- {
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su);
- }
- DEFUN (show_ip_bgp_neighbor_routes,
- show_ip_bgp_neighbor_routes_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display routes learned from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_neighbor);
- }
- DEFUN (show_ip_bgp_neighbor_flap,
- show_ip_bgp_neighbor_flap_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) flap-statistics",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display flap statistics of the routes learned from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_flap_neighbor);
- }
- DEFUN (show_ip_bgp_neighbor_damp,
- show_ip_bgp_neighbor_damp_cmd,
- "show ip bgp neighbors (A.B.C.D|X:X::X:X) dampened-routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display the dampened routes received from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_damp_neighbor);
- }
- DEFUN (show_ip_bgp_ipv4_neighbor_routes,
- show_ip_bgp_ipv4_neighbor_routes_cmd,
- "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes",
- SHOW_STR
- IP_STR
- BGP_STR
- "Address family\n"
- "Address Family modifier\n"
- "Address Family modifier\n"
- "Detailed information on TCP and BGP neighbor connections\n"
- "Neighbor to display information about\n"
- "Neighbor to display information about\n"
- "Display routes learned from neighbor\n")
- {
- struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[1]);
- if (! peer)
- return CMD_WARNING;
-
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_MULTICAST,
- bgp_show_type_neighbor);
- return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
- bgp_show_type_neighbor);
- }
- DEFUN (show_ip_bgp_view_rsclient,
- show_ip_bgp_view_rsclient_cmd,
- "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X)",
- SHOW_STR
- IP_STR
- BGP_STR
- "BGP view\n"
- "BGP view name\n"
- "Information about Route Server Client\n"
- NEIGHBOR_ADDR_STR)
- {
- struct bgp_table *table;
- struct peer *peer;
- if (argc == 2)
- peer = peer_lookup_in_view (vty, argv[0], argv[1]);
- else
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
- return CMD_WARNING;
- if (! peer->afc[AFI_IP][SAFI_UNICAST])
- {
- vty_out (vty, "%% Activate the neighbor for the address family first%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- if ( ! CHECK_FLAG (peer->af
|