ospf6_area.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  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 "linklist.h"
  25. #include "thread.h"
  26. #include "vty.h"
  27. #include "command.h"
  28. #include "if.h"
  29. #include "prefix.h"
  30. #include "table.h"
  31. #include "plist.h"
  32. #include "filter.h"
  33. #include "ospf6_proto.h"
  34. #include "ospf6_lsa.h"
  35. #include "ospf6_lsdb.h"
  36. #include "ospf6_route.h"
  37. #include "ospf6_spf.h"
  38. #include "ospf6_top.h"
  39. #include "ospf6_area.h"
  40. #include "ospf6_interface.h"
  41. #include "ospf6_intra.h"
  42. #include "ospf6_abr.h"
  43. #include "ospf6d.h"
  44. int
  45. ospf6_area_cmp (void *va, void *vb)
  46. {
  47. struct ospf6_area *oa = (struct ospf6_area *) va;
  48. struct ospf6_area *ob = (struct ospf6_area *) vb;
  49. return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
  50. }
  51. /* schedule routing table recalculation */
  52. static void
  53. ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
  54. {
  55. switch (ntohs (lsa->header->type))
  56. {
  57. case OSPF6_LSTYPE_ROUTER:
  58. case OSPF6_LSTYPE_NETWORK:
  59. if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
  60. {
  61. zlog_debug ("Examin %s", lsa->name);
  62. zlog_debug ("Schedule SPF Calculation for %s",
  63. OSPF6_AREA (lsa->lsdb->data)->name);
  64. }
  65. ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
  66. ospf6_lsadd_to_spf_reason(lsa));
  67. break;
  68. case OSPF6_LSTYPE_INTRA_PREFIX:
  69. ospf6_intra_prefix_lsa_add (lsa);
  70. break;
  71. case OSPF6_LSTYPE_INTER_PREFIX:
  72. case OSPF6_LSTYPE_INTER_ROUTER:
  73. ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
  74. break;
  75. default:
  76. break;
  77. }
  78. }
  79. static void
  80. ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
  81. {
  82. switch (ntohs (lsa->header->type))
  83. {
  84. case OSPF6_LSTYPE_ROUTER:
  85. case OSPF6_LSTYPE_NETWORK:
  86. if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
  87. {
  88. zlog_debug ("LSA disappearing: %s", lsa->name);
  89. zlog_debug ("Schedule SPF Calculation for %s",
  90. OSPF6_AREA (lsa->lsdb->data)->name);
  91. }
  92. ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
  93. ospf6_lsremove_to_spf_reason(lsa));
  94. break;
  95. case OSPF6_LSTYPE_INTRA_PREFIX:
  96. ospf6_intra_prefix_lsa_remove (lsa);
  97. break;
  98. case OSPF6_LSTYPE_INTER_PREFIX:
  99. case OSPF6_LSTYPE_INTER_ROUTER:
  100. ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
  101. break;
  102. default:
  103. break;
  104. }
  105. }
  106. static void
  107. ospf6_area_route_hook_add (struct ospf6_route *route)
  108. {
  109. struct ospf6_route *copy = ospf6_route_copy (route);
  110. ospf6_route_add (copy, ospf6->route_table);
  111. }
  112. static void
  113. ospf6_area_route_hook_remove (struct ospf6_route *route)
  114. {
  115. struct ospf6_route *copy;
  116. copy = ospf6_route_lookup_identical (route, ospf6->route_table);
  117. if (copy)
  118. ospf6_route_remove (copy, ospf6->route_table);
  119. }
  120. /* Make new area structure */
  121. struct ospf6_area *
  122. ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
  123. {
  124. struct ospf6_area *oa;
  125. struct ospf6_route *route;
  126. oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
  127. inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
  128. oa->area_id = area_id;
  129. oa->if_list = list_new ();
  130. oa->lsdb = ospf6_lsdb_create (oa);
  131. oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
  132. oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
  133. oa->lsdb_self = ospf6_lsdb_create (oa);
  134. oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
  135. oa->spf_table->scope = oa;
  136. oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
  137. oa->route_table->scope = oa;
  138. oa->route_table->hook_add = ospf6_area_route_hook_add;
  139. oa->route_table->hook_remove = ospf6_area_route_hook_remove;
  140. oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
  141. oa->range_table->scope = oa;
  142. oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
  143. oa->summary_prefix->scope = oa;
  144. oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
  145. oa->summary_router->scope = oa;
  146. /* set default options */
  147. if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
  148. {
  149. OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
  150. OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
  151. }
  152. else
  153. {
  154. OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
  155. OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
  156. }
  157. OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
  158. oa->ospf6 = o;
  159. listnode_add_sort (o->area_list, oa);
  160. /* import athoer area's routes as inter-area routes */
  161. for (route = ospf6_route_head (o->route_table); route;
  162. route = ospf6_route_next (route))
  163. ospf6_abr_originate_summary_to_area (route, oa);
  164. return oa;
  165. }
  166. void
  167. ospf6_area_delete (struct ospf6_area *oa)
  168. {
  169. struct listnode *n;
  170. struct ospf6_interface *oi;
  171. ospf6_route_table_delete (oa->range_table);
  172. ospf6_route_table_delete (oa->summary_prefix);
  173. ospf6_route_table_delete (oa->summary_router);
  174. /* The ospf6_interface structs store configuration
  175. * information which should not be lost/reset when
  176. * deleting an area.
  177. * So just detach the interface from the area and
  178. * keep it around. */
  179. for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
  180. oi->area = NULL;
  181. list_delete (oa->if_list);
  182. ospf6_lsdb_delete (oa->lsdb);
  183. ospf6_lsdb_delete (oa->lsdb_self);
  184. ospf6_spf_table_finish (oa->spf_table);
  185. ospf6_route_table_delete (oa->spf_table);
  186. ospf6_route_table_delete (oa->route_table);
  187. THREAD_OFF (oa->thread_spf_calculation);
  188. THREAD_OFF (oa->thread_route_calculation);
  189. listnode_delete (oa->ospf6->area_list, oa);
  190. oa->ospf6 = NULL;
  191. /* free area */
  192. XFREE (MTYPE_OSPF6_AREA, oa);
  193. }
  194. struct ospf6_area *
  195. ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
  196. {
  197. struct ospf6_area *oa;
  198. struct listnode *n;
  199. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
  200. if (oa->area_id == area_id)
  201. return oa;
  202. return (struct ospf6_area *) NULL;
  203. }
  204. static struct ospf6_area *
  205. ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
  206. {
  207. struct ospf6_area *oa;
  208. oa = ospf6_area_lookup (area_id, o);
  209. if (oa == NULL)
  210. oa = ospf6_area_create (area_id, o);
  211. return oa;
  212. }
  213. void
  214. ospf6_area_enable (struct ospf6_area *oa)
  215. {
  216. struct listnode *node, *nnode;
  217. struct ospf6_interface *oi;
  218. SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  219. for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
  220. ospf6_interface_enable (oi);
  221. ospf6_abr_enable_area (oa);
  222. }
  223. void
  224. ospf6_area_disable (struct ospf6_area *oa)
  225. {
  226. struct listnode *node, *nnode;
  227. struct ospf6_interface *oi;
  228. UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  229. for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
  230. ospf6_interface_disable (oi);
  231. ospf6_abr_disable_area (oa);
  232. ospf6_lsdb_remove_all (oa->lsdb);
  233. ospf6_lsdb_remove_all (oa->lsdb_self);
  234. ospf6_spf_table_finish(oa->spf_table);
  235. ospf6_route_remove_all(oa->route_table);
  236. THREAD_OFF (oa->thread_spf_calculation);
  237. THREAD_OFF (oa->thread_route_calculation);
  238. THREAD_OFF (oa->thread_router_lsa);
  239. THREAD_OFF (oa->thread_intra_prefix_lsa);
  240. }
  241. void
  242. ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
  243. {
  244. struct listnode *i;
  245. struct ospf6_interface *oi;
  246. vty_out (vty, " Area %s%s", oa->name, VNL);
  247. vty_out (vty, " Number of Area scoped LSAs is %u%s",
  248. oa->lsdb->count, VNL);
  249. vty_out (vty, " Interface attached to this area:");
  250. for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
  251. vty_out (vty, " %s", oi->interface->name);
  252. vty_out (vty, "%s", VNL);
  253. }
  254. #define OSPF6_CMD_AREA_LOOKUP(str, oa) \
  255. { \
  256. u_int32_t area_id = 0; \
  257. if (inet_pton (AF_INET, str, &area_id) != 1) \
  258. { \
  259. vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
  260. return CMD_SUCCESS; \
  261. } \
  262. oa = ospf6_area_lookup (area_id, ospf6); \
  263. if (oa == NULL) \
  264. { \
  265. vty_out (vty, "No such Area: %s%s", str, VNL); \
  266. return CMD_SUCCESS; \
  267. } \
  268. }
  269. #define OSPF6_CMD_AREA_GET(str, oa) \
  270. { \
  271. u_int32_t area_id = 0; \
  272. if (inet_pton (AF_INET, str, &area_id) != 1) \
  273. { \
  274. vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
  275. return CMD_SUCCESS; \
  276. } \
  277. oa = ospf6_area_get (area_id, ospf6); \
  278. }
  279. DEFUN (area_range,
  280. area_range_cmd,
  281. "area A.B.C.D range X:X::X:X/M",
  282. "OSPF area parameters\n"
  283. OSPF6_AREA_ID_STR
  284. "Configured address range\n"
  285. "Specify IPv6 prefix\n"
  286. )
  287. {
  288. int ret;
  289. struct ospf6_area *oa;
  290. struct prefix prefix;
  291. struct ospf6_route *range;
  292. OSPF6_CMD_AREA_GET (argv[0], oa);
  293. argc--;
  294. argv++;
  295. ret = str2prefix (argv[0], &prefix);
  296. if (ret != 1 || prefix.family != AF_INET6)
  297. {
  298. vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
  299. return CMD_SUCCESS;
  300. }
  301. argc--;
  302. argv++;
  303. range = ospf6_route_lookup (&prefix, oa->range_table);
  304. if (range == NULL)
  305. {
  306. range = ospf6_route_create ();
  307. range->type = OSPF6_DEST_TYPE_RANGE;
  308. range->prefix = prefix;
  309. }
  310. if (argc)
  311. {
  312. if (! strcmp (argv[0], "not-advertise"))
  313. SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
  314. else if (! strcmp (argv[0], "advertise"))
  315. UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
  316. }
  317. if (range->rnode)
  318. {
  319. vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
  320. return CMD_WARNING;
  321. }
  322. ospf6_route_add (range, oa->range_table);
  323. return CMD_SUCCESS;
  324. }
  325. ALIAS (area_range,
  326. area_range_advertise_cmd,
  327. "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
  328. "OSPF area parameters\n"
  329. OSPF6_AREA_ID_STR
  330. "Configured address range\n"
  331. "Specify IPv6 prefix\n"
  332. )
  333. DEFUN (no_area_range,
  334. no_area_range_cmd,
  335. "no area A.B.C.D range X:X::X:X/M",
  336. "OSPF area parameters\n"
  337. OSPF6_AREA_ID_STR
  338. "Configured address range\n"
  339. "Specify IPv6 prefix\n"
  340. )
  341. {
  342. int ret;
  343. struct ospf6_area *oa;
  344. struct prefix prefix;
  345. struct ospf6_route *range;
  346. OSPF6_CMD_AREA_GET (argv[0], oa);
  347. argc--;
  348. argv++;
  349. ret = str2prefix (argv[0], &prefix);
  350. if (ret != 1 || prefix.family != AF_INET6)
  351. {
  352. vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
  353. return CMD_SUCCESS;
  354. }
  355. range = ospf6_route_lookup (&prefix, oa->range_table);
  356. if (range == NULL)
  357. {
  358. vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
  359. return CMD_SUCCESS;
  360. }
  361. ospf6_route_remove (range, oa->range_table);
  362. return CMD_SUCCESS;
  363. }
  364. void
  365. ospf6_area_config_write (struct vty *vty)
  366. {
  367. struct listnode *node;
  368. struct ospf6_area *oa;
  369. struct ospf6_route *range;
  370. char buf[128];
  371. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  372. {
  373. for (range = ospf6_route_head (oa->range_table); range;
  374. range = ospf6_route_next (range))
  375. {
  376. prefix2str (&range->prefix, buf, sizeof (buf));
  377. vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
  378. }
  379. if (PREFIX_NAME_IN (oa))
  380. vty_out (vty, " area %s filter-list prefix %s in%s",
  381. oa->name, PREFIX_NAME_IN (oa), VNL);
  382. if (PREFIX_NAME_OUT (oa))
  383. vty_out (vty, " area %s filter-list prefix %s out%s",
  384. oa->name, PREFIX_NAME_OUT (oa), VNL);
  385. if (IMPORT_NAME (oa))
  386. vty_out (vty, " area %s import-list %s%s",
  387. oa->name, IMPORT_NAME (oa), VNL);
  388. if (EXPORT_NAME (oa))
  389. vty_out (vty, " area %s export-list %s%s",
  390. oa->name, EXPORT_NAME (oa), VNL);
  391. }
  392. }
  393. DEFUN (area_filter_list,
  394. area_filter_list_cmd,
  395. "area A.B.C.D filter-list prefix WORD (in|out)",
  396. "OSPFv6 area parameters\n"
  397. "OSPFv6 area ID in IP address format\n"
  398. "Filter networks between OSPFv6 areas\n"
  399. "Filter prefixes between OSPFv6 areas\n"
  400. "Name of an IPv6 prefix-list\n"
  401. "Filter networks sent to this area\n"
  402. "Filter networks sent from this area\n")
  403. {
  404. struct ospf6_area *area;
  405. struct prefix_list *plist;
  406. OSPF6_CMD_AREA_GET (argv[0], area);
  407. argc--;
  408. argv++;
  409. plist = prefix_list_lookup (AFI_IP6, argv[0]);
  410. if (strncmp (argv[1], "in", 2) == 0)
  411. {
  412. PREFIX_LIST_IN (area) = plist;
  413. if (PREFIX_NAME_IN (area))
  414. free (PREFIX_NAME_IN (area));
  415. PREFIX_NAME_IN (area) = strdup (argv[0]);
  416. ospf6_abr_reimport (area);
  417. }
  418. else
  419. {
  420. PREFIX_LIST_OUT (area) = plist;
  421. if (PREFIX_NAME_OUT (area))
  422. free (PREFIX_NAME_OUT (area));
  423. PREFIX_NAME_OUT (area) = strdup (argv[0]);
  424. ospf6_abr_enable_area (area);
  425. }
  426. return CMD_SUCCESS;
  427. }
  428. DEFUN (no_area_filter_list,
  429. no_area_filter_list_cmd,
  430. "no area A.B.C.D filter-list prefix WORD (in|out)",
  431. NO_STR
  432. "OSPFv6 area parameters\n"
  433. "OSPFv6 area ID in IP address format\n"
  434. "Filter networks between OSPFv6 areas\n"
  435. "Filter prefixes between OSPFv6 areas\n"
  436. "Name of an IPv6 prefix-list\n"
  437. "Filter networks sent to this area\n"
  438. "Filter networks sent from this area\n")
  439. {
  440. struct ospf6_area *area;
  441. OSPF6_CMD_AREA_GET (argv[0], area);
  442. argc--;
  443. argv++;
  444. if (strncmp (argv[1], "in", 2) == 0)
  445. {
  446. if (PREFIX_NAME_IN (area))
  447. if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
  448. return CMD_SUCCESS;
  449. PREFIX_LIST_IN (area) = NULL;
  450. if (PREFIX_NAME_IN (area))
  451. free (PREFIX_NAME_IN (area));
  452. PREFIX_NAME_IN (area) = NULL;
  453. ospf6_abr_reimport (area);
  454. }
  455. else
  456. {
  457. if (PREFIX_NAME_OUT (area))
  458. if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
  459. return CMD_SUCCESS;
  460. PREFIX_LIST_OUT (area) = NULL;
  461. if (PREFIX_NAME_OUT (area))
  462. free (PREFIX_NAME_OUT (area));
  463. PREFIX_NAME_OUT (area) = NULL;
  464. ospf6_abr_enable_area (area);
  465. }
  466. return CMD_SUCCESS;
  467. }
  468. DEFUN (area_import_list,
  469. area_import_list_cmd,
  470. "area A.B.C.D import-list NAME",
  471. "OSPFv6 area parameters\n"
  472. "OSPFv6 area ID in IP address format\n"
  473. "Set the filter for networks from other areas announced to the specified one\n"
  474. "Name of the acess-list\n")
  475. {
  476. struct ospf6_area *area;
  477. struct access_list *list;
  478. OSPF6_CMD_AREA_GET(argv[0], area);
  479. list = access_list_lookup (AFI_IP6, argv[1]);
  480. IMPORT_LIST (area) = list;
  481. if (IMPORT_NAME (area))
  482. free (IMPORT_NAME (area));
  483. IMPORT_NAME (area) = strdup (argv[1]);
  484. ospf6_abr_reimport (area);
  485. return CMD_SUCCESS;
  486. }
  487. DEFUN (no_area_import_list,
  488. no_area_import_list_cmd,
  489. "no area A.B.C.D import-list NAME",
  490. "OSPFv6 area parameters\n"
  491. "OSPFv6 area ID in IP address format\n"
  492. "Unset the filter for networks announced to other areas\n"
  493. "NAme of the access-list\n")
  494. {
  495. struct ospf6_area *area;
  496. OSPF6_CMD_AREA_GET(argv[0], area);
  497. IMPORT_LIST (area) = 0;
  498. if (IMPORT_NAME (area))
  499. free (IMPORT_NAME (area));
  500. IMPORT_NAME (area) = NULL;
  501. ospf6_abr_reimport (area);
  502. return CMD_SUCCESS;
  503. }
  504. DEFUN (area_export_list,
  505. area_export_list_cmd,
  506. "area A.B.C.D export-list NAME",
  507. "OSPFv6 area parameters\n"
  508. "OSPFv6 area ID in IP address format\n"
  509. "Set the filter for networks announced to other areas\n"
  510. "Name of the acess-list\n")
  511. {
  512. struct ospf6_area *area;
  513. struct access_list *list;
  514. OSPF6_CMD_AREA_GET(argv[0], area);
  515. list = access_list_lookup (AFI_IP6, argv[1]);
  516. EXPORT_LIST (area) = list;
  517. if (EXPORT_NAME (area))
  518. free (EXPORT_NAME (area));
  519. EXPORT_NAME (area) = strdup (argv[1]);
  520. ospf6_abr_enable_area (area);
  521. return CMD_SUCCESS;
  522. }
  523. DEFUN (no_area_export_list,
  524. no_area_export_list_cmd,
  525. "no area A.B.C.D export-list NAME",
  526. "OSPFv6 area parameters\n"
  527. "OSPFv6 area ID in IP address format\n"
  528. "Unset the filter for networks announced to other areas\n"
  529. "Name of the access-list\n")
  530. {
  531. struct ospf6_area *area;
  532. OSPF6_CMD_AREA_GET(argv[0], area);
  533. EXPORT_LIST (area) = 0;
  534. if (EXPORT_NAME (area))
  535. free (EXPORT_NAME (area));
  536. EXPORT_NAME (area) = NULL;
  537. ospf6_abr_enable_area (area);
  538. return CMD_SUCCESS;
  539. }
  540. DEFUN (show_ipv6_ospf6_spf_tree,
  541. show_ipv6_ospf6_spf_tree_cmd,
  542. "show ipv6 ospf6 spf tree",
  543. SHOW_STR
  544. IP6_STR
  545. OSPF6_STR
  546. "Shortest Path First caculation\n"
  547. "Show SPF tree\n")
  548. {
  549. struct listnode *node;
  550. struct ospf6_area *oa;
  551. struct ospf6_vertex *root;
  552. struct ospf6_route *route;
  553. struct prefix prefix;
  554. ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
  555. for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  556. {
  557. route = ospf6_route_lookup (&prefix, oa->spf_table);
  558. if (route == NULL)
  559. {
  560. vty_out (vty, "LS entry for root not found in area %s%s",
  561. oa->name, VNL);
  562. continue;
  563. }
  564. root = (struct ospf6_vertex *) route->route_option;
  565. ospf6_spf_display_subtree (vty, "", 0, root);
  566. }
  567. return CMD_SUCCESS;
  568. }
  569. DEFUN (show_ipv6_ospf6_area_spf_tree,
  570. show_ipv6_ospf6_area_spf_tree_cmd,
  571. "show ipv6 ospf6 area A.B.C.D spf tree",
  572. SHOW_STR
  573. IP6_STR
  574. OSPF6_STR
  575. OSPF6_AREA_STR
  576. OSPF6_AREA_ID_STR
  577. "Shortest Path First caculation\n"
  578. "Show SPF tree\n")
  579. {
  580. u_int32_t area_id;
  581. struct ospf6_area *oa;
  582. struct ospf6_vertex *root;
  583. struct ospf6_route *route;
  584. struct prefix prefix;
  585. ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
  586. if (inet_pton (AF_INET, argv[0], &area_id) != 1)
  587. {
  588. vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
  589. return CMD_SUCCESS;
  590. }
  591. oa = ospf6_area_lookup (area_id, ospf6);
  592. if (oa == NULL)
  593. {
  594. vty_out (vty, "No such Area: %s%s", argv[0], VNL);
  595. return CMD_SUCCESS;
  596. }
  597. route = ospf6_route_lookup (&prefix, oa->spf_table);
  598. if (route == NULL)
  599. {
  600. vty_out (vty, "LS entry for root not found in area %s%s",
  601. oa->name, VNL);
  602. return CMD_SUCCESS;
  603. }
  604. root = (struct ospf6_vertex *) route->route_option;
  605. ospf6_spf_display_subtree (vty, "", 0, root);
  606. return CMD_SUCCESS;
  607. }
  608. DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
  609. show_ipv6_ospf6_simulate_spf_tree_root_cmd,
  610. "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
  611. SHOW_STR
  612. IP6_STR
  613. OSPF6_STR
  614. "Shortest Path First caculation\n"
  615. "Show SPF tree\n"
  616. "Specify root's router-id to calculate another router's SPF tree\n")
  617. {
  618. u_int32_t area_id;
  619. struct ospf6_area *oa;
  620. struct ospf6_vertex *root;
  621. struct ospf6_route *route;
  622. struct prefix prefix;
  623. u_int32_t router_id;
  624. struct ospf6_route_table *spf_table;
  625. unsigned char tmp_debug_ospf6_spf = 0;
  626. inet_pton (AF_INET, argv[0], &router_id);
  627. ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
  628. if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  629. {
  630. vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
  631. return CMD_SUCCESS;
  632. }
  633. oa = ospf6_area_lookup (area_id, ospf6);
  634. if (oa == NULL)
  635. {
  636. vty_out (vty, "No such Area: %s%s", argv[1], VNL);
  637. return CMD_SUCCESS;
  638. }
  639. tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
  640. conf_debug_ospf6_spf = 0;
  641. spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
  642. ospf6_spf_calculation (router_id, spf_table, oa);
  643. conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
  644. route = ospf6_route_lookup (&prefix, spf_table);
  645. if (route == NULL)
  646. {
  647. ospf6_spf_table_finish (spf_table);
  648. ospf6_route_table_delete (spf_table);
  649. return CMD_SUCCESS;
  650. }
  651. root = (struct ospf6_vertex *) route->route_option;
  652. ospf6_spf_display_subtree (vty, "", 0, root);
  653. ospf6_spf_table_finish (spf_table);
  654. ospf6_route_table_delete (spf_table);
  655. return CMD_SUCCESS;
  656. }
  657. void
  658. ospf6_area_init (void)
  659. {
  660. install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
  661. install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
  662. install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
  663. install_element (OSPF6_NODE, &area_range_cmd);
  664. install_element (OSPF6_NODE, &area_range_advertise_cmd);
  665. install_element (OSPF6_NODE, &no_area_range_cmd);
  666. install_element (OSPF6_NODE, &area_import_list_cmd);
  667. install_element (OSPF6_NODE, &no_area_import_list_cmd);
  668. install_element (OSPF6_NODE, &area_export_list_cmd);
  669. install_element (OSPF6_NODE, &no_area_export_list_cmd);
  670. install_element (OSPF6_NODE, &area_filter_list_cmd);
  671. install_element (OSPF6_NODE, &no_area_filter_list_cmd);
  672. }