ospf6_top.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  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_asbr.h"
  41. #include "ospf6_abr.h"
  42. #include "ospf6d.h"
  43. /* global ospf6d variable */
  44. struct ospf6 *ospf6;
  45. void
  46. ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
  47. {
  48. switch (ntohs (lsa->header->type))
  49. {
  50. case OSPF6_LSTYPE_AS_EXTERNAL:
  51. ospf6_asbr_lsa_add (lsa);
  52. break;
  53. default:
  54. if (IS_OSPF6_DEBUG_LSA (RECV))
  55. zlog_info ("Unknown LSA in AS-scoped lsdb");
  56. break;
  57. }
  58. }
  59. void
  60. ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
  61. {
  62. switch (ntohs (lsa->header->type))
  63. {
  64. case OSPF6_LSTYPE_AS_EXTERNAL:
  65. ospf6_asbr_lsa_remove (lsa);
  66. break;
  67. default:
  68. if (IS_OSPF6_DEBUG_LSA (RECV))
  69. zlog_info ("Unknown LSA in AS-scoped lsdb");
  70. break;
  71. }
  72. }
  73. void
  74. ospf6_top_route_hook_add (struct ospf6_route *route)
  75. {
  76. ospf6_abr_originate_prefix (route, ospf6);
  77. ospf6_zebra_route_update_add (route);
  78. }
  79. void
  80. ospf6_top_route_hook_remove (struct ospf6_route *route)
  81. {
  82. ospf6_abr_originate_prefix (route, ospf6);
  83. ospf6_zebra_route_update_remove (route);
  84. }
  85. struct ospf6 *
  86. ospf6_create ()
  87. {
  88. struct ospf6 *o;
  89. o = XMALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6));
  90. memset (o, 0, sizeof (struct ospf6));
  91. /* initialize */
  92. gettimeofday (&o->starttime, (struct timezone *) NULL);
  93. o->area_list = list_new ();
  94. o->area_list->cmp = ospf6_area_cmp;
  95. o->lsdb = ospf6_lsdb_create ();
  96. o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
  97. o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
  98. o->route_table = ospf6_route_table_create ();
  99. o->route_table->hook_add = ospf6_top_route_hook_add;
  100. o->route_table->hook_remove = ospf6_top_route_hook_remove;
  101. o->asbr_table = ospf6_route_table_create ();
  102. o->asbr_table->hook_add = ospf6_asbr_lsentry_add;
  103. o->asbr_table->hook_remove = ospf6_asbr_lsentry_remove;
  104. o->brouter_table = ospf6_route_table_create ();
  105. o->external_table = ospf6_route_table_create ();
  106. o->external_id_table = route_table_init ();
  107. return o;
  108. }
  109. void
  110. ospf6_delete (struct ospf6 *o)
  111. {
  112. listnode i;
  113. struct ospf6_area *oa;
  114. for (i = listhead (o->area_list); i; nextnode (i))
  115. {
  116. oa = (struct ospf6_area *) getdata (i);
  117. ospf6_area_delete (oa);
  118. }
  119. ospf6_lsdb_delete (o->lsdb);
  120. ospf6_route_table_delete (o->route_table);
  121. ospf6_route_table_delete (o->asbr_table);
  122. ospf6_route_table_delete (o->brouter_table);
  123. ospf6_route_table_delete (o->external_table);
  124. route_table_finish (o->external_id_table);
  125. XFREE (MTYPE_OSPF6_TOP, o);
  126. }
  127. void
  128. ospf6_enable (struct ospf6 *o)
  129. {
  130. listnode i;
  131. struct ospf6_area *oa;
  132. if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
  133. {
  134. UNSET_FLAG (o->flag, OSPF6_DISABLED);
  135. for (i = listhead (o->area_list); i; nextnode (i))
  136. {
  137. oa = (struct ospf6_area *) getdata (i);
  138. ospf6_area_enable (oa);
  139. }
  140. }
  141. }
  142. void
  143. ospf6_disable (struct ospf6 *o)
  144. {
  145. listnode i;
  146. struct ospf6_area *oa;
  147. if (! CHECK_FLAG (o->flag, OSPF6_DISABLED))
  148. {
  149. SET_FLAG (o->flag, OSPF6_DISABLED);
  150. for (i = listhead (o->area_list); i; nextnode (i))
  151. {
  152. oa = (struct ospf6_area *) getdata (i);
  153. ospf6_area_disable (oa);
  154. }
  155. ospf6_lsdb_remove_all (o->lsdb);
  156. ospf6_route_remove_all (o->route_table);
  157. ospf6_route_remove_all (o->asbr_table);
  158. }
  159. }
  160. int
  161. ospf6_maxage_remover (struct thread *thread)
  162. {
  163. struct ospf6 *o = (struct ospf6 *) THREAD_ARG (thread);
  164. struct ospf6_area *oa;
  165. struct ospf6_interface *oi;
  166. struct ospf6_neighbor *on;
  167. listnode i, j, k;
  168. o->maxage_remover = (struct thread *) NULL;
  169. if (IS_OSPF6_DEBUG_LSA (TIMER))
  170. zlog_info ("Maxage Remover");
  171. for (i = listhead (o->area_list); i; nextnode (i))
  172. {
  173. oa = (struct ospf6_area *) getdata (i);
  174. for (j = listhead (oa->if_list); j; nextnode (j))
  175. {
  176. oi = (struct ospf6_interface *) getdata (j);
  177. for (k = listhead (oi->neighbor_list); k; nextnode (k))
  178. {
  179. on = (struct ospf6_neighbor *) getdata (k);
  180. if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
  181. on->state != OSPF6_NEIGHBOR_LOADING)
  182. continue;
  183. if (IS_OSPF6_DEBUG_LSA (TIMER))
  184. zlog_info ("Maxage Remover End: %s exchange or loading",
  185. on->name);
  186. return 0;
  187. }
  188. }
  189. }
  190. for (i = listhead (o->area_list); i; nextnode (i))
  191. {
  192. oa = (struct ospf6_area *) getdata (i);
  193. for (j = listhead (oa->if_list); j; nextnode (j))
  194. {
  195. oi = (struct ospf6_interface *) getdata (j);
  196. OSPF6_LSDB_MAXAGE_REMOVER (oi->lsdb);
  197. }
  198. OSPF6_LSDB_MAXAGE_REMOVER (oa->lsdb);
  199. }
  200. OSPF6_LSDB_MAXAGE_REMOVER (o->lsdb);
  201. if (IS_OSPF6_DEBUG_LSA (TIMER))
  202. zlog_info ("Maxage Remover End");
  203. return 0;
  204. }
  205. void
  206. ospf6_maxage_remove (struct ospf6 *o)
  207. {
  208. if (o && ! o->maxage_remover)
  209. o->maxage_remover = thread_add_event (master, ospf6_maxage_remover, o, 0);
  210. }
  211. /* start ospf6 */
  212. DEFUN (router_ospf6,
  213. router_ospf6_cmd,
  214. "router ospf6",
  215. ROUTER_STR
  216. OSPF6_STR)
  217. {
  218. if (ospf6 == NULL)
  219. ospf6 = ospf6_create ();
  220. if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
  221. ospf6_enable (ospf6);
  222. /* set current ospf point. */
  223. vty->node = OSPF6_NODE;
  224. vty->index = ospf6;
  225. return CMD_SUCCESS;
  226. }
  227. /* stop ospf6 */
  228. DEFUN (no_router_ospf6,
  229. no_router_ospf6_cmd,
  230. "no router ospf6",
  231. NO_STR
  232. OSPF6_ROUTER_STR)
  233. {
  234. if (ospf6 == NULL || CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
  235. vty_out (vty, "OSPFv3 is not running%s", VNL);
  236. else
  237. ospf6_disable (ospf6);
  238. /* return to config node . */
  239. vty->node = CONFIG_NODE;
  240. vty->index = NULL;
  241. return CMD_SUCCESS;
  242. }
  243. /* change Router_ID commands. */
  244. DEFUN (ospf6_router_id,
  245. ospf6_router_id_cmd,
  246. "router-id A.B.C.D",
  247. "Configure OSPF Router-ID\n"
  248. V4NOTATION_STR)
  249. {
  250. int ret;
  251. u_int32_t router_id;
  252. struct ospf6 *o;
  253. o = (struct ospf6 *) vty->index;
  254. ret = inet_pton (AF_INET, argv[0], &router_id);
  255. if (ret == 0)
  256. {
  257. vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
  258. return CMD_SUCCESS;
  259. }
  260. o->router_id = router_id;
  261. return CMD_SUCCESS;
  262. }
  263. DEFUN (ospf6_interface_area,
  264. ospf6_interface_area_cmd,
  265. "interface IFNAME area A.B.C.D",
  266. "Enable routing on an IPv6 interface\n"
  267. IFNAME_STR
  268. "Specify the OSPF6 area ID\n"
  269. "OSPF6 area ID in IPv4 address notation\n"
  270. )
  271. {
  272. struct ospf6 *o;
  273. struct ospf6_area *oa;
  274. struct ospf6_interface *oi;
  275. struct interface *ifp;
  276. u_int32_t area_id;
  277. o = (struct ospf6 *) vty->index;
  278. /* find/create ospf6 interface */
  279. ifp = if_get_by_name (argv[0]);
  280. oi = (struct ospf6_interface *) ifp->info;
  281. if (oi == NULL)
  282. oi = ospf6_interface_create (ifp);
  283. if (oi->area)
  284. {
  285. vty_out (vty, "%s already attached to Area %s%s",
  286. oi->interface->name, oi->area->name, VNL);
  287. return CMD_SUCCESS;
  288. }
  289. /* parse Area-ID */
  290. if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  291. {
  292. vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  293. return CMD_SUCCESS;
  294. }
  295. /* find/create ospf6 area */
  296. oa = ospf6_area_lookup (area_id, o);
  297. if (oa == NULL)
  298. oa = ospf6_area_create (area_id, o);
  299. /* attach interface to area */
  300. listnode_add (oa->if_list, oi); /* sort ?? */
  301. oi->area = oa;
  302. /* start up */
  303. thread_add_event (master, interface_up, oi, 0);
  304. return CMD_SUCCESS;
  305. }
  306. DEFUN (no_ospf6_interface_area,
  307. no_ospf6_interface_area_cmd,
  308. "no interface IFNAME area A.B.C.D",
  309. NO_STR
  310. "Disable routing on an IPv6 interface\n"
  311. IFNAME_STR
  312. "Specify the OSPF6 area ID\n"
  313. "OSPF6 area ID in IPv4 address notation\n"
  314. )
  315. {
  316. struct ospf6 *o;
  317. struct ospf6_interface *oi;
  318. struct interface *ifp;
  319. u_int32_t area_id;
  320. o = (struct ospf6 *) vty->index;
  321. ifp = if_lookup_by_name (argv[0]);
  322. if (ifp == NULL)
  323. {
  324. vty_out (vty, "No such interface %s%s", argv[0], VNL);
  325. return CMD_SUCCESS;
  326. }
  327. oi = (struct ospf6_interface *) ifp->info;
  328. if (oi == NULL)
  329. {
  330. vty_out (vty, "Interface %s not enabled%s", ifp->name, VNL);
  331. return CMD_SUCCESS;
  332. }
  333. /* parse Area-ID */
  334. if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  335. {
  336. vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  337. return CMD_SUCCESS;
  338. }
  339. if (oi->area->area_id != area_id)
  340. {
  341. vty_out (vty, "Wrong Area-ID: %s is attached to area %s%s",
  342. oi->interface->name, oi->area->name, VNL);
  343. return CMD_SUCCESS;
  344. }
  345. thread_execute (master, interface_down, oi, 0);
  346. listnode_delete (oi->area->if_list, oi);
  347. oi->area = (struct ospf6_area *) NULL;
  348. return CMD_SUCCESS;
  349. }
  350. void
  351. ospf6_show (struct vty *vty, struct ospf6 *o)
  352. {
  353. listnode n;
  354. struct ospf6_area *oa;
  355. char router_id[16], duration[32];
  356. struct timeval now, running;
  357. /* process id, router id */
  358. inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id));
  359. vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s%s",
  360. router_id, VNL);
  361. /* running time */
  362. gettimeofday (&now, (struct timezone *)NULL);
  363. timersub (&now, &o->starttime, &running);
  364. timerstring (&running, duration, sizeof (duration));
  365. vty_out (vty, " Running %s%s", duration, VNL);
  366. /* Redistribute configuration */
  367. /* XXX */
  368. /* LSAs */
  369. vty_out (vty, " Number of AS scoped LSAs is %u%s",
  370. o->lsdb->count, VNL);
  371. /* Areas */
  372. vty_out (vty, " Number of areas in this router is %u%s",
  373. listcount (o->area_list), VNL);
  374. for (n = listhead (o->area_list); n; nextnode (n))
  375. {
  376. oa = (struct ospf6_area *) getdata (n);
  377. ospf6_area_show (vty, oa);
  378. }
  379. }
  380. /* show top level structures */
  381. DEFUN (show_ipv6_ospf6,
  382. show_ipv6_ospf6_cmd,
  383. "show ipv6 ospf6",
  384. SHOW_STR
  385. IP6_STR
  386. OSPF6_STR)
  387. {
  388. OSPF6_CMD_CHECK_RUNNING ();
  389. ospf6_show (vty, ospf6);
  390. return CMD_SUCCESS;
  391. }
  392. DEFUN (show_ipv6_ospf6_route,
  393. show_ipv6_ospf6_route_cmd,
  394. "show ipv6 ospf6 route",
  395. SHOW_STR
  396. IP6_STR
  397. OSPF6_STR
  398. ROUTE_STR
  399. )
  400. {
  401. ospf6_route_table_show (vty, argc, argv, ospf6->route_table);
  402. return CMD_SUCCESS;
  403. }
  404. ALIAS (show_ipv6_ospf6_route,
  405. show_ipv6_ospf6_route_detail_cmd,
  406. "show ipv6 ospf6 route (X::X|X::X/M|detail|summary)",
  407. SHOW_STR
  408. IP6_STR
  409. OSPF6_STR
  410. ROUTE_STR
  411. "Specify IPv6 address\n"
  412. "Specify IPv6 prefix\n"
  413. "Detailed information\n"
  414. "Summary of route table\n"
  415. );
  416. DEFUN (show_ipv6_ospf6_route_match,
  417. show_ipv6_ospf6_route_match_cmd,
  418. "show ipv6 ospf6 route X::X/M match",
  419. SHOW_STR
  420. IP6_STR
  421. OSPF6_STR
  422. ROUTE_STR
  423. "Specify IPv6 prefix\n"
  424. "Display routes which match the specified route\n"
  425. )
  426. {
  427. char *sargv[CMD_ARGC_MAX];
  428. int i, sargc;
  429. /* copy argv to sargv and then append "match" */
  430. for (i = 0; i < argc; i++)
  431. sargv[i] = argv[i];
  432. sargc = argc;
  433. sargv[sargc++] = "match";
  434. sargv[sargc] = NULL;
  435. ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  436. return CMD_SUCCESS;
  437. }
  438. DEFUN (show_ipv6_ospf6_route_match_detail,
  439. show_ipv6_ospf6_route_match_detail_cmd,
  440. "show ipv6 ospf6 route X::X/M match detail",
  441. SHOW_STR
  442. IP6_STR
  443. OSPF6_STR
  444. ROUTE_STR
  445. "Specify IPv6 prefix\n"
  446. "Display routes which match the specified route\n"
  447. "Detailed information\n"
  448. )
  449. {
  450. char *sargv[CMD_ARGC_MAX];
  451. int i, sargc;
  452. /* copy argv to sargv and then append "match" and "detail" */
  453. for (i = 0; i < argc; i++)
  454. sargv[i] = argv[i];
  455. sargc = argc;
  456. sargv[sargc++] = "match";
  457. sargv[sargc++] = "detail";
  458. sargv[sargc] = NULL;
  459. ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  460. return CMD_SUCCESS;
  461. }
  462. /* OSPF configuration write function. */
  463. int
  464. config_write_ospf6 (struct vty *vty)
  465. {
  466. char router_id[16];
  467. listnode j, k;
  468. struct ospf6_area *oa;
  469. struct ospf6_interface *oi;
  470. /* OSPFv6 configuration. */
  471. if (ospf6 == NULL)
  472. return CMD_SUCCESS;
  473. if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
  474. return CMD_SUCCESS;
  475. inet_ntop (AF_INET, &ospf6->router_id, router_id, sizeof (router_id));
  476. vty_out (vty, "router ospf6%s", VNL);
  477. vty_out (vty, " router-id %s%s", router_id, VNL);
  478. ospf6_redistribute_config_write (vty);
  479. for (j = listhead (ospf6->area_list); j; nextnode (j))
  480. {
  481. oa = (struct ospf6_area *) getdata (j);
  482. for (k = listhead (oa->if_list); k; nextnode (k))
  483. {
  484. oi = (struct ospf6_interface *) getdata (k);
  485. vty_out (vty, " interface %s area %s%s",
  486. oi->interface->name, oa->name, VNL);
  487. }
  488. }
  489. vty_out (vty, "!%s", VNL);
  490. return 0;
  491. }
  492. /* OSPF6 node structure. */
  493. struct cmd_node ospf6_node =
  494. {
  495. OSPF6_NODE,
  496. "%s(config-ospf6)# ",
  497. };
  498. /* Install ospf related commands. */
  499. void
  500. ospf6_top_init ()
  501. {
  502. /* Install ospf6 top node. */
  503. install_node (&ospf6_node, config_write_ospf6);
  504. install_element (VIEW_NODE, &show_ipv6_ospf6_cmd);
  505. install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd);
  506. install_element (CONFIG_NODE, &router_ospf6_cmd);
  507. install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
  508. install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
  509. install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
  510. install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  511. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd);
  512. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_detail_cmd);
  513. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd);
  514. install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  515. install_default (OSPF6_NODE);
  516. install_element (OSPF6_NODE, &ospf6_router_id_cmd);
  517. install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
  518. install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
  519. install_element (OSPF6_NODE, &no_router_ospf6_cmd);
  520. }