zebra_vty.c 56 KB

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