ospf6_top.c 25 KB

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