ospf6_top.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. /*
  2. * Copyright (C) 2003 Yasuhiro Ohara
  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 "log.h"
  23. #include "memory.h"
  24. #include "vty.h"
  25. #include "linklist.h"
  26. #include "prefix.h"
  27. #include "table.h"
  28. #include "thread.h"
  29. #include "command.h"
  30. #include "ospf6_proto.h"
  31. #include "ospf6_message.h"
  32. #include "ospf6_lsa.h"
  33. #include "ospf6_lsdb.h"
  34. #include "ospf6_route.h"
  35. #include "ospf6_zebra.h"
  36. #include "ospf6_top.h"
  37. #include "ospf6_area.h"
  38. #include "ospf6_interface.h"
  39. #include "ospf6_neighbor.h"
  40. #include "ospf6_flood.h"
  41. #include "ospf6_asbr.h"
  42. #include "ospf6_abr.h"
  43. #include "ospf6_intra.h"
  44. #include "ospf6_spf.h"
  45. #include "ospf6d.h"
  46. /* global ospf6d variable */
  47. struct ospf6 *ospf6;
  48. static void ospf6_disable (struct ospf6 *o);
  49. static void
  50. ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
  51. {
  52. switch (ntohs (lsa->header->type))
  53. {
  54. case OSPF6_LSTYPE_AS_EXTERNAL:
  55. ospf6_asbr_lsa_add (lsa);
  56. break;
  57. default:
  58. break;
  59. }
  60. }
  61. static void
  62. ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
  63. {
  64. switch (ntohs (lsa->header->type))
  65. {
  66. case OSPF6_LSTYPE_AS_EXTERNAL:
  67. ospf6_asbr_lsa_remove (lsa);
  68. break;
  69. default:
  70. break;
  71. }
  72. }
  73. static void
  74. ospf6_top_route_hook_add (struct ospf6_route *route)
  75. {
  76. ospf6_abr_originate_summary (route);
  77. ospf6_zebra_route_update_add (route);
  78. }
  79. static void
  80. ospf6_top_route_hook_remove (struct ospf6_route *route)
  81. {
  82. ospf6_abr_originate_summary (route);
  83. ospf6_zebra_route_update_remove (route);
  84. }
  85. static void
  86. ospf6_top_brouter_hook_add (struct ospf6_route *route)
  87. {
  88. ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix));
  89. ospf6_asbr_lsentry_add (route);
  90. ospf6_abr_originate_summary (route);
  91. }
  92. static void
  93. ospf6_top_brouter_hook_remove (struct ospf6_route *route)
  94. {
  95. ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix));
  96. ospf6_asbr_lsentry_remove (route);
  97. ospf6_abr_originate_summary (route);
  98. }
  99. static struct ospf6 *
  100. ospf6_create (void)
  101. {
  102. struct ospf6 *o;
  103. o = XCALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6));
  104. /* initialize */
  105. quagga_gettime (QUAGGA_CLK_MONOTONIC, &o->starttime);
  106. o->area_list = list_new ();
  107. o->area_list->cmp = ospf6_area_cmp;
  108. o->lsdb = ospf6_lsdb_create (o);
  109. o->lsdb_self = ospf6_lsdb_create (o);
  110. o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
  111. o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
  112. o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
  113. o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
  114. o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
  115. o->spf_hold_multiplier = 1;
  116. o->route_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, ROUTES);
  117. o->route_table->scope = o;
  118. o->route_table->hook_add = ospf6_top_route_hook_add;
  119. o->route_table->hook_remove = ospf6_top_route_hook_remove;
  120. o->brouter_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, BORDER_ROUTERS);
  121. o->brouter_table->scope = o;
  122. o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
  123. o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
  124. o->external_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, EXTERNAL_ROUTES);
  125. o->external_table->scope = o;
  126. o->external_id_table = route_table_init ();
  127. o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
  128. return o;
  129. }
  130. void
  131. ospf6_delete (struct ospf6 *o)
  132. {
  133. struct listnode *node, *nnode;
  134. struct ospf6_area *oa;
  135. ospf6_disable (ospf6);
  136. for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  137. ospf6_area_delete (oa);
  138. list_delete (o->area_list);
  139. ospf6_lsdb_delete (o->lsdb);
  140. ospf6_lsdb_delete (o->lsdb_self);
  141. ospf6_route_table_delete (o->route_table);
  142. ospf6_route_table_delete (o->brouter_table);
  143. ospf6_route_table_delete (o->external_table);
  144. route_table_finish (o->external_id_table);
  145. XFREE (MTYPE_OSPF6_TOP, o);
  146. }
  147. static void
  148. __attribute__((unused))
  149. ospf6_enable (struct ospf6 *o)
  150. {
  151. struct listnode *node, *nnode;
  152. struct ospf6_area *oa;
  153. if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
  154. {
  155. UNSET_FLAG (o->flag, OSPF6_DISABLED);
  156. for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  157. ospf6_area_enable (oa);
  158. }
  159. }
  160. static void
  161. ospf6_disable (struct ospf6 *o)
  162. {
  163. struct listnode *node, *nnode;
  164. struct ospf6_area *oa;
  165. if (! CHECK_FLAG (o->flag, OSPF6_DISABLED))
  166. {
  167. SET_FLAG (o->flag, OSPF6_DISABLED);
  168. for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  169. ospf6_area_disable (oa);
  170. /* XXX: This also changes persistent settings */
  171. ospf6_asbr_redistribute_reset();
  172. ospf6_lsdb_remove_all (o->lsdb);
  173. ospf6_route_remove_all (o->route_table);
  174. ospf6_route_remove_all (o->brouter_table);
  175. THREAD_OFF(o->maxage_remover);
  176. THREAD_OFF(o->t_spf_calc);
  177. THREAD_OFF(o->t_ase_calc);
  178. }
  179. }
  180. static int
  181. ospf6_maxage_remover (struct thread *thread)
  182. {
  183. struct ospf6 *o = (struct ospf6 *) THREAD_ARG (thread);
  184. struct ospf6_area *oa;
  185. struct ospf6_interface *oi;
  186. struct ospf6_neighbor *on;
  187. struct listnode *i, *j, *k;
  188. int reschedule = 0;
  189. o->maxage_remover = (struct thread *) NULL;
  190. for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
  191. {
  192. for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  193. {
  194. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
  195. {
  196. if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
  197. on->state != OSPF6_NEIGHBOR_LOADING)
  198. continue;
  199. ospf6_maxage_remove (o);
  200. return 0;
  201. }
  202. }
  203. }
  204. for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
  205. {
  206. for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  207. {
  208. if (ospf6_lsdb_maxage_remover (oi->lsdb))
  209. {
  210. reschedule = 1;
  211. }
  212. }
  213. if (ospf6_lsdb_maxage_remover (oa->lsdb))
  214. {
  215. reschedule = 1;
  216. }
  217. }
  218. if (ospf6_lsdb_maxage_remover (o->lsdb))
  219. {
  220. reschedule = 1;
  221. }
  222. if (reschedule)
  223. {
  224. ospf6_maxage_remove (o);
  225. }
  226. return 0;
  227. }
  228. void
  229. ospf6_maxage_remove (struct ospf6 *o)
  230. {
  231. if (o && ! o->maxage_remover)
  232. o->maxage_remover = thread_add_timer (master, ospf6_maxage_remover, o,
  233. OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT);
  234. }
  235. /* start ospf6 */
  236. DEFUN (router_ospf6,
  237. router_ospf6_cmd,
  238. "router ospf6",
  239. ROUTER_STR
  240. OSPF6_STR)
  241. {
  242. if (ospf6 == NULL)
  243. ospf6 = ospf6_create ();
  244. /* set current ospf point. */
  245. vty->node = OSPF6_NODE;
  246. vty->index = ospf6;
  247. return CMD_SUCCESS;
  248. }
  249. /* stop ospf6 */
  250. DEFUN (no_router_ospf6,
  251. no_router_ospf6_cmd,
  252. "no router ospf6",
  253. NO_STR
  254. OSPF6_ROUTER_STR)
  255. {
  256. if (ospf6 == NULL)
  257. vty_out (vty, "OSPFv3 is not configured%s", VNL);
  258. else
  259. {
  260. ospf6_delete (ospf6);
  261. ospf6 = NULL;
  262. }
  263. /* return to config node . */
  264. vty->node = CONFIG_NODE;
  265. vty->index = NULL;
  266. return CMD_SUCCESS;
  267. }
  268. /* change Router_ID commands. */
  269. DEFUN (ospf6_router_id,
  270. ospf6_router_id_cmd,
  271. "router-id A.B.C.D",
  272. "Configure OSPF Router-ID\n"
  273. V4NOTATION_STR)
  274. {
  275. int ret;
  276. u_int32_t router_id;
  277. struct ospf6 *o;
  278. o = (struct ospf6 *) vty->index;
  279. ret = inet_pton (AF_INET, argv[0], &router_id);
  280. if (ret == 0)
  281. {
  282. vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
  283. return CMD_SUCCESS;
  284. }
  285. o->router_id_static = router_id;
  286. if (o->router_id == 0)
  287. o->router_id = router_id;
  288. return CMD_SUCCESS;
  289. }
  290. DEFUN (ospf6_log_adjacency_changes,
  291. ospf6_log_adjacency_changes_cmd,
  292. "log-adjacency-changes",
  293. "Log changes in adjacency state\n")
  294. {
  295. struct ospf6 *ospf6 = vty->index;
  296. SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  297. return CMD_SUCCESS;
  298. }
  299. DEFUN (ospf6_log_adjacency_changes_detail,
  300. ospf6_log_adjacency_changes_detail_cmd,
  301. "log-adjacency-changes detail",
  302. "Log changes in adjacency state\n"
  303. "Log all state changes\n")
  304. {
  305. struct ospf6 *ospf6 = vty->index;
  306. SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  307. SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  308. return CMD_SUCCESS;
  309. }
  310. DEFUN (no_ospf6_log_adjacency_changes,
  311. no_ospf6_log_adjacency_changes_cmd,
  312. "no log-adjacency-changes",
  313. NO_STR
  314. "Log changes in adjacency state\n")
  315. {
  316. struct ospf6 *ospf6 = vty->index;
  317. UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  318. UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  319. return CMD_SUCCESS;
  320. }
  321. DEFUN (no_ospf6_log_adjacency_changes_detail,
  322. no_ospf6_log_adjacency_changes_detail_cmd,
  323. "no log-adjacency-changes detail",
  324. NO_STR
  325. "Log changes in adjacency state\n"
  326. "Log all state changes\n")
  327. {
  328. struct ospf6 *ospf6 = vty->index;
  329. UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  330. return CMD_SUCCESS;
  331. }
  332. DEFUN (ospf6_interface_area,
  333. ospf6_interface_area_cmd,
  334. "interface IFNAME area A.B.C.D",
  335. "Enable routing on an IPv6 interface\n"
  336. IFNAME_STR
  337. "Specify the OSPF6 area ID\n"
  338. "OSPF6 area ID in IPv4 address notation\n"
  339. )
  340. {
  341. struct ospf6 *o;
  342. struct ospf6_area *oa;
  343. struct ospf6_interface *oi;
  344. struct interface *ifp;
  345. u_int32_t area_id;
  346. o = (struct ospf6 *) vty->index;
  347. /* find/create ospf6 interface */
  348. ifp = if_get_by_name (argv[0]);
  349. oi = (struct ospf6_interface *) ifp->info;
  350. if (oi == NULL)
  351. oi = ospf6_interface_create (ifp);
  352. if (oi->area)
  353. {
  354. vty_out (vty, "%s already attached to Area %s%s",
  355. oi->interface->name, oi->area->name, VNL);
  356. return CMD_SUCCESS;
  357. }
  358. /* parse Area-ID */
  359. if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  360. {
  361. vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  362. return CMD_SUCCESS;
  363. }
  364. /* find/create ospf6 area */
  365. oa = ospf6_area_lookup (area_id, o);
  366. if (oa == NULL)
  367. oa = ospf6_area_create (area_id, o);
  368. /* attach interface to area */
  369. listnode_add (oa->if_list, oi); /* sort ?? */
  370. oi->area = oa;
  371. SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  372. /* ospf6 process is currently disabled, not much more to do */
  373. if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
  374. return CMD_SUCCESS;
  375. /* start up */
  376. ospf6_interface_enable (oi);
  377. /* If the router is ABR, originate summary routes */
  378. if (ospf6_is_router_abr (o))
  379. ospf6_abr_enable_area (oa);
  380. return CMD_SUCCESS;
  381. }
  382. DEFUN (no_ospf6_interface_area,
  383. no_ospf6_interface_area_cmd,
  384. "no interface IFNAME area A.B.C.D",
  385. NO_STR
  386. "Disable routing on an IPv6 interface\n"
  387. IFNAME_STR
  388. "Specify the OSPF6 area ID\n"
  389. "OSPF6 area ID in IPv4 address notation\n"
  390. )
  391. {
  392. struct ospf6_interface *oi;
  393. struct ospf6_area *oa;
  394. struct interface *ifp;
  395. u_int32_t area_id;
  396. ifp = if_lookup_by_name (argv[0]);
  397. if (ifp == NULL)
  398. {
  399. vty_out (vty, "No such interface %s%s", argv[0], VNL);
  400. return CMD_SUCCESS;
  401. }
  402. oi = (struct ospf6_interface *) ifp->info;
  403. if (oi == NULL)
  404. {
  405. vty_out (vty, "Interface %s not enabled%s", ifp->name, VNL);
  406. return CMD_SUCCESS;
  407. }
  408. /* parse Area-ID */
  409. if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  410. {
  411. vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  412. return CMD_SUCCESS;
  413. }
  414. /* Verify Area */
  415. if (oi->area == NULL)
  416. {
  417. vty_out (vty, "No such Area-ID: %s%s", argv[1], VNL);
  418. return CMD_SUCCESS;
  419. }
  420. if (oi->area->area_id != area_id)
  421. {
  422. vty_out (vty, "Wrong Area-ID: %s is attached to area %s%s",
  423. oi->interface->name, oi->area->name, VNL);
  424. return CMD_SUCCESS;
  425. }
  426. thread_execute (master, interface_down, oi, 0);
  427. oa = oi->area;
  428. listnode_delete (oi->area->if_list, oi);
  429. oi->area = (struct ospf6_area *) NULL;
  430. /* Withdraw inter-area routes from this area, if necessary */
  431. if (oa->if_list->count == 0)
  432. {
  433. UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  434. ospf6_abr_disable_area (oa);
  435. }
  436. return CMD_SUCCESS;
  437. }
  438. DEFUN (ospf6_stub_router_admin,
  439. ospf6_stub_router_admin_cmd,
  440. "stub-router administrative",
  441. "Make router a stub router\n"
  442. "Advertise inability to be a transit router\n"
  443. "Administratively applied, for an indefinite period\n")
  444. {
  445. struct listnode *node;
  446. struct ospf6_area *oa;
  447. if (!CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  448. {
  449. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  450. {
  451. OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
  452. OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
  453. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  454. }
  455. SET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
  456. }
  457. return CMD_SUCCESS;
  458. }
  459. DEFUN (no_ospf6_stub_router_admin,
  460. no_ospf6_stub_router_admin_cmd,
  461. "no stub-router administrative",
  462. NO_STR
  463. "Make router a stub router\n"
  464. "Advertise ability to be a transit router\n"
  465. "Administratively applied, for an indefinite period\n")
  466. {
  467. struct listnode *node;
  468. struct ospf6_area *oa;
  469. if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  470. {
  471. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  472. {
  473. OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
  474. OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
  475. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  476. }
  477. UNSET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
  478. }
  479. return CMD_SUCCESS;
  480. }
  481. DEFUN (ospf6_stub_router_startup,
  482. ospf6_stub_router_startup_cmd,
  483. "stub-router on-startup <5-86400>",
  484. "Make router a stub router\n"
  485. "Advertise inability to be a transit router\n"
  486. "Automatically advertise as stub-router on startup of OSPF6\n"
  487. "Time (seconds) to advertise self as stub-router\n")
  488. {
  489. return CMD_SUCCESS;
  490. }
  491. DEFUN (no_ospf6_stub_router_startup,
  492. no_ospf6_stub_router_startup_cmd,
  493. "no stub-router on-startup",
  494. NO_STR
  495. "Make router a stub router\n"
  496. "Advertise inability to be a transit router\n"
  497. "Automatically advertise as stub-router on startup of OSPF6\n"
  498. "Time (seconds) to advertise self as stub-router\n")
  499. {
  500. return CMD_SUCCESS;
  501. }
  502. DEFUN (ospf6_stub_router_shutdown,
  503. ospf6_stub_router_shutdown_cmd,
  504. "stub-router on-shutdown <5-86400>",
  505. "Make router a stub router\n"
  506. "Advertise inability to be a transit router\n"
  507. "Automatically advertise as stub-router before shutdown\n"
  508. "Time (seconds) to advertise self as stub-router\n")
  509. {
  510. return CMD_SUCCESS;
  511. }
  512. DEFUN (no_ospf6_stub_router_shutdown,
  513. no_ospf6_stub_router_shutdown_cmd,
  514. "no stub-router on-shutdown",
  515. NO_STR
  516. "Make router a stub router\n"
  517. "Advertise inability to be a transit router\n"
  518. "Automatically advertise as stub-router before shutdown\n"
  519. "Time (seconds) to advertise self as stub-router\n")
  520. {
  521. return CMD_SUCCESS;
  522. }
  523. static void
  524. ospf6_show (struct vty *vty, struct ospf6 *o)
  525. {
  526. struct listnode *n;
  527. struct ospf6_area *oa;
  528. char router_id[16], duration[32];
  529. struct timeval now, running, result;
  530. char buf[32], rbuf[32];
  531. /* process id, router id */
  532. inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id));
  533. vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s%s",
  534. router_id, VNL);
  535. /* running time */
  536. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  537. timersub (&now, &o->starttime, &running);
  538. timerstring (&running, duration, sizeof (duration));
  539. vty_out (vty, " Running %s%s", duration, VNL);
  540. /* Redistribute configuration */
  541. /* XXX */
  542. /* Show SPF parameters */
  543. vty_out(vty, " Initial SPF scheduling delay %d millisec(s)%s"
  544. " Minimum hold time between consecutive SPFs %d millsecond(s)%s"
  545. " Maximum hold time between consecutive SPFs %d millsecond(s)%s"
  546. " Hold time multiplier is currently %d%s",
  547. o->spf_delay, VNL,
  548. o->spf_holdtime, VNL,
  549. o->spf_max_holdtime, VNL,
  550. o->spf_hold_multiplier, VNL);
  551. vty_out(vty, " SPF algorithm ");
  552. if (o->ts_spf.tv_sec || o->ts_spf.tv_usec)
  553. {
  554. timersub(&now, &o->ts_spf, &result);
  555. timerstring(&result, buf, sizeof(buf));
  556. ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf));
  557. vty_out(vty, "last executed %s ago, reason %s%s", buf, rbuf, VNL);
  558. vty_out (vty, " Last SPF duration %ld sec %ld usec%s",
  559. o->ts_spf_duration.tv_sec, o->ts_spf_duration.tv_usec, VNL);
  560. }
  561. else
  562. vty_out(vty, "has not been run$%s", VNL);
  563. threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
  564. vty_out (vty, " SPF timer %s%s%s",
  565. (o->t_spf_calc ? "due in " : "is "), buf, VNL);
  566. if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
  567. vty_out (vty, " Router Is Stub Router%s", VNL);
  568. /* LSAs */
  569. vty_out (vty, " Number of AS scoped LSAs is %u%s",
  570. o->lsdb->count, VNL);
  571. /* Areas */
  572. vty_out (vty, " Number of areas in this router is %u%s",
  573. listcount (o->area_list), VNL);
  574. if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES))
  575. {
  576. if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
  577. vty_out(vty, " All adjacency changes are logged%s",VTY_NEWLINE);
  578. else
  579. vty_out(vty, " Adjacency changes are logged%s",VTY_NEWLINE);
  580. }
  581. vty_out (vty, "%s",VTY_NEWLINE);
  582. for (ALL_LIST_ELEMENTS_RO (o->area_list, n, oa))
  583. ospf6_area_show (vty, oa);
  584. }
  585. /* show top level structures */
  586. DEFUN (show_ipv6_ospf6,
  587. show_ipv6_ospf6_cmd,
  588. "show ipv6 ospf6",
  589. SHOW_STR
  590. IP6_STR
  591. OSPF6_STR)
  592. {
  593. OSPF6_CMD_CHECK_RUNNING ();
  594. ospf6_show (vty, ospf6);
  595. return CMD_SUCCESS;
  596. }
  597. DEFUN (show_ipv6_ospf6_route,
  598. show_ipv6_ospf6_route_cmd,
  599. "show ipv6 ospf6 route",
  600. SHOW_STR
  601. IP6_STR
  602. OSPF6_STR
  603. ROUTE_STR
  604. )
  605. {
  606. ospf6_route_table_show (vty, argc, argv, ospf6->route_table);
  607. return CMD_SUCCESS;
  608. }
  609. ALIAS (show_ipv6_ospf6_route,
  610. show_ipv6_ospf6_route_detail_cmd,
  611. "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
  612. SHOW_STR
  613. IP6_STR
  614. OSPF6_STR
  615. ROUTE_STR
  616. "Specify IPv6 address\n"
  617. "Specify IPv6 prefix\n"
  618. "Detailed information\n"
  619. "Summary of route table\n"
  620. )
  621. DEFUN (show_ipv6_ospf6_route_match,
  622. show_ipv6_ospf6_route_match_cmd,
  623. "show ipv6 ospf6 route X:X::X:X/M match",
  624. SHOW_STR
  625. IP6_STR
  626. OSPF6_STR
  627. ROUTE_STR
  628. "Specify IPv6 prefix\n"
  629. "Display routes which match the specified route\n"
  630. )
  631. {
  632. const char *sargv[CMD_ARGC_MAX];
  633. int i, sargc;
  634. /* copy argv to sargv and then append "match" */
  635. for (i = 0; i < argc; i++)
  636. sargv[i] = argv[i];
  637. sargc = argc;
  638. sargv[sargc++] = "match";
  639. sargv[sargc] = NULL;
  640. ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  641. return CMD_SUCCESS;
  642. }
  643. DEFUN (show_ipv6_ospf6_route_match_detail,
  644. show_ipv6_ospf6_route_match_detail_cmd,
  645. "show ipv6 ospf6 route X:X::X:X/M match detail",
  646. SHOW_STR
  647. IP6_STR
  648. OSPF6_STR
  649. ROUTE_STR
  650. "Specify IPv6 prefix\n"
  651. "Display routes which match the specified route\n"
  652. "Detailed information\n"
  653. )
  654. {
  655. const char *sargv[CMD_ARGC_MAX];
  656. int i, sargc;
  657. /* copy argv to sargv and then append "match" and "detail" */
  658. for (i = 0; i < argc; i++)
  659. sargv[i] = argv[i];
  660. sargc = argc;
  661. sargv[sargc++] = "match";
  662. sargv[sargc++] = "detail";
  663. sargv[sargc] = NULL;
  664. ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  665. return CMD_SUCCESS;
  666. }
  667. ALIAS (show_ipv6_ospf6_route_match,
  668. show_ipv6_ospf6_route_longer_cmd,
  669. "show ipv6 ospf6 route X:X::X:X/M longer",
  670. SHOW_STR
  671. IP6_STR
  672. OSPF6_STR
  673. ROUTE_STR
  674. "Specify IPv6 prefix\n"
  675. "Display routes longer than the specified route\n"
  676. )
  677. DEFUN (show_ipv6_ospf6_route_match_detail,
  678. show_ipv6_ospf6_route_longer_detail_cmd,
  679. "show ipv6 ospf6 route X:X::X:X/M longer detail",
  680. SHOW_STR
  681. IP6_STR
  682. OSPF6_STR
  683. ROUTE_STR
  684. "Specify IPv6 prefix\n"
  685. "Display routes longer than the specified route\n"
  686. "Detailed information\n"
  687. );
  688. ALIAS (show_ipv6_ospf6_route,
  689. show_ipv6_ospf6_route_type_cmd,
  690. "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
  691. SHOW_STR
  692. IP6_STR
  693. OSPF6_STR
  694. ROUTE_STR
  695. "Display Intra-Area routes\n"
  696. "Display Inter-Area routes\n"
  697. "Display Type-1 External routes\n"
  698. "Display Type-2 External routes\n"
  699. )
  700. DEFUN (show_ipv6_ospf6_route_type_detail,
  701. show_ipv6_ospf6_route_type_detail_cmd,
  702. "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
  703. SHOW_STR
  704. IP6_STR
  705. OSPF6_STR
  706. ROUTE_STR
  707. "Display Intra-Area routes\n"
  708. "Display Inter-Area routes\n"
  709. "Display Type-1 External routes\n"
  710. "Display Type-2 External routes\n"
  711. "Detailed information\n"
  712. )
  713. {
  714. const char *sargv[CMD_ARGC_MAX];
  715. int i, sargc;
  716. /* copy argv to sargv and then append "detail" */
  717. for (i = 0; i < argc; i++)
  718. sargv[i] = argv[i];
  719. sargc = argc;
  720. sargv[sargc++] = "detail";
  721. sargv[sargc] = NULL;
  722. ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  723. return CMD_SUCCESS;
  724. }
  725. static void
  726. ospf6_stub_router_config_write (struct vty *vty)
  727. {
  728. if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  729. {
  730. vty_out (vty, " stub-router administrative%s", VNL);
  731. }
  732. return;
  733. }
  734. /* OSPF configuration write function. */
  735. static int
  736. config_write_ospf6 (struct vty *vty)
  737. {
  738. char router_id[16];
  739. struct listnode *j, *k;
  740. struct ospf6_area *oa;
  741. struct ospf6_interface *oi;
  742. /* OSPFv6 configuration. */
  743. if (ospf6 == NULL)
  744. return CMD_SUCCESS;
  745. inet_ntop (AF_INET, &ospf6->router_id_static, router_id, sizeof (router_id));
  746. vty_out (vty, "router ospf6%s", VNL);
  747. if (ospf6->router_id_static != 0)
  748. vty_out (vty, " router-id %s%s", router_id, VNL);
  749. /* log-adjacency-changes flag print. */
  750. if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES))
  751. {
  752. vty_out(vty, " log-adjacency-changes");
  753. if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
  754. vty_out(vty, " detail");
  755. vty_out(vty, "%s", VTY_NEWLINE);
  756. }
  757. if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
  758. vty_out (vty, " auto-cost reference-bandwidth %d%s", ospf6->ref_bandwidth / 1000,
  759. VNL);
  760. ospf6_stub_router_config_write (vty);
  761. ospf6_redistribute_config_write (vty);
  762. ospf6_area_config_write (vty);
  763. ospf6_spf_config_write (vty);
  764. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, j, oa))
  765. {
  766. for (ALL_LIST_ELEMENTS_RO (oa->if_list, k, oi))
  767. vty_out (vty, " interface %s area %s%s",
  768. oi->interface->name, oa->name, VNL);
  769. }
  770. vty_out (vty, "!%s", VNL);
  771. return 0;
  772. }
  773. /* OSPF6 node structure. */
  774. static struct cmd_node ospf6_node =
  775. {
  776. OSPF6_NODE,
  777. "%s(config-ospf6)# ",
  778. 1 /* VTYSH */
  779. };
  780. /* Install ospf related commands. */
  781. void
  782. ospf6_top_init (void)
  783. {
  784. /* Install ospf6 top node. */
  785. install_node (&ospf6_node, config_write_ospf6);
  786. install_element (VIEW_NODE, &show_ipv6_ospf6_cmd);
  787. install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd);
  788. install_element (CONFIG_NODE, &router_ospf6_cmd);
  789. install_element (CONFIG_NODE, &no_router_ospf6_cmd);
  790. install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
  791. install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
  792. install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
  793. install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  794. install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_cmd);
  795. install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
  796. install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_cmd);
  797. install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
  798. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd);
  799. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_detail_cmd);
  800. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd);
  801. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  802. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_longer_cmd);
  803. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
  804. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_cmd);
  805. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
  806. install_default (OSPF6_NODE);
  807. install_element (OSPF6_NODE, &ospf6_router_id_cmd);
  808. install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
  809. install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
  810. install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
  811. install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
  812. install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
  813. install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
  814. install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd);
  815. install_element (OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
  816. /* For a later time
  817. install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
  818. install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
  819. install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
  820. install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
  821. */
  822. }