bgp_routemap.c 117 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691
  1. /* Route map function of bgpd.
  2. Copyright (C) 1998, 1999 Kunihiro Ishiguro
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING. If not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA. */
  16. #include <zebra.h>
  17. #include "prefix.h"
  18. #include "filter.h"
  19. #include "routemap.h"
  20. #include "command.h"
  21. #include "linklist.h"
  22. #include "plist.h"
  23. #include "memory.h"
  24. #include "log.h"
  25. #ifdef HAVE_LIBPCREPOSIX
  26. # include <pcreposix.h>
  27. #else
  28. # ifdef HAVE_GNU_REGEX
  29. # include <regex.h>
  30. # else
  31. # include "regex-gnu.h"
  32. # endif /* HAVE_GNU_REGEX */
  33. #endif /* HAVE_LIBPCREPOSIX */
  34. #include "buffer.h"
  35. #include "sockunion.h"
  36. #include "bgpd/bgpd.h"
  37. #include "bgpd/bgp_table.h"
  38. #include "bgpd/bgp_attr.h"
  39. #include "bgpd/bgp_aspath.h"
  40. #include "bgpd/bgp_route.h"
  41. #include "bgpd/bgp_regex.h"
  42. #include "bgpd/bgp_community.h"
  43. #include "bgpd/bgp_clist.h"
  44. #include "bgpd/bgp_filter.h"
  45. #include "bgpd/bgp_mplsvpn.h"
  46. #include "bgpd/bgp_ecommunity.h"
  47. #include "bgpd/bgp_lcommunity.h"
  48. #include "bgpd/bgp_vty.h"
  49. /* Memo of route-map commands.
  50. o Cisco route-map
  51. match as-path : Done
  52. community : Done
  53. lcommunity : Done
  54. interface : Not yet
  55. ip address : Done
  56. ip next-hop : Done
  57. ip route-source : Done
  58. ip prefix-list : Done
  59. ipv6 address : Done
  60. ipv6 next-hop : Done
  61. ipv6 route-source: (This will not be implemented by bgpd)
  62. ipv6 prefix-list : Done
  63. length : (This will not be implemented by bgpd)
  64. metric : Done
  65. route-type : (This will not be implemented by bgpd)
  66. tag : Done
  67. local-preference : Done
  68. set as-path prepend : Done
  69. as-path tag : Not yet
  70. automatic-tag : (This will not be implemented by bgpd)
  71. community : Done
  72. large-community : Done
  73. large-comm-list : Done
  74. comm-list : Not yet
  75. dampning : Not yet
  76. default : (This will not be implemented by bgpd)
  77. interface : (This will not be implemented by bgpd)
  78. ip default : (This will not be implemented by bgpd)
  79. ip next-hop : Done
  80. ip precedence : (This will not be implemented by bgpd)
  81. ip tos : (This will not be implemented by bgpd)
  82. level : (This will not be implemented by bgpd)
  83. local-preference : Done
  84. metric : Done
  85. metric-type : Not yet
  86. origin : Done
  87. tag : Done
  88. weight : Done
  89. o Local extensions
  90. set ipv6 next-hop global: Done
  91. set ipv6 next-hop local : Done
  92. set as-path exclude : Done
  93. */
  94. /* generic value manipulation to be shared in multiple rules */
  95. #define RMAP_VALUE_SET 0
  96. #define RMAP_VALUE_ADD 1
  97. #define RMAP_VALUE_SUB 2
  98. struct rmap_value
  99. {
  100. u_int8_t action;
  101. u_int8_t variable;
  102. u_int32_t value;
  103. };
  104. static int
  105. route_value_match (struct rmap_value *rv, u_int32_t value)
  106. {
  107. if (rv->variable == 0 && value == rv->value)
  108. return RMAP_MATCH;
  109. return RMAP_NOMATCH;
  110. }
  111. static u_int32_t
  112. route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
  113. {
  114. u_int32_t value;
  115. switch (rv->variable)
  116. {
  117. case 1:
  118. value = peer->rtt;
  119. break;
  120. default:
  121. value = rv->value;
  122. break;
  123. }
  124. switch (rv->action)
  125. {
  126. case RMAP_VALUE_ADD:
  127. if (current > UINT32_MAX-value)
  128. return UINT32_MAX;
  129. return current + value;
  130. case RMAP_VALUE_SUB:
  131. if (current <= value)
  132. return 0;
  133. return current - value;
  134. default:
  135. return value;
  136. }
  137. }
  138. static void *
  139. route_value_compile (const char *arg)
  140. {
  141. u_int8_t action = RMAP_VALUE_SET, var = 0;
  142. unsigned long larg = 0;
  143. char *endptr = NULL;
  144. struct rmap_value *rv;
  145. if (arg[0] == '+')
  146. {
  147. action = RMAP_VALUE_ADD;
  148. arg++;
  149. }
  150. else if (arg[0] == '-')
  151. {
  152. action = RMAP_VALUE_SUB;
  153. arg++;
  154. }
  155. if (all_digit(arg))
  156. {
  157. errno = 0;
  158. larg = strtoul (arg, &endptr, 10);
  159. if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
  160. return NULL;
  161. }
  162. else
  163. {
  164. if (strcmp(arg, "rtt") == 0)
  165. var = 1;
  166. else
  167. return NULL;
  168. }
  169. rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
  170. if (!rv)
  171. return NULL;
  172. rv->action = action;
  173. rv->variable = var;
  174. rv->value = larg;
  175. return rv;
  176. }
  177. static void
  178. route_value_free (void *rule)
  179. {
  180. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  181. }
  182. /* generic as path object to be shared in multiple rules */
  183. static void *
  184. route_aspath_compile (const char *arg)
  185. {
  186. struct aspath *aspath;
  187. aspath = aspath_str2aspath (arg);
  188. if (! aspath)
  189. return NULL;
  190. return aspath;
  191. }
  192. static void
  193. route_aspath_free (void *rule)
  194. {
  195. struct aspath *aspath = rule;
  196. aspath_free (aspath);
  197. }
  198. /* 'match peer (A.B.C.D|X:X::X:X)' */
  199. /* Compares the peer specified in the 'match peer' clause with the peer
  200. received in bgp_info->peer. If it is the same, or if the peer structure
  201. received is a peer_group containing it, returns RMAP_MATCH. */
  202. static route_map_result_t
  203. route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
  204. void *object)
  205. {
  206. union sockunion *su;
  207. union sockunion su_def = { .sin = { .sin_family = AF_INET,
  208. .sin_addr.s_addr = INADDR_ANY } };
  209. struct peer_group *group;
  210. struct peer *peer;
  211. struct listnode *node, *nnode;
  212. if (type == RMAP_BGP)
  213. {
  214. su = rule;
  215. peer = ((struct bgp_info *) object)->peer;
  216. if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
  217. ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
  218. return RMAP_NOMATCH;
  219. /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
  220. REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
  221. if (sockunion_same (su, &su_def))
  222. {
  223. int ret;
  224. if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
  225. CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
  226. CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
  227. ret = RMAP_MATCH;
  228. else
  229. ret = RMAP_NOMATCH;
  230. return ret;
  231. }
  232. if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
  233. {
  234. if (sockunion_same (su, &peer->su))
  235. return RMAP_MATCH;
  236. return RMAP_NOMATCH;
  237. }
  238. else
  239. {
  240. group = peer->group;
  241. for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
  242. {
  243. if (sockunion_same (su, &peer->su))
  244. return RMAP_MATCH;
  245. }
  246. return RMAP_NOMATCH;
  247. }
  248. }
  249. return RMAP_NOMATCH;
  250. }
  251. static void *
  252. route_match_peer_compile (const char *arg)
  253. {
  254. union sockunion *su;
  255. int ret;
  256. su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
  257. ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
  258. if (ret < 0) {
  259. XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
  260. return NULL;
  261. }
  262. return su;
  263. }
  264. /* Free route map's compiled `ip address' value. */
  265. static void
  266. route_match_peer_free (void *rule)
  267. {
  268. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  269. }
  270. /* Route map commands for ip address matching. */
  271. struct route_map_rule_cmd route_match_peer_cmd =
  272. {
  273. "peer",
  274. route_match_peer,
  275. route_match_peer_compile,
  276. route_match_peer_free
  277. };
  278. /* `match ip address IP_ACCESS_LIST' */
  279. /* Match function should return 1 if match is success else return
  280. zero. */
  281. static route_map_result_t
  282. route_match_ip_address (void *rule, struct prefix *prefix,
  283. route_map_object_t type, void *object)
  284. {
  285. struct access_list *alist;
  286. /* struct prefix_ipv4 match; */
  287. if (type == RMAP_BGP)
  288. {
  289. alist = access_list_lookup (AFI_IP, (char *) rule);
  290. if (alist == NULL)
  291. return RMAP_NOMATCH;
  292. return (access_list_apply (alist, prefix) == FILTER_DENY ?
  293. RMAP_NOMATCH : RMAP_MATCH);
  294. }
  295. return RMAP_NOMATCH;
  296. }
  297. /* Route map `ip address' match statement. `arg' should be
  298. access-list name. */
  299. static void *
  300. route_match_ip_address_compile (const char *arg)
  301. {
  302. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  303. }
  304. /* Free route map's compiled `ip address' value. */
  305. static void
  306. route_match_ip_address_free (void *rule)
  307. {
  308. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  309. }
  310. /* Route map commands for ip address matching. */
  311. struct route_map_rule_cmd route_match_ip_address_cmd =
  312. {
  313. "ip address",
  314. route_match_ip_address,
  315. route_match_ip_address_compile,
  316. route_match_ip_address_free
  317. };
  318. /* `match ip next-hop IP_ADDRESS' */
  319. /* Match function return 1 if match is success else return zero. */
  320. static route_map_result_t
  321. route_match_ip_next_hop (void *rule, struct prefix *prefix,
  322. route_map_object_t type, void *object)
  323. {
  324. struct access_list *alist;
  325. struct bgp_info *bgp_info;
  326. struct prefix_ipv4 p;
  327. if (type == RMAP_BGP)
  328. {
  329. bgp_info = object;
  330. p.family = AF_INET;
  331. p.prefix = bgp_info->attr->nexthop;
  332. p.prefixlen = IPV4_MAX_BITLEN;
  333. alist = access_list_lookup (AFI_IP, (char *) rule);
  334. if (alist == NULL)
  335. return RMAP_NOMATCH;
  336. return (access_list_apply (alist, &p) == FILTER_DENY ?
  337. RMAP_NOMATCH : RMAP_MATCH);
  338. }
  339. return RMAP_NOMATCH;
  340. }
  341. /* Route map `ip next-hop' match statement. `arg' is
  342. access-list name. */
  343. static void *
  344. route_match_ip_next_hop_compile (const char *arg)
  345. {
  346. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  347. }
  348. /* Free route map's compiled `ip address' value. */
  349. static void
  350. route_match_ip_next_hop_free (void *rule)
  351. {
  352. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  353. }
  354. /* Route map commands for ip next-hop matching. */
  355. struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  356. {
  357. "ip next-hop",
  358. route_match_ip_next_hop,
  359. route_match_ip_next_hop_compile,
  360. route_match_ip_next_hop_free
  361. };
  362. /* `match ip route-source ACCESS-LIST' */
  363. /* Match function return 1 if match is success else return zero. */
  364. static route_map_result_t
  365. route_match_ip_route_source (void *rule, struct prefix *prefix,
  366. route_map_object_t type, void *object)
  367. {
  368. struct access_list *alist;
  369. struct bgp_info *bgp_info;
  370. struct peer *peer;
  371. struct prefix_ipv4 p;
  372. if (type == RMAP_BGP)
  373. {
  374. bgp_info = object;
  375. peer = bgp_info->peer;
  376. if (! peer || sockunion_family (&peer->su) != AF_INET)
  377. return RMAP_NOMATCH;
  378. p.family = AF_INET;
  379. p.prefix = peer->su.sin.sin_addr;
  380. p.prefixlen = IPV4_MAX_BITLEN;
  381. alist = access_list_lookup (AFI_IP, (char *) rule);
  382. if (alist == NULL)
  383. return RMAP_NOMATCH;
  384. return (access_list_apply (alist, &p) == FILTER_DENY ?
  385. RMAP_NOMATCH : RMAP_MATCH);
  386. }
  387. return RMAP_NOMATCH;
  388. }
  389. /* Route map `ip route-source' match statement. `arg' is
  390. access-list name. */
  391. static void *
  392. route_match_ip_route_source_compile (const char *arg)
  393. {
  394. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  395. }
  396. /* Free route map's compiled `ip address' value. */
  397. static void
  398. route_match_ip_route_source_free (void *rule)
  399. {
  400. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  401. }
  402. /* Route map commands for ip route-source matching. */
  403. struct route_map_rule_cmd route_match_ip_route_source_cmd =
  404. {
  405. "ip route-source",
  406. route_match_ip_route_source,
  407. route_match_ip_route_source_compile,
  408. route_match_ip_route_source_free
  409. };
  410. /* `match ip address prefix-list PREFIX_LIST' */
  411. static route_map_result_t
  412. route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
  413. route_map_object_t type, void *object)
  414. {
  415. struct prefix_list *plist;
  416. if (type == RMAP_BGP)
  417. {
  418. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  419. if (plist == NULL)
  420. return RMAP_NOMATCH;
  421. return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  422. RMAP_NOMATCH : RMAP_MATCH);
  423. }
  424. return RMAP_NOMATCH;
  425. }
  426. static void *
  427. route_match_ip_address_prefix_list_compile (const char *arg)
  428. {
  429. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  430. }
  431. static void
  432. route_match_ip_address_prefix_list_free (void *rule)
  433. {
  434. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  435. }
  436. struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  437. {
  438. "ip address prefix-list",
  439. route_match_ip_address_prefix_list,
  440. route_match_ip_address_prefix_list_compile,
  441. route_match_ip_address_prefix_list_free
  442. };
  443. /* `match ip next-hop prefix-list PREFIX_LIST' */
  444. static route_map_result_t
  445. route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  446. route_map_object_t type, void *object)
  447. {
  448. struct prefix_list *plist;
  449. struct bgp_info *bgp_info;
  450. struct prefix_ipv4 p;
  451. if (type == RMAP_BGP)
  452. {
  453. bgp_info = object;
  454. p.family = AF_INET;
  455. p.prefix = bgp_info->attr->nexthop;
  456. p.prefixlen = IPV4_MAX_BITLEN;
  457. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  458. if (plist == NULL)
  459. return RMAP_NOMATCH;
  460. return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  461. RMAP_NOMATCH : RMAP_MATCH);
  462. }
  463. return RMAP_NOMATCH;
  464. }
  465. static void *
  466. route_match_ip_next_hop_prefix_list_compile (const char *arg)
  467. {
  468. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  469. }
  470. static void
  471. route_match_ip_next_hop_prefix_list_free (void *rule)
  472. {
  473. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  474. }
  475. struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  476. {
  477. "ip next-hop prefix-list",
  478. route_match_ip_next_hop_prefix_list,
  479. route_match_ip_next_hop_prefix_list_compile,
  480. route_match_ip_next_hop_prefix_list_free
  481. };
  482. /* `match ip route-source prefix-list PREFIX_LIST' */
  483. static route_map_result_t
  484. route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
  485. route_map_object_t type, void *object)
  486. {
  487. struct prefix_list *plist;
  488. struct bgp_info *bgp_info;
  489. struct peer *peer;
  490. struct prefix_ipv4 p;
  491. if (type == RMAP_BGP)
  492. {
  493. bgp_info = object;
  494. peer = bgp_info->peer;
  495. if (! peer || sockunion_family (&peer->su) != AF_INET)
  496. return RMAP_NOMATCH;
  497. p.family = AF_INET;
  498. p.prefix = peer->su.sin.sin_addr;
  499. p.prefixlen = IPV4_MAX_BITLEN;
  500. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  501. if (plist == NULL)
  502. return RMAP_NOMATCH;
  503. return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  504. RMAP_NOMATCH : RMAP_MATCH);
  505. }
  506. return RMAP_NOMATCH;
  507. }
  508. static void *
  509. route_match_ip_route_source_prefix_list_compile (const char *arg)
  510. {
  511. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  512. }
  513. static void
  514. route_match_ip_route_source_prefix_list_free (void *rule)
  515. {
  516. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  517. }
  518. struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
  519. {
  520. "ip route-source prefix-list",
  521. route_match_ip_route_source_prefix_list,
  522. route_match_ip_route_source_prefix_list_compile,
  523. route_match_ip_route_source_prefix_list_free
  524. };
  525. /* `match local-preference LOCAL-PREF' */
  526. /* Match function return 1 if match is success else return zero. */
  527. static route_map_result_t
  528. route_match_local_pref (void *rule, struct prefix *prefix,
  529. route_map_object_t type, void *object)
  530. {
  531. u_int32_t *local_pref;
  532. struct bgp_info *bgp_info;
  533. if (type == RMAP_BGP)
  534. {
  535. local_pref = rule;
  536. bgp_info = object;
  537. if (bgp_info->attr->local_pref == *local_pref)
  538. return RMAP_MATCH;
  539. else
  540. return RMAP_NOMATCH;
  541. }
  542. return RMAP_NOMATCH;
  543. }
  544. /* Route map `match local-preference' match statement.
  545. `arg' is local-pref value */
  546. static void *
  547. route_match_local_pref_compile (const char *arg)
  548. {
  549. u_int32_t *local_pref;
  550. char *endptr = NULL;
  551. unsigned long tmpval;
  552. /* Locpref value shoud be integer. */
  553. if (! all_digit (arg))
  554. return NULL;
  555. errno = 0;
  556. tmpval = strtoul (arg, &endptr, 10);
  557. if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
  558. return NULL;
  559. local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  560. if (!local_pref)
  561. return local_pref;
  562. *local_pref = tmpval;
  563. return local_pref;
  564. }
  565. /* Free route map's compiled `match local-preference' value. */
  566. static void
  567. route_match_local_pref_free (void *rule)
  568. {
  569. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  570. }
  571. /* Route map commands for metric matching. */
  572. struct route_map_rule_cmd route_match_local_pref_cmd =
  573. {
  574. "local-preference",
  575. route_match_local_pref,
  576. route_match_local_pref_compile,
  577. route_match_local_pref_free
  578. };
  579. /* `match metric METRIC' */
  580. /* Match function return 1 if match is success else return zero. */
  581. static route_map_result_t
  582. route_match_metric (void *rule, struct prefix *prefix,
  583. route_map_object_t type, void *object)
  584. {
  585. struct rmap_value *rv;
  586. struct bgp_info *bgp_info;
  587. if (type == RMAP_BGP)
  588. {
  589. rv = rule;
  590. bgp_info = object;
  591. return route_value_match(rv, bgp_info->attr->med);
  592. }
  593. return RMAP_NOMATCH;
  594. }
  595. /* Route map commands for metric matching. */
  596. struct route_map_rule_cmd route_match_metric_cmd =
  597. {
  598. "metric",
  599. route_match_metric,
  600. route_value_compile,
  601. route_value_free,
  602. };
  603. /* `match as-path ASPATH' */
  604. /* Match function for as-path match. I assume given object is */
  605. static route_map_result_t
  606. route_match_aspath (void *rule, struct prefix *prefix,
  607. route_map_object_t type, void *object)
  608. {
  609. struct as_list *as_list;
  610. struct bgp_info *bgp_info;
  611. if (type == RMAP_BGP)
  612. {
  613. as_list = as_list_lookup ((char *) rule);
  614. if (as_list == NULL)
  615. return RMAP_NOMATCH;
  616. bgp_info = object;
  617. /* Perform match. */
  618. return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
  619. }
  620. return RMAP_NOMATCH;
  621. }
  622. /* Compile function for as-path match. */
  623. static void *
  624. route_match_aspath_compile (const char *arg)
  625. {
  626. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  627. }
  628. /* Compile function for as-path match. */
  629. static void
  630. route_match_aspath_free (void *rule)
  631. {
  632. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  633. }
  634. /* Route map commands for aspath matching. */
  635. struct route_map_rule_cmd route_match_aspath_cmd =
  636. {
  637. "as-path",
  638. route_match_aspath,
  639. route_match_aspath_compile,
  640. route_match_aspath_free
  641. };
  642. /* `match community COMMUNIY' */
  643. struct rmap_community
  644. {
  645. char *name;
  646. int exact;
  647. };
  648. /* Match function for community match. */
  649. static route_map_result_t
  650. route_match_community (void *rule, struct prefix *prefix,
  651. route_map_object_t type, void *object)
  652. {
  653. struct community_list *list;
  654. struct bgp_info *bgp_info;
  655. struct rmap_community *rcom;
  656. if (type == RMAP_BGP)
  657. {
  658. bgp_info = object;
  659. rcom = rule;
  660. list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
  661. if (! list)
  662. return RMAP_NOMATCH;
  663. if (rcom->exact)
  664. {
  665. if (community_list_exact_match (bgp_info->attr->community, list))
  666. return RMAP_MATCH;
  667. }
  668. else
  669. {
  670. if (community_list_match (bgp_info->attr->community, list))
  671. return RMAP_MATCH;
  672. }
  673. }
  674. return RMAP_NOMATCH;
  675. }
  676. /* Compile function for community match. */
  677. static void *
  678. route_match_community_compile (const char *arg)
  679. {
  680. struct rmap_community *rcom;
  681. int len;
  682. char *p;
  683. rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
  684. p = strchr (arg, ' ');
  685. if (p)
  686. {
  687. len = p - arg;
  688. rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  689. memcpy (rcom->name, arg, len);
  690. rcom->exact = 1;
  691. }
  692. else
  693. {
  694. rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  695. rcom->exact = 0;
  696. }
  697. return rcom;
  698. }
  699. /* Compile function for community match. */
  700. static void
  701. route_match_community_free (void *rule)
  702. {
  703. struct rmap_community *rcom = rule;
  704. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
  705. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
  706. }
  707. /* Route map commands for community matching. */
  708. struct route_map_rule_cmd route_match_community_cmd =
  709. {
  710. "community",
  711. route_match_community,
  712. route_match_community_compile,
  713. route_match_community_free
  714. };
  715. /* Match function for lcommunity match. */
  716. static route_map_result_t
  717. route_match_lcommunity (void *rule, struct prefix *prefix,
  718. route_map_object_t type, void *object)
  719. {
  720. struct community_list *list;
  721. struct bgp_info *bgp_info;
  722. struct rmap_community *rcom;
  723. if (type == RMAP_BGP)
  724. {
  725. bgp_info = object;
  726. rcom = rule;
  727. list = community_list_lookup (bgp_clist, rcom->name,
  728. LARGE_COMMUNITY_LIST_MASTER);
  729. if (! list)
  730. return RMAP_NOMATCH;
  731. if (bgp_info->attr->extra &&
  732. lcommunity_list_match (bgp_info->attr->extra->lcommunity, list))
  733. return RMAP_MATCH;
  734. }
  735. return RMAP_NOMATCH;
  736. }
  737. /* Compile function for community match. */
  738. static void *
  739. route_match_lcommunity_compile (const char *arg)
  740. {
  741. struct rmap_community *rcom;
  742. int len;
  743. char *p;
  744. rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
  745. p = strchr (arg, ' ');
  746. if (p)
  747. {
  748. len = p - arg;
  749. rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  750. memcpy (rcom->name, arg, len);
  751. }
  752. else
  753. {
  754. rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  755. rcom->exact = 0;
  756. }
  757. return rcom;
  758. }
  759. /* Compile function for community match. */
  760. static void
  761. route_match_lcommunity_free (void *rule)
  762. {
  763. struct rmap_community *rcom = rule;
  764. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
  765. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
  766. }
  767. /* Route map commands for community matching. */
  768. struct route_map_rule_cmd route_match_lcommunity_cmd =
  769. {
  770. "large-community",
  771. route_match_lcommunity,
  772. route_match_lcommunity_compile,
  773. route_match_lcommunity_free
  774. };
  775. /* Match function for extcommunity match. */
  776. static route_map_result_t
  777. route_match_ecommunity (void *rule, struct prefix *prefix,
  778. route_map_object_t type, void *object)
  779. {
  780. struct community_list *list;
  781. struct bgp_info *bgp_info;
  782. if (type == RMAP_BGP)
  783. {
  784. bgp_info = object;
  785. if (!bgp_info->attr->extra)
  786. return RMAP_NOMATCH;
  787. list = community_list_lookup (bgp_clist, (char *) rule,
  788. EXTCOMMUNITY_LIST_MASTER);
  789. if (! list)
  790. return RMAP_NOMATCH;
  791. if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
  792. return RMAP_MATCH;
  793. }
  794. return RMAP_NOMATCH;
  795. }
  796. /* Compile function for extcommunity match. */
  797. static void *
  798. route_match_ecommunity_compile (const char *arg)
  799. {
  800. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  801. }
  802. /* Compile function for extcommunity match. */
  803. static void
  804. route_match_ecommunity_free (void *rule)
  805. {
  806. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  807. }
  808. /* Route map commands for community matching. */
  809. struct route_map_rule_cmd route_match_ecommunity_cmd =
  810. {
  811. "extcommunity",
  812. route_match_ecommunity,
  813. route_match_ecommunity_compile,
  814. route_match_ecommunity_free
  815. };
  816. /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
  817. and `address-family vpnv4'. */
  818. /* `match origin' */
  819. static route_map_result_t
  820. route_match_origin (void *rule, struct prefix *prefix,
  821. route_map_object_t type, void *object)
  822. {
  823. u_char *origin;
  824. struct bgp_info *bgp_info;
  825. if (type == RMAP_BGP)
  826. {
  827. origin = rule;
  828. bgp_info = object;
  829. if (bgp_info->attr->origin == *origin)
  830. return RMAP_MATCH;
  831. }
  832. return RMAP_NOMATCH;
  833. }
  834. static void *
  835. route_match_origin_compile (const char *arg)
  836. {
  837. u_char *origin;
  838. origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
  839. if (strcmp (arg, "igp") == 0)
  840. *origin = 0;
  841. else if (strcmp (arg, "egp") == 0)
  842. *origin = 1;
  843. else
  844. *origin = 2;
  845. return origin;
  846. }
  847. /* Free route map's compiled `ip address' value. */
  848. static void
  849. route_match_origin_free (void *rule)
  850. {
  851. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  852. }
  853. /* Route map commands for origin matching. */
  854. struct route_map_rule_cmd route_match_origin_cmd =
  855. {
  856. "origin",
  857. route_match_origin,
  858. route_match_origin_compile,
  859. route_match_origin_free
  860. };
  861. /* match probability { */
  862. static route_map_result_t
  863. route_match_probability (void *rule, struct prefix *prefix,
  864. route_map_object_t type, void *object)
  865. {
  866. long r = random();
  867. switch (*(long *) rule)
  868. {
  869. case 0: break;
  870. case RAND_MAX: return RMAP_MATCH;
  871. default:
  872. if (r < *(long *) rule)
  873. {
  874. return RMAP_MATCH;
  875. }
  876. }
  877. return RMAP_NOMATCH;
  878. }
  879. static void *
  880. route_match_probability_compile (const char *arg)
  881. {
  882. long *lobule;
  883. unsigned perc;
  884. perc = atoi (arg);
  885. lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
  886. switch (perc)
  887. {
  888. case 0: *lobule = 0; break;
  889. case 100: *lobule = RAND_MAX; break;
  890. default: *lobule = RAND_MAX / 100 * perc;
  891. }
  892. return lobule;
  893. }
  894. static void
  895. route_match_probability_free (void *rule)
  896. {
  897. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  898. }
  899. struct route_map_rule_cmd route_match_probability_cmd =
  900. {
  901. "probability",
  902. route_match_probability,
  903. route_match_probability_compile,
  904. route_match_probability_free
  905. };
  906. /* } */
  907. /* `set ip next-hop IP_ADDRESS' */
  908. /* Match function return 1 if match is success else return zero. */
  909. static route_map_result_t
  910. route_match_tag (void *rule, struct prefix *prefix,
  911. route_map_object_t type, void *object)
  912. {
  913. route_tag_t *tag;
  914. struct bgp_info *bgp_info;
  915. if (type == RMAP_BGP)
  916. {
  917. tag = rule;
  918. bgp_info = object;
  919. if (!bgp_info->attr->extra)
  920. return RMAP_NOMATCH;
  921. return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
  922. }
  923. return RMAP_NOMATCH;
  924. }
  925. /* Route map commands for tag matching. */
  926. static struct route_map_rule_cmd route_match_tag_cmd =
  927. {
  928. "tag",
  929. route_match_tag,
  930. route_map_rule_tag_compile,
  931. route_map_rule_tag_free,
  932. };
  933. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  934. struct rmap_ip_nexthop_set
  935. {
  936. struct in_addr *address;
  937. int peer_address;
  938. };
  939. static route_map_result_t
  940. route_set_ip_nexthop (void *rule, struct prefix *prefix,
  941. route_map_object_t type, void *object)
  942. {
  943. struct rmap_ip_nexthop_set *rins = rule;
  944. struct bgp_info *bgp_info;
  945. struct peer *peer;
  946. if (type == RMAP_BGP)
  947. {
  948. bgp_info = object;
  949. peer = bgp_info->peer;
  950. if (rins->peer_address)
  951. {
  952. if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
  953. CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
  954. && peer->su_remote
  955. && sockunion_family (peer->su_remote) == AF_INET)
  956. {
  957. bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
  958. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  959. }
  960. else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
  961. && peer->su_local
  962. && sockunion_family (peer->su_local) == AF_INET)
  963. {
  964. bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
  965. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  966. }
  967. }
  968. else
  969. {
  970. /* Set next hop value. */
  971. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  972. bgp_info->attr->nexthop = *rins->address;
  973. }
  974. }
  975. return RMAP_OKAY;
  976. }
  977. /* Route map `ip nexthop' compile function. Given string is converted
  978. to struct in_addr structure. */
  979. static void *
  980. route_set_ip_nexthop_compile (const char *arg)
  981. {
  982. struct rmap_ip_nexthop_set *rins;
  983. struct in_addr *address = NULL;
  984. int peer_address = 0;
  985. int ret;
  986. if (strcmp (arg, "peer-address") == 0)
  987. peer_address = 1;
  988. else
  989. {
  990. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  991. ret = inet_aton (arg, address);
  992. if (ret == 0)
  993. {
  994. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  995. return NULL;
  996. }
  997. }
  998. rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
  999. rins->address = address;
  1000. rins->peer_address = peer_address;
  1001. return rins;
  1002. }
  1003. /* Free route map's compiled `ip nexthop' value. */
  1004. static void
  1005. route_set_ip_nexthop_free (void *rule)
  1006. {
  1007. struct rmap_ip_nexthop_set *rins = rule;
  1008. if (rins->address)
  1009. XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
  1010. XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
  1011. }
  1012. /* Route map commands for ip nexthop set. */
  1013. struct route_map_rule_cmd route_set_ip_nexthop_cmd =
  1014. {
  1015. "ip next-hop",
  1016. route_set_ip_nexthop,
  1017. route_set_ip_nexthop_compile,
  1018. route_set_ip_nexthop_free
  1019. };
  1020. /* `set local-preference LOCAL_PREF' */
  1021. /* Set local preference. */
  1022. static route_map_result_t
  1023. route_set_local_pref (void *rule, struct prefix *prefix,
  1024. route_map_object_t type, void *object)
  1025. {
  1026. struct rmap_value *rv;
  1027. struct bgp_info *bgp_info;
  1028. u_int32_t locpref = 0;
  1029. if (type == RMAP_BGP)
  1030. {
  1031. /* Fetch routemap's rule information. */
  1032. rv = rule;
  1033. bgp_info = object;
  1034. /* Set local preference value. */
  1035. if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
  1036. locpref = bgp_info->attr->local_pref;
  1037. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
  1038. bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
  1039. }
  1040. return RMAP_OKAY;
  1041. }
  1042. /* Set local preference rule structure. */
  1043. struct route_map_rule_cmd route_set_local_pref_cmd =
  1044. {
  1045. "local-preference",
  1046. route_set_local_pref,
  1047. route_value_compile,
  1048. route_value_free,
  1049. };
  1050. /* `set weight WEIGHT' */
  1051. /* Set weight. */
  1052. static route_map_result_t
  1053. route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
  1054. void *object)
  1055. {
  1056. struct rmap_value *rv;
  1057. struct bgp_info *bgp_info;
  1058. u_int32_t weight;
  1059. if (type == RMAP_BGP)
  1060. {
  1061. /* Fetch routemap's rule information. */
  1062. rv = rule;
  1063. bgp_info = object;
  1064. /* Set weight value. */
  1065. weight = route_value_adjust(rv, 0, bgp_info->peer);
  1066. if (weight)
  1067. (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
  1068. else if (bgp_info->attr->extra)
  1069. bgp_info->attr->extra->weight = 0;
  1070. }
  1071. return RMAP_OKAY;
  1072. }
  1073. /* Set local preference rule structure. */
  1074. struct route_map_rule_cmd route_set_weight_cmd =
  1075. {
  1076. "weight",
  1077. route_set_weight,
  1078. route_value_compile,
  1079. route_value_free,
  1080. };
  1081. /* `set metric METRIC' */
  1082. /* Set metric to attribute. */
  1083. static route_map_result_t
  1084. route_set_metric (void *rule, struct prefix *prefix,
  1085. route_map_object_t type, void *object)
  1086. {
  1087. struct rmap_value *rv;
  1088. struct bgp_info *bgp_info;
  1089. u_int32_t med = 0;
  1090. if (type == RMAP_BGP)
  1091. {
  1092. /* Fetch routemap's rule information. */
  1093. rv = rule;
  1094. bgp_info = object;
  1095. if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
  1096. med = bgp_info->attr->med;
  1097. bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
  1098. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
  1099. }
  1100. return RMAP_OKAY;
  1101. }
  1102. /* Set metric rule structure. */
  1103. struct route_map_rule_cmd route_set_metric_cmd =
  1104. {
  1105. "metric",
  1106. route_set_metric,
  1107. route_value_compile,
  1108. route_value_free,
  1109. };
  1110. /* `set as-path prepend ASPATH' */
  1111. /* For AS path prepend mechanism. */
  1112. static route_map_result_t
  1113. route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  1114. {
  1115. struct aspath *aspath;
  1116. struct aspath *new;
  1117. struct bgp_info *binfo;
  1118. if (type == RMAP_BGP)
  1119. {
  1120. binfo = object;
  1121. if (binfo->attr->aspath->refcnt)
  1122. new = aspath_dup (binfo->attr->aspath);
  1123. else
  1124. new = binfo->attr->aspath;
  1125. if ((uintptr_t)rule > 10)
  1126. {
  1127. aspath = rule;
  1128. aspath_prepend (aspath, new);
  1129. }
  1130. else
  1131. {
  1132. as_t as = aspath_leftmost(new);
  1133. if (!as) as = binfo->peer->as;
  1134. new = aspath_add_seq_n (new, as, (uintptr_t) rule);
  1135. }
  1136. binfo->attr->aspath = new;
  1137. }
  1138. return RMAP_OKAY;
  1139. }
  1140. static void *
  1141. route_set_aspath_prepend_compile (const char *arg)
  1142. {
  1143. unsigned int num;
  1144. if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
  1145. return (void*)(uintptr_t)num;
  1146. return route_aspath_compile(arg);
  1147. }
  1148. static void
  1149. route_set_aspath_prepend_free (void *rule)
  1150. {
  1151. if ((uintptr_t)rule > 10)
  1152. route_aspath_free(rule);
  1153. }
  1154. /* Set as-path prepend rule structure. */
  1155. struct route_map_rule_cmd route_set_aspath_prepend_cmd =
  1156. {
  1157. "as-path prepend",
  1158. route_set_aspath_prepend,
  1159. route_set_aspath_prepend_compile,
  1160. route_set_aspath_prepend_free,
  1161. };
  1162. /* `set as-path exclude ASn' */
  1163. /* For ASN exclude mechanism.
  1164. * Iterate over ASns requested and filter them from the given AS_PATH one by one.
  1165. * Make a deep copy of existing AS_PATH, but for the first ASn only.
  1166. */
  1167. static route_map_result_t
  1168. route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
  1169. {
  1170. struct aspath * new_path, * exclude_path;
  1171. struct bgp_info *binfo;
  1172. if (type == RMAP_BGP)
  1173. {
  1174. exclude_path = rule;
  1175. binfo = object;
  1176. if (binfo->attr->aspath->refcnt)
  1177. new_path = aspath_dup (binfo->attr->aspath);
  1178. else
  1179. new_path = binfo->attr->aspath;
  1180. binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
  1181. }
  1182. return RMAP_OKAY;
  1183. }
  1184. /* Set ASn exlude rule structure. */
  1185. struct route_map_rule_cmd route_set_aspath_exclude_cmd =
  1186. {
  1187. "as-path exclude",
  1188. route_set_aspath_exclude,
  1189. route_aspath_compile,
  1190. route_aspath_free,
  1191. };
  1192. /* `set community COMMUNITY' */
  1193. struct rmap_com_set
  1194. {
  1195. struct community *com;
  1196. int additive;
  1197. int none;
  1198. };
  1199. /* For community set mechanism. */
  1200. static route_map_result_t
  1201. route_set_community (void *rule, struct prefix *prefix,
  1202. route_map_object_t type, void *object)
  1203. {
  1204. struct rmap_com_set *rcs;
  1205. struct bgp_info *binfo;
  1206. struct attr *attr;
  1207. struct community *new = NULL;
  1208. struct community *old;
  1209. struct community *merge;
  1210. if (type == RMAP_BGP)
  1211. {
  1212. rcs = rule;
  1213. binfo = object;
  1214. attr = binfo->attr;
  1215. old = attr->community;
  1216. /* "none" case. */
  1217. if (rcs->none)
  1218. {
  1219. attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
  1220. attr->community = NULL;
  1221. /* See the longer comment down below. */
  1222. if (old && old->refcnt == 0)
  1223. community_free(old);
  1224. return RMAP_OKAY;
  1225. }
  1226. /* "additive" case. */
  1227. if (rcs->additive && old)
  1228. {
  1229. merge = community_merge (community_dup (old), rcs->com);
  1230. /* HACK: if the old community is not intern'd,
  1231. * we should free it here, or all reference to it may be lost.
  1232. * Really need to cleanup attribute caching sometime.
  1233. */
  1234. if (old->refcnt == 0)
  1235. community_free (old);
  1236. new = community_uniq_sort (merge);
  1237. community_free (merge);
  1238. }
  1239. else
  1240. new = community_dup (rcs->com);
  1241. /* will be interned by caller if required */
  1242. attr->community = new;
  1243. attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  1244. }
  1245. return RMAP_OKAY;
  1246. }
  1247. /* Compile function for set community. */
  1248. static void *
  1249. route_set_community_compile (const char *arg)
  1250. {
  1251. struct rmap_com_set *rcs;
  1252. struct community *com = NULL;
  1253. char *sp;
  1254. int additive = 0;
  1255. int none = 0;
  1256. if (strcmp (arg, "none") == 0)
  1257. none = 1;
  1258. else
  1259. {
  1260. sp = strstr (arg, "additive");
  1261. if (sp && sp > arg)
  1262. {
  1263. /* "additive" keyworkd is included. */
  1264. additive = 1;
  1265. *(sp - 1) = '\0';
  1266. }
  1267. com = community_str2com (arg);
  1268. if (additive)
  1269. *(sp - 1) = ' ';
  1270. if (! com)
  1271. return NULL;
  1272. }
  1273. rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
  1274. rcs->com = com;
  1275. rcs->additive = additive;
  1276. rcs->none = none;
  1277. return rcs;
  1278. }
  1279. /* Free function for set community. */
  1280. static void
  1281. route_set_community_free (void *rule)
  1282. {
  1283. struct rmap_com_set *rcs = rule;
  1284. if (rcs->com)
  1285. community_free (rcs->com);
  1286. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
  1287. }
  1288. /* Set community rule structure. */
  1289. struct route_map_rule_cmd route_set_community_cmd =
  1290. {
  1291. "community",
  1292. route_set_community,
  1293. route_set_community_compile,
  1294. route_set_community_free,
  1295. };
  1296. /* `set community COMMUNITY' */
  1297. struct rmap_lcom_set
  1298. {
  1299. struct lcommunity *lcom;
  1300. int additive;
  1301. int none;
  1302. };
  1303. /* For lcommunity set mechanism. */
  1304. static route_map_result_t
  1305. route_set_lcommunity (void *rule, struct prefix *prefix,
  1306. route_map_object_t type, void *object)
  1307. {
  1308. struct rmap_lcom_set *rcs;
  1309. struct bgp_info *binfo;
  1310. struct attr *attr;
  1311. struct lcommunity *new = NULL;
  1312. struct lcommunity *old;
  1313. struct lcommunity *merge;
  1314. if (type == RMAP_BGP)
  1315. {
  1316. rcs = rule;
  1317. binfo = object;
  1318. attr = binfo->attr;
  1319. old = (attr->extra) ? attr->extra->lcommunity : NULL;
  1320. /* "none" case. */
  1321. if (rcs->none)
  1322. {
  1323. attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
  1324. if (attr->extra) {
  1325. attr->extra->lcommunity = NULL;
  1326. }
  1327. /* See the longer comment down below. */
  1328. if (old && old->refcnt == 0)
  1329. lcommunity_free(&old);
  1330. return RMAP_OKAY;
  1331. }
  1332. if (rcs->additive && old)
  1333. {
  1334. merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom);
  1335. /* HACK: if the old large-community is not intern'd,
  1336. * we should free it here, or all reference to it may be lost.
  1337. * Really need to cleanup attribute caching sometime.
  1338. */
  1339. if (old->refcnt == 0)
  1340. lcommunity_free (&old);
  1341. new = lcommunity_uniq_sort (merge);
  1342. lcommunity_free (&merge);
  1343. }
  1344. else
  1345. {
  1346. new = lcommunity_dup (rcs->lcom);
  1347. }
  1348. /* will be interned by caller if required */
  1349. bgp_attr_extra_get (attr)->lcommunity = new;
  1350. attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
  1351. }
  1352. return RMAP_OKAY;
  1353. }
  1354. /* Compile function for set community. */
  1355. static void *
  1356. route_set_lcommunity_compile (const char *arg)
  1357. {
  1358. struct rmap_lcom_set *rcs;
  1359. struct lcommunity *lcom = NULL;
  1360. char *sp;
  1361. int additive = 0;
  1362. int none = 0;
  1363. if (strcmp (arg, "none") == 0)
  1364. none = 1;
  1365. else
  1366. {
  1367. sp = strstr (arg, "additive");
  1368. if (sp && sp > arg)
  1369. {
  1370. /* "additive" keyworkd is included. */
  1371. additive = 1;
  1372. *(sp - 1) = '\0';
  1373. }
  1374. lcom = lcommunity_str2com (arg);
  1375. if (additive)
  1376. *(sp - 1) = ' ';
  1377. if (! lcom)
  1378. return NULL;
  1379. }
  1380. rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
  1381. rcs->lcom = lcom;
  1382. rcs->additive = additive;
  1383. rcs->none = none;
  1384. return rcs;
  1385. }
  1386. /* Free function for set lcommunity. */
  1387. static void
  1388. route_set_lcommunity_free (void *rule)
  1389. {
  1390. struct rmap_lcom_set *rcs = rule;
  1391. if (rcs->lcom) {
  1392. lcommunity_free (&rcs->lcom);
  1393. }
  1394. XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
  1395. }
  1396. /* Set community rule structure. */
  1397. struct route_map_rule_cmd route_set_lcommunity_cmd =
  1398. {
  1399. "large-community",
  1400. route_set_lcommunity,
  1401. route_set_lcommunity_compile,
  1402. route_set_lcommunity_free,
  1403. };
  1404. /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
  1405. /* For large community set mechanism. */
  1406. static route_map_result_t
  1407. route_set_lcommunity_delete (void *rule, struct prefix *prefix,
  1408. route_map_object_t type, void *object)
  1409. {
  1410. struct community_list *list;
  1411. struct lcommunity *merge;
  1412. struct lcommunity *new;
  1413. struct lcommunity *old;
  1414. struct bgp_info *binfo;
  1415. if (type == RMAP_BGP)
  1416. {
  1417. if (! rule)
  1418. return RMAP_OKAY;
  1419. binfo = object;
  1420. list = community_list_lookup (bgp_clist, rule,
  1421. LARGE_COMMUNITY_LIST_MASTER);
  1422. old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL);
  1423. if (list && old)
  1424. {
  1425. merge = lcommunity_list_match_delete (lcommunity_dup (old), list);
  1426. new = lcommunity_uniq_sort (merge);
  1427. lcommunity_free (&merge);
  1428. /* HACK: if the old community is not intern'd,
  1429. * we should free it here, or all reference to it may be lost.
  1430. * Really need to cleanup attribute caching sometime.
  1431. */
  1432. if (old->refcnt == 0)
  1433. lcommunity_free (&old);
  1434. if (new->size == 0)
  1435. {
  1436. binfo->attr->extra->lcommunity = NULL;
  1437. binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
  1438. lcommunity_free (&new);
  1439. }
  1440. else
  1441. {
  1442. binfo->attr->extra->lcommunity = new;
  1443. binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
  1444. }
  1445. }
  1446. }
  1447. return RMAP_OKAY;
  1448. }
  1449. /* Compile function for set lcommunity. */
  1450. static void *
  1451. route_set_lcommunity_delete_compile (const char *arg)
  1452. {
  1453. char *p;
  1454. char *str;
  1455. int len;
  1456. p = strchr (arg, ' ');
  1457. if (p)
  1458. {
  1459. len = p - arg;
  1460. str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  1461. memcpy (str, arg, len);
  1462. }
  1463. else
  1464. str = NULL;
  1465. return str;
  1466. }
  1467. /* Free function for set lcommunity. */
  1468. static void
  1469. route_set_lcommunity_delete_free (void *rule)
  1470. {
  1471. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1472. }
  1473. /* Set lcommunity rule structure. */
  1474. struct route_map_rule_cmd route_set_lcommunity_delete_cmd =
  1475. {
  1476. "large-comm-list",
  1477. route_set_lcommunity_delete,
  1478. route_set_lcommunity_delete_compile,
  1479. route_set_lcommunity_delete_free,
  1480. };
  1481. /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
  1482. /* For community set mechanism. */
  1483. static route_map_result_t
  1484. route_set_community_delete (void *rule, struct prefix *prefix,
  1485. route_map_object_t type, void *object)
  1486. {
  1487. struct community_list *list;
  1488. struct community *merge;
  1489. struct community *new;
  1490. struct community *old;
  1491. struct bgp_info *binfo;
  1492. if (type == RMAP_BGP)
  1493. {
  1494. if (! rule)
  1495. return RMAP_OKAY;
  1496. binfo = object;
  1497. list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
  1498. old = binfo->attr->community;
  1499. if (list && old)
  1500. {
  1501. merge = community_list_match_delete (community_dup (old), list);
  1502. new = community_uniq_sort (merge);
  1503. community_free (merge);
  1504. /* HACK: if the old community is not intern'd,
  1505. * we should free it here, or all reference to it may be lost.
  1506. * Really need to cleanup attribute caching sometime.
  1507. */
  1508. if (old->refcnt == 0)
  1509. community_free (old);
  1510. if (new->size == 0)
  1511. {
  1512. binfo->attr->community = NULL;
  1513. binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  1514. community_free (new);
  1515. }
  1516. else
  1517. {
  1518. binfo->attr->community = new;
  1519. binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  1520. }
  1521. }
  1522. }
  1523. return RMAP_OKAY;
  1524. }
  1525. /* Compile function for set community. */
  1526. static void *
  1527. route_set_community_delete_compile (const char *arg)
  1528. {
  1529. char *p;
  1530. char *str;
  1531. int len;
  1532. p = strchr (arg, ' ');
  1533. if (p)
  1534. {
  1535. len = p - arg;
  1536. str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  1537. memcpy (str, arg, len);
  1538. }
  1539. else
  1540. str = NULL;
  1541. return str;
  1542. }
  1543. /* Free function for set community. */
  1544. static void
  1545. route_set_community_delete_free (void *rule)
  1546. {
  1547. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1548. }
  1549. /* Set community rule structure. */
  1550. struct route_map_rule_cmd route_set_community_delete_cmd =
  1551. {
  1552. "comm-list",
  1553. route_set_community_delete,
  1554. route_set_community_delete_compile,
  1555. route_set_community_delete_free,
  1556. };
  1557. /* `set extcommunity rt COMMUNITY' */
  1558. /* For community set mechanism. Used by _rt and _soo. */
  1559. static route_map_result_t
  1560. route_set_ecommunity (void *rule, struct prefix *prefix,
  1561. route_map_object_t type, void *object)
  1562. {
  1563. struct ecommunity *ecom;
  1564. struct ecommunity *new_ecom;
  1565. struct ecommunity *old_ecom;
  1566. struct bgp_info *bgp_info;
  1567. if (type == RMAP_BGP)
  1568. {
  1569. ecom = rule;
  1570. bgp_info = object;
  1571. if (! ecom)
  1572. return RMAP_OKAY;
  1573. /* We assume additive for Extended Community. */
  1574. old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
  1575. if (old_ecom)
  1576. {
  1577. new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
  1578. /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
  1579. * ->refcnt = 0 => set by a previous route-map statement */
  1580. if (!old_ecom->refcnt)
  1581. ecommunity_free (&old_ecom);
  1582. }
  1583. else
  1584. new_ecom = ecommunity_dup (ecom);
  1585. /* will be intern()'d or attr_flush()'d by bgp_update_main() */
  1586. bgp_info->attr->extra->ecommunity = new_ecom;
  1587. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
  1588. }
  1589. return RMAP_OKAY;
  1590. }
  1591. /* Compile function for set community. */
  1592. static void *
  1593. route_set_ecommunity_rt_compile (const char *arg)
  1594. {
  1595. struct ecommunity *ecom;
  1596. ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
  1597. if (! ecom)
  1598. return NULL;
  1599. return ecommunity_intern (ecom);
  1600. }
  1601. /* Free function for set community. Used by _rt and _soo */
  1602. static void
  1603. route_set_ecommunity_free (void *rule)
  1604. {
  1605. struct ecommunity *ecom = rule;
  1606. ecommunity_unintern (&ecom);
  1607. }
  1608. /* Set community rule structure. */
  1609. struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
  1610. {
  1611. "extcommunity rt",
  1612. route_set_ecommunity,
  1613. route_set_ecommunity_rt_compile,
  1614. route_set_ecommunity_free,
  1615. };
  1616. /* `set extcommunity soo COMMUNITY' */
  1617. /* Compile function for set community. */
  1618. static void *
  1619. route_set_ecommunity_soo_compile (const char *arg)
  1620. {
  1621. struct ecommunity *ecom;
  1622. ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
  1623. if (! ecom)
  1624. return NULL;
  1625. return ecommunity_intern (ecom);
  1626. }
  1627. /* Set community rule structure. */
  1628. struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
  1629. {
  1630. "extcommunity soo",
  1631. route_set_ecommunity,
  1632. route_set_ecommunity_soo_compile,
  1633. route_set_ecommunity_free,
  1634. };
  1635. /* `set origin ORIGIN' */
  1636. /* For origin set. */
  1637. static route_map_result_t
  1638. route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  1639. {
  1640. u_char *origin;
  1641. struct bgp_info *bgp_info;
  1642. if (type == RMAP_BGP)
  1643. {
  1644. origin = rule;
  1645. bgp_info = object;
  1646. bgp_info->attr->origin = *origin;
  1647. }
  1648. return RMAP_OKAY;
  1649. }
  1650. /* Compile function for origin set. */
  1651. static void *
  1652. route_set_origin_compile (const char *arg)
  1653. {
  1654. u_char *origin;
  1655. origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
  1656. if (strcmp (arg, "igp") == 0)
  1657. *origin = 0;
  1658. else if (strcmp (arg, "egp") == 0)
  1659. *origin = 1;
  1660. else
  1661. *origin = 2;
  1662. return origin;
  1663. }
  1664. /* Compile function for origin set. */
  1665. static void
  1666. route_set_origin_free (void *rule)
  1667. {
  1668. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1669. }
  1670. /* Set origin rule structure. */
  1671. struct route_map_rule_cmd route_set_origin_cmd =
  1672. {
  1673. "origin",
  1674. route_set_origin,
  1675. route_set_origin_compile,
  1676. route_set_origin_free,
  1677. };
  1678. /* `set atomic-aggregate' */
  1679. /* For atomic aggregate set. */
  1680. static route_map_result_t
  1681. route_set_atomic_aggregate (void *rule, struct prefix *prefix,
  1682. route_map_object_t type, void *object)
  1683. {
  1684. struct bgp_info *bgp_info;
  1685. if (type == RMAP_BGP)
  1686. {
  1687. bgp_info = object;
  1688. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
  1689. }
  1690. return RMAP_OKAY;
  1691. }
  1692. /* Compile function for atomic aggregate. */
  1693. static void *
  1694. route_set_atomic_aggregate_compile (const char *arg)
  1695. {
  1696. return (void *)1;
  1697. }
  1698. /* Compile function for atomic aggregate. */
  1699. static void
  1700. route_set_atomic_aggregate_free (void *rule)
  1701. {
  1702. return;
  1703. }
  1704. /* Set atomic aggregate rule structure. */
  1705. struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
  1706. {
  1707. "atomic-aggregate",
  1708. route_set_atomic_aggregate,
  1709. route_set_atomic_aggregate_compile,
  1710. route_set_atomic_aggregate_free,
  1711. };
  1712. /* `set aggregator as AS A.B.C.D' */
  1713. struct aggregator
  1714. {
  1715. as_t as;
  1716. struct in_addr address;
  1717. };
  1718. static route_map_result_t
  1719. route_set_aggregator_as (void *rule, struct prefix *prefix,
  1720. route_map_object_t type, void *object)
  1721. {
  1722. struct bgp_info *bgp_info;
  1723. struct aggregator *aggregator;
  1724. struct attr_extra *ae;
  1725. if (type == RMAP_BGP)
  1726. {
  1727. bgp_info = object;
  1728. aggregator = rule;
  1729. ae = bgp_attr_extra_get (bgp_info->attr);
  1730. ae->aggregator_as = aggregator->as;
  1731. ae->aggregator_addr = aggregator->address;
  1732. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
  1733. }
  1734. return RMAP_OKAY;
  1735. }
  1736. static void *
  1737. route_set_aggregator_as_compile (const char *arg)
  1738. {
  1739. struct aggregator *aggregator;
  1740. char as[10];
  1741. char address[20];
  1742. aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
  1743. sscanf (arg, "%s %s", as, address);
  1744. aggregator->as = strtoul (as, NULL, 10);
  1745. inet_aton (address, &aggregator->address);
  1746. return aggregator;
  1747. }
  1748. static void
  1749. route_set_aggregator_as_free (void *rule)
  1750. {
  1751. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1752. }
  1753. struct route_map_rule_cmd route_set_aggregator_as_cmd =
  1754. {
  1755. "aggregator as",
  1756. route_set_aggregator_as,
  1757. route_set_aggregator_as_compile,
  1758. route_set_aggregator_as_free,
  1759. };
  1760. /* Set tag to object. object must be pointer to struct bgp_info */
  1761. static route_map_result_t
  1762. route_set_tag (void *rule, struct prefix *prefix,
  1763. route_map_object_t type, void *object)
  1764. {
  1765. route_tag_t *tag;
  1766. struct bgp_info *bgp_info;
  1767. struct attr_extra *ae;
  1768. if (type == RMAP_BGP)
  1769. {
  1770. tag = rule;
  1771. bgp_info = object;
  1772. ae = bgp_attr_extra_get (bgp_info->attr);
  1773. /* Set tag value */
  1774. ae->tag=*tag;
  1775. }
  1776. return RMAP_OKAY;
  1777. }
  1778. /* Route map commands for tag set. */
  1779. static struct route_map_rule_cmd route_set_tag_cmd =
  1780. {
  1781. "tag",
  1782. route_set_tag,
  1783. route_map_rule_tag_compile,
  1784. route_map_rule_tag_free,
  1785. };
  1786. /* `match ipv6 address IP_ACCESS_LIST' */
  1787. static route_map_result_t
  1788. route_match_ipv6_address (void *rule, struct prefix *prefix,
  1789. route_map_object_t type, void *object)
  1790. {
  1791. struct access_list *alist;
  1792. if (type == RMAP_BGP)
  1793. {
  1794. alist = access_list_lookup (AFI_IP6, (char *) rule);
  1795. if (alist == NULL)
  1796. return RMAP_NOMATCH;
  1797. return (access_list_apply (alist, prefix) == FILTER_DENY ?
  1798. RMAP_NOMATCH : RMAP_MATCH);
  1799. }
  1800. return RMAP_NOMATCH;
  1801. }
  1802. static void *
  1803. route_match_ipv6_address_compile (const char *arg)
  1804. {
  1805. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  1806. }
  1807. static void
  1808. route_match_ipv6_address_free (void *rule)
  1809. {
  1810. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1811. }
  1812. /* Route map commands for ip address matching. */
  1813. struct route_map_rule_cmd route_match_ipv6_address_cmd =
  1814. {
  1815. "ipv6 address",
  1816. route_match_ipv6_address,
  1817. route_match_ipv6_address_compile,
  1818. route_match_ipv6_address_free
  1819. };
  1820. /* `match ipv6 next-hop IP_ADDRESS' */
  1821. static route_map_result_t
  1822. route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
  1823. route_map_object_t type, void *object)
  1824. {
  1825. struct in6_addr *addr = rule;
  1826. struct bgp_info *bgp_info;
  1827. if (type == RMAP_BGP)
  1828. {
  1829. bgp_info = object;
  1830. if (!bgp_info->attr->extra)
  1831. return RMAP_NOMATCH;
  1832. if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
  1833. return RMAP_MATCH;
  1834. if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
  1835. IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
  1836. return RMAP_MATCH;
  1837. return RMAP_NOMATCH;
  1838. }
  1839. return RMAP_NOMATCH;
  1840. }
  1841. static void *
  1842. route_match_ipv6_next_hop_compile (const char *arg)
  1843. {
  1844. struct in6_addr *address;
  1845. int ret;
  1846. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1847. ret = inet_pton (AF_INET6, arg, address);
  1848. if (!ret)
  1849. {
  1850. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1851. return NULL;
  1852. }
  1853. return address;
  1854. }
  1855. static void
  1856. route_match_ipv6_next_hop_free (void *rule)
  1857. {
  1858. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1859. }
  1860. struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
  1861. {
  1862. "ipv6 next-hop",
  1863. route_match_ipv6_next_hop,
  1864. route_match_ipv6_next_hop_compile,
  1865. route_match_ipv6_next_hop_free
  1866. };
  1867. /* `match ipv6 address prefix-list PREFIX_LIST' */
  1868. static route_map_result_t
  1869. route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
  1870. route_map_object_t type, void *object)
  1871. {
  1872. struct prefix_list *plist;
  1873. if (type == RMAP_BGP)
  1874. {
  1875. plist = prefix_list_lookup (AFI_IP6, (char *) rule);
  1876. if (plist == NULL)
  1877. return RMAP_NOMATCH;
  1878. return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  1879. RMAP_NOMATCH : RMAP_MATCH);
  1880. }
  1881. return RMAP_NOMATCH;
  1882. }
  1883. static void *
  1884. route_match_ipv6_address_prefix_list_compile (const char *arg)
  1885. {
  1886. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  1887. }
  1888. static void
  1889. route_match_ipv6_address_prefix_list_free (void *rule)
  1890. {
  1891. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1892. }
  1893. struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
  1894. {
  1895. "ipv6 address prefix-list",
  1896. route_match_ipv6_address_prefix_list,
  1897. route_match_ipv6_address_prefix_list_compile,
  1898. route_match_ipv6_address_prefix_list_free
  1899. };
  1900. /* `set ipv6 nexthop global IP_ADDRESS' */
  1901. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  1902. static route_map_result_t
  1903. route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
  1904. route_map_object_t type, void *object)
  1905. {
  1906. struct in6_addr *address;
  1907. struct bgp_info *bgp_info;
  1908. if (type == RMAP_BGP)
  1909. {
  1910. /* Fetch routemap's rule information. */
  1911. address = rule;
  1912. bgp_info = object;
  1913. /* Set next hop value. */
  1914. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
  1915. /* Set nexthop length. */
  1916. if (bgp_info->attr->extra->mp_nexthop_len == 0)
  1917. bgp_info->attr->extra->mp_nexthop_len = 16;
  1918. }
  1919. return RMAP_OKAY;
  1920. }
  1921. /* Route map `ip next-hop' compile function. Given string is converted
  1922. to struct in_addr structure. */
  1923. static void *
  1924. route_set_ipv6_nexthop_global_compile (const char *arg)
  1925. {
  1926. int ret;
  1927. struct in6_addr *address;
  1928. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1929. ret = inet_pton (AF_INET6, arg, address);
  1930. if (ret == 0)
  1931. {
  1932. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1933. return NULL;
  1934. }
  1935. return address;
  1936. }
  1937. /* Free route map's compiled `ip next-hop' value. */
  1938. static void
  1939. route_set_ipv6_nexthop_global_free (void *rule)
  1940. {
  1941. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1942. }
  1943. /* Route map commands for ip nexthop set. */
  1944. struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
  1945. {
  1946. "ipv6 next-hop global",
  1947. route_set_ipv6_nexthop_global,
  1948. route_set_ipv6_nexthop_global_compile,
  1949. route_set_ipv6_nexthop_global_free
  1950. };
  1951. /* `set ipv6 nexthop local IP_ADDRESS' */
  1952. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  1953. static route_map_result_t
  1954. route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
  1955. route_map_object_t type, void *object)
  1956. {
  1957. struct in6_addr *address;
  1958. struct bgp_info *bgp_info;
  1959. if (type == RMAP_BGP)
  1960. {
  1961. /* Fetch routemap's rule information. */
  1962. address = rule;
  1963. bgp_info = object;
  1964. /* Set next hop value. */
  1965. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
  1966. /* Set nexthop length. */
  1967. if (bgp_info->attr->extra->mp_nexthop_len != 32)
  1968. bgp_info->attr->extra->mp_nexthop_len = 32;
  1969. }
  1970. return RMAP_OKAY;
  1971. }
  1972. /* Route map `ip nexthop' compile function. Given string is converted
  1973. to struct in_addr structure. */
  1974. static void *
  1975. route_set_ipv6_nexthop_local_compile (const char *arg)
  1976. {
  1977. int ret;
  1978. struct in6_addr *address;
  1979. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1980. ret = inet_pton (AF_INET6, arg, address);
  1981. if (ret == 0)
  1982. {
  1983. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1984. return NULL;
  1985. }
  1986. return address;
  1987. }
  1988. /* Free route map's compiled `ip nexthop' value. */
  1989. static void
  1990. route_set_ipv6_nexthop_local_free (void *rule)
  1991. {
  1992. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1993. }
  1994. /* Route map commands for ip nexthop set. */
  1995. struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
  1996. {
  1997. "ipv6 next-hop local",
  1998. route_set_ipv6_nexthop_local,
  1999. route_set_ipv6_nexthop_local_compile,
  2000. route_set_ipv6_nexthop_local_free
  2001. };
  2002. /* `set ipv6 nexthop peer-address' */
  2003. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  2004. static route_map_result_t
  2005. route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
  2006. route_map_object_t type, void *object)
  2007. {
  2008. struct in6_addr peer_address;
  2009. struct bgp_info *bgp_info;
  2010. struct peer *peer;
  2011. if (type == RMAP_BGP)
  2012. {
  2013. /* Fetch routemap's rule information. */
  2014. bgp_info = object;
  2015. peer = bgp_info->peer;
  2016. if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
  2017. CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
  2018. && peer->su_remote
  2019. && sockunion_family (peer->su_remote) == AF_INET6)
  2020. {
  2021. peer_address = peer->su_remote->sin6.sin6_addr;
  2022. }
  2023. else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
  2024. && peer->su_local
  2025. && sockunion_family (peer->su_local) == AF_INET6)
  2026. {
  2027. peer_address = peer->su_local->sin6.sin6_addr;
  2028. }
  2029. if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
  2030. {
  2031. /* Set next hop value. */
  2032. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
  2033. /* Set nexthop length. */
  2034. if (bgp_info->attr->extra->mp_nexthop_len != 32)
  2035. bgp_info->attr->extra->mp_nexthop_len = 32;
  2036. }
  2037. else
  2038. {
  2039. /* Set next hop value. */
  2040. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
  2041. /* Set nexthop length. */
  2042. if (bgp_info->attr->extra->mp_nexthop_len == 0)
  2043. bgp_info->attr->extra->mp_nexthop_len = 16;
  2044. }
  2045. }
  2046. return RMAP_OKAY;
  2047. }
  2048. /* Route map `ip next-hop' compile function. Given string is converted
  2049. to struct in_addr structure. */
  2050. static void *
  2051. route_set_ipv6_nexthop_peer_compile (const char *arg)
  2052. {
  2053. int *rins = NULL;
  2054. rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
  2055. *rins = 1;
  2056. return rins;
  2057. }
  2058. /* Free route map's compiled `ip next-hop' value. */
  2059. static void
  2060. route_set_ipv6_nexthop_peer_free (void *rule)
  2061. {
  2062. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  2063. }
  2064. /* Route map commands for ip nexthop set. */
  2065. struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
  2066. {
  2067. "ipv6 next-hop peer-address",
  2068. route_set_ipv6_nexthop_peer,
  2069. route_set_ipv6_nexthop_peer_compile,
  2070. route_set_ipv6_nexthop_peer_free
  2071. };
  2072. /* `set vpnv4 nexthop A.B.C.D' */
  2073. static route_map_result_t
  2074. route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
  2075. route_map_object_t type, void *object)
  2076. {
  2077. struct in_addr *address;
  2078. struct bgp_info *bgp_info;
  2079. if (type == RMAP_BGP)
  2080. {
  2081. /* Fetch routemap's rule information. */
  2082. address = rule;
  2083. bgp_info = object;
  2084. /* Set next hop value. */
  2085. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
  2086. (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
  2087. }
  2088. return RMAP_OKAY;
  2089. }
  2090. static void *
  2091. route_set_vpnv4_nexthop_compile (const char *arg)
  2092. {
  2093. int ret;
  2094. struct in_addr *address;
  2095. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  2096. ret = inet_aton (arg, address);
  2097. if (ret == 0)
  2098. {
  2099. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  2100. return NULL;
  2101. }
  2102. return address;
  2103. }
  2104. static void
  2105. route_set_vpnv4_nexthop_free (void *rule)
  2106. {
  2107. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  2108. }
  2109. /* Route map commands for ip nexthop set. */
  2110. struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
  2111. {
  2112. "vpnv4 next-hop",
  2113. route_set_vpnv4_nexthop,
  2114. route_set_vpnv4_nexthop_compile,
  2115. route_set_vpnv4_nexthop_free
  2116. };
  2117. /* `set originator-id' */
  2118. /* For origin set. */
  2119. static route_map_result_t
  2120. route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  2121. {
  2122. struct in_addr *address;
  2123. struct bgp_info *bgp_info;
  2124. if (type == RMAP_BGP)
  2125. {
  2126. address = rule;
  2127. bgp_info = object;
  2128. bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
  2129. (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
  2130. }
  2131. return RMAP_OKAY;
  2132. }
  2133. /* Compile function for originator-id set. */
  2134. static void *
  2135. route_set_originator_id_compile (const char *arg)
  2136. {
  2137. int ret;
  2138. struct in_addr *address;
  2139. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  2140. ret = inet_aton (arg, address);
  2141. if (ret == 0)
  2142. {
  2143. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  2144. return NULL;
  2145. }
  2146. return address;
  2147. }
  2148. /* Compile function for originator_id set. */
  2149. static void
  2150. route_set_originator_id_free (void *rule)
  2151. {
  2152. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  2153. }
  2154. /* Set originator-id rule structure. */
  2155. struct route_map_rule_cmd route_set_originator_id_cmd =
  2156. {
  2157. "originator-id",
  2158. route_set_originator_id,
  2159. route_set_originator_id_compile,
  2160. route_set_originator_id_free,
  2161. };
  2162. /* Add bgp route map rule. */
  2163. static int
  2164. bgp_route_match_add (struct vty *vty, struct route_map_index *index,
  2165. const char *command, const char *arg)
  2166. {
  2167. int ret;
  2168. ret = route_map_add_match (index, command, arg);
  2169. if (ret)
  2170. {
  2171. switch (ret)
  2172. {
  2173. case RMAP_RULE_MISSING:
  2174. vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
  2175. return CMD_WARNING;
  2176. case RMAP_COMPILE_ERROR:
  2177. vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
  2178. return CMD_WARNING;
  2179. }
  2180. }
  2181. return CMD_SUCCESS;
  2182. }
  2183. /* Delete bgp route map rule. */
  2184. static int
  2185. bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
  2186. const char *command, const char *arg)
  2187. {
  2188. int ret;
  2189. ret = route_map_delete_match (index, command, arg);
  2190. if (ret)
  2191. {
  2192. switch (ret)
  2193. {
  2194. case RMAP_RULE_MISSING:
  2195. vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
  2196. return CMD_WARNING;
  2197. case RMAP_COMPILE_ERROR:
  2198. vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
  2199. return CMD_WARNING;
  2200. }
  2201. }
  2202. return CMD_SUCCESS;
  2203. }
  2204. /* Add bgp route map rule. */
  2205. static int
  2206. bgp_route_set_add (struct vty *vty, struct route_map_index *index,
  2207. const char *command, const char *arg)
  2208. {
  2209. int ret;
  2210. ret = route_map_add_set (index, command, arg);
  2211. if (ret)
  2212. {
  2213. switch (ret)
  2214. {
  2215. case RMAP_RULE_MISSING:
  2216. vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
  2217. return CMD_WARNING;
  2218. case RMAP_COMPILE_ERROR:
  2219. vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
  2220. return CMD_WARNING;
  2221. }
  2222. }
  2223. return CMD_SUCCESS;
  2224. }
  2225. /* Delete bgp route map rule. */
  2226. static int
  2227. bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
  2228. const char *command, const char *arg)
  2229. {
  2230. int ret;
  2231. ret = route_map_delete_set (index, command, arg);
  2232. if (ret)
  2233. {
  2234. switch (ret)
  2235. {
  2236. case RMAP_RULE_MISSING:
  2237. vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
  2238. return CMD_WARNING;
  2239. case RMAP_COMPILE_ERROR:
  2240. vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
  2241. return CMD_WARNING;
  2242. }
  2243. }
  2244. return CMD_SUCCESS;
  2245. }
  2246. /* Hook function for updating route_map assignment. */
  2247. static void
  2248. bgp_route_map_update (const char *unused)
  2249. {
  2250. int i;
  2251. afi_t afi;
  2252. safi_t safi;
  2253. int direct;
  2254. struct listnode *node, *nnode;
  2255. struct listnode *mnode, *mnnode;
  2256. struct bgp *bgp;
  2257. struct peer *peer;
  2258. struct peer_group *group;
  2259. struct bgp_filter *filter;
  2260. struct bgp_node *bn;
  2261. struct bgp_static *bgp_static;
  2262. if (bm->bgp == NULL) /* may be called during cleanup */
  2263. return;
  2264. /* For neighbor route-map updates. */
  2265. for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
  2266. {
  2267. for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  2268. {
  2269. for (afi = AFI_IP; afi < AFI_MAX; afi++)
  2270. for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  2271. {
  2272. filter = &peer->filter[afi][safi];
  2273. for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
  2274. {
  2275. if (filter->map[direct].name)
  2276. filter->map[direct].map =
  2277. route_map_lookup_by_name (filter->map[direct].name);
  2278. else
  2279. filter->map[direct].map = NULL;
  2280. }
  2281. if (filter->usmap.name)
  2282. filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
  2283. else
  2284. filter->usmap.map = NULL;
  2285. }
  2286. }
  2287. for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
  2288. {
  2289. for (afi = AFI_IP; afi < AFI_MAX; afi++)
  2290. for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  2291. {
  2292. filter = &group->conf->filter[afi][safi];
  2293. for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
  2294. {
  2295. if (filter->map[direct].name)
  2296. filter->map[direct].map =
  2297. route_map_lookup_by_name (filter->map[direct].name);
  2298. else
  2299. filter->map[direct].map = NULL;
  2300. }
  2301. if (filter->usmap.name)
  2302. filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
  2303. else
  2304. filter->usmap.map = NULL;
  2305. }
  2306. }
  2307. }
  2308. /* For default-originate route-map updates. */
  2309. for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
  2310. {
  2311. for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  2312. {
  2313. for (afi = AFI_IP; afi < AFI_MAX; afi++)
  2314. for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  2315. {
  2316. if (peer->default_rmap[afi][safi].name)
  2317. peer->default_rmap[afi][safi].map =
  2318. route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
  2319. else
  2320. peer->default_rmap[afi][safi].map = NULL;
  2321. }
  2322. }
  2323. }
  2324. /* For network route-map updates. */
  2325. for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
  2326. {
  2327. for (afi = AFI_IP; afi < AFI_MAX; afi++)
  2328. for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  2329. for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
  2330. bn = bgp_route_next (bn))
  2331. if ((bgp_static = bn->info) != NULL)
  2332. {
  2333. if (bgp_static->rmap.name)
  2334. bgp_static->rmap.map =
  2335. route_map_lookup_by_name (bgp_static->rmap.name);
  2336. else
  2337. bgp_static->rmap.map = NULL;
  2338. }
  2339. }
  2340. /* For redistribute route-map updates. */
  2341. for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
  2342. {
  2343. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  2344. {
  2345. if (bgp->rmap[AFI_IP][i].name)
  2346. bgp->rmap[AFI_IP][i].map =
  2347. route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
  2348. if (bgp->rmap[AFI_IP6][i].name)
  2349. bgp->rmap[AFI_IP6][i].map =
  2350. route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
  2351. }
  2352. }
  2353. }
  2354. DEFUN (match_peer,
  2355. match_peer_cmd,
  2356. "match peer (A.B.C.D|X:X::X:X)",
  2357. MATCH_STR
  2358. "Match peer address\n"
  2359. "IP address of peer\n"
  2360. "IPv6 address of peer\n")
  2361. {
  2362. return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
  2363. }
  2364. DEFUN (match_peer_local,
  2365. match_peer_local_cmd,
  2366. "match peer local",
  2367. MATCH_STR
  2368. "Match peer address\n"
  2369. "Static or Redistributed routes\n")
  2370. {
  2371. return bgp_route_match_add (vty, vty->index, "peer", "local");
  2372. }
  2373. DEFUN (no_match_peer,
  2374. no_match_peer_cmd,
  2375. "no match peer",
  2376. NO_STR
  2377. MATCH_STR
  2378. "Match peer address\n")
  2379. {
  2380. if (argc == 0)
  2381. return bgp_route_match_delete (vty, vty->index, "peer", NULL);
  2382. return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
  2383. }
  2384. ALIAS (no_match_peer,
  2385. no_match_peer_val_cmd,
  2386. "no match peer (A.B.C.D|X:X::X:X)",
  2387. NO_STR
  2388. MATCH_STR
  2389. "Match peer address\n"
  2390. "IP address of peer\n"
  2391. "IPv6 address of peer\n")
  2392. ALIAS (no_match_peer,
  2393. no_match_peer_local_cmd,
  2394. "no match peer local",
  2395. NO_STR
  2396. MATCH_STR
  2397. "Match peer address\n"
  2398. "Static or Redistributed routes\n")
  2399. DEFUN (match_ip_address,
  2400. match_ip_address_cmd,
  2401. "match ip address (<1-199>|<1300-2699>|WORD)",
  2402. MATCH_STR
  2403. IP_STR
  2404. "Match address of route\n"
  2405. "IP access-list number\n"
  2406. "IP access-list number (expanded range)\n"
  2407. "IP Access-list name\n")
  2408. {
  2409. return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
  2410. }
  2411. DEFUN (no_match_ip_address,
  2412. no_match_ip_address_cmd,
  2413. "no match ip address",
  2414. NO_STR
  2415. MATCH_STR
  2416. IP_STR
  2417. "Match address of route\n")
  2418. {
  2419. if (argc == 0)
  2420. return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
  2421. return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
  2422. }
  2423. ALIAS (no_match_ip_address,
  2424. no_match_ip_address_val_cmd,
  2425. "no match ip address (<1-199>|<1300-2699>|WORD)",
  2426. NO_STR
  2427. MATCH_STR
  2428. IP_STR
  2429. "Match address of route\n"
  2430. "IP access-list number\n"
  2431. "IP access-list number (expanded range)\n"
  2432. "IP Access-list name\n")
  2433. DEFUN (match_ip_next_hop,
  2434. match_ip_next_hop_cmd,
  2435. "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  2436. MATCH_STR
  2437. IP_STR
  2438. "Match next-hop address of route\n"
  2439. "IP access-list number\n"
  2440. "IP access-list number (expanded range)\n"
  2441. "IP Access-list name\n")
  2442. {
  2443. return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  2444. }
  2445. DEFUN (no_match_ip_next_hop,
  2446. no_match_ip_next_hop_cmd,
  2447. "no match ip next-hop",
  2448. NO_STR
  2449. MATCH_STR
  2450. IP_STR
  2451. "Match next-hop address of route\n")
  2452. {
  2453. if (argc == 0)
  2454. return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  2455. return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  2456. }
  2457. ALIAS (no_match_ip_next_hop,
  2458. no_match_ip_next_hop_val_cmd,
  2459. "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  2460. NO_STR
  2461. MATCH_STR
  2462. IP_STR
  2463. "Match next-hop address of route\n"
  2464. "IP access-list number\n"
  2465. "IP access-list number (expanded range)\n"
  2466. "IP Access-list name\n")
  2467. /* match probability { */
  2468. DEFUN (match_probability,
  2469. match_probability_cmd,
  2470. "match probability <0-100>",
  2471. MATCH_STR
  2472. "Match portion of routes defined by percentage value\n"
  2473. "Percentage of routes\n")
  2474. {
  2475. return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
  2476. }
  2477. DEFUN (no_match_probability,
  2478. no_match_probability_cmd,
  2479. "no match probability",
  2480. NO_STR
  2481. MATCH_STR
  2482. "Match portion of routes defined by percentage value\n")
  2483. {
  2484. return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
  2485. }
  2486. ALIAS (no_match_probability,
  2487. no_match_probability_val_cmd,
  2488. "no match probability <1-99>",
  2489. NO_STR
  2490. MATCH_STR
  2491. "Match portion of routes defined by percentage value\n"
  2492. "Percentage of routes\n")
  2493. /* } */
  2494. DEFUN (match_ip_route_source,
  2495. match_ip_route_source_cmd,
  2496. "match ip route-source (<1-199>|<1300-2699>|WORD)",
  2497. MATCH_STR
  2498. IP_STR
  2499. "Match advertising source address of route\n"
  2500. "IP access-list number\n"
  2501. "IP access-list number (expanded range)\n"
  2502. "IP standard access-list name\n")
  2503. {
  2504. return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
  2505. }
  2506. DEFUN (no_match_ip_route_source,
  2507. no_match_ip_route_source_cmd,
  2508. "no match ip route-source",
  2509. NO_STR
  2510. MATCH_STR
  2511. IP_STR
  2512. "Match advertising source address of route\n")
  2513. {
  2514. if (argc == 0)
  2515. return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
  2516. return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
  2517. }
  2518. ALIAS (no_match_ip_route_source,
  2519. no_match_ip_route_source_val_cmd,
  2520. "no match ip route-source (<1-199>|<1300-2699>|WORD)",
  2521. NO_STR
  2522. MATCH_STR
  2523. IP_STR
  2524. "Match advertising source address of route\n"
  2525. "IP access-list number\n"
  2526. "IP access-list number (expanded range)\n"
  2527. "IP standard access-list name\n")
  2528. DEFUN (match_ip_address_prefix_list,
  2529. match_ip_address_prefix_list_cmd,
  2530. "match ip address prefix-list WORD",
  2531. MATCH_STR
  2532. IP_STR
  2533. "Match address of route\n"
  2534. "Match entries of prefix-lists\n"
  2535. "IP prefix-list name\n")
  2536. {
  2537. return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  2538. }
  2539. DEFUN (no_match_ip_address_prefix_list,
  2540. no_match_ip_address_prefix_list_cmd,
  2541. "no match ip address prefix-list",
  2542. NO_STR
  2543. MATCH_STR
  2544. IP_STR
  2545. "Match address of route\n"
  2546. "Match entries of prefix-lists\n")
  2547. {
  2548. if (argc == 0)
  2549. return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  2550. return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  2551. }
  2552. ALIAS (no_match_ip_address_prefix_list,
  2553. no_match_ip_address_prefix_list_val_cmd,
  2554. "no match ip address prefix-list WORD",
  2555. NO_STR
  2556. MATCH_STR
  2557. IP_STR
  2558. "Match address of route\n"
  2559. "Match entries of prefix-lists\n"
  2560. "IP prefix-list name\n")
  2561. DEFUN (match_ip_next_hop_prefix_list,
  2562. match_ip_next_hop_prefix_list_cmd,
  2563. "match ip next-hop prefix-list WORD",
  2564. MATCH_STR
  2565. IP_STR
  2566. "Match next-hop address of route\n"
  2567. "Match entries of prefix-lists\n"
  2568. "IP prefix-list name\n")
  2569. {
  2570. return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  2571. }
  2572. DEFUN (no_match_ip_next_hop_prefix_list,
  2573. no_match_ip_next_hop_prefix_list_cmd,
  2574. "no match ip next-hop prefix-list",
  2575. NO_STR
  2576. MATCH_STR
  2577. IP_STR
  2578. "Match next-hop address of route\n"
  2579. "Match entries of prefix-lists\n")
  2580. {
  2581. if (argc == 0)
  2582. return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  2583. return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  2584. }
  2585. ALIAS (no_match_ip_next_hop_prefix_list,
  2586. no_match_ip_next_hop_prefix_list_val_cmd,
  2587. "no match ip next-hop prefix-list WORD",
  2588. NO_STR
  2589. MATCH_STR
  2590. IP_STR
  2591. "Match next-hop address of route\n"
  2592. "Match entries of prefix-lists\n"
  2593. "IP prefix-list name\n")
  2594. DEFUN (match_ip_route_source_prefix_list,
  2595. match_ip_route_source_prefix_list_cmd,
  2596. "match ip route-source prefix-list WORD",
  2597. MATCH_STR
  2598. IP_STR
  2599. "Match advertising source address of route\n"
  2600. "Match entries of prefix-lists\n"
  2601. "IP prefix-list name\n")
  2602. {
  2603. return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
  2604. }
  2605. DEFUN (no_match_ip_route_source_prefix_list,
  2606. no_match_ip_route_source_prefix_list_cmd,
  2607. "no match ip route-source prefix-list",
  2608. NO_STR
  2609. MATCH_STR
  2610. IP_STR
  2611. "Match advertising source address of route\n"
  2612. "Match entries of prefix-lists\n")
  2613. {
  2614. if (argc == 0)
  2615. return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
  2616. return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
  2617. }
  2618. ALIAS (no_match_ip_route_source_prefix_list,
  2619. no_match_ip_route_source_prefix_list_val_cmd,
  2620. "no match ip route-source prefix-list WORD",
  2621. NO_STR
  2622. MATCH_STR
  2623. IP_STR
  2624. "Match advertising source address of route\n"
  2625. "Match entries of prefix-lists\n"
  2626. "IP prefix-list name\n")
  2627. DEFUN (match_metric,
  2628. match_metric_cmd,
  2629. "match metric <0-4294967295>",
  2630. MATCH_STR
  2631. "Match metric of route\n"
  2632. "Metric value\n")
  2633. {
  2634. return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
  2635. }
  2636. DEFUN (no_match_metric,
  2637. no_match_metric_cmd,
  2638. "no match metric",
  2639. NO_STR
  2640. MATCH_STR
  2641. "Match metric of route\n")
  2642. {
  2643. if (argc == 0)
  2644. return bgp_route_match_delete (vty, vty->index, "metric", NULL);
  2645. return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
  2646. }
  2647. ALIAS (no_match_metric,
  2648. no_match_metric_val_cmd,
  2649. "no match metric <0-4294967295>",
  2650. NO_STR
  2651. MATCH_STR
  2652. "Match metric of route\n"
  2653. "Metric value\n")
  2654. DEFUN (match_local_pref,
  2655. match_local_pref_cmd,
  2656. "match local-preference <0-4294967295>",
  2657. MATCH_STR
  2658. "Match local-preference of route\n"
  2659. "Metric value\n")
  2660. {
  2661. return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
  2662. }
  2663. DEFUN (no_match_local_pref,
  2664. no_match_local_pref_cmd,
  2665. "no match local-preference",
  2666. NO_STR
  2667. MATCH_STR
  2668. "Match local preference of route\n")
  2669. {
  2670. if (argc == 0)
  2671. return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
  2672. return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
  2673. }
  2674. ALIAS (no_match_local_pref,
  2675. no_match_local_pref_val_cmd,
  2676. "no match local-preference <0-4294967295>",
  2677. NO_STR
  2678. MATCH_STR
  2679. "Match local preference of route\n"
  2680. "Local preference value\n")
  2681. DEFUN (match_community,
  2682. match_community_cmd,
  2683. "match community (<1-99>|<100-500>|WORD)",
  2684. MATCH_STR
  2685. "Match BGP community list\n"
  2686. "Community-list number (standard)\n"
  2687. "Community-list number (expanded)\n"
  2688. "Community-list name\n")
  2689. {
  2690. return bgp_route_match_add (vty, vty->index, "community", argv[0]);
  2691. }
  2692. DEFUN (match_community_exact,
  2693. match_community_exact_cmd,
  2694. "match community (<1-99>|<100-500>|WORD) exact-match",
  2695. MATCH_STR
  2696. "Match BGP community list\n"
  2697. "Community-list number (standard)\n"
  2698. "Community-list number (expanded)\n"
  2699. "Community-list name\n"
  2700. "Do exact matching of communities\n")
  2701. {
  2702. int ret;
  2703. char *argstr;
  2704. argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  2705. strlen (argv[0]) + strlen ("exact-match") + 2);
  2706. sprintf (argstr, "%s exact-match", argv[0]);
  2707. ret = bgp_route_match_add (vty, vty->index, "community", argstr);
  2708. XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  2709. return ret;
  2710. }
  2711. DEFUN (no_match_community,
  2712. no_match_community_cmd,
  2713. "no match community",
  2714. NO_STR
  2715. MATCH_STR
  2716. "Match BGP community list\n")
  2717. {
  2718. return bgp_route_match_delete (vty, vty->index, "community", NULL);
  2719. }
  2720. ALIAS (no_match_community,
  2721. no_match_community_val_cmd,
  2722. "no match community (<1-99>|<100-500>|WORD)",
  2723. NO_STR
  2724. MATCH_STR
  2725. "Match BGP community list\n"
  2726. "Community-list number (standard)\n"
  2727. "Community-list number (expanded)\n"
  2728. "Community-list name\n")
  2729. ALIAS (no_match_community,
  2730. no_match_community_exact_cmd,
  2731. "no match community (<1-99>|<100-500>|WORD) exact-match",
  2732. NO_STR
  2733. MATCH_STR
  2734. "Match BGP community list\n"
  2735. "Community-list number (standard)\n"
  2736. "Community-list number (expanded)\n"
  2737. "Community-list name\n"
  2738. "Do exact matching of communities\n")
  2739. DEFUN (match_lcommunity,
  2740. match_lcommunity_cmd,
  2741. "match large-community (<1-99>|<100-500>|WORD)",
  2742. MATCH_STR
  2743. "Match BGP large community list\n"
  2744. "Large Community-list number (standard)\n"
  2745. "Large Community-list number (expanded)\n"
  2746. "Large Community-list name\n")
  2747. {
  2748. return bgp_route_match_add (vty, vty->index, "large-community", argv[0]);
  2749. }
  2750. DEFUN (no_match_lcommunity,
  2751. no_match_lcommunity_cmd,
  2752. "no match large-community (<1-99>|<100-500>|WORD)",
  2753. NO_STR
  2754. MATCH_STR
  2755. "Match BGP large community list\n"
  2756. "Large Community-list number (standard)\n"
  2757. "Large Community-list number (expanded)\n"
  2758. "Large Community-list name\n")
  2759. {
  2760. return bgp_route_match_delete (vty, vty->index, "large-community", NULL);
  2761. }
  2762. DEFUN (match_ecommunity,
  2763. match_ecommunity_cmd,
  2764. "match extcommunity (<1-99>|<100-500>|WORD)",
  2765. MATCH_STR
  2766. "Match BGP/VPN extended community list\n"
  2767. "Extended community-list number (standard)\n"
  2768. "Extended community-list number (expanded)\n"
  2769. "Extended community-list name\n")
  2770. {
  2771. return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
  2772. }
  2773. DEFUN (no_match_ecommunity,
  2774. no_match_ecommunity_cmd,
  2775. "no match extcommunity",
  2776. NO_STR
  2777. MATCH_STR
  2778. "Match BGP/VPN extended community list\n")
  2779. {
  2780. return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
  2781. }
  2782. ALIAS (no_match_ecommunity,
  2783. no_match_ecommunity_val_cmd,
  2784. "no match extcommunity (<1-99>|<100-500>|WORD)",
  2785. NO_STR
  2786. MATCH_STR
  2787. "Match BGP/VPN extended community list\n"
  2788. "Extended community-list number (standard)\n"
  2789. "Extended community-list number (expanded)\n"
  2790. "Extended community-list name\n")
  2791. DEFUN (match_aspath,
  2792. match_aspath_cmd,
  2793. "match as-path WORD",
  2794. MATCH_STR
  2795. "Match BGP AS path list\n"
  2796. "AS path access-list name\n")
  2797. {
  2798. return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
  2799. }
  2800. DEFUN (no_match_aspath,
  2801. no_match_aspath_cmd,
  2802. "no match as-path",
  2803. NO_STR
  2804. MATCH_STR
  2805. "Match BGP AS path list\n")
  2806. {
  2807. return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
  2808. }
  2809. ALIAS (no_match_aspath,
  2810. no_match_aspath_val_cmd,
  2811. "no match as-path WORD",
  2812. NO_STR
  2813. MATCH_STR
  2814. "Match BGP AS path list\n"
  2815. "AS path access-list name\n")
  2816. DEFUN (match_origin,
  2817. match_origin_cmd,
  2818. "match origin (egp|igp|incomplete)",
  2819. MATCH_STR
  2820. "BGP origin code\n"
  2821. "remote EGP\n"
  2822. "local IGP\n"
  2823. "unknown heritage\n")
  2824. {
  2825. if (strncmp (argv[0], "igp", 2) == 0)
  2826. return bgp_route_match_add (vty, vty->index, "origin", "igp");
  2827. if (strncmp (argv[0], "egp", 1) == 0)
  2828. return bgp_route_match_add (vty, vty->index, "origin", "egp");
  2829. if (strncmp (argv[0], "incomplete", 2) == 0)
  2830. return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
  2831. return CMD_WARNING;
  2832. }
  2833. DEFUN (no_match_origin,
  2834. no_match_origin_cmd,
  2835. "no match origin",
  2836. NO_STR
  2837. MATCH_STR
  2838. "BGP origin code\n")
  2839. {
  2840. return bgp_route_match_delete (vty, vty->index, "origin", NULL);
  2841. }
  2842. ALIAS (no_match_origin,
  2843. no_match_origin_val_cmd,
  2844. "no match origin (egp|igp|incomplete)",
  2845. NO_STR
  2846. MATCH_STR
  2847. "BGP origin code\n"
  2848. "remote EGP\n"
  2849. "local IGP\n"
  2850. "unknown heritage\n")
  2851. DEFUN (match_tag,
  2852. match_tag_cmd,
  2853. "match tag <1-4294967295>",
  2854. MATCH_STR
  2855. "Match tag of route\n"
  2856. "Tag value\n")
  2857. {
  2858. return bgp_route_match_add (vty, vty->index, "tag", argv[0]);
  2859. }
  2860. DEFUN (no_match_tag,
  2861. no_match_tag_cmd,
  2862. "no match tag",
  2863. NO_STR
  2864. MATCH_STR
  2865. "Match tag of route\n")
  2866. {
  2867. if (argc == 0)
  2868. return bgp_route_match_delete (vty, vty->index, "tag", NULL);
  2869. return bgp_route_match_delete (vty, vty->index, "tag", argv[0]);
  2870. }
  2871. ALIAS (no_match_tag,
  2872. no_match_tag_val_cmd,
  2873. "no match tag <1-4294967295>",
  2874. NO_STR
  2875. MATCH_STR
  2876. "Match tag of route\n"
  2877. "Tag value\n")
  2878. DEFUN (set_ip_nexthop,
  2879. set_ip_nexthop_cmd,
  2880. "set ip next-hop A.B.C.D",
  2881. SET_STR
  2882. IP_STR
  2883. "Next hop address\n"
  2884. "IP address of next hop\n")
  2885. {
  2886. union sockunion su;
  2887. int ret;
  2888. ret = str2sockunion (argv[0], &su);
  2889. if (ret < 0)
  2890. {
  2891. vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
  2892. return CMD_WARNING;
  2893. }
  2894. return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
  2895. }
  2896. DEFUN (set_ip_nexthop_peer,
  2897. set_ip_nexthop_peer_cmd,
  2898. "set ip next-hop peer-address",
  2899. SET_STR
  2900. IP_STR
  2901. "Next hop address\n"
  2902. "Use peer address (for BGP only)\n")
  2903. {
  2904. return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
  2905. }
  2906. DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
  2907. no_set_ip_nexthop_peer_cmd,
  2908. "no set ip next-hop peer-address",
  2909. NO_STR
  2910. SET_STR
  2911. IP_STR
  2912. "Next hop address\n"
  2913. "Use peer address (for BGP only)\n")
  2914. {
  2915. return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  2916. }
  2917. DEFUN (no_set_ip_nexthop,
  2918. no_set_ip_nexthop_cmd,
  2919. "no set ip next-hop",
  2920. NO_STR
  2921. SET_STR
  2922. "Next hop address\n")
  2923. {
  2924. if (argc == 0)
  2925. return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  2926. return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
  2927. }
  2928. ALIAS (no_set_ip_nexthop,
  2929. no_set_ip_nexthop_val_cmd,
  2930. "no set ip next-hop A.B.C.D",
  2931. NO_STR
  2932. SET_STR
  2933. IP_STR
  2934. "Next hop address\n"
  2935. "IP address of next hop\n")
  2936. DEFUN (set_metric,
  2937. set_metric_cmd,
  2938. "set metric <0-4294967295>",
  2939. SET_STR
  2940. "Metric value for destination routing protocol\n"
  2941. "Metric value\n")
  2942. {
  2943. return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
  2944. }
  2945. ALIAS (set_metric,
  2946. set_metric_addsub_cmd,
  2947. "set metric <+/-metric>",
  2948. SET_STR
  2949. "Metric value for destination routing protocol\n"
  2950. "Add or subtract metric\n")
  2951. ALIAS (set_metric,
  2952. set_metric_rtt_cmd,
  2953. "set metric (rtt|+rtt|-rtt)",
  2954. SET_STR
  2955. "Metric value for destination routing protocol\n"
  2956. "Assign round trip time\n"
  2957. "Add round trip time\n"
  2958. "Subtract round trip time\n")
  2959. DEFUN (no_set_metric,
  2960. no_set_metric_cmd,
  2961. "no set metric",
  2962. NO_STR
  2963. SET_STR
  2964. "Metric value for destination routing protocol\n")
  2965. {
  2966. if (argc == 0)
  2967. return bgp_route_set_delete (vty, vty->index, "metric", NULL);
  2968. return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
  2969. }
  2970. ALIAS (no_set_metric,
  2971. no_set_metric_val_cmd,
  2972. "no set metric <0-4294967295>",
  2973. NO_STR
  2974. SET_STR
  2975. "Metric value for destination routing protocol\n"
  2976. "Metric value\n")
  2977. DEFUN (set_local_pref,
  2978. set_local_pref_cmd,
  2979. "set local-preference <0-4294967295>",
  2980. SET_STR
  2981. "BGP local preference path attribute\n"
  2982. "Preference value\n")
  2983. {
  2984. return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
  2985. }
  2986. DEFUN (no_set_local_pref,
  2987. no_set_local_pref_cmd,
  2988. "no set local-preference",
  2989. NO_STR
  2990. SET_STR
  2991. "BGP local preference path attribute\n")
  2992. {
  2993. if (argc == 0)
  2994. return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
  2995. return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
  2996. }
  2997. ALIAS (no_set_local_pref,
  2998. no_set_local_pref_val_cmd,
  2999. "no set local-preference <0-4294967295>",
  3000. NO_STR
  3001. SET_STR
  3002. "BGP local preference path attribute\n"
  3003. "Preference value\n")
  3004. DEFUN (set_weight,
  3005. set_weight_cmd,
  3006. "set weight <0-4294967295>",
  3007. SET_STR
  3008. "BGP weight for routing table\n"
  3009. "Weight value\n")
  3010. {
  3011. return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
  3012. }
  3013. DEFUN (no_set_weight,
  3014. no_set_weight_cmd,
  3015. "no set weight",
  3016. NO_STR
  3017. SET_STR
  3018. "BGP weight for routing table\n")
  3019. {
  3020. if (argc == 0)
  3021. return bgp_route_set_delete (vty, vty->index, "weight", NULL);
  3022. return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
  3023. }
  3024. ALIAS (no_set_weight,
  3025. no_set_weight_val_cmd,
  3026. "no set weight <0-4294967295>",
  3027. NO_STR
  3028. SET_STR
  3029. "BGP weight for routing table\n"
  3030. "Weight value\n")
  3031. DEFUN (set_aspath_prepend,
  3032. set_aspath_prepend_cmd,
  3033. "set as-path prepend ." CMD_AS_RANGE,
  3034. SET_STR
  3035. "Transform BGP AS_PATH attribute\n"
  3036. "Prepend to the as-path\n"
  3037. "AS number\n")
  3038. {
  3039. int ret;
  3040. char *str;
  3041. str = argv_concat (argv, argc, 0);
  3042. ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
  3043. XFREE (MTYPE_TMP, str);
  3044. return ret;
  3045. }
  3046. ALIAS (set_aspath_prepend,
  3047. set_aspath_prepend_lastas_cmd,
  3048. "set as-path prepend (last-as) <1-10>",
  3049. SET_STR
  3050. "Transform BGP AS_PATH attribute\n"
  3051. "Prepend to the as-path\n"
  3052. "Use the peer's AS-number\n"
  3053. "Number of times to insert")
  3054. DEFUN (no_set_aspath_prepend,
  3055. no_set_aspath_prepend_cmd,
  3056. "no set as-path prepend",
  3057. NO_STR
  3058. SET_STR
  3059. "Transform BGP AS_PATH attribute\n"
  3060. "Prepend to the as-path\n")
  3061. {
  3062. int ret;
  3063. char *str;
  3064. if (argc == 0)
  3065. return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
  3066. str = argv_concat (argv, argc, 0);
  3067. ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
  3068. XFREE (MTYPE_TMP, str);
  3069. return ret;
  3070. }
  3071. ALIAS (no_set_aspath_prepend,
  3072. no_set_aspath_prepend_val_cmd,
  3073. "no set as-path prepend ." CMD_AS_RANGE,
  3074. NO_STR
  3075. SET_STR
  3076. "Transform BGP AS_PATH attribute\n"
  3077. "Prepend to the as-path\n"
  3078. "AS number\n")
  3079. DEFUN (set_aspath_exclude,
  3080. set_aspath_exclude_cmd,
  3081. "set as-path exclude ." CMD_AS_RANGE,
  3082. SET_STR
  3083. "Transform BGP AS-path attribute\n"
  3084. "Exclude from the as-path\n"
  3085. "AS number\n")
  3086. {
  3087. int ret;
  3088. char *str;
  3089. str = argv_concat (argv, argc, 0);
  3090. ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
  3091. XFREE (MTYPE_TMP, str);
  3092. return ret;
  3093. }
  3094. DEFUN (no_set_aspath_exclude,
  3095. no_set_aspath_exclude_cmd,
  3096. "no set as-path exclude",
  3097. NO_STR
  3098. SET_STR
  3099. "Transform BGP AS_PATH attribute\n"
  3100. "Exclude from the as-path\n")
  3101. {
  3102. int ret;
  3103. char *str;
  3104. if (argc == 0)
  3105. return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
  3106. str = argv_concat (argv, argc, 0);
  3107. ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
  3108. XFREE (MTYPE_TMP, str);
  3109. return ret;
  3110. }
  3111. ALIAS (no_set_aspath_exclude,
  3112. no_set_aspath_exclude_val_cmd,
  3113. "no set as-path exclude ." CMD_AS_RANGE,
  3114. NO_STR
  3115. SET_STR
  3116. "Transform BGP AS_PATH attribute\n"
  3117. "Exclude from the as-path\n"
  3118. "AS number\n")
  3119. DEFUN (set_community,
  3120. set_community_cmd,
  3121. "set community .AA:NN",
  3122. SET_STR
  3123. "BGP community attribute\n"
  3124. "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
  3125. {
  3126. int i;
  3127. int first = 0;
  3128. int additive = 0;
  3129. struct buffer *b;
  3130. struct community *com = NULL;
  3131. char *str;
  3132. char *argstr;
  3133. int ret;
  3134. b = buffer_new (1024);
  3135. for (i = 0; i < argc; i++)
  3136. {
  3137. if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
  3138. {
  3139. additive = 1;
  3140. continue;
  3141. }
  3142. if (first)
  3143. buffer_putc (b, ' ');
  3144. else
  3145. first = 1;
  3146. if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
  3147. {
  3148. buffer_putstr (b, "internet");
  3149. continue;
  3150. }
  3151. if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
  3152. {
  3153. buffer_putstr (b, "local-AS");
  3154. continue;
  3155. }
  3156. if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
  3157. && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
  3158. {
  3159. buffer_putstr (b, "no-advertise");
  3160. continue;
  3161. }
  3162. if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
  3163. && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
  3164. {
  3165. buffer_putstr (b, "no-export");
  3166. continue;
  3167. }
  3168. buffer_putstr (b, argv[i]);
  3169. }
  3170. buffer_putc (b, '\0');
  3171. /* Fetch result string then compile it to communities attribute. */
  3172. str = buffer_getstr (b);
  3173. buffer_free (b);
  3174. if (str)
  3175. {
  3176. com = community_str2com (str);
  3177. XFREE (MTYPE_TMP, str);
  3178. }
  3179. /* Can't compile user input into communities attribute. */
  3180. if (! com)
  3181. {
  3182. vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
  3183. return CMD_WARNING;
  3184. }
  3185. /* Set communites attribute string. */
  3186. str = community_str (com);
  3187. if (additive)
  3188. {
  3189. argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
  3190. strcpy (argstr, str);
  3191. strcpy (argstr + strlen (str), " additive");
  3192. ret = bgp_route_set_add (vty, vty->index, "community", argstr);
  3193. XFREE (MTYPE_TMP, argstr);
  3194. }
  3195. else
  3196. ret = bgp_route_set_add (vty, vty->index, "community", str);
  3197. community_free (com);
  3198. return ret;
  3199. }
  3200. DEFUN (set_community_none,
  3201. set_community_none_cmd,
  3202. "set community none",
  3203. SET_STR
  3204. "BGP community attribute\n"
  3205. "No community attribute\n")
  3206. {
  3207. return bgp_route_set_add (vty, vty->index, "community", "none");
  3208. }
  3209. DEFUN (no_set_community,
  3210. no_set_community_cmd,
  3211. "no set community",
  3212. NO_STR
  3213. SET_STR
  3214. "BGP community attribute\n")
  3215. {
  3216. return bgp_route_set_delete (vty, vty->index, "community", NULL);
  3217. }
  3218. ALIAS (no_set_community,
  3219. no_set_community_val_cmd,
  3220. "no set community .AA:NN",
  3221. NO_STR
  3222. SET_STR
  3223. "BGP community attribute\n"
  3224. "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
  3225. ALIAS (no_set_community,
  3226. no_set_community_none_cmd,
  3227. "no set community none",
  3228. NO_STR
  3229. SET_STR
  3230. "BGP community attribute\n"
  3231. "No community attribute\n")
  3232. DEFUN (set_community_delete,
  3233. set_community_delete_cmd,
  3234. "set comm-list (<1-99>|<100-500>|WORD) delete",
  3235. SET_STR
  3236. "set BGP community list (for deletion)\n"
  3237. "Community-list number (standard)\n"
  3238. "Community-list number (expanded)\n"
  3239. "Community-list name\n"
  3240. "Delete matching communities\n")
  3241. {
  3242. char *str;
  3243. str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
  3244. strcpy (str, argv[0]);
  3245. strcpy (str + strlen (argv[0]), " delete");
  3246. bgp_route_set_add (vty, vty->index, "comm-list", str);
  3247. XFREE (MTYPE_TMP, str);
  3248. return CMD_SUCCESS;
  3249. }
  3250. DEFUN (no_set_community_delete,
  3251. no_set_community_delete_cmd,
  3252. "no set comm-list",
  3253. NO_STR
  3254. SET_STR
  3255. "set BGP community list (for deletion)\n")
  3256. {
  3257. return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
  3258. }
  3259. ALIAS (no_set_community_delete,
  3260. no_set_community_delete_val_cmd,
  3261. "no set comm-list (<1-99>|<100-500>|WORD) delete",
  3262. NO_STR
  3263. SET_STR
  3264. "set BGP community list (for deletion)\n"
  3265. "Community-list number (standard)\n"
  3266. "Community-list number (expanded)\n"
  3267. "Community-list name\n"
  3268. "Delete matching communities\n")
  3269. DEFUN (set_lcommunity,
  3270. set_lcommunity_cmd,
  3271. "set large-community .AA:BB:CC",
  3272. SET_STR
  3273. "BGP large community attribute\n"
  3274. "Large Community number in aa:bb:cc format or additive\n")
  3275. {
  3276. int ret;
  3277. char *str;
  3278. str = argv_concat (argv, argc, 0);
  3279. ret = bgp_route_set_add (vty, vty->index, "large-community", str);
  3280. XFREE (MTYPE_TMP, str);
  3281. return ret;
  3282. }
  3283. DEFUN (set_lcommunity_none,
  3284. set_lcommunity_none_cmd,
  3285. "set large-community none",
  3286. SET_STR
  3287. "BGP large community attribute\n"
  3288. "No large community attribute\n")
  3289. {
  3290. return bgp_route_set_add (vty, vty->index, "large-community", "none");
  3291. }
  3292. DEFUN (no_set_lcommunity,
  3293. no_set_lcommunity_cmd,
  3294. "no set large-community",
  3295. NO_STR
  3296. SET_STR
  3297. "BGP large community attribute\n"
  3298. "Large community\n")
  3299. {
  3300. return bgp_route_set_delete (vty, vty->index, "large-community", NULL);
  3301. }
  3302. ALIAS (no_set_lcommunity,
  3303. no_set_lcommunity_val_cmd,
  3304. "no set large-community .AA:BB:CC",
  3305. NO_STR
  3306. SET_STR
  3307. "BGP large community attribute\n"
  3308. "Large community in .AA:BB:CC format or additive\n")
  3309. ALIAS (no_set_lcommunity,
  3310. no_set_lcommunity_none_cmd,
  3311. "no set large-community none",
  3312. NO_STR
  3313. SET_STR
  3314. "BGP community attribute\n"
  3315. "No community attribute\n")
  3316. DEFUN (set_lcommunity_delete,
  3317. set_lcommunity_delete_cmd,
  3318. "set large-comm-list (<1-99>|<100-500>|WORD) delete",
  3319. SET_STR
  3320. "set BGP large community list (for deletion)\n"
  3321. "Large Community-list number (standard)\n"
  3322. "Large Communitly-list number (expanded)\n"
  3323. "Large Community-list name\n"
  3324. "Delete matching large communities\n")
  3325. {
  3326. char *str;
  3327. str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
  3328. strcpy (str, argv[0]);
  3329. strcpy (str + strlen (argv[0]), " delete");
  3330. bgp_route_set_add (vty, vty->index, "large-comm-list", str);
  3331. XFREE (MTYPE_TMP, str);
  3332. return CMD_SUCCESS;
  3333. }
  3334. DEFUN (no_set_lcommunity_delete,
  3335. no_set_lcommunity_delete_cmd,
  3336. "no set large-comm-list",
  3337. NO_STR
  3338. SET_STR
  3339. "set BGP large community list (for deletion)\n")
  3340. {
  3341. return bgp_route_set_delete (vty, vty->index, "large-comm-list", NULL);
  3342. }
  3343. ALIAS (no_set_lcommunity_delete,
  3344. no_set_lcommunity_delete_val_cmd,
  3345. "no set large-comm-list (<1-99>|<100-500>|WORD) delete",
  3346. NO_STR
  3347. SET_STR
  3348. "set BGP large community list (for deletion)\n"
  3349. "Large Community-list number (standard)\n"
  3350. "Large Communitly-list number (expanded)\n"
  3351. "Large Community-list name\n"
  3352. "Delete matching large communities\n")
  3353. DEFUN (set_ecommunity_rt,
  3354. set_ecommunity_rt_cmd,
  3355. "set extcommunity rt .ASN:nn_or_IP-address:nn",
  3356. SET_STR
  3357. "BGP extended community attribute\n"
  3358. "Route Target extended community\n"
  3359. "VPN extended community\n")
  3360. {
  3361. int ret;
  3362. char *str;
  3363. str = argv_concat (argv, argc, 0);
  3364. ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
  3365. XFREE (MTYPE_TMP, str);
  3366. return ret;
  3367. }
  3368. DEFUN (no_set_ecommunity_rt,
  3369. no_set_ecommunity_rt_cmd,
  3370. "no set extcommunity rt",
  3371. NO_STR
  3372. SET_STR
  3373. "BGP extended community attribute\n"
  3374. "Route Target extended community\n")
  3375. {
  3376. return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
  3377. }
  3378. ALIAS (no_set_ecommunity_rt,
  3379. no_set_ecommunity_rt_val_cmd,
  3380. "no set extcommunity rt .ASN:nn_or_IP-address:nn",
  3381. NO_STR
  3382. SET_STR
  3383. "BGP extended community attribute\n"
  3384. "Route Target extended community\n"
  3385. "VPN extended community\n")
  3386. DEFUN (set_ecommunity_soo,
  3387. set_ecommunity_soo_cmd,
  3388. "set extcommunity soo .ASN:nn_or_IP-address:nn",
  3389. SET_STR
  3390. "BGP extended community attribute\n"
  3391. "Site-of-Origin extended community\n"
  3392. "VPN extended community\n")
  3393. {
  3394. int ret;
  3395. char *str;
  3396. str = argv_concat (argv, argc, 0);
  3397. ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
  3398. XFREE (MTYPE_TMP, str);
  3399. return ret;
  3400. }
  3401. DEFUN (no_set_ecommunity_soo,
  3402. no_set_ecommunity_soo_cmd,
  3403. "no set extcommunity soo",
  3404. NO_STR
  3405. SET_STR
  3406. "BGP extended community attribute\n"
  3407. "Site-of-Origin extended community\n")
  3408. {
  3409. return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
  3410. }
  3411. ALIAS (no_set_ecommunity_soo,
  3412. no_set_ecommunity_soo_val_cmd,
  3413. "no set extcommunity soo .ASN:nn_or_IP-address:nn",
  3414. NO_STR
  3415. SET_STR
  3416. "BGP extended community attribute\n"
  3417. "Site-of-Origin extended community\n"
  3418. "VPN extended community\n")
  3419. DEFUN (set_origin,
  3420. set_origin_cmd,
  3421. "set origin (egp|igp|incomplete)",
  3422. SET_STR
  3423. "BGP origin code\n"
  3424. "remote EGP\n"
  3425. "local IGP\n"
  3426. "unknown heritage\n")
  3427. {
  3428. if (strncmp (argv[0], "igp", 2) == 0)
  3429. return bgp_route_set_add (vty, vty->index, "origin", "igp");
  3430. if (strncmp (argv[0], "egp", 1) == 0)
  3431. return bgp_route_set_add (vty, vty->index, "origin", "egp");
  3432. if (strncmp (argv[0], "incomplete", 2) == 0)
  3433. return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
  3434. return CMD_WARNING;
  3435. }
  3436. DEFUN (no_set_origin,
  3437. no_set_origin_cmd,
  3438. "no set origin",
  3439. NO_STR
  3440. SET_STR
  3441. "BGP origin code\n")
  3442. {
  3443. return bgp_route_set_delete (vty, vty->index, "origin", NULL);
  3444. }
  3445. ALIAS (no_set_origin,
  3446. no_set_origin_val_cmd,
  3447. "no set origin (egp|igp|incomplete)",
  3448. NO_STR
  3449. SET_STR
  3450. "BGP origin code\n"
  3451. "remote EGP\n"
  3452. "local IGP\n"
  3453. "unknown heritage\n")
  3454. DEFUN (set_atomic_aggregate,
  3455. set_atomic_aggregate_cmd,
  3456. "set atomic-aggregate",
  3457. SET_STR
  3458. "BGP atomic aggregate attribute\n" )
  3459. {
  3460. return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
  3461. }
  3462. DEFUN (no_set_atomic_aggregate,
  3463. no_set_atomic_aggregate_cmd,
  3464. "no set atomic-aggregate",
  3465. NO_STR
  3466. SET_STR
  3467. "BGP atomic aggregate attribute\n" )
  3468. {
  3469. return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
  3470. }
  3471. DEFUN (set_aggregator_as,
  3472. set_aggregator_as_cmd,
  3473. "set aggregator as " CMD_AS_RANGE " A.B.C.D",
  3474. SET_STR
  3475. "BGP aggregator attribute\n"
  3476. "AS number of aggregator\n"
  3477. "AS number\n"
  3478. "IP address of aggregator\n")
  3479. {
  3480. int ret;
  3481. as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
  3482. struct in_addr address;
  3483. char *argstr;
  3484. VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
  3485. ret = inet_aton (argv[1], &address);
  3486. if (ret == 0)
  3487. {
  3488. vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
  3489. return CMD_WARNING;
  3490. }
  3491. argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  3492. strlen (argv[0]) + strlen (argv[1]) + 2);
  3493. sprintf (argstr, "%s %s", argv[0], argv[1]);
  3494. ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
  3495. XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  3496. return ret;
  3497. }
  3498. DEFUN (no_set_aggregator_as,
  3499. no_set_aggregator_as_cmd,
  3500. "no set aggregator as",
  3501. NO_STR
  3502. SET_STR
  3503. "BGP aggregator attribute\n"
  3504. "AS number of aggregator\n")
  3505. {
  3506. int ret;
  3507. as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
  3508. struct in_addr address;
  3509. char *argstr;
  3510. if (argv == 0)
  3511. return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
  3512. VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
  3513. ret = inet_aton (argv[1], &address);
  3514. if (ret == 0)
  3515. {
  3516. vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
  3517. return CMD_WARNING;
  3518. }
  3519. argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  3520. strlen (argv[0]) + strlen (argv[1]) + 2);
  3521. sprintf (argstr, "%s %s", argv[0], argv[1]);
  3522. ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
  3523. XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  3524. return ret;
  3525. }
  3526. ALIAS (no_set_aggregator_as,
  3527. no_set_aggregator_as_val_cmd,
  3528. "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
  3529. NO_STR
  3530. SET_STR
  3531. "BGP aggregator attribute\n"
  3532. "AS number of aggregator\n"
  3533. "AS number\n"
  3534. "IP address of aggregator\n")
  3535. DEFUN (set_tag,
  3536. set_tag_cmd,
  3537. "set tag <1-4294967295>",
  3538. SET_STR
  3539. "Tag value for routing protocol\n"
  3540. "Tag value\n")
  3541. {
  3542. return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
  3543. }
  3544. DEFUN (no_set_tag,
  3545. no_set_tag_cmd,
  3546. "no set tag",
  3547. NO_STR
  3548. SET_STR
  3549. "Tag value for routing protocol\n")
  3550. {
  3551. if (argc == 0)
  3552. bgp_route_set_delete(vty, vty->index, "tag", NULL);
  3553. return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
  3554. }
  3555. ALIAS (no_set_tag,
  3556. no_set_tag_val_cmd,
  3557. "no set tag <1-4294967295>",
  3558. NO_STR
  3559. SET_STR
  3560. "Tag value for routing protocol\n"
  3561. "Tag value\n")
  3562. DEFUN (match_ipv6_address,
  3563. match_ipv6_address_cmd,
  3564. "match ipv6 address WORD",
  3565. MATCH_STR
  3566. IPV6_STR
  3567. "Match IPv6 address of route\n"
  3568. "IPv6 access-list name\n")
  3569. {
  3570. return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
  3571. }
  3572. DEFUN (no_match_ipv6_address,
  3573. no_match_ipv6_address_cmd,
  3574. "no match ipv6 address WORD",
  3575. NO_STR
  3576. MATCH_STR
  3577. IPV6_STR
  3578. "Match IPv6 address of route\n"
  3579. "IPv6 access-list name\n")
  3580. {
  3581. return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
  3582. }
  3583. DEFUN (match_ipv6_next_hop,
  3584. match_ipv6_next_hop_cmd,
  3585. "match ipv6 next-hop X:X::X:X",
  3586. MATCH_STR
  3587. IPV6_STR
  3588. "Match IPv6 next-hop address of route\n"
  3589. "IPv6 address of next hop\n")
  3590. {
  3591. return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
  3592. }
  3593. DEFUN (no_match_ipv6_next_hop,
  3594. no_match_ipv6_next_hop_cmd,
  3595. "no match ipv6 next-hop X:X::X:X",
  3596. NO_STR
  3597. MATCH_STR
  3598. IPV6_STR
  3599. "Match IPv6 next-hop address of route\n"
  3600. "IPv6 address of next hop\n")
  3601. {
  3602. return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
  3603. }
  3604. DEFUN (match_ipv6_address_prefix_list,
  3605. match_ipv6_address_prefix_list_cmd,
  3606. "match ipv6 address prefix-list WORD",
  3607. MATCH_STR
  3608. IPV6_STR
  3609. "Match address of route\n"
  3610. "Match entries of prefix-lists\n"
  3611. "IP prefix-list name\n")
  3612. {
  3613. return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
  3614. }
  3615. DEFUN (no_match_ipv6_address_prefix_list,
  3616. no_match_ipv6_address_prefix_list_cmd,
  3617. "no match ipv6 address prefix-list WORD",
  3618. NO_STR
  3619. MATCH_STR
  3620. IPV6_STR
  3621. "Match address of route\n"
  3622. "Match entries of prefix-lists\n"
  3623. "IP prefix-list name\n")
  3624. {
  3625. return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
  3626. }
  3627. DEFUN (set_ipv6_nexthop_peer,
  3628. set_ipv6_nexthop_peer_cmd,
  3629. "set ipv6 next-hop peer-address",
  3630. SET_STR
  3631. IPV6_STR
  3632. "Next hop address\n"
  3633. "Use peer address (for BGP only)\n")
  3634. {
  3635. return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
  3636. }
  3637. DEFUN (no_set_ipv6_nexthop_peer,
  3638. no_set_ipv6_nexthop_peer_cmd,
  3639. "no set ipv6 next-hop peer-address",
  3640. NO_STR
  3641. SET_STR
  3642. IPV6_STR
  3643. "IPv6 next-hop address\n"
  3644. )
  3645. {
  3646. return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
  3647. }
  3648. DEFUN (set_ipv6_nexthop_global,
  3649. set_ipv6_nexthop_global_cmd,
  3650. "set ipv6 next-hop global X:X::X:X",
  3651. SET_STR
  3652. IPV6_STR
  3653. "IPv6 next-hop address\n"
  3654. "IPv6 global address\n"
  3655. "IPv6 address of next hop\n")
  3656. {
  3657. return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
  3658. }
  3659. DEFUN (no_set_ipv6_nexthop_global,
  3660. no_set_ipv6_nexthop_global_cmd,
  3661. "no set ipv6 next-hop global",
  3662. NO_STR
  3663. SET_STR
  3664. IPV6_STR
  3665. "IPv6 next-hop address\n"
  3666. "IPv6 global address\n")
  3667. {
  3668. if (argc == 0)
  3669. return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
  3670. return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
  3671. }
  3672. ALIAS (no_set_ipv6_nexthop_global,
  3673. no_set_ipv6_nexthop_global_val_cmd,
  3674. "no set ipv6 next-hop global X:X::X:X",
  3675. NO_STR
  3676. SET_STR
  3677. IPV6_STR
  3678. "IPv6 next-hop address\n"
  3679. "IPv6 global address\n"
  3680. "IPv6 address of next hop\n")
  3681. DEFUN (set_ipv6_nexthop_local,
  3682. set_ipv6_nexthop_local_cmd,
  3683. "set ipv6 next-hop local X:X::X:X",
  3684. SET_STR
  3685. IPV6_STR
  3686. "IPv6 next-hop address\n"
  3687. "IPv6 local address\n"
  3688. "IPv6 address of next hop\n")
  3689. {
  3690. return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
  3691. }
  3692. DEFUN (no_set_ipv6_nexthop_local,
  3693. no_set_ipv6_nexthop_local_cmd,
  3694. "no set ipv6 next-hop local",
  3695. NO_STR
  3696. SET_STR
  3697. IPV6_STR
  3698. "IPv6 next-hop address\n"
  3699. "IPv6 local address\n")
  3700. {
  3701. if (argc == 0)
  3702. return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
  3703. return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
  3704. }
  3705. ALIAS (no_set_ipv6_nexthop_local,
  3706. no_set_ipv6_nexthop_local_val_cmd,
  3707. "no set ipv6 next-hop local X:X::X:X",
  3708. NO_STR
  3709. SET_STR
  3710. IPV6_STR
  3711. "IPv6 next-hop address\n"
  3712. "IPv6 local address\n"
  3713. "IPv6 address of next hop\n")
  3714. DEFUN (set_vpnv4_nexthop,
  3715. set_vpnv4_nexthop_cmd,
  3716. "set vpnv4 next-hop A.B.C.D",
  3717. SET_STR
  3718. "VPNv4 information\n"
  3719. "VPNv4 next-hop address\n"
  3720. "IP address of next hop\n")
  3721. {
  3722. return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
  3723. }
  3724. DEFUN (no_set_vpnv4_nexthop,
  3725. no_set_vpnv4_nexthop_cmd,
  3726. "no set vpnv4 next-hop",
  3727. NO_STR
  3728. SET_STR
  3729. "VPNv4 information\n"
  3730. "VPNv4 next-hop address\n")
  3731. {
  3732. if (argc == 0)
  3733. return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
  3734. return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
  3735. }
  3736. ALIAS (no_set_vpnv4_nexthop,
  3737. no_set_vpnv4_nexthop_val_cmd,
  3738. "no set vpnv4 next-hop A.B.C.D",
  3739. NO_STR
  3740. SET_STR
  3741. "VPNv4 information\n"
  3742. "VPNv4 next-hop address\n"
  3743. "IP address of next hop\n")
  3744. DEFUN (set_originator_id,
  3745. set_originator_id_cmd,
  3746. "set originator-id A.B.C.D",
  3747. SET_STR
  3748. "BGP originator ID attribute\n"
  3749. "IP address of originator\n")
  3750. {
  3751. return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
  3752. }
  3753. DEFUN (no_set_originator_id,
  3754. no_set_originator_id_cmd,
  3755. "no set originator-id",
  3756. NO_STR
  3757. SET_STR
  3758. "BGP originator ID attribute\n")
  3759. {
  3760. if (argc == 0)
  3761. return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
  3762. return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
  3763. }
  3764. ALIAS (no_set_originator_id,
  3765. no_set_originator_id_val_cmd,
  3766. "no set originator-id A.B.C.D",
  3767. NO_STR
  3768. SET_STR
  3769. "BGP originator ID attribute\n"
  3770. "IP address of originator\n")
  3771. DEFUN_DEPRECATED (set_pathlimit_ttl,
  3772. set_pathlimit_ttl_cmd,
  3773. "set pathlimit ttl <1-255>",
  3774. SET_STR
  3775. "BGP AS-Pathlimit attribute\n"
  3776. "Set AS-Path Hop-count TTL\n")
  3777. {
  3778. return CMD_SUCCESS;
  3779. }
  3780. DEFUN_DEPRECATED (no_set_pathlimit_ttl,
  3781. no_set_pathlimit_ttl_cmd,
  3782. "no set pathlimit ttl",
  3783. NO_STR
  3784. SET_STR
  3785. "BGP AS-Pathlimit attribute\n"
  3786. "Set AS-Path Hop-count TTL\n")
  3787. {
  3788. return CMD_SUCCESS;
  3789. }
  3790. ALIAS (no_set_pathlimit_ttl,
  3791. no_set_pathlimit_ttl_val_cmd,
  3792. "no set pathlimit ttl <1-255>",
  3793. NO_STR
  3794. MATCH_STR
  3795. "BGP AS-Pathlimit attribute\n"
  3796. "Set AS-Path Hop-count TTL\n")
  3797. DEFUN_DEPRECATED (match_pathlimit_as,
  3798. match_pathlimit_as_cmd,
  3799. "match pathlimit as <1-65535>",
  3800. MATCH_STR
  3801. "BGP AS-Pathlimit attribute\n"
  3802. "Match Pathlimit AS number\n")
  3803. {
  3804. return CMD_SUCCESS;
  3805. }
  3806. DEFUN_DEPRECATED (no_match_pathlimit_as,
  3807. no_match_pathlimit_as_cmd,
  3808. "no match pathlimit as",
  3809. NO_STR
  3810. MATCH_STR
  3811. "BGP AS-Pathlimit attribute\n"
  3812. "Match Pathlimit AS number\n")
  3813. {
  3814. return CMD_SUCCESS;
  3815. }
  3816. ALIAS (no_match_pathlimit_as,
  3817. no_match_pathlimit_as_val_cmd,
  3818. "no match pathlimit as <1-65535>",
  3819. NO_STR
  3820. MATCH_STR
  3821. "BGP AS-Pathlimit attribute\n"
  3822. "Match Pathlimit ASN\n")
  3823. /* Initialization of route map. */
  3824. void
  3825. bgp_route_map_init (void)
  3826. {
  3827. route_map_init ();
  3828. route_map_init_vty ();
  3829. route_map_add_hook (bgp_route_map_update);
  3830. route_map_delete_hook (bgp_route_map_update);
  3831. route_map_install_match (&route_match_peer_cmd);
  3832. route_map_install_match (&route_match_local_pref_cmd);
  3833. route_map_install_match (&route_match_ip_address_cmd);
  3834. route_map_install_match (&route_match_ip_next_hop_cmd);
  3835. route_map_install_match (&route_match_ip_route_source_cmd);
  3836. route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  3837. route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  3838. route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
  3839. route_map_install_match (&route_match_aspath_cmd);
  3840. route_map_install_match (&route_match_community_cmd);
  3841. route_map_install_match (&route_match_lcommunity_cmd);
  3842. route_map_install_match (&route_match_ecommunity_cmd);
  3843. route_map_install_match (&route_match_local_pref_cmd);
  3844. route_map_install_match (&route_match_metric_cmd);
  3845. route_map_install_match (&route_match_origin_cmd);
  3846. route_map_install_match (&route_match_probability_cmd);
  3847. route_map_install_match (&route_match_tag_cmd);
  3848. route_map_install_set (&route_set_ip_nexthop_cmd);
  3849. route_map_install_set (&route_set_local_pref_cmd);
  3850. route_map_install_set (&route_set_weight_cmd);
  3851. route_map_install_set (&route_set_metric_cmd);
  3852. route_map_install_set (&route_set_aspath_prepend_cmd);
  3853. route_map_install_set (&route_set_aspath_exclude_cmd);
  3854. route_map_install_set (&route_set_origin_cmd);
  3855. route_map_install_set (&route_set_atomic_aggregate_cmd);
  3856. route_map_install_set (&route_set_aggregator_as_cmd);
  3857. route_map_install_set (&route_set_community_cmd);
  3858. route_map_install_set (&route_set_community_delete_cmd);
  3859. route_map_install_set (&route_set_lcommunity_cmd);
  3860. route_map_install_set (&route_set_lcommunity_delete_cmd);
  3861. route_map_install_set (&route_set_vpnv4_nexthop_cmd);
  3862. route_map_install_set (&route_set_originator_id_cmd);
  3863. route_map_install_set (&route_set_ecommunity_rt_cmd);
  3864. route_map_install_set (&route_set_ecommunity_soo_cmd);
  3865. route_map_install_set (&route_set_tag_cmd);
  3866. install_element (RMAP_NODE, &match_peer_cmd);
  3867. install_element (RMAP_NODE, &match_peer_local_cmd);
  3868. install_element (RMAP_NODE, &no_match_peer_cmd);
  3869. install_element (RMAP_NODE, &no_match_peer_val_cmd);
  3870. install_element (RMAP_NODE, &no_match_peer_local_cmd);
  3871. install_element (RMAP_NODE, &match_ip_address_cmd);
  3872. install_element (RMAP_NODE, &no_match_ip_address_cmd);
  3873. install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  3874. install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  3875. install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  3876. install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  3877. install_element (RMAP_NODE, &match_ip_route_source_cmd);
  3878. install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
  3879. install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
  3880. install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  3881. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  3882. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  3883. install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  3884. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  3885. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  3886. install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
  3887. install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
  3888. install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
  3889. install_element (RMAP_NODE, &match_aspath_cmd);
  3890. install_element (RMAP_NODE, &no_match_aspath_cmd);
  3891. install_element (RMAP_NODE, &no_match_aspath_val_cmd);
  3892. install_element (RMAP_NODE, &match_metric_cmd);
  3893. install_element (RMAP_NODE, &no_match_metric_cmd);
  3894. install_element (RMAP_NODE, &no_match_metric_val_cmd);
  3895. install_element (RMAP_NODE, &match_local_pref_cmd);
  3896. install_element (RMAP_NODE, &no_match_local_pref_cmd);
  3897. install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
  3898. install_element (RMAP_NODE, &match_community_cmd);
  3899. install_element (RMAP_NODE, &match_community_exact_cmd);
  3900. install_element (RMAP_NODE, &no_match_community_cmd);
  3901. install_element (RMAP_NODE, &no_match_community_val_cmd);
  3902. install_element (RMAP_NODE, &no_match_community_exact_cmd);
  3903. install_element (RMAP_NODE, &match_lcommunity_cmd);
  3904. install_element (RMAP_NODE, &no_match_lcommunity_cmd);
  3905. install_element (RMAP_NODE, &match_ecommunity_cmd);
  3906. install_element (RMAP_NODE, &no_match_ecommunity_cmd);
  3907. install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
  3908. install_element (RMAP_NODE, &match_origin_cmd);
  3909. install_element (RMAP_NODE, &no_match_origin_cmd);
  3910. install_element (RMAP_NODE, &no_match_origin_val_cmd);
  3911. install_element (RMAP_NODE, &match_probability_cmd);
  3912. install_element (RMAP_NODE, &no_match_probability_cmd);
  3913. install_element (RMAP_NODE, &no_match_probability_val_cmd);
  3914. install_element (RMAP_NODE, &match_tag_cmd);
  3915. install_element (RMAP_NODE, &no_match_tag_cmd);
  3916. install_element (RMAP_NODE, &no_match_tag_val_cmd);
  3917. install_element (RMAP_NODE, &set_ip_nexthop_cmd);
  3918. install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
  3919. install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
  3920. install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
  3921. install_element (RMAP_NODE, &set_local_pref_cmd);
  3922. install_element (RMAP_NODE, &no_set_local_pref_cmd);
  3923. install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
  3924. install_element (RMAP_NODE, &set_weight_cmd);
  3925. install_element (RMAP_NODE, &no_set_weight_cmd);
  3926. install_element (RMAP_NODE, &no_set_weight_val_cmd);
  3927. install_element (RMAP_NODE, &set_metric_cmd);
  3928. install_element (RMAP_NODE, &set_metric_addsub_cmd);
  3929. install_element (RMAP_NODE, &set_metric_rtt_cmd);
  3930. install_element (RMAP_NODE, &no_set_metric_cmd);
  3931. install_element (RMAP_NODE, &no_set_metric_val_cmd);
  3932. install_element (RMAP_NODE, &set_aspath_prepend_cmd);
  3933. install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
  3934. install_element (RMAP_NODE, &set_aspath_exclude_cmd);
  3935. install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
  3936. install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
  3937. install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
  3938. install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
  3939. install_element (RMAP_NODE, &set_origin_cmd);
  3940. install_element (RMAP_NODE, &no_set_origin_cmd);
  3941. install_element (RMAP_NODE, &no_set_origin_val_cmd);
  3942. install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
  3943. install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
  3944. install_element (RMAP_NODE, &set_aggregator_as_cmd);
  3945. install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
  3946. install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
  3947. install_element (RMAP_NODE, &set_community_cmd);
  3948. install_element (RMAP_NODE, &set_community_none_cmd);
  3949. install_element (RMAP_NODE, &no_set_community_cmd);
  3950. install_element (RMAP_NODE, &no_set_community_val_cmd);
  3951. install_element (RMAP_NODE, &no_set_community_none_cmd);
  3952. install_element (RMAP_NODE, &set_community_delete_cmd);
  3953. install_element (RMAP_NODE, &no_set_community_delete_cmd);
  3954. install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
  3955. install_element (RMAP_NODE, &set_lcommunity_cmd);
  3956. install_element (RMAP_NODE, &set_lcommunity_none_cmd);
  3957. install_element (RMAP_NODE, &no_set_lcommunity_cmd);
  3958. install_element (RMAP_NODE, &no_set_lcommunity_val_cmd);
  3959. install_element (RMAP_NODE, &no_set_lcommunity_none_cmd);
  3960. install_element (RMAP_NODE, &set_lcommunity_delete_cmd);
  3961. install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd);
  3962. install_element (RMAP_NODE, &no_set_lcommunity_delete_val_cmd);
  3963. install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
  3964. install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
  3965. install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
  3966. install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
  3967. install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
  3968. install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
  3969. install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
  3970. install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
  3971. install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
  3972. install_element (RMAP_NODE, &set_originator_id_cmd);
  3973. install_element (RMAP_NODE, &no_set_originator_id_cmd);
  3974. install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
  3975. install_element (RMAP_NODE, &set_tag_cmd);
  3976. install_element (RMAP_NODE, &no_set_tag_cmd);
  3977. install_element (RMAP_NODE, &no_set_tag_val_cmd);
  3978. route_map_install_match (&route_match_ipv6_address_cmd);
  3979. route_map_install_match (&route_match_ipv6_next_hop_cmd);
  3980. route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
  3981. route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
  3982. route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
  3983. route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
  3984. install_element (RMAP_NODE, &match_ipv6_address_cmd);
  3985. install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
  3986. install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
  3987. install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
  3988. install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
  3989. install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
  3990. install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
  3991. install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
  3992. install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
  3993. install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
  3994. install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
  3995. install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
  3996. install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
  3997. install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
  3998. /* AS-Pathlimit: functionality removed, commands kept for
  3999. * compatibility.
  4000. */
  4001. install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
  4002. install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
  4003. install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
  4004. install_element (RMAP_NODE, &match_pathlimit_as_cmd);
  4005. install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
  4006. install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
  4007. }