bgp_routemap.c 117 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690
  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. }