pim_cmd.c 132 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981
  1. /*
  2. PIM for Quagga
  3. Copyright (C) 2008 Everton da Silva Marques
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program 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 this program; see the file COPYING; if not, write to the
  14. Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  15. MA 02110-1301 USA
  16. $QuaggaId: $Format:%an, %ai, %h$ $
  17. */
  18. #include <sys/ioctl.h>
  19. #include <zebra.h>
  20. #include "command.h"
  21. #include "if.h"
  22. #include "prefix.h"
  23. #include "zclient.h"
  24. #include "pimd.h"
  25. #include "pim_cmd.h"
  26. #include "pim_iface.h"
  27. #include "pim_vty.h"
  28. #include "pim_mroute.h"
  29. #include "pim_str.h"
  30. #include "pim_igmp.h"
  31. #include "pim_igmpv3.h"
  32. #include "pim_sock.h"
  33. #include "pim_time.h"
  34. #include "pim_util.h"
  35. #include "pim_oil.h"
  36. #include "pim_neighbor.h"
  37. #include "pim_pim.h"
  38. #include "pim_ifchannel.h"
  39. #include "pim_hello.h"
  40. #include "pim_msg.h"
  41. #include "pim_upstream.h"
  42. #include "pim_rpf.h"
  43. #include "pim_macro.h"
  44. #include "pim_ssmpingd.h"
  45. #include "pim_zebra.h"
  46. #include "pim_static.h"
  47. static struct cmd_node pim_global_node = {
  48. PIM_NODE,
  49. "",
  50. 1 /* vtysh ? yes */
  51. };
  52. static struct cmd_node interface_node = {
  53. INTERFACE_NODE,
  54. "%s(config-if)# ",
  55. 1 /* vtysh ? yes */
  56. };
  57. static void pim_if_membership_clear(struct interface *ifp)
  58. {
  59. struct pim_interface *pim_ifp;
  60. pim_ifp = ifp->info;
  61. zassert(pim_ifp);
  62. if (PIM_IF_TEST_PIM(pim_ifp->options) &&
  63. PIM_IF_TEST_IGMP(pim_ifp->options)) {
  64. return;
  65. }
  66. pim_ifchannel_membership_clear(ifp);
  67. }
  68. /*
  69. When PIM is disabled on interface, IGMPv3 local membership
  70. information is not injected into PIM interface state.
  71. The function pim_if_membership_refresh() fetches all IGMPv3 local
  72. membership information into PIM. It is intented to be called
  73. whenever PIM is enabled on the interface in order to collect missed
  74. local membership information.
  75. */
  76. static void pim_if_membership_refresh(struct interface *ifp)
  77. {
  78. struct pim_interface *pim_ifp;
  79. struct listnode *sock_node;
  80. struct igmp_sock *igmp;
  81. pim_ifp = ifp->info;
  82. zassert(pim_ifp);
  83. if (!PIM_IF_TEST_PIM(pim_ifp->options))
  84. return;
  85. if (!PIM_IF_TEST_IGMP(pim_ifp->options))
  86. return;
  87. /*
  88. First clear off membership from all PIM (S,G) entries on the
  89. interface
  90. */
  91. pim_ifchannel_membership_clear(ifp);
  92. /*
  93. Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
  94. the interface
  95. */
  96. /* scan igmp sockets */
  97. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  98. struct listnode *grpnode;
  99. struct igmp_group *grp;
  100. /* scan igmp groups */
  101. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  102. struct listnode *srcnode;
  103. struct igmp_source *src;
  104. /* scan group sources */
  105. for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
  106. if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
  107. pim_ifchannel_local_membership_add(ifp,
  108. src->source_addr,
  109. grp->group_addr);
  110. }
  111. } /* scan group sources */
  112. } /* scan igmp groups */
  113. } /* scan igmp sockets */
  114. /*
  115. Finally delete every PIM (S,G) entry lacking all state info
  116. */
  117. pim_ifchannel_delete_on_noinfo(ifp);
  118. }
  119. static void pim_show_assert(struct vty *vty)
  120. {
  121. struct listnode *ifnode;
  122. struct interface *ifp;
  123. time_t now;
  124. now = pim_time_monotonic_sec();
  125. vty_out(vty,
  126. "Interface Address Source Group State Winner Uptime Timer%s",
  127. VTY_NEWLINE);
  128. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  129. struct pim_interface *pim_ifp;
  130. struct in_addr ifaddr;
  131. struct listnode *ch_node;
  132. struct pim_ifchannel *ch;
  133. pim_ifp = ifp->info;
  134. if (!pim_ifp)
  135. continue;
  136. ifaddr = pim_ifp->primary_address;
  137. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  138. char ch_src_str[100];
  139. char ch_grp_str[100];
  140. char winner_str[100];
  141. char uptime[10];
  142. char timer[10];
  143. pim_inet4_dump("<ch_src?>", ch->source_addr,
  144. ch_src_str, sizeof(ch_src_str));
  145. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  146. ch_grp_str, sizeof(ch_grp_str));
  147. pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
  148. winner_str, sizeof(winner_str));
  149. pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
  150. pim_time_timer_to_mmss(timer, sizeof(timer),
  151. ch->t_ifassert_timer);
  152. vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
  153. ifp->name,
  154. inet_ntoa(ifaddr),
  155. ch_src_str,
  156. ch_grp_str,
  157. pim_ifchannel_ifassert_name(ch->ifassert_state),
  158. winner_str,
  159. uptime,
  160. timer,
  161. VTY_NEWLINE);
  162. } /* scan interface channels */
  163. } /* scan interfaces */
  164. }
  165. static void pim_show_assert_internal(struct vty *vty)
  166. {
  167. struct listnode *ifnode;
  168. struct interface *ifp;
  169. vty_out(vty,
  170. "CA: CouldAssert%s"
  171. "ECA: Evaluate CouldAssert%s"
  172. "ATD: AssertTrackingDesired%s"
  173. "eATD: Evaluate AssertTrackingDesired%s%s",
  174. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  175. vty_out(vty,
  176. "Interface Address Source Group CA eCA ATD eATD%s",
  177. VTY_NEWLINE);
  178. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  179. struct pim_interface *pim_ifp;
  180. struct in_addr ifaddr;
  181. struct listnode *ch_node;
  182. struct pim_ifchannel *ch;
  183. pim_ifp = ifp->info;
  184. if (!pim_ifp)
  185. continue;
  186. ifaddr = pim_ifp->primary_address;
  187. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  188. char ch_src_str[100];
  189. char ch_grp_str[100];
  190. pim_inet4_dump("<ch_src?>", ch->source_addr,
  191. ch_src_str, sizeof(ch_src_str));
  192. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  193. ch_grp_str, sizeof(ch_grp_str));
  194. vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
  195. ifp->name,
  196. inet_ntoa(ifaddr),
  197. ch_src_str,
  198. ch_grp_str,
  199. PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
  200. pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
  201. PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
  202. pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
  203. VTY_NEWLINE);
  204. } /* scan interface channels */
  205. } /* scan interfaces */
  206. }
  207. static void pim_show_assert_metric(struct vty *vty)
  208. {
  209. struct listnode *ifnode;
  210. struct interface *ifp;
  211. vty_out(vty,
  212. "Interface Address Source Group RPT Pref Metric Address %s",
  213. VTY_NEWLINE);
  214. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  215. struct pim_interface *pim_ifp;
  216. struct in_addr ifaddr;
  217. struct listnode *ch_node;
  218. struct pim_ifchannel *ch;
  219. pim_ifp = ifp->info;
  220. if (!pim_ifp)
  221. continue;
  222. ifaddr = pim_ifp->primary_address;
  223. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  224. char ch_src_str[100];
  225. char ch_grp_str[100];
  226. char addr_str[100];
  227. struct pim_assert_metric am;
  228. am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
  229. pim_inet4_dump("<ch_src?>", ch->source_addr,
  230. ch_src_str, sizeof(ch_src_str));
  231. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  232. ch_grp_str, sizeof(ch_grp_str));
  233. pim_inet4_dump("<addr?>", am.ip_address,
  234. addr_str, sizeof(addr_str));
  235. vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
  236. ifp->name,
  237. inet_ntoa(ifaddr),
  238. ch_src_str,
  239. ch_grp_str,
  240. am.rpt_bit_flag ? "yes" : "no",
  241. am.metric_preference,
  242. am.route_metric,
  243. addr_str,
  244. VTY_NEWLINE);
  245. } /* scan interface channels */
  246. } /* scan interfaces */
  247. }
  248. static void pim_show_assert_winner_metric(struct vty *vty)
  249. {
  250. struct listnode *ifnode;
  251. struct interface *ifp;
  252. vty_out(vty,
  253. "Interface Address Source Group RPT Pref Metric Address %s",
  254. VTY_NEWLINE);
  255. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  256. struct pim_interface *pim_ifp;
  257. struct in_addr ifaddr;
  258. struct listnode *ch_node;
  259. struct pim_ifchannel *ch;
  260. pim_ifp = ifp->info;
  261. if (!pim_ifp)
  262. continue;
  263. ifaddr = pim_ifp->primary_address;
  264. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  265. char ch_src_str[100];
  266. char ch_grp_str[100];
  267. char addr_str[100];
  268. struct pim_assert_metric *am;
  269. char pref_str[5];
  270. char metr_str[7];
  271. am = &ch->ifassert_winner_metric;
  272. pim_inet4_dump("<ch_src?>", ch->source_addr,
  273. ch_src_str, sizeof(ch_src_str));
  274. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  275. ch_grp_str, sizeof(ch_grp_str));
  276. pim_inet4_dump("<addr?>", am->ip_address,
  277. addr_str, sizeof(addr_str));
  278. if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
  279. snprintf(pref_str, sizeof(pref_str), "INFI");
  280. else
  281. snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
  282. if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
  283. snprintf(metr_str, sizeof(metr_str), "INFI");
  284. else
  285. snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
  286. vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
  287. ifp->name,
  288. inet_ntoa(ifaddr),
  289. ch_src_str,
  290. ch_grp_str,
  291. am->rpt_bit_flag ? "yes" : "no",
  292. pref_str,
  293. metr_str,
  294. addr_str,
  295. VTY_NEWLINE);
  296. } /* scan interface channels */
  297. } /* scan interfaces */
  298. }
  299. static void pim_show_membership(struct vty *vty)
  300. {
  301. struct listnode *ifnode;
  302. struct interface *ifp;
  303. vty_out(vty,
  304. "Interface Address Source Group Membership%s",
  305. VTY_NEWLINE);
  306. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  307. struct pim_interface *pim_ifp;
  308. struct in_addr ifaddr;
  309. struct listnode *ch_node;
  310. struct pim_ifchannel *ch;
  311. pim_ifp = ifp->info;
  312. if (!pim_ifp)
  313. continue;
  314. ifaddr = pim_ifp->primary_address;
  315. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  316. char ch_src_str[100];
  317. char ch_grp_str[100];
  318. pim_inet4_dump("<ch_src?>", ch->source_addr,
  319. ch_src_str, sizeof(ch_src_str));
  320. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  321. ch_grp_str, sizeof(ch_grp_str));
  322. vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
  323. ifp->name,
  324. inet_ntoa(ifaddr),
  325. ch_src_str,
  326. ch_grp_str,
  327. ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
  328. "NOINFO" : "INCLUDE",
  329. VTY_NEWLINE);
  330. } /* scan interface channels */
  331. } /* scan interfaces */
  332. }
  333. static void igmp_show_interfaces(struct vty *vty)
  334. {
  335. struct listnode *node;
  336. struct interface *ifp;
  337. time_t now;
  338. now = pim_time_monotonic_sec();
  339. vty_out(vty,
  340. "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
  341. VTY_NEWLINE);
  342. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  343. struct pim_interface *pim_ifp;
  344. struct listnode *sock_node;
  345. struct igmp_sock *igmp;
  346. pim_ifp = ifp->info;
  347. if (!pim_ifp)
  348. continue;
  349. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  350. char uptime[10];
  351. int mloop;
  352. pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
  353. mloop = pim_socket_mcastloop_get(igmp->fd);
  354. vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
  355. ifp->name,
  356. inet_ntoa(igmp->ifaddr),
  357. ifp->ifindex,
  358. igmp->fd,
  359. uptime,
  360. if_is_multicast(ifp) ? "yes" : "no",
  361. if_is_broadcast(ifp) ? "yes" : "no",
  362. (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
  363. (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
  364. (ifp->flags & IFF_PROMISC) ? "yes" : "no",
  365. PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
  366. VTY_NEWLINE);
  367. }
  368. }
  369. }
  370. static void igmp_show_interface_join(struct vty *vty)
  371. {
  372. struct listnode *node;
  373. struct interface *ifp;
  374. time_t now;
  375. now = pim_time_monotonic_sec();
  376. vty_out(vty,
  377. "Interface Address Source Group Socket Uptime %s",
  378. VTY_NEWLINE);
  379. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  380. struct pim_interface *pim_ifp;
  381. struct listnode *join_node;
  382. struct igmp_join *ij;
  383. struct in_addr pri_addr;
  384. char pri_addr_str[100];
  385. pim_ifp = ifp->info;
  386. if (!pim_ifp)
  387. continue;
  388. if (!pim_ifp->igmp_join_list)
  389. continue;
  390. pri_addr = pim_find_primary_addr(ifp);
  391. pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
  392. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
  393. char group_str[100];
  394. char source_str[100];
  395. char uptime[10];
  396. pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
  397. pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
  398. pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
  399. vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s%s",
  400. ifp->name,
  401. pri_addr_str,
  402. source_str,
  403. group_str,
  404. ij->sock_fd,
  405. uptime,
  406. VTY_NEWLINE);
  407. } /* for (pim_ifp->igmp_join_list) */
  408. } /* for (iflist) */
  409. }
  410. static void show_interface_address(struct vty *vty)
  411. {
  412. struct listnode *ifpnode;
  413. struct interface *ifp;
  414. vty_out(vty,
  415. "Interface Primary Secondary %s",
  416. VTY_NEWLINE);
  417. for (ALL_LIST_ELEMENTS_RO(iflist, ifpnode, ifp)) {
  418. struct listnode *ifcnode;
  419. struct connected *ifc;
  420. struct in_addr pri_addr;
  421. char pri_addr_str[100];
  422. pri_addr = pim_find_primary_addr(ifp);
  423. pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
  424. for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
  425. char sec_addr_str[100];
  426. struct prefix *p = ifc->address;
  427. if (p->family != AF_INET)
  428. continue;
  429. if (p->u.prefix4.s_addr == pri_addr.s_addr) {
  430. sec_addr_str[0] = '\0';
  431. }
  432. else {
  433. pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
  434. }
  435. vty_out(vty, "%-9s %-15s %-15s%s",
  436. ifp->name,
  437. pri_addr_str,
  438. sec_addr_str,
  439. VTY_NEWLINE);
  440. }
  441. }
  442. }
  443. static void pim_show_dr(struct vty *vty)
  444. {
  445. struct listnode *node;
  446. struct interface *ifp;
  447. time_t now;
  448. now = pim_time_monotonic_sec();
  449. vty_out(vty,
  450. "NonPri: Number of neighbors missing DR Priority hello option%s"
  451. "DrPri: Designated Router Priority sent%s%s",
  452. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  453. vty_out(vty, "Interface Address DR Uptime Elections Changes NonPri DrPri%s", VTY_NEWLINE);
  454. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  455. struct pim_interface *pim_ifp;
  456. struct in_addr ifaddr;
  457. char dr_str[100];
  458. char dr_uptime[10];
  459. pim_ifp = ifp->info;
  460. if (!pim_ifp)
  461. continue;
  462. if (pim_ifp->pim_sock_fd < 0)
  463. continue;
  464. ifaddr = pim_ifp->primary_address;
  465. pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
  466. now, pim_ifp->pim_dr_election_last);
  467. pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
  468. dr_str, sizeof(dr_str));
  469. vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
  470. ifp->name,
  471. inet_ntoa(ifaddr),
  472. dr_str,
  473. dr_uptime,
  474. pim_ifp->pim_dr_election_count,
  475. pim_ifp->pim_dr_election_changes,
  476. pim_ifp->pim_dr_num_nondrpri_neighbors,
  477. pim_ifp->pim_dr_priority,
  478. VTY_NEWLINE);
  479. }
  480. }
  481. static void pim_show_hello(struct vty *vty)
  482. {
  483. struct listnode *node;
  484. struct interface *ifp;
  485. time_t now;
  486. now = pim_time_monotonic_sec();
  487. vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
  488. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  489. struct pim_interface *pim_ifp;
  490. struct in_addr ifaddr;
  491. char hello_period[10];
  492. char hello_timer[10];
  493. char stat_uptime[10];
  494. pim_ifp = ifp->info;
  495. if (!pim_ifp)
  496. continue;
  497. if (pim_ifp->pim_sock_fd < 0)
  498. continue;
  499. ifaddr = pim_ifp->primary_address;
  500. pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
  501. pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
  502. pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
  503. vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
  504. ifp->name,
  505. inet_ntoa(ifaddr),
  506. hello_period,
  507. hello_timer,
  508. stat_uptime,
  509. pim_ifp->pim_ifstat_hello_recv,
  510. pim_ifp->pim_ifstat_hello_recvfail,
  511. pim_ifp->pim_ifstat_hello_sent,
  512. pim_ifp->pim_ifstat_hello_sendfail,
  513. VTY_NEWLINE);
  514. }
  515. }
  516. static void pim_show_interfaces(struct vty *vty)
  517. {
  518. struct listnode *node;
  519. struct interface *ifp;
  520. time_t now;
  521. now = pim_time_monotonic_sec();
  522. vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
  523. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  524. struct pim_interface *pim_ifp;
  525. struct in_addr ifaddr;
  526. char uptime[10];
  527. int mloop;
  528. pim_ifp = ifp->info;
  529. if (!pim_ifp)
  530. continue;
  531. if (pim_ifp->pim_sock_fd < 0)
  532. continue;
  533. ifaddr = pim_ifp->primary_address;
  534. pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
  535. mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
  536. vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
  537. ifp->name,
  538. inet_ntoa(ifaddr),
  539. ifp->ifindex,
  540. pim_ifp->pim_sock_fd,
  541. uptime,
  542. if_is_multicast(ifp) ? "yes" : "no",
  543. if_is_broadcast(ifp) ? "yes" : "no",
  544. (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
  545. (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
  546. (ifp->flags & IFF_PROMISC) ? "yes" : "no",
  547. PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
  548. VTY_NEWLINE);
  549. }
  550. }
  551. static void pim_show_join(struct vty *vty)
  552. {
  553. struct listnode *ifnode;
  554. struct interface *ifp;
  555. time_t now;
  556. now = pim_time_monotonic_sec();
  557. vty_out(vty,
  558. "Interface Address Source Group State Uptime Expire Prune%s",
  559. VTY_NEWLINE);
  560. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  561. struct pim_interface *pim_ifp;
  562. struct in_addr ifaddr;
  563. struct listnode *ch_node;
  564. struct pim_ifchannel *ch;
  565. pim_ifp = ifp->info;
  566. if (!pim_ifp)
  567. continue;
  568. ifaddr = pim_ifp->primary_address;
  569. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  570. char ch_src_str[100];
  571. char ch_grp_str[100];
  572. char uptime[10];
  573. char expire[10];
  574. char prune[10];
  575. pim_inet4_dump("<ch_src?>", ch->source_addr,
  576. ch_src_str, sizeof(ch_src_str));
  577. pim_inet4_dump("<ch_grp?>", ch->group_addr,
  578. ch_grp_str, sizeof(ch_grp_str));
  579. pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
  580. pim_time_timer_to_mmss(expire, sizeof(expire),
  581. ch->t_ifjoin_expiry_timer);
  582. pim_time_timer_to_mmss(prune, sizeof(prune),
  583. ch->t_ifjoin_prune_pending_timer);
  584. vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
  585. ifp->name,
  586. inet_ntoa(ifaddr),
  587. ch_src_str,
  588. ch_grp_str,
  589. pim_ifchannel_ifjoin_name(ch->ifjoin_state),
  590. uptime,
  591. expire,
  592. prune,
  593. VTY_NEWLINE);
  594. } /* scan interface channels */
  595. } /* scan interfaces */
  596. }
  597. static void pim_show_neighbors(struct vty *vty)
  598. {
  599. struct listnode *node;
  600. struct interface *ifp;
  601. time_t now;
  602. now = pim_time_monotonic_sec();
  603. vty_out(vty,
  604. "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
  605. " T=can_disable_join_suppression%s%s",
  606. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  607. vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
  608. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  609. struct pim_interface *pim_ifp;
  610. struct in_addr ifaddr;
  611. struct listnode *neighnode;
  612. struct pim_neighbor *neigh;
  613. pim_ifp = ifp->info;
  614. if (!pim_ifp)
  615. continue;
  616. if (pim_ifp->pim_sock_fd < 0)
  617. continue;
  618. ifaddr = pim_ifp->primary_address;
  619. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  620. char uptime[10];
  621. char holdtime[10];
  622. char expire[10];
  623. char neigh_src_str[100];
  624. char recv[7];
  625. pim_inet4_dump("<src?>", neigh->source_addr,
  626. neigh_src_str, sizeof(neigh_src_str));
  627. pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
  628. pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
  629. pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
  630. recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
  631. recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
  632. recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
  633. recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
  634. recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
  635. recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
  636. recv[6] = '\0';
  637. vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
  638. ifp->name,
  639. inet_ntoa(ifaddr),
  640. neigh_src_str,
  641. uptime,
  642. expire,
  643. holdtime,
  644. neigh->dr_priority,
  645. neigh->generation_id,
  646. recv,
  647. VTY_NEWLINE);
  648. }
  649. }
  650. }
  651. static void pim_show_lan_prune_delay(struct vty *vty)
  652. {
  653. struct listnode *node;
  654. struct interface *ifp;
  655. vty_out(vty,
  656. "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
  657. "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
  658. "NoDly=number_of_non_lan_delay_neighbors%s"
  659. "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
  660. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  661. vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T | Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
  662. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  663. struct pim_interface *pim_ifp;
  664. struct in_addr ifaddr;
  665. struct listnode *neighnode;
  666. struct pim_neighbor *neigh;
  667. pim_ifp = ifp->info;
  668. if (!pim_ifp)
  669. continue;
  670. if (pim_ifp->pim_sock_fd < 0)
  671. continue;
  672. ifaddr = pim_ifp->primary_address;
  673. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  674. char neigh_src_str[100];
  675. pim_inet4_dump("<src?>", neigh->source_addr,
  676. neigh_src_str, sizeof(neigh_src_str));
  677. vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
  678. ifp->name,
  679. inet_ntoa(ifaddr),
  680. pim_ifp->pim_propagation_delay_msec,
  681. pim_ifp->pim_override_interval_msec,
  682. pim_ifp->pim_number_of_nonlandelay_neighbors,
  683. pim_ifp->pim_neighbors_highest_propagation_delay_msec,
  684. pim_ifp->pim_neighbors_highest_override_interval_msec,
  685. PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
  686. neigh_src_str,
  687. PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
  688. neigh->propagation_delay_msec,
  689. neigh->override_interval_msec,
  690. PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
  691. PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
  692. VTY_NEWLINE);
  693. }
  694. }
  695. }
  696. static void pim_show_jp_override_interval(struct vty *vty)
  697. {
  698. struct listnode *node;
  699. struct interface *ifp;
  700. vty_out(vty,
  701. "EffPDelay=effective_propagation_delay (msec)%s"
  702. "EffOvrInt=override_interval (msec)%s"
  703. "JPOvrInt=jp_override_interval (msec)%s%s",
  704. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  705. vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
  706. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  707. struct pim_interface *pim_ifp;
  708. struct in_addr ifaddr;
  709. pim_ifp = ifp->info;
  710. if (!pim_ifp)
  711. continue;
  712. if (pim_ifp->pim_sock_fd < 0)
  713. continue;
  714. ifaddr = pim_ifp->primary_address;
  715. vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
  716. ifp->name,
  717. inet_ntoa(ifaddr),
  718. pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
  719. pim_if_effective_propagation_delay_msec(ifp),
  720. pim_if_effective_override_interval_msec(ifp),
  721. pim_if_jp_override_interval_msec(ifp),
  722. VTY_NEWLINE);
  723. }
  724. }
  725. static void pim_show_neighbors_secondary(struct vty *vty)
  726. {
  727. struct listnode *node;
  728. struct interface *ifp;
  729. vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
  730. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  731. struct pim_interface *pim_ifp;
  732. struct in_addr ifaddr;
  733. struct listnode *neighnode;
  734. struct pim_neighbor *neigh;
  735. pim_ifp = ifp->info;
  736. if (!pim_ifp)
  737. continue;
  738. if (pim_ifp->pim_sock_fd < 0)
  739. continue;
  740. ifaddr = pim_ifp->primary_address;
  741. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  742. char neigh_src_str[100];
  743. struct listnode *prefix_node;
  744. struct prefix *p;
  745. if (!neigh->prefix_list)
  746. continue;
  747. pim_inet4_dump("<src?>", neigh->source_addr,
  748. neigh_src_str, sizeof(neigh_src_str));
  749. for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
  750. char neigh_sec_str[100];
  751. if (p->family != AF_INET)
  752. continue;
  753. pim_inet4_dump("<src?>", p->u.prefix4,
  754. neigh_sec_str, sizeof(neigh_sec_str));
  755. vty_out(vty, "%-9s %-15s %-15s %-15s%s",
  756. ifp->name,
  757. inet_ntoa(ifaddr),
  758. neigh_src_str,
  759. neigh_sec_str,
  760. VTY_NEWLINE);
  761. }
  762. }
  763. }
  764. }
  765. static void pim_show_upstream(struct vty *vty)
  766. {
  767. struct listnode *upnode;
  768. struct pim_upstream *up;
  769. time_t now;
  770. now = pim_time_monotonic_sec();
  771. vty_out(vty, "Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
  772. for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
  773. char src_str[100];
  774. char grp_str[100];
  775. char uptime[10];
  776. char join_timer[10];
  777. pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
  778. pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
  779. pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
  780. pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
  781. vty_out(vty, "%-15s %-15s %-5s %-8s %-9s %6d%s",
  782. src_str,
  783. grp_str,
  784. up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
  785. uptime,
  786. join_timer,
  787. up->ref_count,
  788. VTY_NEWLINE);
  789. }
  790. }
  791. static void pim_show_join_desired(struct vty *vty)
  792. {
  793. struct listnode *ifnode;
  794. struct listnode *chnode;
  795. struct interface *ifp;
  796. struct pim_interface *pim_ifp;
  797. struct pim_ifchannel *ch;
  798. char src_str[100];
  799. char grp_str[100];
  800. vty_out(vty,
  801. "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
  802. VTY_NEWLINE);
  803. /* scan all interfaces */
  804. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  805. pim_ifp = ifp->info;
  806. if (!pim_ifp)
  807. continue;
  808. /* scan per-interface (S,G) state */
  809. for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
  810. struct pim_upstream *up = ch->upstream;
  811. pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
  812. pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
  813. vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
  814. ifp->name,
  815. src_str,
  816. grp_str,
  817. pim_macro_ch_lost_assert(ch) ? "yes" : "no",
  818. pim_macro_chisin_joins(ch) ? "yes" : "no",
  819. pim_macro_chisin_pim_include(ch) ? "yes" : "no",
  820. PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
  821. pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
  822. VTY_NEWLINE);
  823. }
  824. }
  825. }
  826. static void pim_show_upstream_rpf(struct vty *vty)
  827. {
  828. struct listnode *upnode;
  829. struct pim_upstream *up;
  830. vty_out(vty,
  831. "Source Group RpfIface RibNextHop RpfAddress %s",
  832. VTY_NEWLINE);
  833. for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
  834. char src_str[100];
  835. char grp_str[100];
  836. char rpf_nexthop_str[100];
  837. char rpf_addr_str[100];
  838. struct pim_rpf *rpf;
  839. const char *rpf_ifname;
  840. rpf = &up->rpf;
  841. pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
  842. pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
  843. pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
  844. pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
  845. rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
  846. vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
  847. src_str,
  848. grp_str,
  849. rpf_ifname,
  850. rpf_nexthop_str,
  851. rpf_addr_str,
  852. VTY_NEWLINE);
  853. }
  854. }
  855. static void show_rpf_refresh_stats(struct vty *vty, time_t now)
  856. {
  857. char refresh_uptime[10];
  858. pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
  859. vty_out(vty,
  860. "RPF Cache Refresh Delay: %ld msecs%s"
  861. "RPF Cache Refresh Timer: %ld msecs%s"
  862. "RPF Cache Refresh Requests: %lld%s"
  863. "RPF Cache Refresh Events: %lld%s"
  864. "RPF Cache Refresh Last: %s%s",
  865. qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
  866. pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
  867. (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
  868. (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
  869. refresh_uptime, VTY_NEWLINE);
  870. }
  871. static void show_scan_oil_stats(struct vty *vty, time_t now)
  872. {
  873. char uptime_scan_oil[10];
  874. char uptime_mroute_add[10];
  875. char uptime_mroute_del[10];
  876. pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
  877. pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
  878. pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
  879. vty_out(vty,
  880. "Scan OIL - Last: %s Events: %lld%s"
  881. "MFC Add - Last: %s Events: %lld%s"
  882. "MFC Del - Last: %s Events: %lld%s",
  883. uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
  884. uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
  885. uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
  886. }
  887. static void pim_show_rpf(struct vty *vty)
  888. {
  889. struct listnode *up_node;
  890. struct pim_upstream *up;
  891. time_t now = pim_time_monotonic_sec();
  892. show_rpf_refresh_stats(vty, now);
  893. vty_out(vty, "%s", VTY_NEWLINE);
  894. vty_out(vty,
  895. "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
  896. VTY_NEWLINE);
  897. for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
  898. char src_str[100];
  899. char grp_str[100];
  900. char rpf_addr_str[100];
  901. char rib_nexthop_str[100];
  902. const char *rpf_ifname;
  903. struct pim_rpf *rpf = &up->rpf;
  904. pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
  905. pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
  906. pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
  907. pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
  908. rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
  909. vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
  910. src_str,
  911. grp_str,
  912. rpf_ifname,
  913. rpf_addr_str,
  914. rib_nexthop_str,
  915. rpf->source_nexthop.mrib_route_metric,
  916. rpf->source_nexthop.mrib_metric_preference,
  917. VTY_NEWLINE);
  918. }
  919. }
  920. static void igmp_show_querier(struct vty *vty)
  921. {
  922. struct listnode *node;
  923. struct interface *ifp;
  924. vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
  925. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  926. struct pim_interface *pim_ifp = ifp->info;
  927. struct listnode *sock_node;
  928. struct igmp_sock *igmp;
  929. if (!pim_ifp)
  930. continue;
  931. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  932. char query_hhmmss[10];
  933. char other_hhmmss[10];
  934. pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
  935. pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
  936. vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
  937. ifp->name,
  938. inet_ntoa(igmp->ifaddr),
  939. igmp->t_igmp_query_timer ? "THIS" : "OTHER",
  940. igmp->startup_query_count,
  941. query_hhmmss,
  942. other_hhmmss,
  943. VTY_NEWLINE);
  944. }
  945. }
  946. }
  947. static void igmp_show_groups(struct vty *vty)
  948. {
  949. struct listnode *ifnode;
  950. struct interface *ifp;
  951. time_t now;
  952. now = pim_time_monotonic_sec();
  953. vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
  954. /* scan interfaces */
  955. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  956. struct pim_interface *pim_ifp = ifp->info;
  957. struct listnode *sock_node;
  958. struct igmp_sock *igmp;
  959. if (!pim_ifp)
  960. continue;
  961. /* scan igmp sockets */
  962. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  963. char ifaddr_str[100];
  964. struct listnode *grpnode;
  965. struct igmp_group *grp;
  966. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  967. /* scan igmp groups */
  968. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  969. char group_str[100];
  970. char hhmmss[10];
  971. char uptime[10];
  972. pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
  973. pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
  974. pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
  975. vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
  976. ifp->name,
  977. ifaddr_str,
  978. group_str,
  979. grp->group_filtermode_isexcl ? "EXCL" : "INCL",
  980. hhmmss,
  981. grp->group_source_list ? listcount(grp->group_source_list) : 0,
  982. igmp_group_compat_mode(igmp, grp),
  983. uptime,
  984. VTY_NEWLINE);
  985. } /* scan igmp groups */
  986. } /* scan igmp sockets */
  987. } /* scan interfaces */
  988. }
  989. static void igmp_show_group_retransmission(struct vty *vty)
  990. {
  991. struct listnode *ifnode;
  992. struct interface *ifp;
  993. vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
  994. /* scan interfaces */
  995. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  996. struct pim_interface *pim_ifp = ifp->info;
  997. struct listnode *sock_node;
  998. struct igmp_sock *igmp;
  999. if (!pim_ifp)
  1000. continue;
  1001. /* scan igmp sockets */
  1002. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  1003. char ifaddr_str[100];
  1004. struct listnode *grpnode;
  1005. struct igmp_group *grp;
  1006. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  1007. /* scan igmp groups */
  1008. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  1009. char group_str[100];
  1010. char grp_retr_mmss[10];
  1011. struct listnode *src_node;
  1012. struct igmp_source *src;
  1013. int grp_retr_sources = 0;
  1014. pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
  1015. pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
  1016. /* count group sources with retransmission state */
  1017. for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
  1018. if (src->source_query_retransmit_count > 0) {
  1019. ++grp_retr_sources;
  1020. }
  1021. }
  1022. vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
  1023. ifp->name,
  1024. ifaddr_str,
  1025. group_str,
  1026. grp_retr_mmss,
  1027. grp->group_specific_query_retransmit_count,
  1028. grp_retr_sources,
  1029. VTY_NEWLINE);
  1030. } /* scan igmp groups */
  1031. } /* scan igmp sockets */
  1032. } /* scan interfaces */
  1033. }
  1034. static void igmp_show_parameters(struct vty *vty)
  1035. {
  1036. struct listnode *ifnode;
  1037. struct interface *ifp;
  1038. vty_out(vty,
  1039. "QRV: Robustness Variable SQI: Startup Query Interval%s"
  1040. "QQI: Query Interval OQPI: Other Querier Present Interval%s"
  1041. "QRI: Query Response Interval LMQT: Last Member Query Time%s"
  1042. "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
  1043. VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  1044. vty_out(vty,
  1045. "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
  1046. VTY_NEWLINE);
  1047. /* scan interfaces */
  1048. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  1049. struct pim_interface *pim_ifp = ifp->info;
  1050. struct listnode *sock_node;
  1051. struct igmp_sock *igmp;
  1052. if (!pim_ifp)
  1053. continue;
  1054. /* scan igmp sockets */
  1055. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  1056. char ifaddr_str[100];
  1057. long gmi_dsec; /* Group Membership Interval */
  1058. long oqpi_dsec; /* Other Querier Present Interval */
  1059. int sqi;
  1060. long lmqt_dsec;
  1061. long ohpi_dsec;
  1062. long qri_dsec;
  1063. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  1064. gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
  1065. igmp->querier_query_interval,
  1066. pim_ifp->igmp_query_max_response_time_dsec) / 100;
  1067. sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
  1068. oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
  1069. igmp->querier_query_interval,
  1070. pim_ifp->igmp_query_max_response_time_dsec) / 100;
  1071. lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
  1072. igmp->querier_robustness_variable) / 100;
  1073. ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
  1074. igmp->querier_query_interval,
  1075. pim_ifp->igmp_query_max_response_time_dsec);
  1076. qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
  1077. vty_out(vty,
  1078. "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
  1079. ifp->name,
  1080. ifaddr_str,
  1081. igmp->querier_robustness_variable,
  1082. igmp->querier_query_interval,
  1083. qri_dsec / 10, qri_dsec % 10,
  1084. gmi_dsec / 10, gmi_dsec % 10,
  1085. sqi,
  1086. oqpi_dsec / 10, oqpi_dsec % 10,
  1087. lmqt_dsec / 10, lmqt_dsec % 10,
  1088. ohpi_dsec / 10, ohpi_dsec % 10,
  1089. VTY_NEWLINE);
  1090. } /* scan igmp sockets */
  1091. } /* scan interfaces */
  1092. }
  1093. static void igmp_show_sources(struct vty *vty)
  1094. {
  1095. struct listnode *ifnode;
  1096. struct interface *ifp;
  1097. time_t now;
  1098. now = pim_time_monotonic_sec();
  1099. vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
  1100. /* scan interfaces */
  1101. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  1102. struct pim_interface *pim_ifp = ifp->info;
  1103. struct listnode *sock_node;
  1104. struct igmp_sock *igmp;
  1105. if (!pim_ifp)
  1106. continue;
  1107. /* scan igmp sockets */
  1108. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  1109. char ifaddr_str[100];
  1110. struct listnode *grpnode;
  1111. struct igmp_group *grp;
  1112. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  1113. /* scan igmp groups */
  1114. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  1115. char group_str[100];
  1116. struct listnode *srcnode;
  1117. struct igmp_source *src;
  1118. pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
  1119. /* scan group sources */
  1120. for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
  1121. char source_str[100];
  1122. char mmss[10];
  1123. char uptime[10];
  1124. pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
  1125. pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
  1126. pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
  1127. vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
  1128. ifp->name,
  1129. ifaddr_str,
  1130. group_str,
  1131. source_str,
  1132. mmss,
  1133. IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
  1134. uptime,
  1135. VTY_NEWLINE);
  1136. } /* scan group sources */
  1137. } /* scan igmp groups */
  1138. } /* scan igmp sockets */
  1139. } /* scan interfaces */
  1140. }
  1141. static void igmp_show_source_retransmission(struct vty *vty)
  1142. {
  1143. struct listnode *ifnode;
  1144. struct interface *ifp;
  1145. vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
  1146. /* scan interfaces */
  1147. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  1148. struct pim_interface *pim_ifp = ifp->info;
  1149. struct listnode *sock_node;
  1150. struct igmp_sock *igmp;
  1151. if (!pim_ifp)
  1152. continue;
  1153. /* scan igmp sockets */
  1154. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  1155. char ifaddr_str[100];
  1156. struct listnode *grpnode;
  1157. struct igmp_group *grp;
  1158. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  1159. /* scan igmp groups */
  1160. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  1161. char group_str[100];
  1162. struct listnode *srcnode;
  1163. struct igmp_source *src;
  1164. pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
  1165. /* scan group sources */
  1166. for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
  1167. char source_str[100];
  1168. pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
  1169. vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
  1170. ifp->name,
  1171. ifaddr_str,
  1172. group_str,
  1173. source_str,
  1174. src->source_query_retransmit_count,
  1175. VTY_NEWLINE);
  1176. } /* scan group sources */
  1177. } /* scan igmp groups */
  1178. } /* scan igmp sockets */
  1179. } /* scan interfaces */
  1180. }
  1181. static void clear_igmp_interfaces()
  1182. {
  1183. struct listnode *ifnode;
  1184. struct listnode *ifnextnode;
  1185. struct interface *ifp;
  1186. for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
  1187. pim_if_addr_del_all_igmp(ifp);
  1188. }
  1189. for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
  1190. pim_if_addr_add_all(ifp);
  1191. }
  1192. }
  1193. static void clear_pim_interfaces()
  1194. {
  1195. struct listnode *ifnode;
  1196. struct listnode *ifnextnode;
  1197. struct interface *ifp;
  1198. for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
  1199. if (ifp->info) {
  1200. pim_neighbor_delete_all(ifp, "interface cleared");
  1201. }
  1202. }
  1203. }
  1204. static void clear_interfaces()
  1205. {
  1206. clear_igmp_interfaces();
  1207. clear_pim_interfaces();
  1208. }
  1209. DEFUN (pim_interface,
  1210. pim_interface_cmd,
  1211. "interface IFNAME",
  1212. "Select an interface to configure\n"
  1213. "Interface's name\n")
  1214. {
  1215. struct interface *ifp;
  1216. const char *ifname = argv[0];
  1217. size_t sl;
  1218. sl = strlen(ifname);
  1219. if (sl > INTERFACE_NAMSIZ) {
  1220. vty_out(vty, "%% Interface name %s is invalid: length exceeds "
  1221. "%d characters%s",
  1222. ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
  1223. return CMD_WARNING;
  1224. }
  1225. ifp = if_lookup_by_name_len(ifname, sl);
  1226. if (!ifp) {
  1227. vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
  1228. /* Returning here would prevent pimd from booting when there are
  1229. interface commands in pimd.conf, since all interfaces are
  1230. unknown at pimd boot time (the zebra daemon has not been
  1231. contacted for interface discovery). */
  1232. ifp = if_get_by_name_len(ifname, sl);
  1233. if (!ifp) {
  1234. vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
  1235. return CMD_WARNING;
  1236. }
  1237. }
  1238. vty->index = ifp;
  1239. vty->node = INTERFACE_NODE;
  1240. return CMD_SUCCESS;
  1241. }
  1242. DEFUN (clear_ip_interfaces,
  1243. clear_ip_interfaces_cmd,
  1244. "clear ip interfaces",
  1245. CLEAR_STR
  1246. IP_STR
  1247. "Reset interfaces\n")
  1248. {
  1249. clear_interfaces();
  1250. return CMD_SUCCESS;
  1251. }
  1252. DEFUN (clear_ip_igmp_interfaces,
  1253. clear_ip_igmp_interfaces_cmd,
  1254. "clear ip igmp interfaces",
  1255. CLEAR_STR
  1256. IP_STR
  1257. CLEAR_IP_IGMP_STR
  1258. "Reset IGMP interfaces\n")
  1259. {
  1260. clear_igmp_interfaces();
  1261. return CMD_SUCCESS;
  1262. }
  1263. static void mroute_add_all()
  1264. {
  1265. struct listnode *node;
  1266. struct channel_oil *c_oil;
  1267. for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
  1268. if (pim_mroute_add(&c_oil->oil)) {
  1269. /* just log warning */
  1270. char source_str[100];
  1271. char group_str[100];
  1272. pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
  1273. pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
  1274. zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
  1275. __FILE__, __PRETTY_FUNCTION__,
  1276. source_str, group_str);
  1277. }
  1278. }
  1279. }
  1280. static void mroute_del_all()
  1281. {
  1282. struct listnode *node;
  1283. struct channel_oil *c_oil;
  1284. for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
  1285. if (pim_mroute_del(&c_oil->oil)) {
  1286. /* just log warning */
  1287. char source_str[100];
  1288. char group_str[100];
  1289. pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
  1290. pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
  1291. zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
  1292. __FILE__, __PRETTY_FUNCTION__,
  1293. source_str, group_str);
  1294. }
  1295. }
  1296. }
  1297. static void static_mroute_add_all()
  1298. {
  1299. struct listnode *node;
  1300. struct static_route *s_route;
  1301. for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
  1302. if (pim_mroute_add(&s_route->mc)) {
  1303. /* just log warning */
  1304. char source_str[100];
  1305. char group_str[100];
  1306. pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
  1307. pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
  1308. zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
  1309. __FILE__, __PRETTY_FUNCTION__,
  1310. source_str, group_str);
  1311. }
  1312. }
  1313. }
  1314. static void static_mroute_del_all()
  1315. {
  1316. struct listnode *node;
  1317. struct static_route *s_route;
  1318. for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
  1319. if (pim_mroute_del(&s_route->mc)) {
  1320. /* just log warning */
  1321. char source_str[100];
  1322. char group_str[100];
  1323. pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
  1324. pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
  1325. zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
  1326. __FILE__, __PRETTY_FUNCTION__,
  1327. source_str, group_str);
  1328. }
  1329. }
  1330. }
  1331. DEFUN (clear_ip_mroute,
  1332. clear_ip_mroute_cmd,
  1333. "clear ip mroute",
  1334. CLEAR_STR
  1335. IP_STR
  1336. "Reset multicast routes\n")
  1337. {
  1338. mroute_del_all();
  1339. mroute_add_all();
  1340. return CMD_SUCCESS;
  1341. }
  1342. DEFUN (clear_ip_pim_interfaces,
  1343. clear_ip_pim_interfaces_cmd,
  1344. "clear ip pim interfaces",
  1345. CLEAR_STR
  1346. IP_STR
  1347. CLEAR_IP_PIM_STR
  1348. "Reset PIM interfaces\n")
  1349. {
  1350. clear_pim_interfaces();
  1351. return CMD_SUCCESS;
  1352. }
  1353. DEFUN (clear_ip_pim_oil,
  1354. clear_ip_pim_oil_cmd,
  1355. "clear ip pim oil",
  1356. CLEAR_STR
  1357. IP_STR
  1358. CLEAR_IP_PIM_STR
  1359. "Rescan PIM OIL (output interface list)\n")
  1360. {
  1361. pim_scan_oil();
  1362. return CMD_SUCCESS;
  1363. }
  1364. DEFUN (show_ip_igmp_interface,
  1365. show_ip_igmp_interface_cmd,
  1366. "show ip igmp interface",
  1367. SHOW_STR
  1368. IP_STR
  1369. IGMP_STR
  1370. "IGMP interface information\n")
  1371. {
  1372. igmp_show_interfaces(vty);
  1373. return CMD_SUCCESS;
  1374. }
  1375. DEFUN (show_ip_igmp_join,
  1376. show_ip_igmp_join_cmd,
  1377. "show ip igmp join",
  1378. SHOW_STR
  1379. IP_STR
  1380. IGMP_STR
  1381. "IGMP static join information\n")
  1382. {
  1383. igmp_show_interface_join(vty);
  1384. return CMD_SUCCESS;
  1385. }
  1386. DEFUN (show_ip_igmp_groups,
  1387. show_ip_igmp_groups_cmd,
  1388. "show ip igmp groups",
  1389. SHOW_STR
  1390. IP_STR
  1391. IGMP_STR
  1392. IGMP_GROUP_STR)
  1393. {
  1394. igmp_show_groups(vty);
  1395. return CMD_SUCCESS;
  1396. }
  1397. DEFUN (show_ip_igmp_groups_retransmissions,
  1398. show_ip_igmp_groups_retransmissions_cmd,
  1399. "show ip igmp groups retransmissions",
  1400. SHOW_STR
  1401. IP_STR
  1402. IGMP_STR
  1403. IGMP_GROUP_STR
  1404. "IGMP group retransmissions\n")
  1405. {
  1406. igmp_show_group_retransmission(vty);
  1407. return CMD_SUCCESS;
  1408. }
  1409. DEFUN (show_ip_igmp_parameters,
  1410. show_ip_igmp_parameters_cmd,
  1411. "show ip igmp parameters",
  1412. SHOW_STR
  1413. IP_STR
  1414. IGMP_STR
  1415. "IGMP parameters information\n")
  1416. {
  1417. igmp_show_parameters(vty);
  1418. return CMD_SUCCESS;
  1419. }
  1420. DEFUN (show_ip_igmp_sources,
  1421. show_ip_igmp_sources_cmd,
  1422. "show ip igmp sources",
  1423. SHOW_STR
  1424. IP_STR
  1425. IGMP_STR
  1426. IGMP_SOURCE_STR)
  1427. {
  1428. igmp_show_sources(vty);
  1429. return CMD_SUCCESS;
  1430. }
  1431. DEFUN (show_ip_igmp_sources_retransmissions,
  1432. show_ip_igmp_sources_retransmissions_cmd,
  1433. "show ip igmp sources retransmissions",
  1434. SHOW_STR
  1435. IP_STR
  1436. IGMP_STR
  1437. IGMP_SOURCE_STR
  1438. "IGMP source retransmissions\n")
  1439. {
  1440. igmp_show_source_retransmission(vty);
  1441. return CMD_SUCCESS;
  1442. }
  1443. DEFUN (show_ip_igmp_querier,
  1444. show_ip_igmp_querier_cmd,
  1445. "show ip igmp querier",
  1446. SHOW_STR
  1447. IP_STR
  1448. IGMP_STR
  1449. "IGMP querier information\n")
  1450. {
  1451. igmp_show_querier(vty);
  1452. return CMD_SUCCESS;
  1453. }
  1454. DEFUN (show_ip_pim_address,
  1455. show_ip_pim_address_cmd,
  1456. "show ip pim address",
  1457. SHOW_STR
  1458. IP_STR
  1459. PIM_STR
  1460. "PIM interface address\n")
  1461. {
  1462. show_interface_address(vty);
  1463. return CMD_SUCCESS;
  1464. }
  1465. DEFUN (show_ip_pim_assert,
  1466. show_ip_pim_assert_cmd,
  1467. "show ip pim assert",
  1468. SHOW_STR
  1469. IP_STR
  1470. PIM_STR
  1471. "PIM interface assert\n")
  1472. {
  1473. pim_show_assert(vty);
  1474. return CMD_SUCCESS;
  1475. }
  1476. DEFUN (show_ip_pim_assert_internal,
  1477. show_ip_pim_assert_internal_cmd,
  1478. "show ip pim assert-internal",
  1479. SHOW_STR
  1480. IP_STR
  1481. PIM_STR
  1482. "PIM interface internal assert state\n")
  1483. {
  1484. pim_show_assert_internal(vty);
  1485. return CMD_SUCCESS;
  1486. }
  1487. DEFUN (show_ip_pim_assert_metric,
  1488. show_ip_pim_assert_metric_cmd,
  1489. "show ip pim assert-metric",
  1490. SHOW_STR
  1491. IP_STR
  1492. PIM_STR
  1493. "PIM interface assert metric\n")
  1494. {
  1495. pim_show_assert_metric(vty);
  1496. return CMD_SUCCESS;
  1497. }
  1498. DEFUN (show_ip_pim_assert_winner_metric,
  1499. show_ip_pim_assert_winner_metric_cmd,
  1500. "show ip pim assert-winner-metric",
  1501. SHOW_STR
  1502. IP_STR
  1503. PIM_STR
  1504. "PIM interface assert winner metric\n")
  1505. {
  1506. pim_show_assert_winner_metric(vty);
  1507. return CMD_SUCCESS;
  1508. }
  1509. DEFUN (show_ip_pim_dr,
  1510. show_ip_pim_dr_cmd,
  1511. "show ip pim designated-router",
  1512. SHOW_STR
  1513. IP_STR
  1514. PIM_STR
  1515. "PIM interface designated router\n")
  1516. {
  1517. pim_show_dr(vty);
  1518. return CMD_SUCCESS;
  1519. }
  1520. DEFUN (show_ip_pim_hello,
  1521. show_ip_pim_hello_cmd,
  1522. "show ip pim hello",
  1523. SHOW_STR
  1524. IP_STR
  1525. PIM_STR
  1526. "PIM interface hello information\n")
  1527. {
  1528. pim_show_hello(vty);
  1529. return CMD_SUCCESS;
  1530. }
  1531. DEFUN (show_ip_pim_interface,
  1532. show_ip_pim_interface_cmd,
  1533. "show ip pim interface",
  1534. SHOW_STR
  1535. IP_STR
  1536. PIM_STR
  1537. "PIM interface information\n")
  1538. {
  1539. pim_show_interfaces(vty);
  1540. return CMD_SUCCESS;
  1541. }
  1542. DEFUN (show_ip_pim_join,
  1543. show_ip_pim_join_cmd,
  1544. "show ip pim join",
  1545. SHOW_STR
  1546. IP_STR
  1547. PIM_STR
  1548. "PIM interface join information\n")
  1549. {
  1550. pim_show_join(vty);
  1551. return CMD_SUCCESS;
  1552. }
  1553. DEFUN (show_ip_pim_lan_prune_delay,
  1554. show_ip_pim_lan_prune_delay_cmd,
  1555. "show ip pim lan-prune-delay",
  1556. SHOW_STR
  1557. IP_STR
  1558. PIM_STR
  1559. "PIM neighbors LAN prune delay parameters\n")
  1560. {
  1561. pim_show_lan_prune_delay(vty);
  1562. return CMD_SUCCESS;
  1563. }
  1564. DEFUN (show_ip_pim_local_membership,
  1565. show_ip_pim_local_membership_cmd,
  1566. "show ip pim local-membership",
  1567. SHOW_STR
  1568. IP_STR
  1569. PIM_STR
  1570. "PIM interface local-membership\n")
  1571. {
  1572. pim_show_membership(vty);
  1573. return CMD_SUCCESS;
  1574. }
  1575. DEFUN (show_ip_pim_jp_override_interval,
  1576. show_ip_pim_jp_override_interval_cmd,
  1577. "show ip pim jp-override-interval",
  1578. SHOW_STR
  1579. IP_STR
  1580. PIM_STR
  1581. "PIM interface J/P override interval\n")
  1582. {
  1583. pim_show_jp_override_interval(vty);
  1584. return CMD_SUCCESS;
  1585. }
  1586. DEFUN (show_ip_pim_neighbor,
  1587. show_ip_pim_neighbor_cmd,
  1588. "show ip pim neighbor",
  1589. SHOW_STR
  1590. IP_STR
  1591. PIM_STR
  1592. "PIM neighbor information\n")
  1593. {
  1594. pim_show_neighbors(vty);
  1595. return CMD_SUCCESS;
  1596. }
  1597. DEFUN (show_ip_pim_secondary,
  1598. show_ip_pim_secondary_cmd,
  1599. "show ip pim secondary",
  1600. SHOW_STR
  1601. IP_STR
  1602. PIM_STR
  1603. "PIM neighbor addresses\n")
  1604. {
  1605. pim_show_neighbors_secondary(vty);
  1606. return CMD_SUCCESS;
  1607. }
  1608. DEFUN (show_ip_pim_upstream,
  1609. show_ip_pim_upstream_cmd,
  1610. "show ip pim upstream",
  1611. SHOW_STR
  1612. IP_STR
  1613. PIM_STR
  1614. "PIM upstream information\n")
  1615. {
  1616. pim_show_upstream(vty);
  1617. return CMD_SUCCESS;
  1618. }
  1619. DEFUN (show_ip_pim_upstream_join_desired,
  1620. show_ip_pim_upstream_join_desired_cmd,
  1621. "show ip pim upstream-join-desired",
  1622. SHOW_STR
  1623. IP_STR
  1624. PIM_STR
  1625. "PIM upstream join-desired\n")
  1626. {
  1627. pim_show_join_desired(vty);
  1628. return CMD_SUCCESS;
  1629. }
  1630. DEFUN (show_ip_pim_upstream_rpf,
  1631. show_ip_pim_upstream_rpf_cmd,
  1632. "show ip pim upstream-rpf",
  1633. SHOW_STR
  1634. IP_STR
  1635. PIM_STR
  1636. "PIM upstream source rpf\n")
  1637. {
  1638. pim_show_upstream_rpf(vty);
  1639. return CMD_SUCCESS;
  1640. }
  1641. DEFUN (show_ip_pim_rpf,
  1642. show_ip_pim_rpf_cmd,
  1643. "show ip pim rpf",
  1644. SHOW_STR
  1645. IP_STR
  1646. PIM_STR
  1647. "PIM cached source rpf information\n")
  1648. {
  1649. pim_show_rpf(vty);
  1650. return CMD_SUCCESS;
  1651. }
  1652. static void show_multicast_interfaces(struct vty *vty)
  1653. {
  1654. struct listnode *node;
  1655. struct interface *ifp;
  1656. vty_out(vty, "%s", VTY_NEWLINE);
  1657. vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
  1658. VTY_NEWLINE);
  1659. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  1660. struct pim_interface *pim_ifp;
  1661. struct in_addr ifaddr;
  1662. struct sioc_vif_req vreq;
  1663. pim_ifp = ifp->info;
  1664. if (!pim_ifp)
  1665. continue;
  1666. memset(&vreq, 0, sizeof(vreq));
  1667. vreq.vifi = pim_ifp->mroute_vif_index;
  1668. if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
  1669. zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
  1670. (unsigned long)SIOCGETVIFCNT,
  1671. ifp->name,
  1672. pim_ifp->mroute_vif_index,
  1673. errno,
  1674. safe_strerror(errno),
  1675. VTY_NEWLINE);
  1676. }
  1677. ifaddr = pim_ifp->primary_address;
  1678. vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
  1679. ifp->name,
  1680. inet_ntoa(ifaddr),
  1681. ifp->ifindex,
  1682. pim_ifp->mroute_vif_index,
  1683. vreq.icount,
  1684. vreq.ocount,
  1685. vreq.ibytes,
  1686. vreq.obytes,
  1687. VTY_NEWLINE);
  1688. }
  1689. }
  1690. DEFUN (show_ip_multicast,
  1691. show_ip_multicast_cmd,
  1692. "show ip multicast",
  1693. SHOW_STR
  1694. IP_STR
  1695. "Multicast global information\n")
  1696. {
  1697. time_t now = pim_time_monotonic_sec();
  1698. if (PIM_MROUTE_IS_ENABLED) {
  1699. char uptime[10];
  1700. vty_out(vty, "Mroute socket descriptor: %d%s",
  1701. qpim_mroute_socket_fd,
  1702. VTY_NEWLINE);
  1703. pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
  1704. vty_out(vty, "Mroute socket uptime: %s%s",
  1705. uptime,
  1706. VTY_NEWLINE);
  1707. }
  1708. else {
  1709. vty_out(vty, "Multicast disabled%s",
  1710. VTY_NEWLINE);
  1711. }
  1712. vty_out(vty, "%s", VTY_NEWLINE);
  1713. vty_out(vty, "Zclient update socket: ");
  1714. if (qpim_zclient_update) {
  1715. vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
  1716. qpim_zclient_update->fail, VTY_NEWLINE);
  1717. }
  1718. else {
  1719. vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
  1720. }
  1721. vty_out(vty, "Zclient lookup socket: ");
  1722. if (qpim_zclient_lookup) {
  1723. vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
  1724. qpim_zclient_lookup->fail, VTY_NEWLINE);
  1725. }
  1726. else {
  1727. vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
  1728. }
  1729. vty_out(vty, "%s", VTY_NEWLINE);
  1730. vty_out(vty, "Current highest VifIndex: %d%s",
  1731. qpim_mroute_oif_highest_vif_index,
  1732. VTY_NEWLINE);
  1733. vty_out(vty, "Maximum highest VifIndex: %d%s",
  1734. MAXVIFS - 1,
  1735. VTY_NEWLINE);
  1736. vty_out(vty, "%s", VTY_NEWLINE);
  1737. vty_out(vty, "Upstream Join Timer: %d secs%s",
  1738. qpim_t_periodic,
  1739. VTY_NEWLINE);
  1740. vty_out(vty, "Join/Prune Holdtime: %d secs%s",
  1741. PIM_JP_HOLDTIME,
  1742. VTY_NEWLINE);
  1743. vty_out(vty, "%s", VTY_NEWLINE);
  1744. show_rpf_refresh_stats(vty, now);
  1745. vty_out(vty, "%s", VTY_NEWLINE);
  1746. show_scan_oil_stats(vty, now);
  1747. show_multicast_interfaces(vty);
  1748. return CMD_SUCCESS;
  1749. }
  1750. static void show_mroute(struct vty *vty)
  1751. {
  1752. struct listnode *node;
  1753. struct channel_oil *c_oil;
  1754. struct static_route *s_route;
  1755. time_t now;
  1756. vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC%s%s", VTY_NEWLINE, VTY_NEWLINE);
  1757. vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
  1758. VTY_NEWLINE);
  1759. now = pim_time_monotonic_sec();
  1760. /* print list of PIM and IGMP routes */
  1761. for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
  1762. char group_str[100];
  1763. char source_str[100];
  1764. int oif_vif_index;
  1765. pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
  1766. pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
  1767. for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
  1768. struct interface *ifp_in;
  1769. struct interface *ifp_out;
  1770. char oif_uptime[10];
  1771. int ttl;
  1772. char proto[5];
  1773. ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
  1774. if (ttl < 1)
  1775. continue;
  1776. ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
  1777. ifp_out = pim_if_find_by_vif_index(oif_vif_index);
  1778. pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
  1779. proto[0] = '\0';
  1780. if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
  1781. strcat(proto, "P");
  1782. }
  1783. if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
  1784. strcat(proto, "I");
  1785. }
  1786. vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
  1787. source_str,
  1788. group_str,
  1789. proto,
  1790. ifp_in ? ifp_in->name : "<iif?>",
  1791. c_oil->oil.mfcc_parent,
  1792. ifp_out ? ifp_out->name : "<oif?>",
  1793. oif_vif_index,
  1794. ttl,
  1795. oif_uptime,
  1796. VTY_NEWLINE);
  1797. }
  1798. }
  1799. /* Print list of static routes */
  1800. for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
  1801. char group_str[100];
  1802. char source_str[100];
  1803. int oif_vif_index;
  1804. pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
  1805. pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
  1806. for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
  1807. struct interface *ifp_in;
  1808. struct interface *ifp_out;
  1809. char oif_uptime[10];
  1810. int ttl;
  1811. char proto[5];
  1812. ttl = s_route->oif_ttls[oif_vif_index];
  1813. if (ttl < 1)
  1814. continue;
  1815. ifp_in = pim_if_find_by_vif_index(s_route->iif);
  1816. ifp_out = pim_if_find_by_vif_index(oif_vif_index);
  1817. pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->creation[oif_vif_index]);
  1818. proto[0] = '\0';
  1819. strcat(proto, "S");
  1820. vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
  1821. source_str,
  1822. group_str,
  1823. proto,
  1824. ifp_in ? ifp_in->name : "<iif?>",
  1825. s_route->iif,
  1826. ifp_out ? ifp_out->name : "<oif?>",
  1827. oif_vif_index,
  1828. ttl,
  1829. oif_uptime,
  1830. VTY_NEWLINE);
  1831. }
  1832. }
  1833. }
  1834. DEFUN (show_ip_mroute,
  1835. show_ip_mroute_cmd,
  1836. "show ip mroute",
  1837. SHOW_STR
  1838. IP_STR
  1839. MROUTE_STR)
  1840. {
  1841. show_mroute(vty);
  1842. return CMD_SUCCESS;
  1843. }
  1844. static void show_mroute_count(struct vty *vty)
  1845. {
  1846. struct listnode *node;
  1847. struct channel_oil *c_oil;
  1848. struct static_route *s_route;
  1849. vty_out(vty, "%s", VTY_NEWLINE);
  1850. vty_out(vty, "Source Group Packets Bytes WrongIf %s",
  1851. VTY_NEWLINE);
  1852. /* Print PIM and IGMP route counts */
  1853. for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
  1854. char group_str[100];
  1855. char source_str[100];
  1856. struct sioc_sg_req sgreq;
  1857. memset(&sgreq, 0, sizeof(sgreq));
  1858. sgreq.src = c_oil->oil.mfcc_origin;
  1859. sgreq.grp = c_oil->oil.mfcc_mcastgrp;
  1860. pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
  1861. pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
  1862. if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
  1863. int e = errno;
  1864. vty_out(vty,
  1865. "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
  1866. (unsigned long)SIOCGETSGCNT,
  1867. source_str,
  1868. group_str,
  1869. e,
  1870. safe_strerror(e),
  1871. VTY_NEWLINE);
  1872. continue;
  1873. }
  1874. vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
  1875. source_str,
  1876. group_str,
  1877. sgreq.pktcnt,
  1878. sgreq.bytecnt,
  1879. sgreq.wrong_if,
  1880. VTY_NEWLINE);
  1881. }
  1882. /* Print static route counts */
  1883. for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
  1884. char group_str[100];
  1885. char source_str[100];
  1886. struct sioc_sg_req sgreq;
  1887. memset(&sgreq, 0, sizeof(sgreq));
  1888. sgreq.src = s_route->mc.mfcc_origin;
  1889. sgreq.grp = s_route->mc.mfcc_mcastgrp;
  1890. pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
  1891. pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
  1892. if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
  1893. int e = errno;
  1894. vty_out(vty,
  1895. "ioctl(SIOCGETSGCNT=%d) failure for (S,G)=(%s,%s): errno=%d: %s%s",
  1896. SIOCGETSGCNT,
  1897. source_str,
  1898. group_str,
  1899. e,
  1900. safe_strerror(e),
  1901. VTY_NEWLINE);
  1902. continue;
  1903. }
  1904. vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
  1905. source_str,
  1906. group_str,
  1907. sgreq.pktcnt,
  1908. sgreq.bytecnt,
  1909. sgreq.wrong_if,
  1910. VTY_NEWLINE);
  1911. }
  1912. }
  1913. DEFUN (show_ip_mroute_count,
  1914. show_ip_mroute_count_cmd,
  1915. "show ip mroute count",
  1916. SHOW_STR
  1917. IP_STR
  1918. MROUTE_STR
  1919. "Route and packet count data\n")
  1920. {
  1921. show_mroute_count(vty);
  1922. return CMD_SUCCESS;
  1923. }
  1924. DEFUN (show_ip_rib,
  1925. show_ip_rib_cmd,
  1926. "show ip rib A.B.C.D",
  1927. SHOW_STR
  1928. IP_STR
  1929. RIB_STR
  1930. "Unicast address\n")
  1931. {
  1932. struct in_addr addr;
  1933. const char *addr_str;
  1934. struct pim_nexthop nexthop;
  1935. char nexthop_addr_str[100];
  1936. int result;
  1937. addr_str = argv[0];
  1938. result = inet_pton(AF_INET, addr_str, &addr);
  1939. if (result <= 0) {
  1940. vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
  1941. addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
  1942. return CMD_WARNING;
  1943. }
  1944. if (pim_nexthop_lookup(&nexthop, addr)) {
  1945. vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
  1946. addr_str, VTY_NEWLINE);
  1947. return CMD_WARNING;
  1948. }
  1949. vty_out(vty, "Address NextHop Interface Metric Preference%s",
  1950. VTY_NEWLINE);
  1951. pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
  1952. nexthop_addr_str, sizeof(nexthop_addr_str));
  1953. vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
  1954. addr_str,
  1955. nexthop_addr_str,
  1956. nexthop.interface ? nexthop.interface->name : "<ifname?>",
  1957. nexthop.mrib_route_metric,
  1958. nexthop.mrib_metric_preference,
  1959. VTY_NEWLINE);
  1960. return CMD_SUCCESS;
  1961. }
  1962. static void show_ssmpingd(struct vty *vty)
  1963. {
  1964. struct listnode *node;
  1965. struct ssmpingd_sock *ss;
  1966. time_t now;
  1967. vty_out(vty, "Source Socket Address Port Uptime Requests%s",
  1968. VTY_NEWLINE);
  1969. if (!qpim_ssmpingd_list)
  1970. return;
  1971. now = pim_time_monotonic_sec();
  1972. for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
  1973. char source_str[100];
  1974. char ss_uptime[10];
  1975. struct sockaddr_in bind_addr;
  1976. socklen_t len = sizeof(bind_addr);
  1977. char bind_addr_str[100];
  1978. pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
  1979. if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
  1980. vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
  1981. source_str, ss->sock_fd, VTY_NEWLINE);
  1982. }
  1983. pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
  1984. pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
  1985. vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
  1986. source_str,
  1987. ss->sock_fd,
  1988. bind_addr_str,
  1989. ntohs(bind_addr.sin_port),
  1990. ss_uptime,
  1991. (long long)ss->requests,
  1992. VTY_NEWLINE);
  1993. }
  1994. }
  1995. DEFUN (show_ip_ssmpingd,
  1996. show_ip_ssmpingd_cmd,
  1997. "show ip ssmpingd",
  1998. SHOW_STR
  1999. IP_STR
  2000. SHOW_SSMPINGD_STR)
  2001. {
  2002. show_ssmpingd(vty);
  2003. return CMD_SUCCESS;
  2004. }
  2005. DEFUN (ip_multicast_routing,
  2006. ip_multicast_routing_cmd,
  2007. PIM_CMD_IP_MULTICAST_ROUTING,
  2008. IP_STR
  2009. "Enable IP multicast forwarding\n")
  2010. {
  2011. pim_mroute_socket_enable();
  2012. pim_if_add_vif_all();
  2013. mroute_add_all();
  2014. static_mroute_add_all();
  2015. return CMD_SUCCESS;
  2016. }
  2017. DEFUN (no_ip_multicast_routing,
  2018. no_ip_multicast_routing_cmd,
  2019. PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
  2020. NO_STR
  2021. IP_STR
  2022. "Global IP configuration subcommands\n"
  2023. "Enable IP multicast forwarding\n")
  2024. {
  2025. mroute_del_all();
  2026. static_mroute_del_all();
  2027. pim_if_del_vif_all();
  2028. pim_mroute_socket_disable();
  2029. return CMD_SUCCESS;
  2030. }
  2031. DEFUN (ip_ssmpingd,
  2032. ip_ssmpingd_cmd,
  2033. "ip ssmpingd [A.B.C.D]",
  2034. IP_STR
  2035. CONF_SSMPINGD_STR
  2036. "Source address\n")
  2037. {
  2038. int result;
  2039. struct in_addr source_addr;
  2040. const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
  2041. result = inet_pton(AF_INET, source_str, &source_addr);
  2042. if (result <= 0) {
  2043. vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
  2044. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2045. return CMD_WARNING;
  2046. }
  2047. result = pim_ssmpingd_start(source_addr);
  2048. if (result) {
  2049. vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
  2050. source_str, result, VTY_NEWLINE);
  2051. return CMD_WARNING;
  2052. }
  2053. return CMD_SUCCESS;
  2054. }
  2055. DEFUN (no_ip_ssmpingd,
  2056. no_ip_ssmpingd_cmd,
  2057. "no ip ssmpingd [A.B.C.D]",
  2058. NO_STR
  2059. IP_STR
  2060. CONF_SSMPINGD_STR
  2061. "Source address\n")
  2062. {
  2063. int result;
  2064. struct in_addr source_addr;
  2065. const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
  2066. result = inet_pton(AF_INET, source_str, &source_addr);
  2067. if (result <= 0) {
  2068. vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
  2069. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2070. return CMD_WARNING;
  2071. }
  2072. result = pim_ssmpingd_stop(source_addr);
  2073. if (result) {
  2074. vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
  2075. source_str, result, VTY_NEWLINE);
  2076. return CMD_WARNING;
  2077. }
  2078. return CMD_SUCCESS;
  2079. }
  2080. DEFUN (interface_ip_igmp,
  2081. interface_ip_igmp_cmd,
  2082. "ip igmp",
  2083. IP_STR
  2084. IFACE_IGMP_STR)
  2085. {
  2086. struct interface *ifp;
  2087. struct pim_interface *pim_ifp;
  2088. ifp = vty->index;
  2089. pim_ifp = ifp->info;
  2090. if (!pim_ifp) {
  2091. pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
  2092. if (!pim_ifp) {
  2093. vty_out(vty, "Could not enable IGMP on interface %s%s",
  2094. ifp->name, VTY_NEWLINE);
  2095. return CMD_WARNING;
  2096. }
  2097. }
  2098. else {
  2099. PIM_IF_DO_IGMP(pim_ifp->options);
  2100. }
  2101. pim_if_addr_add_all(ifp);
  2102. pim_if_membership_refresh(ifp);
  2103. return CMD_SUCCESS;
  2104. }
  2105. DEFUN (interface_no_ip_igmp,
  2106. interface_no_ip_igmp_cmd,
  2107. "no ip igmp",
  2108. NO_STR
  2109. IP_STR
  2110. IFACE_IGMP_STR)
  2111. {
  2112. struct interface *ifp;
  2113. struct pim_interface *pim_ifp;
  2114. ifp = vty->index;
  2115. pim_ifp = ifp->info;
  2116. if (!pim_ifp)
  2117. return CMD_SUCCESS;
  2118. PIM_IF_DONT_IGMP(pim_ifp->options);
  2119. pim_if_membership_clear(ifp);
  2120. pim_if_addr_del_all_igmp(ifp);
  2121. if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
  2122. pim_if_delete(ifp);
  2123. }
  2124. return CMD_SUCCESS;
  2125. }
  2126. DEFUN (interface_ip_igmp_join,
  2127. interface_ip_igmp_join_cmd,
  2128. "ip igmp join A.B.C.D A.B.C.D",
  2129. IP_STR
  2130. IFACE_IGMP_STR
  2131. "IGMP join multicast group\n"
  2132. "Multicast group address\n"
  2133. "Source address\n")
  2134. {
  2135. struct interface *ifp;
  2136. const char *group_str;
  2137. const char *source_str;
  2138. struct in_addr group_addr;
  2139. struct in_addr source_addr;
  2140. int result;
  2141. ifp = vty->index;
  2142. /* Group address */
  2143. group_str = argv[0];
  2144. result = inet_pton(AF_INET, group_str, &group_addr);
  2145. if (result <= 0) {
  2146. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2147. group_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2148. return CMD_WARNING;
  2149. }
  2150. /* Source address */
  2151. source_str = argv[1];
  2152. result = inet_pton(AF_INET, source_str, &source_addr);
  2153. if (result <= 0) {
  2154. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  2155. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2156. return CMD_WARNING;
  2157. }
  2158. result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
  2159. if (result) {
  2160. vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
  2161. group_str, source_str, ifp->name, result, VTY_NEWLINE);
  2162. return CMD_WARNING;
  2163. }
  2164. return CMD_SUCCESS;
  2165. }
  2166. DEFUN (interface_no_ip_igmp_join,
  2167. interface_no_ip_igmp_join_cmd,
  2168. "no ip igmp join A.B.C.D A.B.C.D",
  2169. NO_STR
  2170. IP_STR
  2171. IFACE_IGMP_STR
  2172. "IGMP join multicast group\n"
  2173. "Multicast group address\n"
  2174. "Source address\n")
  2175. {
  2176. struct interface *ifp;
  2177. const char *group_str;
  2178. const char *source_str;
  2179. struct in_addr group_addr;
  2180. struct in_addr source_addr;
  2181. int result;
  2182. ifp = vty->index;
  2183. /* Group address */
  2184. group_str = argv[0];
  2185. result = inet_pton(AF_INET, group_str, &group_addr);
  2186. if (result <= 0) {
  2187. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2188. group_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2189. return CMD_WARNING;
  2190. }
  2191. /* Source address */
  2192. source_str = argv[1];
  2193. result = inet_pton(AF_INET, source_str, &source_addr);
  2194. if (result <= 0) {
  2195. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  2196. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2197. return CMD_WARNING;
  2198. }
  2199. result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
  2200. if (result) {
  2201. vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
  2202. group_str, source_str, ifp->name, result, VTY_NEWLINE);
  2203. return CMD_WARNING;
  2204. }
  2205. return CMD_SUCCESS;
  2206. }
  2207. /*
  2208. CLI reconfiguration affects the interface level (struct pim_interface).
  2209. This function propagates the reconfiguration to every active socket
  2210. for that interface.
  2211. */
  2212. static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
  2213. {
  2214. struct interface *ifp;
  2215. struct pim_interface *pim_ifp;
  2216. zassert(igmp);
  2217. /* other querier present? */
  2218. if (igmp->t_other_querier_timer)
  2219. return;
  2220. /* this is the querier */
  2221. zassert(igmp->interface);
  2222. zassert(igmp->interface->info);
  2223. ifp = igmp->interface;
  2224. pim_ifp = ifp->info;
  2225. if (PIM_DEBUG_IGMP_TRACE) {
  2226. char ifaddr_str[100];
  2227. pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
  2228. zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
  2229. __PRETTY_FUNCTION__,
  2230. ifaddr_str,
  2231. ifp->name,
  2232. pim_ifp->igmp_default_query_interval);
  2233. }
  2234. /*
  2235. igmp_startup_mode_on() will reset QQI:
  2236. igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
  2237. */
  2238. igmp_startup_mode_on(igmp);
  2239. }
  2240. static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
  2241. {
  2242. if (igmp->t_igmp_query_timer) {
  2243. /* other querier present */
  2244. zassert(igmp->t_igmp_query_timer);
  2245. zassert(!igmp->t_other_querier_timer);
  2246. pim_igmp_general_query_off(igmp);
  2247. pim_igmp_general_query_on(igmp);
  2248. zassert(igmp->t_igmp_query_timer);
  2249. zassert(!igmp->t_other_querier_timer);
  2250. }
  2251. else {
  2252. /* this is the querier */
  2253. zassert(!igmp->t_igmp_query_timer);
  2254. zassert(igmp->t_other_querier_timer);
  2255. pim_igmp_other_querier_timer_off(igmp);
  2256. pim_igmp_other_querier_timer_on(igmp);
  2257. zassert(!igmp->t_igmp_query_timer);
  2258. zassert(igmp->t_other_querier_timer);
  2259. }
  2260. }
  2261. static void change_query_interval(struct pim_interface *pim_ifp,
  2262. int query_interval)
  2263. {
  2264. struct listnode *sock_node;
  2265. struct igmp_sock *igmp;
  2266. pim_ifp->igmp_default_query_interval = query_interval;
  2267. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  2268. igmp_sock_query_interval_reconfig(igmp);
  2269. igmp_sock_query_reschedule(igmp);
  2270. }
  2271. }
  2272. static void change_query_max_response_time(struct pim_interface *pim_ifp,
  2273. int query_max_response_time_dsec)
  2274. {
  2275. struct listnode *sock_node;
  2276. struct igmp_sock *igmp;
  2277. pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
  2278. /*
  2279. Below we modify socket/group/source timers in order to quickly
  2280. reflect the change. Otherwise, those timers would eventually catch
  2281. up.
  2282. */
  2283. /* scan all sockets */
  2284. for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  2285. struct listnode *grp_node;
  2286. struct igmp_group *grp;
  2287. /* reschedule socket general query */
  2288. igmp_sock_query_reschedule(igmp);
  2289. /* scan socket groups */
  2290. for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
  2291. struct listnode *src_node;
  2292. struct igmp_source *src;
  2293. /* reset group timers for groups in EXCLUDE mode */
  2294. if (grp->group_filtermode_isexcl) {
  2295. igmp_group_reset_gmi(grp);
  2296. }
  2297. /* scan group sources */
  2298. for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
  2299. /* reset source timers for sources with running timers */
  2300. if (src->t_source_timer) {
  2301. igmp_source_reset_gmi(igmp, grp, src);
  2302. }
  2303. }
  2304. }
  2305. }
  2306. }
  2307. #define IGMP_QUERY_INTERVAL_MIN (1)
  2308. #define IGMP_QUERY_INTERVAL_MAX (1800)
  2309. DEFUN (interface_ip_igmp_query_interval,
  2310. interface_ip_igmp_query_interval_cmd,
  2311. PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
  2312. IP_STR
  2313. IFACE_IGMP_STR
  2314. IFACE_IGMP_QUERY_INTERVAL_STR
  2315. "Query interval in seconds\n")
  2316. {
  2317. struct interface *ifp;
  2318. struct pim_interface *pim_ifp;
  2319. int query_interval;
  2320. int query_interval_dsec;
  2321. ifp = vty->index;
  2322. pim_ifp = ifp->info;
  2323. if (!pim_ifp) {
  2324. vty_out(vty,
  2325. "IGMP not enabled on interface %s. Please enable IGMP first.%s",
  2326. ifp->name,
  2327. VTY_NEWLINE);
  2328. return CMD_WARNING;
  2329. }
  2330. query_interval = atoi(argv[0]);
  2331. query_interval_dsec = 10 * query_interval;
  2332. /*
  2333. It seems we don't need to check bounds since command.c does it
  2334. already, but we verify them anyway for extra safety.
  2335. */
  2336. if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
  2337. vty_out(vty, "General query interval %d lower than minimum %d%s",
  2338. query_interval,
  2339. IGMP_QUERY_INTERVAL_MIN,
  2340. VTY_NEWLINE);
  2341. return CMD_WARNING;
  2342. }
  2343. if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
  2344. vty_out(vty, "General query interval %d higher than maximum %d%s",
  2345. query_interval,
  2346. IGMP_QUERY_INTERVAL_MAX,
  2347. VTY_NEWLINE);
  2348. return CMD_WARNING;
  2349. }
  2350. if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
  2351. vty_out(vty,
  2352. "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
  2353. query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
  2354. VTY_NEWLINE);
  2355. return CMD_WARNING;
  2356. }
  2357. change_query_interval(pim_ifp, query_interval);
  2358. return CMD_SUCCESS;
  2359. }
  2360. DEFUN (interface_no_ip_igmp_query_interval,
  2361. interface_no_ip_igmp_query_interval_cmd,
  2362. PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
  2363. NO_STR
  2364. IP_STR
  2365. IFACE_IGMP_STR
  2366. IFACE_IGMP_QUERY_INTERVAL_STR)
  2367. {
  2368. struct interface *ifp;
  2369. struct pim_interface *pim_ifp;
  2370. int default_query_interval_dsec;
  2371. ifp = vty->index;
  2372. pim_ifp = ifp->info;
  2373. if (!pim_ifp)
  2374. return CMD_SUCCESS;
  2375. default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
  2376. if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
  2377. vty_out(vty,
  2378. "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
  2379. default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
  2380. VTY_NEWLINE);
  2381. return CMD_WARNING;
  2382. }
  2383. change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
  2384. return CMD_SUCCESS;
  2385. }
  2386. #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
  2387. #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
  2388. DEFUN (interface_ip_igmp_query_max_response_time,
  2389. interface_ip_igmp_query_max_response_time_cmd,
  2390. PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
  2391. IP_STR
  2392. IFACE_IGMP_STR
  2393. IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
  2394. "Query response value in seconds\n")
  2395. {
  2396. struct interface *ifp;
  2397. struct pim_interface *pim_ifp;
  2398. int query_max_response_time;
  2399. ifp = vty->index;
  2400. pim_ifp = ifp->info;
  2401. if (!pim_ifp) {
  2402. vty_out(vty,
  2403. "IGMP not enabled on interface %s. Please enable IGMP first.%s",
  2404. ifp->name,
  2405. VTY_NEWLINE);
  2406. return CMD_WARNING;
  2407. }
  2408. query_max_response_time = atoi(argv[0]);
  2409. /*
  2410. It seems we don't need to check bounds since command.c does it
  2411. already, but we verify them anyway for extra safety.
  2412. */
  2413. if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
  2414. vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
  2415. query_max_response_time,
  2416. IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
  2417. VTY_NEWLINE);
  2418. return CMD_WARNING;
  2419. }
  2420. if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
  2421. vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
  2422. query_max_response_time,
  2423. IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
  2424. VTY_NEWLINE);
  2425. return CMD_WARNING;
  2426. }
  2427. if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
  2428. vty_out(vty,
  2429. "Can't set query max response time %d sec >= general query interval %d sec%s",
  2430. query_max_response_time, pim_ifp->igmp_default_query_interval,
  2431. VTY_NEWLINE);
  2432. return CMD_WARNING;
  2433. }
  2434. change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
  2435. return CMD_SUCCESS;
  2436. }
  2437. DEFUN (interface_no_ip_igmp_query_max_response_time,
  2438. interface_no_ip_igmp_query_max_response_time_cmd,
  2439. PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
  2440. NO_STR
  2441. IP_STR
  2442. IFACE_IGMP_STR
  2443. IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
  2444. {
  2445. struct interface *ifp;
  2446. struct pim_interface *pim_ifp;
  2447. int default_query_interval_dsec;
  2448. ifp = vty->index;
  2449. pim_ifp = ifp->info;
  2450. if (!pim_ifp)
  2451. return CMD_SUCCESS;
  2452. default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
  2453. if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
  2454. vty_out(vty,
  2455. "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
  2456. IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
  2457. VTY_NEWLINE);
  2458. return CMD_WARNING;
  2459. }
  2460. change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
  2461. return CMD_SUCCESS;
  2462. }
  2463. #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
  2464. #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
  2465. DEFUN (interface_ip_igmp_query_max_response_time_dsec,
  2466. interface_ip_igmp_query_max_response_time_dsec_cmd,
  2467. PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
  2468. IP_STR
  2469. IFACE_IGMP_STR
  2470. IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
  2471. "Query response value in deciseconds\n")
  2472. {
  2473. struct interface *ifp;
  2474. struct pim_interface *pim_ifp;
  2475. int query_max_response_time_dsec;
  2476. int default_query_interval_dsec;
  2477. ifp = vty->index;
  2478. pim_ifp = ifp->info;
  2479. if (!pim_ifp) {
  2480. vty_out(vty,
  2481. "IGMP not enabled on interface %s. Please enable IGMP first.%s",
  2482. ifp->name,
  2483. VTY_NEWLINE);
  2484. return CMD_WARNING;
  2485. }
  2486. query_max_response_time_dsec = atoi(argv[0]);
  2487. /*
  2488. It seems we don't need to check bounds since command.c does it
  2489. already, but we verify them anyway for extra safety.
  2490. */
  2491. if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
  2492. vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
  2493. query_max_response_time_dsec,
  2494. IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
  2495. VTY_NEWLINE);
  2496. return CMD_WARNING;
  2497. }
  2498. if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
  2499. vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
  2500. query_max_response_time_dsec,
  2501. IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
  2502. VTY_NEWLINE);
  2503. return CMD_WARNING;
  2504. }
  2505. default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
  2506. if (query_max_response_time_dsec >= default_query_interval_dsec) {
  2507. vty_out(vty,
  2508. "Can't set query max response time %d dsec >= general query interval %d dsec%s",
  2509. query_max_response_time_dsec, default_query_interval_dsec,
  2510. VTY_NEWLINE);
  2511. return CMD_WARNING;
  2512. }
  2513. change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
  2514. return CMD_SUCCESS;
  2515. }
  2516. DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
  2517. interface_no_ip_igmp_query_max_response_time_dsec_cmd,
  2518. PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
  2519. NO_STR
  2520. IP_STR
  2521. IFACE_IGMP_STR
  2522. IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
  2523. {
  2524. struct interface *ifp;
  2525. struct pim_interface *pim_ifp;
  2526. int default_query_interval_dsec;
  2527. ifp = vty->index;
  2528. pim_ifp = ifp->info;
  2529. if (!pim_ifp)
  2530. return CMD_SUCCESS;
  2531. default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
  2532. if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
  2533. vty_out(vty,
  2534. "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
  2535. IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
  2536. VTY_NEWLINE);
  2537. return CMD_WARNING;
  2538. }
  2539. change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
  2540. return CMD_SUCCESS;
  2541. }
  2542. DEFUN (interface_ip_pim_drprio,
  2543. interface_ip_pim_drprio_cmd,
  2544. "ip pim drpriority <1-4294967295>",
  2545. IP_STR
  2546. PIM_STR
  2547. "Set the Designated Router Election Priority\n"
  2548. "Value of the new DR Priority\n")
  2549. {
  2550. struct interface *ifp;
  2551. struct pim_interface *pim_ifp;
  2552. uint32_t old_dr_prio;
  2553. ifp = vty->index;
  2554. pim_ifp = ifp->info;
  2555. if (!pim_ifp) {
  2556. vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
  2557. return CMD_WARNING;
  2558. }
  2559. old_dr_prio = pim_ifp->pim_dr_priority;
  2560. pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
  2561. if (old_dr_prio != pim_ifp->pim_dr_priority) {
  2562. if (pim_if_dr_election(ifp))
  2563. pim_hello_restart_now(ifp);
  2564. }
  2565. return CMD_SUCCESS;
  2566. }
  2567. DEFUN (interface_no_ip_pim_drprio,
  2568. interface_no_ip_pim_drprio_cmd,
  2569. "no ip pim drpriority {<1-4294967295>}",
  2570. IP_STR
  2571. PIM_STR
  2572. "Revert the Designated Router Priority to default\n"
  2573. "Old Value of the Priority\n")
  2574. {
  2575. struct interface *ifp;
  2576. struct pim_interface *pim_ifp;
  2577. ifp = vty->index;
  2578. pim_ifp = ifp->info;
  2579. if (!pim_ifp) {
  2580. vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
  2581. return CMD_WARNING;
  2582. }
  2583. if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
  2584. pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
  2585. if (pim_if_dr_election(ifp))
  2586. pim_hello_restart_now(ifp);
  2587. }
  2588. return CMD_SUCCESS;
  2589. }
  2590. DEFUN (interface_ip_pim_ssm,
  2591. interface_ip_pim_ssm_cmd,
  2592. "ip pim ssm",
  2593. IP_STR
  2594. PIM_STR
  2595. IFACE_PIM_STR)
  2596. {
  2597. struct interface *ifp;
  2598. struct pim_interface *pim_ifp;
  2599. ifp = vty->index;
  2600. pim_ifp = ifp->info;
  2601. if (!pim_ifp) {
  2602. pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
  2603. if (!pim_ifp) {
  2604. vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
  2605. return CMD_WARNING;
  2606. }
  2607. }
  2608. else {
  2609. PIM_IF_DO_PIM(pim_ifp->options);
  2610. }
  2611. pim_if_addr_add_all(ifp);
  2612. pim_if_membership_refresh(ifp);
  2613. return CMD_SUCCESS;
  2614. }
  2615. DEFUN (interface_no_ip_pim_ssm,
  2616. interface_no_ip_pim_ssm_cmd,
  2617. "no ip pim ssm",
  2618. NO_STR
  2619. IP_STR
  2620. PIM_STR
  2621. IFACE_PIM_STR)
  2622. {
  2623. struct interface *ifp;
  2624. struct pim_interface *pim_ifp;
  2625. ifp = vty->index;
  2626. pim_ifp = ifp->info;
  2627. if (!pim_ifp)
  2628. return CMD_SUCCESS;
  2629. PIM_IF_DONT_PIM(pim_ifp->options);
  2630. pim_if_membership_clear(ifp);
  2631. /*
  2632. pim_if_addr_del_all() removes all sockets from
  2633. pim_ifp->igmp_socket_list.
  2634. */
  2635. pim_if_addr_del_all(ifp);
  2636. /*
  2637. pim_sock_delete() removes all neighbors from
  2638. pim_ifp->pim_neighbor_list.
  2639. */
  2640. pim_sock_delete(ifp, "pim unconfigured on interface");
  2641. if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
  2642. pim_if_delete(ifp);
  2643. }
  2644. return CMD_SUCCESS;
  2645. }
  2646. DEFUN (interface_ip_mroute,
  2647. interface_ip_mroute_cmd,
  2648. "ip mroute INTERFACE A.B.C.D",
  2649. IP_STR
  2650. "Add multicast route\n"
  2651. "Outgoing interface name\n"
  2652. "Group address\n")
  2653. {
  2654. struct interface *iif;
  2655. struct interface *oif;
  2656. const char *oifname;
  2657. const char *grp_str;
  2658. struct in_addr grp_addr;
  2659. struct in_addr src_addr;
  2660. int result;
  2661. iif = vty->index;
  2662. oifname = argv[0];
  2663. oif = if_lookup_by_name(oifname);
  2664. if (!oif) {
  2665. vty_out(vty, "No such interface name %s%s",
  2666. oifname, VTY_NEWLINE);
  2667. return CMD_WARNING;
  2668. }
  2669. grp_str = argv[1];
  2670. result = inet_pton(AF_INET, grp_str, &grp_addr);
  2671. if (result <= 0) {
  2672. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2673. grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2674. return CMD_WARNING;
  2675. }
  2676. src_addr.s_addr = INADDR_ANY;
  2677. if (pim_static_add(iif, oif, grp_addr, src_addr)) {
  2678. vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
  2679. return CMD_WARNING;
  2680. }
  2681. return CMD_SUCCESS;
  2682. }
  2683. DEFUN (interface_ip_mroute_source,
  2684. interface_ip_mroute_source_cmd,
  2685. "ip mroute INTERFACE A.B.C.D A.B.C.D",
  2686. IP_STR
  2687. "Add multicast route\n"
  2688. "Outgoing interface name\n"
  2689. "Group address\n"
  2690. "Source address\n")
  2691. {
  2692. struct interface *iif;
  2693. struct interface *oif;
  2694. const char *oifname;
  2695. const char *grp_str;
  2696. struct in_addr grp_addr;
  2697. const char *src_str;
  2698. struct in_addr src_addr;
  2699. int result;
  2700. iif = vty->index;
  2701. oifname = argv[0];
  2702. oif = if_lookup_by_name(oifname);
  2703. if (!oif) {
  2704. vty_out(vty, "No such interface name %s%s",
  2705. oifname, VTY_NEWLINE);
  2706. return CMD_WARNING;
  2707. }
  2708. grp_str = argv[1];
  2709. result = inet_pton(AF_INET, grp_str, &grp_addr);
  2710. if (result <= 0) {
  2711. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2712. grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2713. return CMD_WARNING;
  2714. }
  2715. src_str = argv[2];
  2716. result = inet_pton(AF_INET, src_str, &src_addr);
  2717. if (result <= 0) {
  2718. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  2719. src_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2720. return CMD_WARNING;
  2721. }
  2722. if (pim_static_add(iif, oif, grp_addr, src_addr)) {
  2723. vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
  2724. return CMD_WARNING;
  2725. }
  2726. return CMD_SUCCESS;
  2727. }
  2728. DEFUN (interface_no_ip_mroute,
  2729. interface_no_ip_mroute_cmd,
  2730. "no ip mroute INTERFACE A.B.C.D",
  2731. NO_STR
  2732. IP_STR
  2733. "Add multicast route\n"
  2734. "Outgoing interface name\n"
  2735. "Group Address\n")
  2736. {
  2737. struct interface *iif;
  2738. struct interface *oif;
  2739. const char *oifname;
  2740. const char *grp_str;
  2741. struct in_addr grp_addr;
  2742. struct in_addr src_addr;
  2743. int result;
  2744. iif = vty->index;
  2745. oifname = argv[0];
  2746. oif = if_lookup_by_name(oifname);
  2747. if (!oif) {
  2748. vty_out(vty, "No such interface name %s%s",
  2749. oifname, VTY_NEWLINE);
  2750. return CMD_WARNING;
  2751. }
  2752. grp_str = argv[1];
  2753. result = inet_pton(AF_INET, grp_str, &grp_addr);
  2754. if (result <= 0) {
  2755. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2756. grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2757. return CMD_WARNING;
  2758. }
  2759. src_addr.s_addr = INADDR_ANY;
  2760. if (pim_static_del(iif, oif, grp_addr, src_addr)) {
  2761. vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
  2762. return CMD_WARNING;
  2763. }
  2764. return CMD_SUCCESS;
  2765. }
  2766. DEFUN (interface_no_ip_mroute_source,
  2767. interface_no_ip_mroute_source_cmd,
  2768. "no ip mroute INTERFACE A.B.C.D A.B.C.D",
  2769. NO_STR
  2770. IP_STR
  2771. "Add multicast route\n"
  2772. "Outgoing interface name\n"
  2773. "Group Address\n"
  2774. "Source Address\n")
  2775. {
  2776. struct interface *iif;
  2777. struct interface *oif;
  2778. const char *oifname;
  2779. const char *grp_str;
  2780. struct in_addr grp_addr;
  2781. const char *src_str;
  2782. struct in_addr src_addr;
  2783. int result;
  2784. iif = vty->index;
  2785. oifname = argv[0];
  2786. oif = if_lookup_by_name(oifname);
  2787. if (!oif) {
  2788. vty_out(vty, "No such interface name %s%s",
  2789. oifname, VTY_NEWLINE);
  2790. return CMD_WARNING;
  2791. }
  2792. grp_str = argv[1];
  2793. result = inet_pton(AF_INET, grp_str, &grp_addr);
  2794. if (result <= 0) {
  2795. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  2796. grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2797. return CMD_WARNING;
  2798. }
  2799. src_str = argv[2];
  2800. result = inet_pton(AF_INET, src_str, &src_addr);
  2801. if (result <= 0) {
  2802. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  2803. src_str, errno, safe_strerror(errno), VTY_NEWLINE);
  2804. return CMD_WARNING;
  2805. }
  2806. if (pim_static_del(iif, oif, grp_addr, src_addr)) {
  2807. vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
  2808. return CMD_WARNING;
  2809. }
  2810. return CMD_SUCCESS;
  2811. }
  2812. DEFUN (interface_ip_pim_hello,
  2813. interface_ip_pim_hello_cmd,
  2814. "ip pim hello <1-180>",
  2815. IP_STR
  2816. PIM_STR
  2817. IFACE_PIM_HELLO_STR
  2818. IFACE_PIM_HELLO_TIME_STR)
  2819. {
  2820. struct interface *ifp;
  2821. struct pim_interface *pim_ifp;
  2822. ifp = vty->index;
  2823. pim_ifp = ifp->info;
  2824. if (!pim_ifp) {
  2825. vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
  2826. return CMD_WARNING;
  2827. }
  2828. pim_ifp->pim_hello_period = strtol(argv[0], NULL, 10);
  2829. if (argc == 2)
  2830. pim_ifp->pim_default_holdtime = strtol(argv[1], NULL, 10);
  2831. return CMD_SUCCESS;
  2832. }
  2833. ALIAS (interface_ip_pim_hello,
  2834. interface_ip_pim_hello_hold_cmd,
  2835. "ip pim hello <1-180> <1-180>",
  2836. IP_STR
  2837. PIM_STR
  2838. IFACE_PIM_HELLO_STR
  2839. IFACE_PIM_HELLO_TIME_STR
  2840. IFACE_PIM_HELLO_HOLD_STR)
  2841. DEFUN (interface_no_ip_pim_hello,
  2842. interface_no_ip_pim_hello_cmd,
  2843. "no ip pim hello {<1-180> <1-180>}",
  2844. NO_STR
  2845. IP_STR
  2846. PIM_STR
  2847. IFACE_PIM_HELLO_STR
  2848. IFACE_PIM_HELLO_TIME_STR
  2849. IFACE_PIM_HELLO_HOLD_STR)
  2850. {
  2851. struct interface *ifp;
  2852. struct pim_interface *pim_ifp;
  2853. ifp = vty->index;
  2854. pim_ifp = ifp->info;
  2855. if (!pim_ifp) {
  2856. vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
  2857. return CMD_WARNING;
  2858. }
  2859. pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
  2860. pim_ifp->pim_default_holdtime = -1;
  2861. return CMD_SUCCESS;
  2862. }
  2863. DEFUN (debug_igmp,
  2864. debug_igmp_cmd,
  2865. "debug igmp",
  2866. DEBUG_STR
  2867. DEBUG_IGMP_STR)
  2868. {
  2869. PIM_DO_DEBUG_IGMP_EVENTS;
  2870. PIM_DO_DEBUG_IGMP_PACKETS;
  2871. PIM_DO_DEBUG_IGMP_TRACE;
  2872. return CMD_SUCCESS;
  2873. }
  2874. DEFUN (no_debug_igmp,
  2875. no_debug_igmp_cmd,
  2876. "no debug igmp",
  2877. NO_STR
  2878. DEBUG_STR
  2879. DEBUG_IGMP_STR)
  2880. {
  2881. PIM_DONT_DEBUG_IGMP_EVENTS;
  2882. PIM_DONT_DEBUG_IGMP_PACKETS;
  2883. PIM_DONT_DEBUG_IGMP_TRACE;
  2884. return CMD_SUCCESS;
  2885. }
  2886. ALIAS (no_debug_igmp,
  2887. undebug_igmp_cmd,
  2888. "undebug igmp",
  2889. UNDEBUG_STR
  2890. DEBUG_IGMP_STR)
  2891. DEFUN (debug_igmp_events,
  2892. debug_igmp_events_cmd,
  2893. "debug igmp events",
  2894. DEBUG_STR
  2895. DEBUG_IGMP_STR
  2896. DEBUG_IGMP_EVENTS_STR)
  2897. {
  2898. PIM_DO_DEBUG_IGMP_EVENTS;
  2899. return CMD_SUCCESS;
  2900. }
  2901. DEFUN (no_debug_igmp_events,
  2902. no_debug_igmp_events_cmd,
  2903. "no debug igmp events",
  2904. NO_STR
  2905. DEBUG_STR
  2906. DEBUG_IGMP_STR
  2907. DEBUG_IGMP_EVENTS_STR)
  2908. {
  2909. PIM_DONT_DEBUG_IGMP_EVENTS;
  2910. return CMD_SUCCESS;
  2911. }
  2912. ALIAS (no_debug_igmp_events,
  2913. undebug_igmp_events_cmd,
  2914. "undebug igmp events",
  2915. UNDEBUG_STR
  2916. DEBUG_IGMP_STR
  2917. DEBUG_IGMP_EVENTS_STR)
  2918. DEFUN (debug_igmp_packets,
  2919. debug_igmp_packets_cmd,
  2920. "debug igmp packets",
  2921. DEBUG_STR
  2922. DEBUG_IGMP_STR
  2923. DEBUG_IGMP_PACKETS_STR)
  2924. {
  2925. PIM_DO_DEBUG_IGMP_PACKETS;
  2926. return CMD_SUCCESS;
  2927. }
  2928. DEFUN (no_debug_igmp_packets,
  2929. no_debug_igmp_packets_cmd,
  2930. "no debug igmp packets",
  2931. NO_STR
  2932. DEBUG_STR
  2933. DEBUG_IGMP_STR
  2934. DEBUG_IGMP_PACKETS_STR)
  2935. {
  2936. PIM_DONT_DEBUG_IGMP_PACKETS;
  2937. return CMD_SUCCESS;
  2938. }
  2939. ALIAS (no_debug_igmp_packets,
  2940. undebug_igmp_packets_cmd,
  2941. "undebug igmp packets",
  2942. UNDEBUG_STR
  2943. DEBUG_IGMP_STR
  2944. DEBUG_IGMP_PACKETS_STR)
  2945. DEFUN (debug_igmp_trace,
  2946. debug_igmp_trace_cmd,
  2947. "debug igmp trace",
  2948. DEBUG_STR
  2949. DEBUG_IGMP_STR
  2950. DEBUG_IGMP_TRACE_STR)
  2951. {
  2952. PIM_DO_DEBUG_IGMP_TRACE;
  2953. return CMD_SUCCESS;
  2954. }
  2955. DEFUN (no_debug_igmp_trace,
  2956. no_debug_igmp_trace_cmd,
  2957. "no debug igmp trace",
  2958. NO_STR
  2959. DEBUG_STR
  2960. DEBUG_IGMP_STR
  2961. DEBUG_IGMP_TRACE_STR)
  2962. {
  2963. PIM_DONT_DEBUG_IGMP_TRACE;
  2964. return CMD_SUCCESS;
  2965. }
  2966. ALIAS (no_debug_igmp_trace,
  2967. undebug_igmp_trace_cmd,
  2968. "undebug igmp trace",
  2969. UNDEBUG_STR
  2970. DEBUG_IGMP_STR
  2971. DEBUG_IGMP_TRACE_STR)
  2972. DEFUN (debug_mroute,
  2973. debug_mroute_cmd,
  2974. "debug mroute",
  2975. DEBUG_STR
  2976. DEBUG_MROUTE_STR)
  2977. {
  2978. PIM_DO_DEBUG_MROUTE;
  2979. return CMD_SUCCESS;
  2980. }
  2981. DEFUN (no_debug_mroute,
  2982. no_debug_mroute_cmd,
  2983. "no debug mroute",
  2984. NO_STR
  2985. DEBUG_STR
  2986. DEBUG_MROUTE_STR)
  2987. {
  2988. PIM_DONT_DEBUG_MROUTE;
  2989. return CMD_SUCCESS;
  2990. }
  2991. ALIAS (no_debug_mroute,
  2992. undebug_mroute_cmd,
  2993. "undebug mroute",
  2994. UNDEBUG_STR
  2995. DEBUG_MROUTE_STR)
  2996. DEFUN (debug_static,
  2997. debug_static_cmd,
  2998. "debug static",
  2999. DEBUG_STR
  3000. DEBUG_STATIC_STR)
  3001. {
  3002. PIM_DO_DEBUG_STATIC;
  3003. return CMD_SUCCESS;
  3004. }
  3005. DEFUN (no_debug_static,
  3006. no_debug_static_cmd,
  3007. "no debug static",
  3008. NO_STR
  3009. DEBUG_STR
  3010. DEBUG_STATIC_STR)
  3011. {
  3012. PIM_DONT_DEBUG_STATIC;
  3013. return CMD_SUCCESS;
  3014. }
  3015. ALIAS (no_debug_static,
  3016. undebug_static_cmd,
  3017. "undebug static",
  3018. UNDEBUG_STR
  3019. DEBUG_STATIC_STR)
  3020. DEFUN (debug_pim,
  3021. debug_pim_cmd,
  3022. "debug pim",
  3023. DEBUG_STR
  3024. DEBUG_PIM_STR)
  3025. {
  3026. PIM_DO_DEBUG_PIM_EVENTS;
  3027. PIM_DO_DEBUG_PIM_PACKETS;
  3028. PIM_DO_DEBUG_PIM_TRACE;
  3029. return CMD_SUCCESS;
  3030. }
  3031. DEFUN (no_debug_pim,
  3032. no_debug_pim_cmd,
  3033. "no debug pim",
  3034. NO_STR
  3035. DEBUG_STR
  3036. DEBUG_PIM_STR)
  3037. {
  3038. PIM_DONT_DEBUG_PIM_EVENTS;
  3039. PIM_DONT_DEBUG_PIM_PACKETS;
  3040. PIM_DONT_DEBUG_PIM_TRACE;
  3041. PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
  3042. PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
  3043. return CMD_SUCCESS;
  3044. }
  3045. ALIAS (no_debug_pim,
  3046. undebug_pim_cmd,
  3047. "undebug pim",
  3048. UNDEBUG_STR
  3049. DEBUG_PIM_STR)
  3050. DEFUN (debug_pim_events,
  3051. debug_pim_events_cmd,
  3052. "debug pim events",
  3053. DEBUG_STR
  3054. DEBUG_PIM_STR
  3055. DEBUG_PIM_EVENTS_STR)
  3056. {
  3057. PIM_DO_DEBUG_PIM_EVENTS;
  3058. return CMD_SUCCESS;
  3059. }
  3060. DEFUN (no_debug_pim_events,
  3061. no_debug_pim_events_cmd,
  3062. "no debug pim events",
  3063. NO_STR
  3064. DEBUG_STR
  3065. DEBUG_PIM_STR
  3066. DEBUG_PIM_EVENTS_STR)
  3067. {
  3068. PIM_DONT_DEBUG_PIM_EVENTS;
  3069. return CMD_SUCCESS;
  3070. }
  3071. ALIAS (no_debug_pim_events,
  3072. undebug_pim_events_cmd,
  3073. "undebug pim events",
  3074. UNDEBUG_STR
  3075. DEBUG_PIM_STR
  3076. DEBUG_PIM_EVENTS_STR)
  3077. DEFUN (debug_pim_packets,
  3078. debug_pim_packets_cmd,
  3079. "debug pim packets",
  3080. DEBUG_STR
  3081. DEBUG_PIM_STR
  3082. DEBUG_PIM_PACKETS_STR)
  3083. {
  3084. PIM_DO_DEBUG_PIM_PACKETS;
  3085. vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
  3086. return CMD_SUCCESS;
  3087. }
  3088. DEFUN (debug_pim_packets_filter,
  3089. debug_pim_packets_filter_cmd,
  3090. "debug pim packets (hello|joins)",
  3091. DEBUG_STR
  3092. DEBUG_PIM_STR
  3093. DEBUG_PIM_PACKETS_STR
  3094. DEBUG_PIM_HELLO_PACKETS_STR
  3095. DEBUG_PIM_J_P_PACKETS_STR)
  3096. {
  3097. if (strncmp(argv[0],"h",1) == 0)
  3098. {
  3099. PIM_DO_DEBUG_PIM_HELLO;
  3100. vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
  3101. }
  3102. else if (strncmp(argv[0],"j",1) == 0)
  3103. {
  3104. PIM_DO_DEBUG_PIM_J_P;
  3105. vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
  3106. }
  3107. return CMD_SUCCESS;
  3108. }
  3109. DEFUN (no_debug_pim_packets,
  3110. no_debug_pim_packets_cmd,
  3111. "no debug pim packets",
  3112. NO_STR
  3113. DEBUG_STR
  3114. DEBUG_PIM_STR
  3115. DEBUG_PIM_PACKETS_STR
  3116. DEBUG_PIM_HELLO_PACKETS_STR
  3117. DEBUG_PIM_J_P_PACKETS_STR)
  3118. {
  3119. PIM_DONT_DEBUG_PIM_PACKETS;
  3120. vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
  3121. return CMD_SUCCESS;
  3122. }
  3123. DEFUN (no_debug_pim_packets_filter,
  3124. no_debug_pim_packets_filter_cmd,
  3125. "no debug pim packets (hello|joins)",
  3126. NO_STR
  3127. DEBUG_STR
  3128. DEBUG_PIM_STR
  3129. DEBUG_PIM_PACKETS_STR
  3130. DEBUG_PIM_HELLO_PACKETS_STR
  3131. DEBUG_PIM_J_P_PACKETS_STR)
  3132. {
  3133. if (strncmp(argv[0],"h",1) == 0)
  3134. {
  3135. PIM_DONT_DEBUG_PIM_HELLO;
  3136. vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
  3137. }
  3138. else if (strncmp(argv[0],"j",1) == 0)
  3139. {
  3140. PIM_DONT_DEBUG_PIM_J_P;
  3141. vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
  3142. }
  3143. return CMD_SUCCESS;
  3144. }
  3145. ALIAS (no_debug_pim_packets,
  3146. undebug_pim_packets_cmd,
  3147. "undebug pim packets",
  3148. UNDEBUG_STR
  3149. DEBUG_PIM_STR
  3150. DEBUG_PIM_PACKETS_STR)
  3151. DEFUN (debug_pim_packetdump_send,
  3152. debug_pim_packetdump_send_cmd,
  3153. "debug pim packet-dump send",
  3154. DEBUG_STR
  3155. DEBUG_PIM_STR
  3156. DEBUG_PIM_PACKETDUMP_STR
  3157. DEBUG_PIM_PACKETDUMP_SEND_STR)
  3158. {
  3159. PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
  3160. return CMD_SUCCESS;
  3161. }
  3162. DEFUN (no_debug_pim_packetdump_send,
  3163. no_debug_pim_packetdump_send_cmd,
  3164. "no debug pim packet-dump send",
  3165. NO_STR
  3166. DEBUG_STR
  3167. DEBUG_PIM_STR
  3168. DEBUG_PIM_PACKETDUMP_STR
  3169. DEBUG_PIM_PACKETDUMP_SEND_STR)
  3170. {
  3171. PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
  3172. return CMD_SUCCESS;
  3173. }
  3174. ALIAS (no_debug_pim_packetdump_send,
  3175. undebug_pim_packetdump_send_cmd,
  3176. "undebug pim packet-dump send",
  3177. UNDEBUG_STR
  3178. DEBUG_PIM_STR
  3179. DEBUG_PIM_PACKETDUMP_STR
  3180. DEBUG_PIM_PACKETDUMP_SEND_STR)
  3181. DEFUN (debug_pim_packetdump_recv,
  3182. debug_pim_packetdump_recv_cmd,
  3183. "debug pim packet-dump receive",
  3184. DEBUG_STR
  3185. DEBUG_PIM_STR
  3186. DEBUG_PIM_PACKETDUMP_STR
  3187. DEBUG_PIM_PACKETDUMP_RECV_STR)
  3188. {
  3189. PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
  3190. return CMD_SUCCESS;
  3191. }
  3192. DEFUN (no_debug_pim_packetdump_recv,
  3193. no_debug_pim_packetdump_recv_cmd,
  3194. "no debug pim packet-dump receive",
  3195. NO_STR
  3196. DEBUG_STR
  3197. DEBUG_PIM_STR
  3198. DEBUG_PIM_PACKETDUMP_STR
  3199. DEBUG_PIM_PACKETDUMP_RECV_STR)
  3200. {
  3201. PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
  3202. return CMD_SUCCESS;
  3203. }
  3204. ALIAS (no_debug_pim_packetdump_recv,
  3205. undebug_pim_packetdump_recv_cmd,
  3206. "undebug pim packet-dump receive",
  3207. UNDEBUG_STR
  3208. DEBUG_PIM_STR
  3209. DEBUG_PIM_PACKETDUMP_STR
  3210. DEBUG_PIM_PACKETDUMP_RECV_STR)
  3211. DEFUN (debug_pim_trace,
  3212. debug_pim_trace_cmd,
  3213. "debug pim trace",
  3214. DEBUG_STR
  3215. DEBUG_PIM_STR
  3216. DEBUG_PIM_TRACE_STR)
  3217. {
  3218. PIM_DO_DEBUG_PIM_TRACE;
  3219. return CMD_SUCCESS;
  3220. }
  3221. DEFUN (no_debug_pim_trace,
  3222. no_debug_pim_trace_cmd,
  3223. "no debug pim trace",
  3224. NO_STR
  3225. DEBUG_STR
  3226. DEBUG_PIM_STR
  3227. DEBUG_PIM_TRACE_STR)
  3228. {
  3229. PIM_DONT_DEBUG_PIM_TRACE;
  3230. return CMD_SUCCESS;
  3231. }
  3232. ALIAS (no_debug_pim_trace,
  3233. undebug_pim_trace_cmd,
  3234. "undebug pim trace",
  3235. UNDEBUG_STR
  3236. DEBUG_PIM_STR
  3237. DEBUG_PIM_TRACE_STR)
  3238. DEFUN (debug_ssmpingd,
  3239. debug_ssmpingd_cmd,
  3240. "debug ssmpingd",
  3241. DEBUG_STR
  3242. DEBUG_PIM_STR
  3243. DEBUG_SSMPINGD_STR)
  3244. {
  3245. PIM_DO_DEBUG_SSMPINGD;
  3246. return CMD_SUCCESS;
  3247. }
  3248. DEFUN (no_debug_ssmpingd,
  3249. no_debug_ssmpingd_cmd,
  3250. "no debug ssmpingd",
  3251. NO_STR
  3252. DEBUG_STR
  3253. DEBUG_PIM_STR
  3254. DEBUG_SSMPINGD_STR)
  3255. {
  3256. PIM_DONT_DEBUG_SSMPINGD;
  3257. return CMD_SUCCESS;
  3258. }
  3259. ALIAS (no_debug_ssmpingd,
  3260. undebug_ssmpingd_cmd,
  3261. "undebug ssmpingd",
  3262. UNDEBUG_STR
  3263. DEBUG_PIM_STR
  3264. DEBUG_SSMPINGD_STR)
  3265. DEFUN (debug_pim_zebra,
  3266. debug_pim_zebra_cmd,
  3267. "debug pim zebra",
  3268. DEBUG_STR
  3269. DEBUG_PIM_STR
  3270. DEBUG_PIM_ZEBRA_STR)
  3271. {
  3272. PIM_DO_DEBUG_ZEBRA;
  3273. return CMD_SUCCESS;
  3274. }
  3275. DEFUN (no_debug_pim_zebra,
  3276. no_debug_pim_zebra_cmd,
  3277. "no debug pim zebra",
  3278. NO_STR
  3279. DEBUG_STR
  3280. DEBUG_PIM_STR
  3281. DEBUG_PIM_ZEBRA_STR)
  3282. {
  3283. PIM_DONT_DEBUG_ZEBRA;
  3284. return CMD_SUCCESS;
  3285. }
  3286. ALIAS (no_debug_pim_zebra,
  3287. undebug_pim_zebra_cmd,
  3288. "undebug pim zebra",
  3289. UNDEBUG_STR
  3290. DEBUG_PIM_STR
  3291. DEBUG_PIM_ZEBRA_STR)
  3292. DEFUN (show_debugging_pim,
  3293. show_debugging_pim_cmd,
  3294. "show debugging pim",
  3295. SHOW_STR
  3296. DEBUG_STR
  3297. PIM_STR)
  3298. {
  3299. pim_debug_config_write(vty);
  3300. return CMD_SUCCESS;
  3301. }
  3302. static struct igmp_sock *find_igmp_sock_by_fd(int fd)
  3303. {
  3304. struct listnode *ifnode;
  3305. struct interface *ifp;
  3306. /* scan all interfaces */
  3307. for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  3308. struct pim_interface *pim_ifp;
  3309. struct igmp_sock *igmp;
  3310. if (!ifp->info)
  3311. continue;
  3312. pim_ifp = ifp->info;
  3313. /* lookup igmp socket under current interface */
  3314. igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
  3315. if (igmp)
  3316. return igmp;
  3317. }
  3318. return 0;
  3319. }
  3320. DEFUN (test_igmp_receive_report,
  3321. test_igmp_receive_report_cmd,
  3322. "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
  3323. "Test\n"
  3324. "Test IGMP protocol\n"
  3325. "Test IGMP message\n"
  3326. "Test IGMP report\n"
  3327. "Socket\n"
  3328. "IGMP group address\n"
  3329. "Record type\n"
  3330. "Sources\n")
  3331. {
  3332. char buf[1000];
  3333. char *igmp_msg;
  3334. struct ip *ip_hdr;
  3335. size_t ip_hlen; /* ip header length in bytes */
  3336. int ip_msg_len;
  3337. int igmp_msg_len;
  3338. const char *socket;
  3339. int socket_fd;
  3340. const char *grp_str;
  3341. struct in_addr grp_addr;
  3342. const char *record_type_str;
  3343. int record_type;
  3344. const char *src_str;
  3345. int result;
  3346. struct igmp_sock *igmp;
  3347. char *group_record;
  3348. int num_sources;
  3349. struct in_addr *sources;
  3350. struct in_addr *src_addr;
  3351. int argi;
  3352. socket = argv[0];
  3353. socket_fd = atoi(socket);
  3354. igmp = find_igmp_sock_by_fd(socket_fd);
  3355. if (!igmp) {
  3356. vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
  3357. socket, socket_fd, VTY_NEWLINE);
  3358. return CMD_WARNING;
  3359. }
  3360. grp_str = argv[1];
  3361. result = inet_pton(AF_INET, grp_str, &grp_addr);
  3362. if (result <= 0) {
  3363. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  3364. grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3365. return CMD_WARNING;
  3366. }
  3367. record_type_str = argv[2];
  3368. record_type = atoi(record_type_str);
  3369. /*
  3370. Tweak IP header
  3371. */
  3372. ip_hdr = (struct ip *) buf;
  3373. ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
  3374. ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
  3375. ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
  3376. ip_hdr->ip_src = igmp->ifaddr;
  3377. ip_hdr->ip_dst = igmp->ifaddr;
  3378. /*
  3379. Build IGMP v3 report message
  3380. */
  3381. igmp_msg = buf + ip_hlen;
  3382. group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
  3383. *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
  3384. *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
  3385. *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
  3386. *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
  3387. memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
  3388. /* Scan LINE sources */
  3389. sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
  3390. src_addr = sources;
  3391. for (argi = 3; argi < argc; ++argi,++src_addr) {
  3392. src_str = argv[argi];
  3393. result = inet_pton(AF_INET, src_str, src_addr);
  3394. if (result <= 0) {
  3395. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  3396. src_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3397. return CMD_WARNING;
  3398. }
  3399. }
  3400. num_sources = src_addr - sources;
  3401. *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
  3402. igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
  3403. /* compute checksum */
  3404. *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
  3405. /* "receive" message */
  3406. ip_msg_len = ip_hlen + igmp_msg_len;
  3407. result = pim_igmp_packet(igmp, buf, ip_msg_len);
  3408. if (result) {
  3409. vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
  3410. ip_msg_len, result, VTY_NEWLINE);
  3411. return CMD_WARNING;
  3412. }
  3413. return CMD_SUCCESS;
  3414. }
  3415. static int hexval(uint8_t ch)
  3416. {
  3417. return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
  3418. }
  3419. DEFUN (test_pim_receive_dump,
  3420. test_pim_receive_dump_cmd,
  3421. "test pim receive dump INTERFACE A.B.C.D .LINE",
  3422. "Test\n"
  3423. "Test PIM protocol\n"
  3424. "Test PIM message reception\n"
  3425. "Test PIM packet dump reception from neighbor\n"
  3426. "Interface\n"
  3427. "Neighbor address\n"
  3428. "Packet dump\n")
  3429. {
  3430. uint8_t buf[1000];
  3431. uint8_t *pim_msg;
  3432. struct ip *ip_hdr;
  3433. size_t ip_hlen; /* ip header length in bytes */
  3434. int ip_msg_len;
  3435. int pim_msg_size;
  3436. const char *neigh_str;
  3437. struct in_addr neigh_addr;
  3438. const char *ifname;
  3439. struct interface *ifp;
  3440. int argi;
  3441. int result;
  3442. /* Find interface */
  3443. ifname = argv[0];
  3444. ifp = if_lookup_by_name(ifname);
  3445. if (!ifp) {
  3446. vty_out(vty, "No such interface name %s%s",
  3447. ifname, VTY_NEWLINE);
  3448. return CMD_WARNING;
  3449. }
  3450. /* Neighbor address */
  3451. neigh_str = argv[1];
  3452. result = inet_pton(AF_INET, neigh_str, &neigh_addr);
  3453. if (result <= 0) {
  3454. vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
  3455. neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3456. return CMD_WARNING;
  3457. }
  3458. /*
  3459. Tweak IP header
  3460. */
  3461. ip_hdr = (struct ip *) buf;
  3462. ip_hdr->ip_p = PIM_IP_PROTO_PIM;
  3463. ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
  3464. ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
  3465. ip_hdr->ip_src = neigh_addr;
  3466. ip_hdr->ip_dst = qpim_all_pim_routers_addr;
  3467. /*
  3468. Build PIM hello message
  3469. */
  3470. pim_msg = buf + ip_hlen;
  3471. pim_msg_size = 0;
  3472. /* Scan LINE dump into buffer */
  3473. for (argi = 2; argi < argc; ++argi) {
  3474. const char *str = argv[argi];
  3475. int str_len = strlen(str);
  3476. int str_last = str_len - 1;
  3477. int i;
  3478. if (str_len % 2) {
  3479. vty_out(vty, "%% Uneven hex array arg %d=%s%s",
  3480. argi, str, VTY_NEWLINE);
  3481. return CMD_WARNING;
  3482. }
  3483. for (i = 0; i < str_last; i += 2) {
  3484. uint8_t octet;
  3485. int left;
  3486. uint8_t h1 = str[i];
  3487. uint8_t h2 = str[i + 1];
  3488. if (!isxdigit(h1) || !isxdigit(h2)) {
  3489. vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
  3490. h1, h2, argi, str, VTY_NEWLINE);
  3491. return CMD_WARNING;
  3492. }
  3493. octet = (hexval(h1) << 4) + hexval(h2);
  3494. left = sizeof(buf) - ip_hlen - pim_msg_size;
  3495. if (left < 1) {
  3496. vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
  3497. sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
  3498. return CMD_WARNING;
  3499. }
  3500. pim_msg[pim_msg_size++] = octet;
  3501. }
  3502. }
  3503. ip_msg_len = ip_hlen + pim_msg_size;
  3504. vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
  3505. sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
  3506. /* "receive" message */
  3507. result = pim_pim_packet(ifp, buf, ip_msg_len);
  3508. if (result) {
  3509. vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
  3510. ip_msg_len, result, VTY_NEWLINE);
  3511. return CMD_WARNING;
  3512. }
  3513. return CMD_SUCCESS;
  3514. }
  3515. DEFUN (test_pim_receive_hello,
  3516. test_pim_receive_hello_cmd,
  3517. "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
  3518. "Test\n"
  3519. "Test PIM protocol\n"
  3520. "Test PIM message reception\n"
  3521. "Test PIM hello reception from neighbor\n"
  3522. "Interface\n"
  3523. "Neighbor address\n"
  3524. "Neighbor holdtime\n"
  3525. "Neighbor DR priority\n"
  3526. "Neighbor generation ID\n"
  3527. "Neighbor propagation delay (msec)\n"
  3528. "Neighbor override interval (msec)\n"
  3529. "Neighbor LAN prune delay T-bit\n"
  3530. "Neighbor secondary addresses\n")
  3531. {
  3532. uint8_t buf[1000];
  3533. uint8_t *pim_msg;
  3534. struct ip *ip_hdr;
  3535. size_t ip_hlen; /* ip header length in bytes */
  3536. int ip_msg_len;
  3537. int pim_tlv_size;
  3538. int pim_msg_size;
  3539. const char *neigh_str;
  3540. struct in_addr neigh_addr;
  3541. const char *ifname;
  3542. struct interface *ifp;
  3543. uint16_t neigh_holdtime;
  3544. uint16_t neigh_propagation_delay;
  3545. uint16_t neigh_override_interval;
  3546. int neigh_can_disable_join_suppression;
  3547. uint32_t neigh_dr_priority;
  3548. uint32_t neigh_generation_id;
  3549. int argi;
  3550. int result;
  3551. /* Find interface */
  3552. ifname = argv[0];
  3553. ifp = if_lookup_by_name(ifname);
  3554. if (!ifp) {
  3555. vty_out(vty, "No such interface name %s%s",
  3556. ifname, VTY_NEWLINE);
  3557. return CMD_WARNING;
  3558. }
  3559. /* Neighbor address */
  3560. neigh_str = argv[1];
  3561. result = inet_pton(AF_INET, neigh_str, &neigh_addr);
  3562. if (result <= 0) {
  3563. vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
  3564. neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3565. return CMD_WARNING;
  3566. }
  3567. neigh_holdtime = atoi(argv[2]);
  3568. neigh_dr_priority = atoi(argv[3]);
  3569. neigh_generation_id = atoi(argv[4]);
  3570. neigh_propagation_delay = atoi(argv[5]);
  3571. neigh_override_interval = atoi(argv[6]);
  3572. neigh_can_disable_join_suppression = atoi(argv[7]);
  3573. /*
  3574. Tweak IP header
  3575. */
  3576. ip_hdr = (struct ip *) buf;
  3577. ip_hdr->ip_p = PIM_IP_PROTO_PIM;
  3578. ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
  3579. ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
  3580. ip_hdr->ip_src = neigh_addr;
  3581. ip_hdr->ip_dst = qpim_all_pim_routers_addr;
  3582. /*
  3583. Build PIM hello message
  3584. */
  3585. pim_msg = buf + ip_hlen;
  3586. /* Scan LINE addresses */
  3587. for (argi = 8; argi < argc; ++argi) {
  3588. const char *sec_str = argv[argi];
  3589. struct in_addr sec_addr;
  3590. result = inet_pton(AF_INET, sec_str, &sec_addr);
  3591. if (result <= 0) {
  3592. vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
  3593. sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3594. return CMD_WARNING;
  3595. }
  3596. vty_out(vty,
  3597. "FIXME WRITEME consider neighbor secondary address %s%s",
  3598. sec_str, VTY_NEWLINE);
  3599. }
  3600. pim_tlv_size = pim_hello_build_tlv(ifp->name,
  3601. pim_msg + PIM_PIM_MIN_LEN,
  3602. sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
  3603. neigh_holdtime,
  3604. neigh_dr_priority,
  3605. neigh_generation_id,
  3606. neigh_propagation_delay,
  3607. neigh_override_interval,
  3608. neigh_can_disable_join_suppression,
  3609. 0 /* FIXME secondary address list */);
  3610. if (pim_tlv_size < 0) {
  3611. vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
  3612. pim_tlv_size, VTY_NEWLINE);
  3613. return CMD_WARNING;
  3614. }
  3615. pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
  3616. pim_msg_build_header(pim_msg, pim_msg_size,
  3617. PIM_MSG_TYPE_HELLO);
  3618. /* "receive" message */
  3619. ip_msg_len = ip_hlen + pim_msg_size;
  3620. result = pim_pim_packet(ifp, buf, ip_msg_len);
  3621. if (result) {
  3622. vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
  3623. ip_msg_len, result, VTY_NEWLINE);
  3624. return CMD_WARNING;
  3625. }
  3626. return CMD_SUCCESS;
  3627. }
  3628. DEFUN (test_pim_receive_assert,
  3629. test_pim_receive_assert_cmd,
  3630. "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
  3631. "Test\n"
  3632. "Test PIM protocol\n"
  3633. "Test PIM message reception\n"
  3634. "Test reception of PIM assert\n"
  3635. "Interface\n"
  3636. "Neighbor address\n"
  3637. "Assert multicast group address\n"
  3638. "Assert unicast source address\n"
  3639. "Assert metric preference\n"
  3640. "Assert route metric\n"
  3641. "Assert RPT bit flag\n")
  3642. {
  3643. uint8_t buf[1000];
  3644. uint8_t *buf_pastend = buf + sizeof(buf);
  3645. uint8_t *pim_msg;
  3646. struct ip *ip_hdr;
  3647. size_t ip_hlen; /* ip header length in bytes */
  3648. int ip_msg_len;
  3649. int pim_msg_size;
  3650. const char *neigh_str;
  3651. struct in_addr neigh_addr;
  3652. const char *group_str;
  3653. struct in_addr group_addr;
  3654. const char *source_str;
  3655. struct in_addr source_addr;
  3656. const char *ifname;
  3657. struct interface *ifp;
  3658. uint32_t assert_metric_preference;
  3659. uint32_t assert_route_metric;
  3660. uint32_t assert_rpt_bit_flag;
  3661. int remain;
  3662. int result;
  3663. /* Find interface */
  3664. ifname = argv[0];
  3665. ifp = if_lookup_by_name(ifname);
  3666. if (!ifp) {
  3667. vty_out(vty, "No such interface name %s%s",
  3668. ifname, VTY_NEWLINE);
  3669. return CMD_WARNING;
  3670. }
  3671. /* Neighbor address */
  3672. neigh_str = argv[1];
  3673. result = inet_pton(AF_INET, neigh_str, &neigh_addr);
  3674. if (result <= 0) {
  3675. vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
  3676. neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3677. return CMD_WARNING;
  3678. }
  3679. /* Group address */
  3680. group_str = argv[2];
  3681. result = inet_pton(AF_INET, group_str, &group_addr);
  3682. if (result <= 0) {
  3683. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  3684. group_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3685. return CMD_WARNING;
  3686. }
  3687. /* Source address */
  3688. source_str = argv[3];
  3689. result = inet_pton(AF_INET, source_str, &source_addr);
  3690. if (result <= 0) {
  3691. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  3692. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3693. return CMD_WARNING;
  3694. }
  3695. assert_metric_preference = atoi(argv[4]);
  3696. assert_route_metric = atoi(argv[5]);
  3697. assert_rpt_bit_flag = atoi(argv[6]);
  3698. remain = buf_pastend - buf;
  3699. if (remain < (int) sizeof(struct ip)) {
  3700. vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
  3701. remain, sizeof(struct ip), VTY_NEWLINE);
  3702. return CMD_WARNING;
  3703. }
  3704. /*
  3705. Tweak IP header
  3706. */
  3707. ip_hdr = (struct ip *) buf;
  3708. ip_hdr->ip_p = PIM_IP_PROTO_PIM;
  3709. ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
  3710. ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
  3711. ip_hdr->ip_src = neigh_addr;
  3712. ip_hdr->ip_dst = qpim_all_pim_routers_addr;
  3713. /*
  3714. Build PIM assert message
  3715. */
  3716. pim_msg = buf + ip_hlen; /* skip ip header */
  3717. pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
  3718. group_addr, source_addr,
  3719. assert_metric_preference,
  3720. assert_route_metric,
  3721. assert_rpt_bit_flag);
  3722. if (pim_msg_size < 0) {
  3723. vty_out(vty, "Failure building PIM assert message: size=%d%s",
  3724. pim_msg_size, VTY_NEWLINE);
  3725. return CMD_WARNING;
  3726. }
  3727. /* "receive" message */
  3728. ip_msg_len = ip_hlen + pim_msg_size;
  3729. result = pim_pim_packet(ifp, buf, ip_msg_len);
  3730. if (result) {
  3731. vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
  3732. ip_msg_len, result, VTY_NEWLINE);
  3733. return CMD_WARNING;
  3734. }
  3735. return CMD_SUCCESS;
  3736. }
  3737. static int recv_joinprune(struct vty *vty,
  3738. const char *argv[],
  3739. int src_is_join)
  3740. {
  3741. uint8_t buf[1000];
  3742. const uint8_t *buf_pastend = buf + sizeof(buf);
  3743. uint8_t *pim_msg;
  3744. uint8_t *pim_msg_curr;
  3745. int pim_msg_size;
  3746. struct ip *ip_hdr;
  3747. size_t ip_hlen; /* ip header length in bytes */
  3748. int ip_msg_len;
  3749. uint16_t neigh_holdtime;
  3750. const char *neigh_dst_str;
  3751. struct in_addr neigh_dst_addr;
  3752. const char *neigh_src_str;
  3753. struct in_addr neigh_src_addr;
  3754. const char *group_str;
  3755. struct in_addr group_addr;
  3756. const char *source_str;
  3757. struct in_addr source_addr;
  3758. const char *ifname;
  3759. struct interface *ifp;
  3760. int result;
  3761. int remain;
  3762. uint16_t num_joined;
  3763. uint16_t num_pruned;
  3764. /* Find interface */
  3765. ifname = argv[0];
  3766. ifp = if_lookup_by_name(ifname);
  3767. if (!ifp) {
  3768. vty_out(vty, "No such interface name %s%s",
  3769. ifname, VTY_NEWLINE);
  3770. return CMD_WARNING;
  3771. }
  3772. neigh_holdtime = atoi(argv[1]);
  3773. /* Neighbor destination address */
  3774. neigh_dst_str = argv[2];
  3775. result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
  3776. if (result <= 0) {
  3777. vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
  3778. neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3779. return CMD_WARNING;
  3780. }
  3781. /* Neighbor source address */
  3782. neigh_src_str = argv[3];
  3783. result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
  3784. if (result <= 0) {
  3785. vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
  3786. neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3787. return CMD_WARNING;
  3788. }
  3789. /* Multicast group address */
  3790. group_str = argv[4];
  3791. result = inet_pton(AF_INET, group_str, &group_addr);
  3792. if (result <= 0) {
  3793. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  3794. group_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3795. return CMD_WARNING;
  3796. }
  3797. /* Multicast source address */
  3798. source_str = argv[5];
  3799. result = inet_pton(AF_INET, source_str, &source_addr);
  3800. if (result <= 0) {
  3801. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  3802. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3803. return CMD_WARNING;
  3804. }
  3805. /*
  3806. Tweak IP header
  3807. */
  3808. ip_hdr = (struct ip *) buf;
  3809. ip_hdr->ip_p = PIM_IP_PROTO_PIM;
  3810. ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
  3811. ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
  3812. ip_hdr->ip_src = neigh_src_addr;
  3813. ip_hdr->ip_dst = qpim_all_pim_routers_addr;
  3814. /*
  3815. Build PIM message
  3816. */
  3817. pim_msg = buf + ip_hlen;
  3818. /* skip room for pim header */
  3819. pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
  3820. remain = buf_pastend - pim_msg_curr;
  3821. pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
  3822. remain,
  3823. neigh_dst_addr);
  3824. if (!pim_msg_curr) {
  3825. vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
  3826. neigh_dst_str, remain, VTY_NEWLINE);
  3827. return CMD_WARNING;
  3828. }
  3829. remain = buf_pastend - pim_msg_curr;
  3830. if (remain < 4) {
  3831. vty_out(vty, "Group will not fit: space left=%d%s",
  3832. remain, VTY_NEWLINE);
  3833. return CMD_WARNING;
  3834. }
  3835. *pim_msg_curr = 0; /* reserved */
  3836. ++pim_msg_curr;
  3837. *pim_msg_curr = 1; /* number of groups */
  3838. ++pim_msg_curr;
  3839. *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
  3840. ++pim_msg_curr;
  3841. ++pim_msg_curr;
  3842. remain = buf_pastend - pim_msg_curr;
  3843. pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
  3844. remain,
  3845. group_addr);
  3846. if (!pim_msg_curr) {
  3847. vty_out(vty, "Failure encoding group address %s: space left=%d%s",
  3848. group_str, remain, VTY_NEWLINE);
  3849. return CMD_WARNING;
  3850. }
  3851. remain = buf_pastend - pim_msg_curr;
  3852. if (remain < 4) {
  3853. vty_out(vty, "Sources will not fit: space left=%d%s",
  3854. remain, VTY_NEWLINE);
  3855. return CMD_WARNING;
  3856. }
  3857. if (src_is_join) {
  3858. num_joined = 1;
  3859. num_pruned = 0;
  3860. }
  3861. else {
  3862. num_joined = 0;
  3863. num_pruned = 1;
  3864. }
  3865. /* number of joined sources */
  3866. *((uint16_t *) pim_msg_curr) = htons(num_joined);
  3867. ++pim_msg_curr;
  3868. ++pim_msg_curr;
  3869. /* number of pruned sources */
  3870. *((uint16_t *) pim_msg_curr) = htons(num_pruned);
  3871. ++pim_msg_curr;
  3872. ++pim_msg_curr;
  3873. remain = buf_pastend - pim_msg_curr;
  3874. pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
  3875. remain,
  3876. source_addr);
  3877. if (!pim_msg_curr) {
  3878. vty_out(vty, "Failure encoding source address %s: space left=%d%s",
  3879. source_str, remain, VTY_NEWLINE);
  3880. return CMD_WARNING;
  3881. }
  3882. /* Add PIM header */
  3883. pim_msg_size = pim_msg_curr - pim_msg;
  3884. pim_msg_build_header(pim_msg, pim_msg_size,
  3885. PIM_MSG_TYPE_JOIN_PRUNE);
  3886. /*
  3887. "Receive" message
  3888. */
  3889. ip_msg_len = ip_hlen + pim_msg_size;
  3890. result = pim_pim_packet(ifp, buf, ip_msg_len);
  3891. if (result) {
  3892. vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
  3893. ip_msg_len, result, VTY_NEWLINE);
  3894. return CMD_WARNING;
  3895. }
  3896. return CMD_SUCCESS;
  3897. }
  3898. DEFUN (test_pim_receive_join,
  3899. test_pim_receive_join_cmd,
  3900. "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
  3901. "Test\n"
  3902. "Test PIM protocol\n"
  3903. "Test PIM message reception\n"
  3904. "Test PIM join reception from neighbor\n"
  3905. "Interface\n"
  3906. "Neighbor holdtime\n"
  3907. "Upstream neighbor unicast destination address\n"
  3908. "Downstream neighbor unicast source address\n"
  3909. "Multicast group address\n"
  3910. "Unicast source address\n")
  3911. {
  3912. return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
  3913. }
  3914. DEFUN (test_pim_receive_prune,
  3915. test_pim_receive_prune_cmd,
  3916. "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
  3917. "Test\n"
  3918. "Test PIM protocol\n"
  3919. "Test PIM message reception\n"
  3920. "Test PIM prune reception from neighbor\n"
  3921. "Interface\n"
  3922. "Neighbor holdtime\n"
  3923. "Upstream neighbor unicast destination address\n"
  3924. "Downstream neighbor unicast source address\n"
  3925. "Multicast group address\n"
  3926. "Unicast source address\n")
  3927. {
  3928. return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
  3929. }
  3930. DEFUN (test_pim_receive_upcall,
  3931. test_pim_receive_upcall_cmd,
  3932. "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
  3933. "Test\n"
  3934. "Test PIM protocol\n"
  3935. "Test PIM message reception\n"
  3936. "Test reception of kernel upcall\n"
  3937. "NOCACHE kernel upcall\n"
  3938. "WRONGVIF kernel upcall\n"
  3939. "WHOLEPKT kernel upcall\n"
  3940. "Input interface vif index\n"
  3941. "Multicast group address\n"
  3942. "Multicast source address\n")
  3943. {
  3944. struct igmpmsg msg;
  3945. const char *upcall_type;
  3946. const char *group_str;
  3947. const char *source_str;
  3948. int result;
  3949. upcall_type = argv[0];
  3950. if (upcall_type[0] == 'n')
  3951. msg.im_msgtype = IGMPMSG_NOCACHE;
  3952. else if (upcall_type[1] == 'r')
  3953. msg.im_msgtype = IGMPMSG_WRONGVIF;
  3954. else if (upcall_type[1] == 'h')
  3955. msg.im_msgtype = IGMPMSG_WHOLEPKT;
  3956. else {
  3957. vty_out(vty, "Unknown kernel upcall type: %s%s",
  3958. upcall_type, VTY_NEWLINE);
  3959. return CMD_WARNING;
  3960. }
  3961. msg.im_vif = atoi(argv[1]);
  3962. /* Group address */
  3963. group_str = argv[2];
  3964. result = inet_pton(AF_INET, group_str, &msg.im_dst);
  3965. if (result <= 0) {
  3966. vty_out(vty, "Bad group address %s: errno=%d: %s%s",
  3967. group_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3968. return CMD_WARNING;
  3969. }
  3970. /* Source address */
  3971. source_str = argv[3];
  3972. result = inet_pton(AF_INET, source_str, &msg.im_src);
  3973. if (result <= 0) {
  3974. vty_out(vty, "Bad source address %s: errno=%d: %s%s",
  3975. source_str, errno, safe_strerror(errno), VTY_NEWLINE);
  3976. return CMD_WARNING;
  3977. }
  3978. msg.im_mbz = 0; /* Must be zero */
  3979. result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
  3980. if (result) {
  3981. vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
  3982. sizeof(msg), result, VTY_NEWLINE);
  3983. return CMD_WARNING;
  3984. }
  3985. return CMD_SUCCESS;
  3986. }
  3987. void pim_cmd_init()
  3988. {
  3989. install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
  3990. install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
  3991. install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
  3992. install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
  3993. install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
  3994. install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
  3995. #if 0
  3996. install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
  3997. #else
  3998. install_element (CONFIG_NODE, &pim_interface_cmd);
  3999. #endif
  4000. install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
  4001. install_default (INTERFACE_NODE);
  4002. install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
  4003. install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
  4004. install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
  4005. install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
  4006. install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
  4007. install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
  4008. install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
  4009. install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
  4010. install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
  4011. install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
  4012. install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
  4013. install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
  4014. install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
  4015. install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
  4016. install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
  4017. install_element (INTERFACE_NODE, &interface_ip_pim_hello_hold_cmd);
  4018. install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
  4019. // Static mroutes NEB
  4020. install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
  4021. install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
  4022. install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
  4023. install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
  4024. install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
  4025. install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
  4026. install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
  4027. install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
  4028. install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
  4029. install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
  4030. install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
  4031. install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
  4032. install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
  4033. install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
  4034. install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
  4035. install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
  4036. install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
  4037. install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
  4038. install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
  4039. install_element (VIEW_NODE, &show_ip_pim_join_cmd);
  4040. install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
  4041. install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
  4042. install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
  4043. install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
  4044. install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
  4045. install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
  4046. install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
  4047. install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
  4048. install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
  4049. install_element (VIEW_NODE, &show_ip_multicast_cmd);
  4050. install_element (VIEW_NODE, &show_ip_mroute_cmd);
  4051. install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
  4052. install_element (VIEW_NODE, &show_ip_rib_cmd);
  4053. install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
  4054. install_element (VIEW_NODE, &show_debugging_pim_cmd);
  4055. install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
  4056. install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
  4057. install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
  4058. install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
  4059. install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
  4060. install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
  4061. install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
  4062. install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
  4063. install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
  4064. install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
  4065. install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
  4066. install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
  4067. install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
  4068. install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
  4069. install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
  4070. install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
  4071. install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
  4072. install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
  4073. install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
  4074. install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
  4075. install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
  4076. install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
  4077. install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
  4078. install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
  4079. install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
  4080. install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
  4081. install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
  4082. install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
  4083. install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
  4084. install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
  4085. install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
  4086. install_element (ENABLE_NODE, &show_ip_multicast_cmd);
  4087. install_element (ENABLE_NODE, &show_ip_mroute_cmd);
  4088. install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
  4089. install_element (ENABLE_NODE, &show_ip_rib_cmd);
  4090. install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
  4091. install_element (ENABLE_NODE, &show_debugging_pim_cmd);
  4092. install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
  4093. install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
  4094. install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
  4095. install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
  4096. install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
  4097. install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
  4098. install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
  4099. install_element (ENABLE_NODE, &debug_igmp_cmd);
  4100. install_element (ENABLE_NODE, &no_debug_igmp_cmd);
  4101. install_element (ENABLE_NODE, &undebug_igmp_cmd);
  4102. install_element (ENABLE_NODE, &debug_igmp_events_cmd);
  4103. install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
  4104. install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
  4105. install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
  4106. install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
  4107. install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
  4108. install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
  4109. install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
  4110. install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
  4111. install_element (ENABLE_NODE, &debug_mroute_cmd);
  4112. install_element (ENABLE_NODE, &no_debug_mroute_cmd);
  4113. install_element (ENABLE_NODE, &debug_static_cmd);
  4114. install_element (ENABLE_NODE, &no_debug_static_cmd);
  4115. install_element (ENABLE_NODE, &debug_pim_cmd);
  4116. install_element (ENABLE_NODE, &no_debug_pim_cmd);
  4117. install_element (ENABLE_NODE, &undebug_pim_cmd);
  4118. install_element (ENABLE_NODE, &debug_pim_events_cmd);
  4119. install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
  4120. install_element (ENABLE_NODE, &undebug_pim_events_cmd);
  4121. install_element (ENABLE_NODE, &debug_pim_packets_cmd);
  4122. install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
  4123. install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
  4124. install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
  4125. install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
  4126. install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
  4127. install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
  4128. install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
  4129. install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
  4130. install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
  4131. install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
  4132. install_element (ENABLE_NODE, &debug_pim_trace_cmd);
  4133. install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
  4134. install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
  4135. install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
  4136. install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
  4137. install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
  4138. install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
  4139. install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
  4140. install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
  4141. install_element (CONFIG_NODE, &debug_igmp_cmd);
  4142. install_element (CONFIG_NODE, &no_debug_igmp_cmd);
  4143. install_element (CONFIG_NODE, &undebug_igmp_cmd);
  4144. install_element (CONFIG_NODE, &debug_igmp_events_cmd);
  4145. install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
  4146. install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
  4147. install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
  4148. install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
  4149. install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
  4150. install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
  4151. install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
  4152. install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
  4153. install_element (CONFIG_NODE, &debug_mroute_cmd);
  4154. install_element (CONFIG_NODE, &no_debug_mroute_cmd);
  4155. install_element (CONFIG_NODE, &debug_static_cmd);
  4156. install_element (CONFIG_NODE, &no_debug_static_cmd);
  4157. install_element (CONFIG_NODE, &debug_pim_cmd);
  4158. install_element (CONFIG_NODE, &no_debug_pim_cmd);
  4159. install_element (CONFIG_NODE, &undebug_pim_cmd);
  4160. install_element (CONFIG_NODE, &debug_pim_events_cmd);
  4161. install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
  4162. install_element (CONFIG_NODE, &undebug_pim_events_cmd);
  4163. install_element (CONFIG_NODE, &debug_pim_packets_cmd);
  4164. install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
  4165. install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
  4166. install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
  4167. install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
  4168. install_element (CONFIG_NODE, &debug_pim_trace_cmd);
  4169. install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
  4170. install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
  4171. install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
  4172. install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
  4173. install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
  4174. install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
  4175. install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
  4176. install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
  4177. }