zebra_vty.c 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144
  1. /* Zebra VTY functions
  2. * Copyright (C) 2002 Kunihiro Ishiguro
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "memory.h"
  23. #include "if.h"
  24. #include "prefix.h"
  25. #include "command.h"
  26. #include "table.h"
  27. #include "rib.h"
  28. #include "zebra/zserv.h"
  29. /* General fucntion for static route. */
  30. static int
  31. zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
  32. const char *mask_str, const char *gate_str,
  33. const char *flag_str, const char *distance_str)
  34. {
  35. int ret;
  36. u_char distance;
  37. struct prefix p;
  38. struct in_addr gate;
  39. struct in_addr mask;
  40. const char *ifname;
  41. u_char flag = 0;
  42. ret = str2prefix (dest_str, &p);
  43. if (ret <= 0)
  44. {
  45. vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
  46. return CMD_WARNING;
  47. }
  48. /* Cisco like mask notation. */
  49. if (mask_str)
  50. {
  51. ret = inet_aton (mask_str, &mask);
  52. if (ret == 0)
  53. {
  54. vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
  55. return CMD_WARNING;
  56. }
  57. p.prefixlen = ip_masklen (mask);
  58. }
  59. /* Apply mask for given prefix. */
  60. apply_mask (&p);
  61. /* Administrative distance. */
  62. if (distance_str)
  63. distance = atoi (distance_str);
  64. else
  65. distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
  66. /* Null0 static route. */
  67. if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
  68. {
  69. if (flag_str)
  70. {
  71. vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
  72. return CMD_WARNING;
  73. }
  74. if (add_cmd)
  75. static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
  76. else
  77. static_delete_ipv4 (&p, NULL, NULL, distance, 0);
  78. return CMD_SUCCESS;
  79. }
  80. /* Route flags */
  81. if (flag_str) {
  82. switch(flag_str[0]) {
  83. case 'r':
  84. case 'R': /* XXX */
  85. SET_FLAG (flag, ZEBRA_FLAG_REJECT);
  86. break;
  87. case 'b':
  88. case 'B': /* XXX */
  89. SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
  90. break;
  91. default:
  92. vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
  93. return CMD_WARNING;
  94. }
  95. }
  96. if (gate_str == NULL)
  97. {
  98. if (add_cmd)
  99. static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
  100. else
  101. static_delete_ipv4 (&p, NULL, NULL, distance, 0);
  102. return CMD_SUCCESS;
  103. }
  104. /* When gateway is A.B.C.D format, gate is treated as nexthop
  105. address other case gate is treated as interface name. */
  106. ret = inet_aton (gate_str, &gate);
  107. if (ret)
  108. ifname = NULL;
  109. else
  110. ifname = gate_str;
  111. if (add_cmd)
  112. static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
  113. else
  114. static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
  115. return CMD_SUCCESS;
  116. }
  117. /* Static route configuration. */
  118. DEFUN (ip_route,
  119. ip_route_cmd,
  120. "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
  121. IP_STR
  122. "Establish static routes\n"
  123. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  124. "IP gateway address\n"
  125. "IP gateway interface name\n"
  126. "Null interface\n")
  127. {
  128. return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
  129. }
  130. DEFUN (ip_route_flags,
  131. ip_route_flags_cmd,
  132. "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
  133. IP_STR
  134. "Establish static routes\n"
  135. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  136. "IP gateway address\n"
  137. "IP gateway interface name\n"
  138. "Emit an ICMP unreachable when matched\n"
  139. "Silently discard pkts when matched\n")
  140. {
  141. return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
  142. }
  143. DEFUN (ip_route_flags2,
  144. ip_route_flags2_cmd,
  145. "ip route A.B.C.D/M (reject|blackhole)",
  146. IP_STR
  147. "Establish static routes\n"
  148. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  149. "Emit an ICMP unreachable when matched\n"
  150. "Silently discard pkts when matched\n")
  151. {
  152. return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
  153. }
  154. /* Mask as A.B.C.D format. */
  155. DEFUN (ip_route_mask,
  156. ip_route_mask_cmd,
  157. "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
  158. IP_STR
  159. "Establish static routes\n"
  160. "IP destination prefix\n"
  161. "IP destination prefix mask\n"
  162. "IP gateway address\n"
  163. "IP gateway interface name\n"
  164. "Null interface\n")
  165. {
  166. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
  167. }
  168. DEFUN (ip_route_mask_flags,
  169. ip_route_mask_flags_cmd,
  170. "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
  171. IP_STR
  172. "Establish static routes\n"
  173. "IP destination prefix\n"
  174. "IP destination prefix mask\n"
  175. "IP gateway address\n"
  176. "IP gateway interface name\n"
  177. "Emit an ICMP unreachable when matched\n"
  178. "Silently discard pkts when matched\n")
  179. {
  180. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
  181. }
  182. DEFUN (ip_route_mask_flags2,
  183. ip_route_mask_flags2_cmd,
  184. "ip route A.B.C.D A.B.C.D (reject|blackhole)",
  185. IP_STR
  186. "Establish static routes\n"
  187. "IP destination prefix\n"
  188. "IP destination prefix mask\n"
  189. "Emit an ICMP unreachable when matched\n"
  190. "Silently discard pkts when matched\n")
  191. {
  192. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
  193. }
  194. /* Distance option value. */
  195. DEFUN (ip_route_distance,
  196. ip_route_distance_cmd,
  197. "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
  198. IP_STR
  199. "Establish static routes\n"
  200. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  201. "IP gateway address\n"
  202. "IP gateway interface name\n"
  203. "Null interface\n"
  204. "Distance value for this route\n")
  205. {
  206. return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
  207. }
  208. DEFUN (ip_route_flags_distance,
  209. ip_route_flags_distance_cmd,
  210. "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  211. IP_STR
  212. "Establish static routes\n"
  213. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  214. "IP gateway address\n"
  215. "IP gateway interface name\n"
  216. "Emit an ICMP unreachable when matched\n"
  217. "Silently discard pkts when matched\n"
  218. "Distance value for this route\n")
  219. {
  220. return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
  221. }
  222. DEFUN (ip_route_flags_distance2,
  223. ip_route_flags_distance2_cmd,
  224. "ip route A.B.C.D/M (reject|blackhole) <1-255>",
  225. IP_STR
  226. "Establish static routes\n"
  227. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  228. "Emit an ICMP unreachable when matched\n"
  229. "Silently discard pkts when matched\n"
  230. "Distance value for this route\n")
  231. {
  232. return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
  233. }
  234. DEFUN (ip_route_mask_distance,
  235. ip_route_mask_distance_cmd,
  236. "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
  237. IP_STR
  238. "Establish static routes\n"
  239. "IP destination prefix\n"
  240. "IP destination prefix mask\n"
  241. "IP gateway address\n"
  242. "IP gateway interface name\n"
  243. "Null interface\n"
  244. "Distance value for this route\n")
  245. {
  246. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
  247. }
  248. DEFUN (ip_route_mask_flags_distance,
  249. ip_route_mask_flags_distance_cmd,
  250. "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  251. IP_STR
  252. "Establish static routes\n"
  253. "IP destination prefix\n"
  254. "IP destination prefix mask\n"
  255. "IP gateway address\n"
  256. "IP gateway interface name\n"
  257. "Distance value for this route\n"
  258. "Emit an ICMP unreachable when matched\n"
  259. "Silently discard pkts when matched\n")
  260. {
  261. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
  262. }
  263. DEFUN (ip_route_mask_flags_distance2,
  264. ip_route_mask_flags_distance2_cmd,
  265. "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
  266. IP_STR
  267. "Establish static routes\n"
  268. "IP destination prefix\n"
  269. "IP destination prefix mask\n"
  270. "Distance value for this route\n"
  271. "Emit an ICMP unreachable when matched\n"
  272. "Silently discard pkts when matched\n")
  273. {
  274. return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
  275. }
  276. DEFUN (no_ip_route,
  277. no_ip_route_cmd,
  278. "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
  279. NO_STR
  280. IP_STR
  281. "Establish static routes\n"
  282. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  283. "IP gateway address\n"
  284. "IP gateway interface name\n"
  285. "Null interface\n")
  286. {
  287. return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
  288. }
  289. ALIAS (no_ip_route,
  290. no_ip_route_flags_cmd,
  291. "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
  292. NO_STR
  293. IP_STR
  294. "Establish static routes\n"
  295. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  296. "IP gateway address\n"
  297. "IP gateway interface name\n"
  298. "Emit an ICMP unreachable when matched\n"
  299. "Silently discard pkts when matched\n")
  300. DEFUN (no_ip_route_flags2,
  301. no_ip_route_flags2_cmd,
  302. "no ip route A.B.C.D/M (reject|blackhole)",
  303. NO_STR
  304. IP_STR
  305. "Establish static routes\n"
  306. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  307. "Emit an ICMP unreachable when matched\n"
  308. "Silently discard pkts when matched\n")
  309. {
  310. return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
  311. }
  312. DEFUN (no_ip_route_mask,
  313. no_ip_route_mask_cmd,
  314. "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
  315. NO_STR
  316. IP_STR
  317. "Establish static routes\n"
  318. "IP destination prefix\n"
  319. "IP destination prefix mask\n"
  320. "IP gateway address\n"
  321. "IP gateway interface name\n"
  322. "Null interface\n")
  323. {
  324. return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
  325. }
  326. ALIAS (no_ip_route_mask,
  327. no_ip_route_mask_flags_cmd,
  328. "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
  329. NO_STR
  330. IP_STR
  331. "Establish static routes\n"
  332. "IP destination prefix\n"
  333. "IP destination prefix mask\n"
  334. "IP gateway address\n"
  335. "IP gateway interface name\n"
  336. "Emit an ICMP unreachable when matched\n"
  337. "Silently discard pkts when matched\n")
  338. DEFUN (no_ip_route_mask_flags2,
  339. no_ip_route_mask_flags2_cmd,
  340. "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
  341. NO_STR
  342. IP_STR
  343. "Establish static routes\n"
  344. "IP destination prefix\n"
  345. "IP destination prefix mask\n"
  346. "Emit an ICMP unreachable when matched\n"
  347. "Silently discard pkts when matched\n")
  348. {
  349. return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
  350. }
  351. DEFUN (no_ip_route_distance,
  352. no_ip_route_distance_cmd,
  353. "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
  354. NO_STR
  355. IP_STR
  356. "Establish static routes\n"
  357. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  358. "IP gateway address\n"
  359. "IP gateway interface name\n"
  360. "Null interface\n"
  361. "Distance value for this route\n")
  362. {
  363. return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
  364. }
  365. DEFUN (no_ip_route_flags_distance,
  366. no_ip_route_flags_distance_cmd,
  367. "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  368. NO_STR
  369. IP_STR
  370. "Establish static routes\n"
  371. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  372. "IP gateway address\n"
  373. "IP gateway interface name\n"
  374. "Emit an ICMP unreachable when matched\n"
  375. "Silently discard pkts when matched\n"
  376. "Distance value for this route\n")
  377. {
  378. return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
  379. }
  380. DEFUN (no_ip_route_flags_distance2,
  381. no_ip_route_flags_distance2_cmd,
  382. "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
  383. NO_STR
  384. IP_STR
  385. "Establish static routes\n"
  386. "IP destination prefix (e.g. 10.0.0.0/8)\n"
  387. "Emit an ICMP unreachable when matched\n"
  388. "Silently discard pkts when matched\n"
  389. "Distance value for this route\n")
  390. {
  391. return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
  392. }
  393. DEFUN (no_ip_route_mask_distance,
  394. no_ip_route_mask_distance_cmd,
  395. "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
  396. NO_STR
  397. IP_STR
  398. "Establish static routes\n"
  399. "IP destination prefix\n"
  400. "IP destination prefix mask\n"
  401. "IP gateway address\n"
  402. "IP gateway interface name\n"
  403. "Null interface\n"
  404. "Distance value for this route\n")
  405. {
  406. return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
  407. }
  408. DEFUN (no_ip_route_mask_flags_distance,
  409. no_ip_route_mask_flags_distance_cmd,
  410. "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
  411. NO_STR
  412. IP_STR
  413. "Establish static routes\n"
  414. "IP destination prefix\n"
  415. "IP destination prefix mask\n"
  416. "IP gateway address\n"
  417. "IP gateway interface name\n"
  418. "Emit an ICMP unreachable when matched\n"
  419. "Silently discard pkts when matched\n"
  420. "Distance value for this route\n")
  421. {
  422. return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
  423. }
  424. DEFUN (no_ip_route_mask_flags_distance2,
  425. no_ip_route_mask_flags_distance2_cmd,
  426. "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
  427. NO_STR
  428. IP_STR
  429. "Establish static routes\n"
  430. "IP destination prefix\n"
  431. "IP destination prefix mask\n"
  432. "Emit an ICMP unreachable when matched\n"
  433. "Silently discard pkts when matched\n"
  434. "Distance value for this route\n")
  435. {
  436. return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
  437. }
  438. char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
  439. DEFUN (ip_protocol,
  440. ip_protocol_cmd,
  441. "ip protocol PROTO route-map ROUTE-MAP",
  442. NO_STR
  443. "Apply route map to PROTO\n"
  444. "Protocol name\n"
  445. "Route map name\n")
  446. {
  447. int i;
  448. if (strcasecmp(argv[0], "any") == 0)
  449. i = ZEBRA_ROUTE_MAX;
  450. else
  451. i = proto_name2num(argv[0]);
  452. if (i < 0)
  453. {
  454. vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
  455. VTY_NEWLINE);
  456. return CMD_WARNING;
  457. }
  458. if (proto_rm[AFI_IP][i])
  459. XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
  460. proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
  461. return CMD_SUCCESS;
  462. }
  463. DEFUN (no_ip_protocol,
  464. no_ip_protocol_cmd,
  465. "no ip protocol PROTO",
  466. NO_STR
  467. "Remove route map from PROTO\n"
  468. "Protocol name\n")
  469. {
  470. int i;
  471. if (strcasecmp(argv[0], "any") == 0)
  472. i = ZEBRA_ROUTE_MAX;
  473. else
  474. i = proto_name2num(argv[0]);
  475. if (i < 0)
  476. {
  477. vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
  478. VTY_NEWLINE);
  479. return CMD_WARNING;
  480. }
  481. if (proto_rm[AFI_IP][i])
  482. XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
  483. proto_rm[AFI_IP][i] = NULL;
  484. return CMD_SUCCESS;
  485. }
  486. /* New RIB. Detailed information for IPv4 route. */
  487. static void
  488. vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
  489. {
  490. struct rib *rib;
  491. struct nexthop *nexthop, *tnexthop;
  492. int recursing;
  493. RNODE_FOREACH_RIB (rn, rib)
  494. {
  495. vty_out (vty, "Routing entry for %s/%d%s",
  496. inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
  497. VTY_NEWLINE);
  498. vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
  499. vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
  500. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
  501. vty_out (vty, ", best");
  502. if (rib->refcnt)
  503. vty_out (vty, ", refcnt %ld", rib->refcnt);
  504. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  505. vty_out (vty, ", blackhole");
  506. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  507. vty_out (vty, ", reject");
  508. vty_out (vty, "%s", VTY_NEWLINE);
  509. #define ONE_DAY_SECOND 60*60*24
  510. #define ONE_WEEK_SECOND 60*60*24*7
  511. if (rib->type == ZEBRA_ROUTE_RIP
  512. || rib->type == ZEBRA_ROUTE_OSPF
  513. || rib->type == ZEBRA_ROUTE_BABEL
  514. || rib->type == ZEBRA_ROUTE_ISIS
  515. || rib->type == ZEBRA_ROUTE_BGP)
  516. {
  517. time_t uptime;
  518. struct tm *tm;
  519. uptime = time (NULL);
  520. uptime -= rib->uptime;
  521. tm = gmtime (&uptime);
  522. vty_out (vty, " Last update ");
  523. if (uptime < ONE_DAY_SECOND)
  524. vty_out (vty, "%02d:%02d:%02d",
  525. tm->tm_hour, tm->tm_min, tm->tm_sec);
  526. else if (uptime < ONE_WEEK_SECOND)
  527. vty_out (vty, "%dd%02dh%02dm",
  528. tm->tm_yday, tm->tm_hour, tm->tm_min);
  529. else
  530. vty_out (vty, "%02dw%dd%02dh",
  531. tm->tm_yday/7,
  532. tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  533. vty_out (vty, " ago%s", VTY_NEWLINE);
  534. }
  535. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  536. {
  537. char addrstr[32];
  538. vty_out (vty, " %c%s",
  539. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
  540. recursing ? " " : "");
  541. switch (nexthop->type)
  542. {
  543. case NEXTHOP_TYPE_IPV4:
  544. case NEXTHOP_TYPE_IPV4_IFINDEX:
  545. vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
  546. if (nexthop->ifindex)
  547. vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
  548. break;
  549. case NEXTHOP_TYPE_IFINDEX:
  550. vty_out (vty, " directly connected, %s",
  551. ifindex2ifname (nexthop->ifindex));
  552. break;
  553. case NEXTHOP_TYPE_IFNAME:
  554. vty_out (vty, " directly connected, %s", nexthop->ifname);
  555. break;
  556. case NEXTHOP_TYPE_BLACKHOLE:
  557. vty_out (vty, " directly connected, Null0");
  558. break;
  559. default:
  560. break;
  561. }
  562. if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  563. vty_out (vty, " inactive");
  564. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
  565. vty_out (vty, " onlink");
  566. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  567. vty_out (vty, " (recursive)");
  568. switch (nexthop->type)
  569. {
  570. case NEXTHOP_TYPE_IPV4:
  571. case NEXTHOP_TYPE_IPV4_IFINDEX:
  572. case NEXTHOP_TYPE_IPV4_IFNAME:
  573. if (nexthop->src.ipv4.s_addr)
  574. {
  575. if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
  576. sizeof addrstr))
  577. vty_out (vty, ", src %s", addrstr);
  578. }
  579. break;
  580. #ifdef HAVE_IPV6
  581. case NEXTHOP_TYPE_IPV6:
  582. case NEXTHOP_TYPE_IPV6_IFINDEX:
  583. case NEXTHOP_TYPE_IPV6_IFNAME:
  584. if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
  585. {
  586. if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
  587. sizeof addrstr))
  588. vty_out (vty, ", src %s", addrstr);
  589. }
  590. break;
  591. #endif /* HAVE_IPV6 */
  592. default:
  593. break;
  594. }
  595. vty_out (vty, "%s", VTY_NEWLINE);
  596. }
  597. vty_out (vty, "%s", VTY_NEWLINE);
  598. }
  599. }
  600. static void
  601. vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
  602. {
  603. struct nexthop *nexthop, *tnexthop;
  604. int recursing;
  605. int len = 0;
  606. char buf[BUFSIZ];
  607. /* Nexthop information. */
  608. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  609. {
  610. if (nexthop == rib->nexthop)
  611. {
  612. /* Prefix information. */
  613. len = vty_out (vty, "%c%c%c %s/%d",
  614. zebra_route_char (rib->type),
  615. CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
  616. ? '>' : ' ',
  617. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  618. ? '*' : ' ',
  619. inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
  620. rn->p.prefixlen);
  621. /* Distance and metric display. */
  622. if (rib->type != ZEBRA_ROUTE_CONNECT
  623. && rib->type != ZEBRA_ROUTE_KERNEL)
  624. len += vty_out (vty, " [%d/%d]", rib->distance,
  625. rib->metric);
  626. }
  627. else
  628. vty_out (vty, " %c%*c",
  629. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  630. ? '*' : ' ',
  631. len - 3 + (2 * recursing), ' ');
  632. switch (nexthop->type)
  633. {
  634. case NEXTHOP_TYPE_IPV4:
  635. case NEXTHOP_TYPE_IPV4_IFINDEX:
  636. vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
  637. if (nexthop->ifindex)
  638. vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
  639. break;
  640. case NEXTHOP_TYPE_IFINDEX:
  641. vty_out (vty, " is directly connected, %s",
  642. ifindex2ifname (nexthop->ifindex));
  643. break;
  644. case NEXTHOP_TYPE_IFNAME:
  645. vty_out (vty, " is directly connected, %s", nexthop->ifname);
  646. break;
  647. case NEXTHOP_TYPE_BLACKHOLE:
  648. vty_out (vty, " is directly connected, Null0");
  649. break;
  650. default:
  651. break;
  652. }
  653. if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  654. vty_out (vty, " inactive");
  655. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
  656. vty_out (vty, " onlink");
  657. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  658. vty_out (vty, " (recursive)");
  659. switch (nexthop->type)
  660. {
  661. case NEXTHOP_TYPE_IPV4:
  662. case NEXTHOP_TYPE_IPV4_IFINDEX:
  663. case NEXTHOP_TYPE_IPV4_IFNAME:
  664. if (nexthop->src.ipv4.s_addr)
  665. {
  666. if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
  667. vty_out (vty, ", src %s", buf);
  668. }
  669. break;
  670. #ifdef HAVE_IPV6
  671. case NEXTHOP_TYPE_IPV6:
  672. case NEXTHOP_TYPE_IPV6_IFINDEX:
  673. case NEXTHOP_TYPE_IPV6_IFNAME:
  674. if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
  675. {
  676. if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
  677. vty_out (vty, ", src %s", buf);
  678. }
  679. break;
  680. #endif /* HAVE_IPV6 */
  681. default:
  682. break;
  683. }
  684. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  685. vty_out (vty, ", bh");
  686. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  687. vty_out (vty, ", rej");
  688. if (rib->type == ZEBRA_ROUTE_RIP
  689. || rib->type == ZEBRA_ROUTE_OSPF
  690. || rib->type == ZEBRA_ROUTE_BABEL
  691. || rib->type == ZEBRA_ROUTE_ISIS
  692. || rib->type == ZEBRA_ROUTE_BGP)
  693. {
  694. time_t uptime;
  695. struct tm *tm;
  696. uptime = time (NULL);
  697. uptime -= rib->uptime;
  698. tm = gmtime (&uptime);
  699. #define ONE_DAY_SECOND 60*60*24
  700. #define ONE_WEEK_SECOND 60*60*24*7
  701. if (uptime < ONE_DAY_SECOND)
  702. vty_out (vty, ", %02d:%02d:%02d",
  703. tm->tm_hour, tm->tm_min, tm->tm_sec);
  704. else if (uptime < ONE_WEEK_SECOND)
  705. vty_out (vty, ", %dd%02dh%02dm",
  706. tm->tm_yday, tm->tm_hour, tm->tm_min);
  707. else
  708. vty_out (vty, ", %02dw%dd%02dh",
  709. tm->tm_yday/7,
  710. tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  711. }
  712. vty_out (vty, "%s", VTY_NEWLINE);
  713. }
  714. }
  715. DEFUN (show_ip_route,
  716. show_ip_route_cmd,
  717. "show ip route",
  718. SHOW_STR
  719. IP_STR
  720. "IP routing table\n")
  721. {
  722. struct route_table *table;
  723. struct route_node *rn;
  724. struct rib *rib;
  725. int first = 1;
  726. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  727. if (! table)
  728. return CMD_SUCCESS;
  729. /* Show all IPv4 routes. */
  730. for (rn = route_top (table); rn; rn = route_next (rn))
  731. RNODE_FOREACH_RIB (rn, rib)
  732. {
  733. if (first)
  734. {
  735. vty_out (vty, SHOW_ROUTE_V4_HEADER);
  736. first = 0;
  737. }
  738. vty_show_ip_route (vty, rn, rib);
  739. }
  740. return CMD_SUCCESS;
  741. }
  742. DEFUN (show_ip_route_prefix_longer,
  743. show_ip_route_prefix_longer_cmd,
  744. "show ip route A.B.C.D/M longer-prefixes",
  745. SHOW_STR
  746. IP_STR
  747. "IP routing table\n"
  748. "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  749. "Show route matching the specified Network/Mask pair only\n")
  750. {
  751. struct route_table *table;
  752. struct route_node *rn;
  753. struct rib *rib;
  754. struct prefix p;
  755. int ret;
  756. int first = 1;
  757. ret = str2prefix (argv[0], &p);
  758. if (! ret)
  759. {
  760. vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
  761. return CMD_WARNING;
  762. }
  763. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  764. if (! table)
  765. return CMD_SUCCESS;
  766. /* Show matched type IPv4 routes. */
  767. for (rn = route_top (table); rn; rn = route_next (rn))
  768. RNODE_FOREACH_RIB (rn, rib)
  769. if (prefix_match (&p, &rn->p))
  770. {
  771. if (first)
  772. {
  773. vty_out (vty, SHOW_ROUTE_V4_HEADER);
  774. first = 0;
  775. }
  776. vty_show_ip_route (vty, rn, rib);
  777. }
  778. return CMD_SUCCESS;
  779. }
  780. DEFUN (show_ip_route_supernets,
  781. show_ip_route_supernets_cmd,
  782. "show ip route supernets-only",
  783. SHOW_STR
  784. IP_STR
  785. "IP routing table\n"
  786. "Show supernet entries only\n")
  787. {
  788. struct route_table *table;
  789. struct route_node *rn;
  790. struct rib *rib;
  791. u_int32_t addr;
  792. int first = 1;
  793. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  794. if (! table)
  795. return CMD_SUCCESS;
  796. /* Show matched type IPv4 routes. */
  797. for (rn = route_top (table); rn; rn = route_next (rn))
  798. RNODE_FOREACH_RIB (rn, rib)
  799. {
  800. addr = ntohl (rn->p.u.prefix4.s_addr);
  801. if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
  802. || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
  803. || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
  804. {
  805. if (first)
  806. {
  807. vty_out (vty, SHOW_ROUTE_V4_HEADER);
  808. first = 0;
  809. }
  810. vty_show_ip_route (vty, rn, rib);
  811. }
  812. }
  813. return CMD_SUCCESS;
  814. }
  815. DEFUN (show_ip_route_protocol,
  816. show_ip_route_protocol_cmd,
  817. "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
  818. SHOW_STR
  819. IP_STR
  820. "IP routing table\n"
  821. QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
  822. {
  823. int type;
  824. struct route_table *table;
  825. struct route_node *rn;
  826. struct rib *rib;
  827. int first = 1;
  828. type = proto_redistnum (AFI_IP, argv[0]);
  829. if (type < 0)
  830. {
  831. vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
  832. return CMD_WARNING;
  833. }
  834. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  835. if (! table)
  836. return CMD_SUCCESS;
  837. /* Show matched type IPv4 routes. */
  838. for (rn = route_top (table); rn; rn = route_next (rn))
  839. RNODE_FOREACH_RIB (rn, rib)
  840. if (rib->type == type)
  841. {
  842. if (first)
  843. {
  844. vty_out (vty, SHOW_ROUTE_V4_HEADER);
  845. first = 0;
  846. }
  847. vty_show_ip_route (vty, rn, rib);
  848. }
  849. return CMD_SUCCESS;
  850. }
  851. DEFUN (show_ip_route_addr,
  852. show_ip_route_addr_cmd,
  853. "show ip route A.B.C.D",
  854. SHOW_STR
  855. IP_STR
  856. "IP routing table\n"
  857. "Network in the IP routing table to display\n")
  858. {
  859. int ret;
  860. struct prefix_ipv4 p;
  861. struct route_table *table;
  862. struct route_node *rn;
  863. ret = str2prefix_ipv4 (argv[0], &p);
  864. if (ret <= 0)
  865. {
  866. vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
  867. return CMD_WARNING;
  868. }
  869. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  870. if (! table)
  871. return CMD_SUCCESS;
  872. rn = route_node_match (table, (struct prefix *) &p);
  873. if (! rn)
  874. {
  875. vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  876. return CMD_WARNING;
  877. }
  878. vty_show_ip_route_detail (vty, rn);
  879. route_unlock_node (rn);
  880. return CMD_SUCCESS;
  881. }
  882. DEFUN (show_ip_route_prefix,
  883. show_ip_route_prefix_cmd,
  884. "show ip route A.B.C.D/M",
  885. SHOW_STR
  886. IP_STR
  887. "IP routing table\n"
  888. "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
  889. {
  890. int ret;
  891. struct prefix_ipv4 p;
  892. struct route_table *table;
  893. struct route_node *rn;
  894. ret = str2prefix_ipv4 (argv[0], &p);
  895. if (ret <= 0)
  896. {
  897. vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
  898. return CMD_WARNING;
  899. }
  900. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  901. if (! table)
  902. return CMD_SUCCESS;
  903. rn = route_node_match (table, (struct prefix *) &p);
  904. if (! rn || rn->p.prefixlen != p.prefixlen)
  905. {
  906. vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  907. return CMD_WARNING;
  908. }
  909. vty_show_ip_route_detail (vty, rn);
  910. route_unlock_node (rn);
  911. return CMD_SUCCESS;
  912. }
  913. static void
  914. vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
  915. {
  916. struct route_node *rn;
  917. struct rib *rib;
  918. struct nexthop *nexthop;
  919. #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
  920. #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
  921. u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
  922. u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
  923. u_int32_t i;
  924. memset (&rib_cnt, 0, sizeof(rib_cnt));
  925. memset (&fib_cnt, 0, sizeof(fib_cnt));
  926. for (rn = route_top (table); rn; rn = route_next (rn))
  927. RNODE_FOREACH_RIB (rn, rib)
  928. for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  929. {
  930. rib_cnt[ZEBRA_ROUTE_TOTAL]++;
  931. rib_cnt[rib->type]++;
  932. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  933. || nexthop_has_fib_child(nexthop))
  934. {
  935. fib_cnt[ZEBRA_ROUTE_TOTAL]++;
  936. fib_cnt[rib->type]++;
  937. }
  938. if (rib->type == ZEBRA_ROUTE_BGP &&
  939. CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
  940. {
  941. rib_cnt[ZEBRA_ROUTE_IBGP]++;
  942. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  943. || nexthop_has_fib_child(nexthop))
  944. fib_cnt[ZEBRA_ROUTE_IBGP]++;
  945. }
  946. }
  947. vty_out (vty, "%-20s %-20s %-20s %s",
  948. "Route Source", "Routes", "FIB", VTY_NEWLINE);
  949. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  950. {
  951. if (rib_cnt[i] > 0)
  952. {
  953. if (i == ZEBRA_ROUTE_BGP)
  954. {
  955. vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
  956. rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
  957. fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
  958. VTY_NEWLINE);
  959. vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
  960. rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
  961. VTY_NEWLINE);
  962. }
  963. else
  964. vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
  965. rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
  966. }
  967. }
  968. vty_out (vty, "------%s", VTY_NEWLINE);
  969. vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
  970. fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
  971. }
  972. /* Show route summary. */
  973. DEFUN (show_ip_route_summary,
  974. show_ip_route_summary_cmd,
  975. "show ip route summary",
  976. SHOW_STR
  977. IP_STR
  978. "IP routing table\n"
  979. "Summary of all routes\n")
  980. {
  981. struct route_table *table;
  982. table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
  983. if (! table)
  984. return CMD_SUCCESS;
  985. vty_show_ip_route_summary (vty, table);
  986. return CMD_SUCCESS;
  987. }
  988. /* Write IPv4 static route configuration. */
  989. static int
  990. static_config_ipv4 (struct vty *vty)
  991. {
  992. struct route_node *rn;
  993. struct static_ipv4 *si;
  994. struct route_table *stable;
  995. int write;
  996. write = 0;
  997. /* Lookup table. */
  998. stable = vrf_static_table (AFI_IP, SAFI_UNICAST, 0);
  999. if (! stable)
  1000. return -1;
  1001. for (rn = route_top (stable); rn; rn = route_next (rn))
  1002. for (si = rn->info; si; si = si->next)
  1003. {
  1004. vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
  1005. rn->p.prefixlen);
  1006. switch (si->type)
  1007. {
  1008. case STATIC_IPV4_GATEWAY:
  1009. vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
  1010. break;
  1011. case STATIC_IPV4_IFNAME:
  1012. vty_out (vty, " %s", si->gate.ifname);
  1013. break;
  1014. case STATIC_IPV4_BLACKHOLE:
  1015. vty_out (vty, " Null0");
  1016. break;
  1017. }
  1018. /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
  1019. if (si->type != STATIC_IPV4_BLACKHOLE)
  1020. {
  1021. if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
  1022. vty_out (vty, " %s", "reject");
  1023. if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
  1024. vty_out (vty, " %s", "blackhole");
  1025. }
  1026. if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
  1027. vty_out (vty, " %d", si->distance);
  1028. vty_out (vty, "%s", VTY_NEWLINE);
  1029. write = 1;
  1030. }
  1031. return write;
  1032. }
  1033. DEFUN (show_ip_protocol,
  1034. show_ip_protocol_cmd,
  1035. "show ip protocol",
  1036. SHOW_STR
  1037. IP_STR
  1038. "IP protocol filtering status\n")
  1039. {
  1040. int i;
  1041. vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
  1042. vty_out(vty, "------------------------%s", VTY_NEWLINE);
  1043. for (i=0;i<ZEBRA_ROUTE_MAX;i++)
  1044. {
  1045. if (proto_rm[AFI_IP][i])
  1046. vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
  1047. proto_rm[AFI_IP][i],
  1048. VTY_NEWLINE);
  1049. else
  1050. vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
  1051. }
  1052. if (proto_rm[AFI_IP][i])
  1053. vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
  1054. VTY_NEWLINE);
  1055. else
  1056. vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
  1057. return CMD_SUCCESS;
  1058. }
  1059. /*
  1060. * Show IP mroute command to dump the BGP Multicast
  1061. * routing table
  1062. */
  1063. DEFUN (show_ip_mroute,
  1064. show_ip_mroute_cmd,
  1065. "show ip mroute",
  1066. SHOW_STR
  1067. IP_STR
  1068. "IP Multicast routing table\n")
  1069. {
  1070. struct route_table *table;
  1071. struct route_node *rn;
  1072. struct rib *rib;
  1073. int first = 1;
  1074. table = vrf_table (AFI_IP, SAFI_MULTICAST, 0);
  1075. if (! table)
  1076. return CMD_SUCCESS;
  1077. /* Show all IPv4 routes. */
  1078. for (rn = route_top (table); rn; rn = route_next (rn))
  1079. RNODE_FOREACH_RIB (rn, rib)
  1080. {
  1081. if (first)
  1082. {
  1083. vty_out (vty, SHOW_ROUTE_V4_HEADER);
  1084. first = 0;
  1085. }
  1086. vty_show_ip_route (vty, rn, rib);
  1087. }
  1088. return CMD_SUCCESS;
  1089. }
  1090. #ifdef HAVE_IPV6
  1091. /* General fucntion for IPv6 static route. */
  1092. static int
  1093. static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
  1094. const char *gate_str, const char *ifname,
  1095. const char *flag_str, const char *distance_str)
  1096. {
  1097. int ret;
  1098. u_char distance;
  1099. struct prefix p;
  1100. struct in6_addr *gate = NULL;
  1101. struct in6_addr gate_addr;
  1102. u_char type = 0;
  1103. int table = 0;
  1104. u_char flag = 0;
  1105. ret = str2prefix (dest_str, &p);
  1106. if (ret <= 0)
  1107. {
  1108. vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
  1109. return CMD_WARNING;
  1110. }
  1111. /* Apply mask for given prefix. */
  1112. apply_mask (&p);
  1113. /* Route flags */
  1114. if (flag_str) {
  1115. switch(flag_str[0]) {
  1116. case 'r':
  1117. case 'R': /* XXX */
  1118. SET_FLAG (flag, ZEBRA_FLAG_REJECT);
  1119. break;
  1120. case 'b':
  1121. case 'B': /* XXX */
  1122. SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
  1123. break;
  1124. default:
  1125. vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
  1126. return CMD_WARNING;
  1127. }
  1128. }
  1129. /* Administrative distance. */
  1130. if (distance_str)
  1131. distance = atoi (distance_str);
  1132. else
  1133. distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
  1134. /* When gateway is valid IPv6 addrees, then gate is treated as
  1135. nexthop address other case gate is treated as interface name. */
  1136. ret = inet_pton (AF_INET6, gate_str, &gate_addr);
  1137. if (ifname)
  1138. {
  1139. /* When ifname is specified. It must be come with gateway
  1140. address. */
  1141. if (ret != 1)
  1142. {
  1143. vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
  1144. return CMD_WARNING;
  1145. }
  1146. type = STATIC_IPV6_GATEWAY_IFNAME;
  1147. gate = &gate_addr;
  1148. }
  1149. else
  1150. {
  1151. if (ret == 1)
  1152. {
  1153. type = STATIC_IPV6_GATEWAY;
  1154. gate = &gate_addr;
  1155. }
  1156. else
  1157. {
  1158. type = STATIC_IPV6_IFNAME;
  1159. ifname = gate_str;
  1160. }
  1161. }
  1162. if (add_cmd)
  1163. static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
  1164. else
  1165. static_delete_ipv6 (&p, type, gate, ifname, distance, table);
  1166. return CMD_SUCCESS;
  1167. }
  1168. DEFUN (ipv6_route,
  1169. ipv6_route_cmd,
  1170. "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
  1171. IP_STR
  1172. "Establish static routes\n"
  1173. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1174. "IPv6 gateway address\n"
  1175. "IPv6 gateway interface name\n")
  1176. {
  1177. return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
  1178. }
  1179. DEFUN (ipv6_route_flags,
  1180. ipv6_route_flags_cmd,
  1181. "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
  1182. IP_STR
  1183. "Establish static routes\n"
  1184. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1185. "IPv6 gateway address\n"
  1186. "IPv6 gateway interface name\n"
  1187. "Emit an ICMP unreachable when matched\n"
  1188. "Silently discard pkts when matched\n")
  1189. {
  1190. return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
  1191. }
  1192. DEFUN (ipv6_route_ifname,
  1193. ipv6_route_ifname_cmd,
  1194. "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
  1195. IP_STR
  1196. "Establish static routes\n"
  1197. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1198. "IPv6 gateway address\n"
  1199. "IPv6 gateway interface name\n")
  1200. {
  1201. return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
  1202. }
  1203. DEFUN (ipv6_route_ifname_flags,
  1204. ipv6_route_ifname_flags_cmd,
  1205. "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
  1206. IP_STR
  1207. "Establish static routes\n"
  1208. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1209. "IPv6 gateway address\n"
  1210. "IPv6 gateway interface name\n"
  1211. "Emit an ICMP unreachable when matched\n"
  1212. "Silently discard pkts when matched\n")
  1213. {
  1214. return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
  1215. }
  1216. DEFUN (ipv6_route_pref,
  1217. ipv6_route_pref_cmd,
  1218. "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
  1219. IP_STR
  1220. "Establish static routes\n"
  1221. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1222. "IPv6 gateway address\n"
  1223. "IPv6 gateway interface name\n"
  1224. "Distance value for this prefix\n")
  1225. {
  1226. return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
  1227. }
  1228. DEFUN (ipv6_route_flags_pref,
  1229. ipv6_route_flags_pref_cmd,
  1230. "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
  1231. IP_STR
  1232. "Establish static routes\n"
  1233. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1234. "IPv6 gateway address\n"
  1235. "IPv6 gateway interface name\n"
  1236. "Emit an ICMP unreachable when matched\n"
  1237. "Silently discard pkts when matched\n"
  1238. "Distance value for this prefix\n")
  1239. {
  1240. return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
  1241. }
  1242. DEFUN (ipv6_route_ifname_pref,
  1243. ipv6_route_ifname_pref_cmd,
  1244. "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
  1245. IP_STR
  1246. "Establish static routes\n"
  1247. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1248. "IPv6 gateway address\n"
  1249. "IPv6 gateway interface name\n"
  1250. "Distance value for this prefix\n")
  1251. {
  1252. return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
  1253. }
  1254. DEFUN (ipv6_route_ifname_flags_pref,
  1255. ipv6_route_ifname_flags_pref_cmd,
  1256. "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
  1257. IP_STR
  1258. "Establish static routes\n"
  1259. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1260. "IPv6 gateway address\n"
  1261. "IPv6 gateway interface name\n"
  1262. "Emit an ICMP unreachable when matched\n"
  1263. "Silently discard pkts when matched\n"
  1264. "Distance value for this prefix\n")
  1265. {
  1266. return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
  1267. }
  1268. DEFUN (no_ipv6_route,
  1269. no_ipv6_route_cmd,
  1270. "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
  1271. NO_STR
  1272. IP_STR
  1273. "Establish static routes\n"
  1274. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1275. "IPv6 gateway address\n"
  1276. "IPv6 gateway interface name\n")
  1277. {
  1278. return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
  1279. }
  1280. ALIAS (no_ipv6_route,
  1281. no_ipv6_route_flags_cmd,
  1282. "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
  1283. NO_STR
  1284. IP_STR
  1285. "Establish static routes\n"
  1286. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1287. "IPv6 gateway address\n"
  1288. "IPv6 gateway interface name\n"
  1289. "Emit an ICMP unreachable when matched\n"
  1290. "Silently discard pkts when matched\n")
  1291. DEFUN (no_ipv6_route_ifname,
  1292. no_ipv6_route_ifname_cmd,
  1293. "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
  1294. NO_STR
  1295. IP_STR
  1296. "Establish static routes\n"
  1297. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1298. "IPv6 gateway address\n"
  1299. "IPv6 gateway interface name\n")
  1300. {
  1301. return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
  1302. }
  1303. ALIAS (no_ipv6_route_ifname,
  1304. no_ipv6_route_ifname_flags_cmd,
  1305. "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
  1306. NO_STR
  1307. IP_STR
  1308. "Establish static routes\n"
  1309. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1310. "IPv6 gateway address\n"
  1311. "IPv6 gateway interface name\n"
  1312. "Emit an ICMP unreachable when matched\n"
  1313. "Silently discard pkts when matched\n")
  1314. DEFUN (no_ipv6_route_pref,
  1315. no_ipv6_route_pref_cmd,
  1316. "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
  1317. NO_STR
  1318. IP_STR
  1319. "Establish static routes\n"
  1320. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1321. "IPv6 gateway address\n"
  1322. "IPv6 gateway interface name\n"
  1323. "Distance value for this prefix\n")
  1324. {
  1325. return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
  1326. }
  1327. DEFUN (no_ipv6_route_flags_pref,
  1328. no_ipv6_route_flags_pref_cmd,
  1329. "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
  1330. NO_STR
  1331. IP_STR
  1332. "Establish static routes\n"
  1333. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1334. "IPv6 gateway address\n"
  1335. "IPv6 gateway interface name\n"
  1336. "Emit an ICMP unreachable when matched\n"
  1337. "Silently discard pkts when matched\n"
  1338. "Distance value for this prefix\n")
  1339. {
  1340. /* We do not care about argv[2] */
  1341. return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
  1342. }
  1343. DEFUN (no_ipv6_route_ifname_pref,
  1344. no_ipv6_route_ifname_pref_cmd,
  1345. "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
  1346. NO_STR
  1347. IP_STR
  1348. "Establish static routes\n"
  1349. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1350. "IPv6 gateway address\n"
  1351. "IPv6 gateway interface name\n"
  1352. "Distance value for this prefix\n")
  1353. {
  1354. return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
  1355. }
  1356. DEFUN (no_ipv6_route_ifname_flags_pref,
  1357. no_ipv6_route_ifname_flags_pref_cmd,
  1358. "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
  1359. NO_STR
  1360. IP_STR
  1361. "Establish static routes\n"
  1362. "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
  1363. "IPv6 gateway address\n"
  1364. "IPv6 gateway interface name\n"
  1365. "Emit an ICMP unreachable when matched\n"
  1366. "Silently discard pkts when matched\n"
  1367. "Distance value for this prefix\n")
  1368. {
  1369. return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
  1370. }
  1371. /* New RIB. Detailed information for IPv6 route. */
  1372. static void
  1373. vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
  1374. {
  1375. struct rib *rib;
  1376. struct nexthop *nexthop, *tnexthop;
  1377. int recursing;
  1378. char buf[BUFSIZ];
  1379. RNODE_FOREACH_RIB (rn, rib)
  1380. {
  1381. vty_out (vty, "Routing entry for %s/%d%s",
  1382. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
  1383. rn->p.prefixlen,
  1384. VTY_NEWLINE);
  1385. vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
  1386. vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
  1387. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
  1388. vty_out (vty, ", best");
  1389. if (rib->refcnt)
  1390. vty_out (vty, ", refcnt %ld", rib->refcnt);
  1391. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  1392. vty_out (vty, ", blackhole");
  1393. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  1394. vty_out (vty, ", reject");
  1395. vty_out (vty, "%s", VTY_NEWLINE);
  1396. #define ONE_DAY_SECOND 60*60*24
  1397. #define ONE_WEEK_SECOND 60*60*24*7
  1398. if (rib->type == ZEBRA_ROUTE_RIPNG
  1399. || rib->type == ZEBRA_ROUTE_OSPF6
  1400. || rib->type == ZEBRA_ROUTE_BABEL
  1401. || rib->type == ZEBRA_ROUTE_ISIS
  1402. || rib->type == ZEBRA_ROUTE_BGP)
  1403. {
  1404. time_t uptime;
  1405. struct tm *tm;
  1406. uptime = time (NULL);
  1407. uptime -= rib->uptime;
  1408. tm = gmtime (&uptime);
  1409. vty_out (vty, " Last update ");
  1410. if (uptime < ONE_DAY_SECOND)
  1411. vty_out (vty, "%02d:%02d:%02d",
  1412. tm->tm_hour, tm->tm_min, tm->tm_sec);
  1413. else if (uptime < ONE_WEEK_SECOND)
  1414. vty_out (vty, "%dd%02dh%02dm",
  1415. tm->tm_yday, tm->tm_hour, tm->tm_min);
  1416. else
  1417. vty_out (vty, "%02dw%dd%02dh",
  1418. tm->tm_yday/7,
  1419. tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  1420. vty_out (vty, " ago%s", VTY_NEWLINE);
  1421. }
  1422. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1423. {
  1424. vty_out (vty, " %c%s",
  1425. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
  1426. recursing ? " " : "");
  1427. switch (nexthop->type)
  1428. {
  1429. case NEXTHOP_TYPE_IPV6:
  1430. case NEXTHOP_TYPE_IPV6_IFINDEX:
  1431. case NEXTHOP_TYPE_IPV6_IFNAME:
  1432. vty_out (vty, " %s",
  1433. inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
  1434. if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
  1435. vty_out (vty, ", %s", nexthop->ifname);
  1436. else if (nexthop->ifindex)
  1437. vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
  1438. break;
  1439. case NEXTHOP_TYPE_IFINDEX:
  1440. vty_out (vty, " directly connected, %s",
  1441. ifindex2ifname (nexthop->ifindex));
  1442. break;
  1443. case NEXTHOP_TYPE_IFNAME:
  1444. vty_out (vty, " directly connected, %s",
  1445. nexthop->ifname);
  1446. break;
  1447. default:
  1448. break;
  1449. }
  1450. if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1451. vty_out (vty, " inactive");
  1452. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
  1453. vty_out (vty, " onlink");
  1454. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1455. vty_out (vty, " (recursive)");
  1456. vty_out (vty, "%s", VTY_NEWLINE);
  1457. }
  1458. vty_out (vty, "%s", VTY_NEWLINE);
  1459. }
  1460. }
  1461. static void
  1462. vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
  1463. struct rib *rib)
  1464. {
  1465. struct nexthop *nexthop, *tnexthop;
  1466. int recursing;
  1467. int len = 0;
  1468. char buf[BUFSIZ];
  1469. /* Nexthop information. */
  1470. for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
  1471. {
  1472. if (nexthop == rib->nexthop)
  1473. {
  1474. /* Prefix information. */
  1475. len = vty_out (vty, "%c%c%c %s/%d",
  1476. zebra_route_char (rib->type),
  1477. CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
  1478. ? '>' : ' ',
  1479. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  1480. ? '*' : ' ',
  1481. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
  1482. rn->p.prefixlen);
  1483. /* Distance and metric display. */
  1484. if (rib->type != ZEBRA_ROUTE_CONNECT
  1485. && rib->type != ZEBRA_ROUTE_KERNEL)
  1486. len += vty_out (vty, " [%d/%d]", rib->distance,
  1487. rib->metric);
  1488. }
  1489. else
  1490. vty_out (vty, " %c%*c",
  1491. CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
  1492. ? '*' : ' ',
  1493. len - 3 + (2 * recursing), ' ');
  1494. switch (nexthop->type)
  1495. {
  1496. case NEXTHOP_TYPE_IPV6:
  1497. case NEXTHOP_TYPE_IPV6_IFINDEX:
  1498. case NEXTHOP_TYPE_IPV6_IFNAME:
  1499. vty_out (vty, " via %s",
  1500. inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
  1501. if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
  1502. vty_out (vty, ", %s", nexthop->ifname);
  1503. else if (nexthop->ifindex)
  1504. vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
  1505. break;
  1506. case NEXTHOP_TYPE_IFINDEX:
  1507. vty_out (vty, " is directly connected, %s",
  1508. ifindex2ifname (nexthop->ifindex));
  1509. break;
  1510. case NEXTHOP_TYPE_IFNAME:
  1511. vty_out (vty, " is directly connected, %s",
  1512. nexthop->ifname);
  1513. break;
  1514. default:
  1515. break;
  1516. }
  1517. if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1518. vty_out (vty, " inactive");
  1519. if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1520. vty_out (vty, " (recursive)");
  1521. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
  1522. vty_out (vty, ", bh");
  1523. if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
  1524. vty_out (vty, ", rej");
  1525. if (rib->type == ZEBRA_ROUTE_RIPNG
  1526. || rib->type == ZEBRA_ROUTE_OSPF6
  1527. || rib->type == ZEBRA_ROUTE_BABEL
  1528. || rib->type == ZEBRA_ROUTE_ISIS
  1529. || rib->type == ZEBRA_ROUTE_BGP)
  1530. {
  1531. time_t uptime;
  1532. struct tm *tm;
  1533. uptime = time (NULL);
  1534. uptime -= rib->uptime;
  1535. tm = gmtime (&uptime);
  1536. #define ONE_DAY_SECOND 60*60*24
  1537. #define ONE_WEEK_SECOND 60*60*24*7
  1538. if (uptime < ONE_DAY_SECOND)
  1539. vty_out (vty, ", %02d:%02d:%02d",
  1540. tm->tm_hour, tm->tm_min, tm->tm_sec);
  1541. else if (uptime < ONE_WEEK_SECOND)
  1542. vty_out (vty, ", %dd%02dh%02dm",
  1543. tm->tm_yday, tm->tm_hour, tm->tm_min);
  1544. else
  1545. vty_out (vty, ", %02dw%dd%02dh",
  1546. tm->tm_yday/7,
  1547. tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  1548. }
  1549. vty_out (vty, "%s", VTY_NEWLINE);
  1550. }
  1551. }
  1552. DEFUN (show_ipv6_route,
  1553. show_ipv6_route_cmd,
  1554. "show ipv6 route",
  1555. SHOW_STR
  1556. IP_STR
  1557. "IPv6 routing table\n")
  1558. {
  1559. struct route_table *table;
  1560. struct route_node *rn;
  1561. struct rib *rib;
  1562. int first = 1;
  1563. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1564. if (! table)
  1565. return CMD_SUCCESS;
  1566. /* Show all IPv6 route. */
  1567. for (rn = route_top (table); rn; rn = route_next (rn))
  1568. RNODE_FOREACH_RIB (rn, rib)
  1569. {
  1570. if (first)
  1571. {
  1572. vty_out (vty, SHOW_ROUTE_V6_HEADER);
  1573. first = 0;
  1574. }
  1575. vty_show_ipv6_route (vty, rn, rib);
  1576. }
  1577. return CMD_SUCCESS;
  1578. }
  1579. DEFUN (show_ipv6_route_prefix_longer,
  1580. show_ipv6_route_prefix_longer_cmd,
  1581. "show ipv6 route X:X::X:X/M longer-prefixes",
  1582. SHOW_STR
  1583. IP_STR
  1584. "IPv6 routing table\n"
  1585. "IPv6 prefix\n"
  1586. "Show route matching the specified Network/Mask pair only\n")
  1587. {
  1588. struct route_table *table;
  1589. struct route_node *rn;
  1590. struct rib *rib;
  1591. struct prefix p;
  1592. int ret;
  1593. int first = 1;
  1594. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1595. if (! table)
  1596. return CMD_SUCCESS;
  1597. ret = str2prefix (argv[0], &p);
  1598. if (! ret)
  1599. {
  1600. vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
  1601. return CMD_WARNING;
  1602. }
  1603. /* Show matched type IPv6 routes. */
  1604. for (rn = route_top (table); rn; rn = route_next (rn))
  1605. RNODE_FOREACH_RIB (rn, rib)
  1606. if (prefix_match (&p, &rn->p))
  1607. {
  1608. if (first)
  1609. {
  1610. vty_out (vty, SHOW_ROUTE_V6_HEADER);
  1611. first = 0;
  1612. }
  1613. vty_show_ipv6_route (vty, rn, rib);
  1614. }
  1615. return CMD_SUCCESS;
  1616. }
  1617. DEFUN (show_ipv6_route_protocol,
  1618. show_ipv6_route_protocol_cmd,
  1619. "show ipv6 route " QUAGGA_IP6_REDIST_STR_ZEBRA,
  1620. SHOW_STR
  1621. IP_STR
  1622. "IP routing table\n"
  1623. QUAGGA_IP6_REDIST_HELP_STR_ZEBRA)
  1624. {
  1625. int type;
  1626. struct route_table *table;
  1627. struct route_node *rn;
  1628. struct rib *rib;
  1629. int first = 1;
  1630. type = proto_redistnum (AFI_IP6, argv[0]);
  1631. if (type < 0)
  1632. {
  1633. vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
  1634. return CMD_WARNING;
  1635. }
  1636. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1637. if (! table)
  1638. return CMD_SUCCESS;
  1639. /* Show matched type IPv6 routes. */
  1640. for (rn = route_top (table); rn; rn = route_next (rn))
  1641. RNODE_FOREACH_RIB (rn, rib)
  1642. if (rib->type == type)
  1643. {
  1644. if (first)
  1645. {
  1646. vty_out (vty, SHOW_ROUTE_V6_HEADER);
  1647. first = 0;
  1648. }
  1649. vty_show_ipv6_route (vty, rn, rib);
  1650. }
  1651. return CMD_SUCCESS;
  1652. }
  1653. DEFUN (show_ipv6_route_addr,
  1654. show_ipv6_route_addr_cmd,
  1655. "show ipv6 route X:X::X:X",
  1656. SHOW_STR
  1657. IP_STR
  1658. "IPv6 routing table\n"
  1659. "IPv6 Address\n")
  1660. {
  1661. int ret;
  1662. struct prefix_ipv6 p;
  1663. struct route_table *table;
  1664. struct route_node *rn;
  1665. ret = str2prefix_ipv6 (argv[0], &p);
  1666. if (ret <= 0)
  1667. {
  1668. vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE);
  1669. return CMD_WARNING;
  1670. }
  1671. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1672. if (! table)
  1673. return CMD_SUCCESS;
  1674. rn = route_node_match (table, (struct prefix *) &p);
  1675. if (! rn)
  1676. {
  1677. vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  1678. return CMD_WARNING;
  1679. }
  1680. vty_show_ipv6_route_detail (vty, rn);
  1681. route_unlock_node (rn);
  1682. return CMD_SUCCESS;
  1683. }
  1684. DEFUN (show_ipv6_route_prefix,
  1685. show_ipv6_route_prefix_cmd,
  1686. "show ipv6 route X:X::X:X/M",
  1687. SHOW_STR
  1688. IP_STR
  1689. "IPv6 routing table\n"
  1690. "IPv6 prefix\n")
  1691. {
  1692. int ret;
  1693. struct prefix_ipv6 p;
  1694. struct route_table *table;
  1695. struct route_node *rn;
  1696. ret = str2prefix_ipv6 (argv[0], &p);
  1697. if (ret <= 0)
  1698. {
  1699. vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
  1700. return CMD_WARNING;
  1701. }
  1702. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1703. if (! table)
  1704. return CMD_SUCCESS;
  1705. rn = route_node_match (table, (struct prefix *) &p);
  1706. if (! rn || rn->p.prefixlen != p.prefixlen)
  1707. {
  1708. vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  1709. return CMD_WARNING;
  1710. }
  1711. vty_show_ipv6_route_detail (vty, rn);
  1712. route_unlock_node (rn);
  1713. return CMD_SUCCESS;
  1714. }
  1715. /* Show route summary. */
  1716. DEFUN (show_ipv6_route_summary,
  1717. show_ipv6_route_summary_cmd,
  1718. "show ipv6 route summary",
  1719. SHOW_STR
  1720. IP_STR
  1721. "IPv6 routing table\n"
  1722. "Summary of all IPv6 routes\n")
  1723. {
  1724. struct route_table *table;
  1725. table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
  1726. if (! table)
  1727. return CMD_SUCCESS;
  1728. vty_show_ip_route_summary (vty, table);
  1729. return CMD_SUCCESS;
  1730. }
  1731. /*
  1732. * Show IPv6 mroute command.Used to dump
  1733. * the Multicast routing table.
  1734. */
  1735. DEFUN (show_ipv6_mroute,
  1736. show_ipv6_mroute_cmd,
  1737. "show ipv6 mroute",
  1738. SHOW_STR
  1739. IP_STR
  1740. "IPv6 Multicast routing table\n")
  1741. {
  1742. struct route_table *table;
  1743. struct route_node *rn;
  1744. struct rib *rib;
  1745. int first = 1;
  1746. table = vrf_table (AFI_IP6, SAFI_MULTICAST, 0);
  1747. if (! table)
  1748. return CMD_SUCCESS;
  1749. /* Show all IPv6 route. */
  1750. for (rn = route_top (table); rn; rn = route_next (rn))
  1751. RNODE_FOREACH_RIB (rn, rib)
  1752. {
  1753. if (first)
  1754. {
  1755. vty_out (vty, SHOW_ROUTE_V6_HEADER);
  1756. first = 0;
  1757. }
  1758. vty_show_ipv6_route (vty, rn, rib);
  1759. }
  1760. return CMD_SUCCESS;
  1761. }
  1762. /* Write IPv6 static route configuration. */
  1763. static int
  1764. static_config_ipv6 (struct vty *vty)
  1765. {
  1766. struct route_node *rn;
  1767. struct static_ipv6 *si;
  1768. int write;
  1769. char buf[BUFSIZ];
  1770. struct route_table *stable;
  1771. write = 0;
  1772. /* Lookup table. */
  1773. stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
  1774. if (! stable)
  1775. return -1;
  1776. for (rn = route_top (stable); rn; rn = route_next (rn))
  1777. for (si = rn->info; si; si = si->next)
  1778. {
  1779. vty_out (vty, "ipv6 route %s/%d",
  1780. inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
  1781. rn->p.prefixlen);
  1782. switch (si->type)
  1783. {
  1784. case STATIC_IPV6_GATEWAY:
  1785. vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
  1786. break;
  1787. case STATIC_IPV6_IFNAME:
  1788. vty_out (vty, " %s", si->ifname);
  1789. break;
  1790. case STATIC_IPV6_GATEWAY_IFNAME:
  1791. vty_out (vty, " %s %s",
  1792. inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
  1793. break;
  1794. }
  1795. if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
  1796. vty_out (vty, " %s", "reject");
  1797. if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
  1798. vty_out (vty, " %s", "blackhole");
  1799. if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
  1800. vty_out (vty, " %d", si->distance);
  1801. vty_out (vty, "%s", VTY_NEWLINE);
  1802. write = 1;
  1803. }
  1804. return write;
  1805. }
  1806. #endif /* HAVE_IPV6 */
  1807. /* Static ip route configuration write function. */
  1808. static int
  1809. zebra_ip_config (struct vty *vty)
  1810. {
  1811. int write = 0;
  1812. write += static_config_ipv4 (vty);
  1813. #ifdef HAVE_IPV6
  1814. write += static_config_ipv6 (vty);
  1815. #endif /* HAVE_IPV6 */
  1816. return write;
  1817. }
  1818. /* ip protocol configuration write function */
  1819. static int config_write_protocol(struct vty *vty)
  1820. {
  1821. int i;
  1822. for (i=0;i<ZEBRA_ROUTE_MAX;i++)
  1823. {
  1824. if (proto_rm[AFI_IP][i])
  1825. vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
  1826. proto_rm[AFI_IP][i], VTY_NEWLINE);
  1827. }
  1828. if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
  1829. vty_out (vty, "ip protocol %s route-map %s%s", "any",
  1830. proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
  1831. return 1;
  1832. }
  1833. /* table node for protocol filtering */
  1834. static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
  1835. /* IP node for static routes. */
  1836. static struct cmd_node ip_node = { IP_NODE, "", 1 };
  1837. /* Route VTY. */
  1838. void
  1839. zebra_vty_init (void)
  1840. {
  1841. install_node (&ip_node, zebra_ip_config);
  1842. install_node (&protocol_node, config_write_protocol);
  1843. install_element (CONFIG_NODE, &ip_protocol_cmd);
  1844. install_element (CONFIG_NODE, &no_ip_protocol_cmd);
  1845. install_element (VIEW_NODE, &show_ip_protocol_cmd);
  1846. install_element (ENABLE_NODE, &show_ip_protocol_cmd);
  1847. install_element (CONFIG_NODE, &ip_route_cmd);
  1848. install_element (CONFIG_NODE, &ip_route_flags_cmd);
  1849. install_element (CONFIG_NODE, &ip_route_flags2_cmd);
  1850. install_element (CONFIG_NODE, &ip_route_mask_cmd);
  1851. install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
  1852. install_element (CONFIG_NODE, &ip_route_mask_flags2_cmd);
  1853. install_element (CONFIG_NODE, &no_ip_route_cmd);
  1854. install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
  1855. install_element (CONFIG_NODE, &no_ip_route_flags2_cmd);
  1856. install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
  1857. install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
  1858. install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd);
  1859. install_element (CONFIG_NODE, &ip_route_distance_cmd);
  1860. install_element (CONFIG_NODE, &ip_route_flags_distance_cmd);
  1861. install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd);
  1862. install_element (CONFIG_NODE, &ip_route_mask_distance_cmd);
  1863. install_element (CONFIG_NODE, &ip_route_mask_flags_distance_cmd);
  1864. install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_cmd);
  1865. install_element (CONFIG_NODE, &no_ip_route_distance_cmd);
  1866. install_element (CONFIG_NODE, &no_ip_route_flags_distance_cmd);
  1867. install_element (CONFIG_NODE, &no_ip_route_flags_distance2_cmd);
  1868. install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
  1869. install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
  1870. install_element (VIEW_NODE, &show_ip_route_cmd);
  1871. install_element (VIEW_NODE, &show_ip_route_addr_cmd);
  1872. install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
  1873. install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
  1874. install_element (VIEW_NODE, &show_ip_route_protocol_cmd);
  1875. install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
  1876. install_element (VIEW_NODE, &show_ip_route_summary_cmd);
  1877. install_element (ENABLE_NODE, &show_ip_route_cmd);
  1878. install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
  1879. install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
  1880. install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
  1881. install_element (ENABLE_NODE, &show_ip_route_protocol_cmd);
  1882. install_element (ENABLE_NODE, &show_ip_route_supernets_cmd);
  1883. install_element (ENABLE_NODE, &show_ip_route_summary_cmd);
  1884. install_element (VIEW_NODE, &show_ip_mroute_cmd);
  1885. install_element (ENABLE_NODE, &show_ip_mroute_cmd);
  1886. #ifdef HAVE_IPV6
  1887. install_element (CONFIG_NODE, &ipv6_route_cmd);
  1888. install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
  1889. install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
  1890. install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
  1891. install_element (CONFIG_NODE, &no_ipv6_route_cmd);
  1892. install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
  1893. install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
  1894. install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
  1895. install_element (CONFIG_NODE, &ipv6_route_pref_cmd);
  1896. install_element (CONFIG_NODE, &ipv6_route_flags_pref_cmd);
  1897. install_element (CONFIG_NODE, &ipv6_route_ifname_pref_cmd);
  1898. install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_cmd);
  1899. install_element (CONFIG_NODE, &no_ipv6_route_pref_cmd);
  1900. install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
  1901. install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
  1902. install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
  1903. install_element (VIEW_NODE, &show_ipv6_route_cmd);
  1904. install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
  1905. install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
  1906. install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
  1907. install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
  1908. install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
  1909. install_element (ENABLE_NODE, &show_ipv6_route_cmd);
  1910. install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
  1911. install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
  1912. install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
  1913. install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
  1914. install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
  1915. install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
  1916. install_element (ENABLE_NODE, &show_ipv6_mroute_cmd);
  1917. #endif /* HAVE_IPV6 */
  1918. }