ospf6_abr.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /*
  2. * Area Border Router function.
  3. * Copyright (C) 2004 Yasuhiro Ohara
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the
  19. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. * Boston, MA 02111-1307, USA.
  21. */
  22. #include <zebra.h>
  23. #include "log.h"
  24. #include "prefix.h"
  25. #include "table.h"
  26. #include "vty.h"
  27. #include "linklist.h"
  28. #include "command.h"
  29. #include "thread.h"
  30. #include "plist.h"
  31. #include "filter.h"
  32. #include "ospf6_proto.h"
  33. #include "ospf6_route.h"
  34. #include "ospf6_lsa.h"
  35. #include "ospf6_route.h"
  36. #include "ospf6_lsdb.h"
  37. #include "ospf6_message.h"
  38. #include "ospf6_top.h"
  39. #include "ospf6_area.h"
  40. #include "ospf6_interface.h"
  41. #include "ospf6_neighbor.h"
  42. #include "ospf6_flood.h"
  43. #include "ospf6_intra.h"
  44. #include "ospf6_abr.h"
  45. #include "ospf6d.h"
  46. unsigned char conf_debug_ospf6_abr;
  47. int
  48. ospf6_is_router_abr (struct ospf6 *o)
  49. {
  50. struct listnode *node;
  51. struct ospf6_area *oa;
  52. int area_count = 0;
  53. for (ALL_LIST_ELEMENTS_RO (o->area_list, node, oa))
  54. if (IS_AREA_ENABLED (oa))
  55. area_count++;
  56. if (area_count > 1)
  57. return 1;
  58. return 0;
  59. }
  60. void
  61. ospf6_abr_enable_area (struct ospf6_area *area)
  62. {
  63. struct ospf6_area *oa;
  64. struct ospf6_route *ro;
  65. struct listnode *node, *nnode;
  66. for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
  67. {
  68. /* update B bit for each area */
  69. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  70. /* install other area's configured address range */
  71. if (oa != area)
  72. {
  73. for (ro = ospf6_route_head (oa->range_table); ro;
  74. ro = ospf6_route_next (ro))
  75. {
  76. if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
  77. ospf6_abr_originate_summary_to_area (ro, area);
  78. }
  79. }
  80. }
  81. /* install calculated routes to border routers */
  82. for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;
  83. ro = ospf6_route_next (ro))
  84. ospf6_abr_originate_summary_to_area (ro, area);
  85. /* install calculated routes to network (may be rejected by ranges) */
  86. for (ro = ospf6_route_head (area->ospf6->route_table); ro;
  87. ro = ospf6_route_next (ro))
  88. ospf6_abr_originate_summary_to_area (ro, area);
  89. }
  90. void
  91. ospf6_abr_disable_area (struct ospf6_area *area)
  92. {
  93. struct ospf6_area *oa;
  94. struct ospf6_route *ro;
  95. struct ospf6_lsa *old;
  96. struct listnode *node, *nnode;
  97. /* Withdraw all summary prefixes previously originated */
  98. for (ro = ospf6_route_head (area->summary_prefix); ro;
  99. ro = ospf6_route_next (ro))
  100. {
  101. old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
  102. area->ospf6->router_id, area->lsdb);
  103. if (old)
  104. ospf6_lsa_purge (old);
  105. ospf6_route_remove (ro, area->summary_prefix);
  106. }
  107. /* Withdraw all summary router-routes previously originated */
  108. for (ro = ospf6_route_head (area->summary_router); ro;
  109. ro = ospf6_route_next (ro))
  110. {
  111. old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,
  112. area->ospf6->router_id, area->lsdb);
  113. if (old)
  114. ospf6_lsa_purge (old);
  115. ospf6_route_remove (ro, area->summary_router);
  116. }
  117. /* Schedule Router-LSA for each area (ABR status may change) */
  118. for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
  119. /* update B bit for each area */
  120. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  121. }
  122. /* RFC 2328 12.4.3. Summary-LSAs */
  123. void
  124. ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
  125. struct ospf6_area *area)
  126. {
  127. struct ospf6_lsa *lsa, *old = NULL;
  128. struct ospf6_interface *oi;
  129. struct ospf6_route *summary, *range = NULL;
  130. struct ospf6_area *route_area;
  131. char buffer[OSPF6_MAX_LSASIZE];
  132. struct ospf6_lsa_header *lsa_header;
  133. caddr_t p;
  134. struct ospf6_inter_prefix_lsa *prefix_lsa;
  135. struct ospf6_inter_router_lsa *router_lsa;
  136. struct ospf6_route_table *summary_table = NULL;
  137. u_int16_t type;
  138. char buf[64];
  139. int is_debug = 0;
  140. if (route->type == OSPF6_DEST_TYPE_ROUTER)
  141. {
  142. if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER))
  143. {
  144. is_debug++;
  145. inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  146. buf, sizeof (buf));
  147. zlog_debug ("Originating summary in area %s for ASBR %s",
  148. area->name, buf);
  149. }
  150. summary_table = area->summary_router;
  151. }
  152. else
  153. {
  154. if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX))
  155. {
  156. is_debug++;
  157. prefix2str (&route->prefix, buf, sizeof (buf));
  158. zlog_debug ("Originating summary in area %s for %s",
  159. area->name, buf);
  160. }
  161. summary_table = area->summary_prefix;
  162. }
  163. summary = ospf6_route_lookup (&route->prefix, summary_table);
  164. if (summary)
  165. old = ospf6_lsdb_lookup (summary->path.origin.type,
  166. summary->path.origin.id,
  167. area->ospf6->router_id, area->lsdb);
  168. /* if this route has just removed, remove corresponding LSA */
  169. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
  170. {
  171. if (is_debug)
  172. zlog_debug ("The route has just removed, purge previous LSA");
  173. if (summary)
  174. ospf6_route_remove (summary, summary_table);
  175. if (old)
  176. ospf6_lsa_purge (old);
  177. return;
  178. }
  179. /* Only destination type network, range or ASBR are considered */
  180. if (route->type != OSPF6_DEST_TYPE_NETWORK &&
  181. route->type != OSPF6_DEST_TYPE_RANGE &&
  182. (route->type != OSPF6_DEST_TYPE_ROUTER ||
  183. ! CHECK_FLAG (route->path.router_bits, OSPF6_ROUTER_BIT_E)))
  184. {
  185. if (is_debug)
  186. zlog_debug ("Route type is none of network, range nor ASBR, withdraw");
  187. if (summary)
  188. ospf6_route_remove (summary, summary_table);
  189. if (old)
  190. ospf6_lsa_purge (old);
  191. return;
  192. }
  193. /* AS External routes are never considered */
  194. if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
  195. route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
  196. {
  197. if (is_debug)
  198. zlog_debug ("Path type is external, withdraw");
  199. if (summary)
  200. ospf6_route_remove (summary, summary_table);
  201. if (old)
  202. ospf6_lsa_purge (old);
  203. return;
  204. }
  205. /* do not generate if the path's area is the same as target area */
  206. if (route->path.area_id == area->area_id)
  207. {
  208. if (is_debug)
  209. zlog_debug ("The route is in the area itself, ignore");
  210. if (summary)
  211. ospf6_route_remove (summary, summary_table);
  212. if (old)
  213. ospf6_lsa_purge (old);
  214. return;
  215. }
  216. /* do not generate if the nexthops belongs to the target area */
  217. oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);
  218. if (oi && oi->area && oi->area == area)
  219. {
  220. if (is_debug)
  221. zlog_debug ("The route's nexthop is in the same area, ignore");
  222. if (summary)
  223. ospf6_route_remove (summary, summary_table);
  224. if (old)
  225. ospf6_lsa_purge (old);
  226. return;
  227. }
  228. /* do not generate if the route cost is greater or equal to LSInfinity */
  229. if (route->path.cost >= LS_INFINITY)
  230. {
  231. if (is_debug)
  232. zlog_debug ("The cost exceeds LSInfinity, withdraw");
  233. if (summary)
  234. ospf6_route_remove (summary, summary_table);
  235. if (old)
  236. ospf6_lsa_purge (old);
  237. return;
  238. }
  239. /* if this is a route to ASBR */
  240. if (route->type == OSPF6_DEST_TYPE_ROUTER)
  241. {
  242. /* Only the prefered best path is considered */
  243. if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST))
  244. {
  245. if (is_debug)
  246. zlog_debug ("This is the secondary path to the ASBR, ignore");
  247. if (summary)
  248. ospf6_route_remove (summary, summary_table);
  249. if (old)
  250. ospf6_lsa_purge (old);
  251. return;
  252. }
  253. /* Do not generate if the area is stub */
  254. /* XXX */
  255. }
  256. /* if this is an intra-area route, this may be suppressed by aggregation */
  257. if (route->type == OSPF6_DEST_TYPE_NETWORK &&
  258. route->path.type == OSPF6_PATH_TYPE_INTRA)
  259. {
  260. /* search for configured address range for the route's area */
  261. route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
  262. assert (route_area);
  263. range = ospf6_route_lookup_bestmatch (&route->prefix,
  264. route_area->range_table);
  265. /* ranges are ignored when originate backbone routes to transit area.
  266. Otherwise, if ranges are configured, the route is suppressed. */
  267. if (range && ! CHECK_FLAG (range->flag, OSPF6_ROUTE_REMOVE) &&
  268. (route->path.area_id != BACKBONE_AREA_ID ||
  269. ! IS_AREA_TRANSIT (area)))
  270. {
  271. if (is_debug)
  272. {
  273. prefix2str (&range->prefix, buf, sizeof (buf));
  274. zlog_debug ("Suppressed by range %s of area %s",
  275. buf, route_area->name);
  276. }
  277. if (summary)
  278. ospf6_route_remove (summary, summary_table);
  279. if (old)
  280. ospf6_lsa_purge (old);
  281. return;
  282. }
  283. }
  284. /* If this is a configured address range */
  285. if (route->type == OSPF6_DEST_TYPE_RANGE)
  286. {
  287. /* If DoNotAdvertise is set */
  288. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
  289. {
  290. if (is_debug)
  291. zlog_debug ("This is the range with DoNotAdvertise set. ignore");
  292. if (summary)
  293. ospf6_route_remove (summary, summary_table);
  294. if (old)
  295. ospf6_lsa_purge (old);
  296. return;
  297. }
  298. /* Whether the route have active longer prefix */
  299. if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
  300. {
  301. if (is_debug)
  302. zlog_debug ("The range is not active. withdraw");
  303. if (summary)
  304. ospf6_route_remove (summary, summary_table);
  305. if (old)
  306. ospf6_lsa_purge (old);
  307. return;
  308. }
  309. }
  310. /* Check export list */
  311. if (EXPORT_NAME (area))
  312. {
  313. if (EXPORT_LIST (area) == NULL)
  314. EXPORT_LIST (area) =
  315. access_list_lookup (AFI_IP6, EXPORT_NAME (area));
  316. if (EXPORT_LIST (area))
  317. if (access_list_apply (EXPORT_LIST (area),
  318. &route->prefix) == FILTER_DENY)
  319. {
  320. if (is_debug)
  321. {
  322. inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  323. buf, sizeof(buf));
  324. zlog_debug ("prefix %s was denied by export list", buf);
  325. }
  326. return;
  327. }
  328. }
  329. /* Check filter-list */
  330. if (PREFIX_NAME_OUT (area))
  331. {
  332. if (PREFIX_LIST_OUT (area) == NULL)
  333. PREFIX_LIST_OUT (area) =
  334. prefix_list_lookup(AFI_IP6, PREFIX_NAME_OUT (area));
  335. if (PREFIX_LIST_OUT (area))
  336. if (prefix_list_apply (PREFIX_LIST_OUT (area),
  337. &route->prefix) != PREFIX_PERMIT)
  338. {
  339. if (is_debug)
  340. {
  341. inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
  342. buf, sizeof (buf));
  343. zlog_debug ("prefix %s was denied by filter-list out", buf);
  344. }
  345. return;
  346. }
  347. }
  348. /* the route is going to be originated. store it in area's summary_table */
  349. if (summary == NULL)
  350. {
  351. summary = ospf6_route_copy (route);
  352. if (route->type == OSPF6_DEST_TYPE_NETWORK ||
  353. route->type == OSPF6_DEST_TYPE_RANGE)
  354. summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  355. else
  356. summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  357. summary->path.origin.adv_router = area->ospf6->router_id;
  358. summary->path.origin.id =
  359. ospf6_new_ls_id (summary->path.origin.type,
  360. summary->path.origin.adv_router, area->lsdb);
  361. summary = ospf6_route_add (summary, summary_table);
  362. }
  363. else
  364. {
  365. summary->type = route->type;
  366. quagga_gettime (QUAGGA_CLK_MONOTONIC, &summary->changed);
  367. }
  368. summary->path.router_bits = route->path.router_bits;
  369. summary->path.options[0] = route->path.options[0];
  370. summary->path.options[1] = route->path.options[1];
  371. summary->path.options[2] = route->path.options[2];
  372. summary->path.prefix_options = route->path.prefix_options;
  373. summary->path.area_id = area->area_id;
  374. summary->path.type = OSPF6_PATH_TYPE_INTER;
  375. summary->path.cost = route->path.cost;
  376. summary->nexthop[0] = route->nexthop[0];
  377. /* prepare buffer */
  378. memset (buffer, 0, sizeof (buffer));
  379. lsa_header = (struct ospf6_lsa_header *) buffer;
  380. if (route->type == OSPF6_DEST_TYPE_ROUTER)
  381. {
  382. router_lsa = (struct ospf6_inter_router_lsa *)
  383. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  384. p = (caddr_t) router_lsa + sizeof (struct ospf6_inter_router_lsa);
  385. /* Fill Inter-Area-Router-LSA */
  386. router_lsa->options[0] = route->path.options[0];
  387. router_lsa->options[1] = route->path.options[1];
  388. router_lsa->options[2] = route->path.options[2];
  389. OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa, route->path.cost);
  390. router_lsa->router_id = ADV_ROUTER_IN_PREFIX (&route->prefix);
  391. type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  392. }
  393. else
  394. {
  395. prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  396. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  397. p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
  398. /* Fill Inter-Area-Prefix-LSA */
  399. OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
  400. prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
  401. prefix_lsa->prefix.prefix_options = route->path.prefix_options;
  402. /* set Prefix */
  403. memcpy (p, &route->prefix.u.prefix6,
  404. OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
  405. ospf6_prefix_apply_mask (&prefix_lsa->prefix);
  406. p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
  407. type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  408. }
  409. /* Fill LSA Header */
  410. lsa_header->age = 0;
  411. lsa_header->type = type;
  412. lsa_header->id = summary->path.origin.id;
  413. lsa_header->adv_router = area->ospf6->router_id;
  414. lsa_header->seqnum =
  415. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  416. lsa_header->adv_router, area->lsdb);
  417. lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
  418. /* LSA checksum */
  419. ospf6_lsa_checksum (lsa_header);
  420. /* create LSA */
  421. lsa = ospf6_lsa_create (lsa_header);
  422. /* Originate */
  423. ospf6_lsa_originate_area (lsa, area);
  424. }
  425. static void
  426. ospf6_abr_range_update (struct ospf6_route *range)
  427. {
  428. u_int32_t cost = 0;
  429. struct ospf6_route *ro;
  430. assert (range->type == OSPF6_DEST_TYPE_RANGE);
  431. /* update range's cost and active flag */
  432. for (ro = ospf6_route_match_head (&range->prefix, ospf6->route_table);
  433. ro; ro = ospf6_route_match_next (&range->prefix, ro))
  434. {
  435. if (ro->path.area_id == range->path.area_id &&
  436. ! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
  437. cost = MAX (cost, ro->path.cost);
  438. }
  439. if (range->path.cost != cost)
  440. {
  441. range->path.cost = cost;
  442. if (range->path.cost)
  443. SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
  444. else
  445. UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
  446. ospf6_abr_originate_summary (range);
  447. }
  448. }
  449. void
  450. ospf6_abr_originate_summary (struct ospf6_route *route)
  451. {
  452. struct listnode *node, *nnode;
  453. struct ospf6_area *oa;
  454. struct ospf6_route *range = NULL;
  455. if (route->type == OSPF6_DEST_TYPE_NETWORK)
  456. {
  457. oa = ospf6_area_lookup (route->path.area_id, ospf6);
  458. range = ospf6_route_lookup_bestmatch (&route->prefix, oa->range_table);
  459. if (range)
  460. ospf6_abr_range_update (range);
  461. }
  462. for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
  463. ospf6_abr_originate_summary_to_area (route, oa);
  464. }
  465. /* RFC 2328 16.2. Calculating the inter-area routes */
  466. void
  467. ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
  468. {
  469. struct prefix prefix, abr_prefix;
  470. struct ospf6_route_table *table = NULL;
  471. struct ospf6_route *range, *route, *old = NULL;
  472. struct ospf6_route *abr_entry;
  473. u_char type = 0;
  474. char options[3] = {0, 0, 0};
  475. u_int8_t prefix_options = 0;
  476. u_int32_t cost = 0;
  477. u_char router_bits = 0;
  478. int i;
  479. char buf[64];
  480. int is_debug = 0;
  481. memset (&prefix, 0, sizeof (prefix));
  482. if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
  483. {
  484. struct ospf6_inter_prefix_lsa *prefix_lsa;
  485. if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX))
  486. {
  487. is_debug++;
  488. zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
  489. }
  490. prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  491. OSPF6_LSA_HEADER_END (lsa->header);
  492. prefix.family = AF_INET6;
  493. prefix.prefixlen = prefix_lsa->prefix.prefix_length;
  494. ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix);
  495. prefix2str (&prefix, buf, sizeof (buf));
  496. table = oa->ospf6->route_table;
  497. type = OSPF6_DEST_TYPE_NETWORK;
  498. prefix_options = prefix_lsa->prefix.prefix_options;
  499. cost = OSPF6_ABR_SUMMARY_METRIC (prefix_lsa);
  500. }
  501. else if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
  502. {
  503. struct ospf6_inter_router_lsa *router_lsa;
  504. if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER))
  505. {
  506. is_debug++;
  507. zlog_debug ("Examin %s in area %s", lsa->name, oa->name);
  508. }
  509. router_lsa = (struct ospf6_inter_router_lsa *)
  510. OSPF6_LSA_HEADER_END (lsa->header);
  511. ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix);
  512. inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
  513. table = oa->ospf6->brouter_table;
  514. type = OSPF6_DEST_TYPE_ROUTER;
  515. options[0] = router_lsa->options[0];
  516. options[1] = router_lsa->options[1];
  517. options[2] = router_lsa->options[2];
  518. cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa);
  519. SET_FLAG (router_bits, OSPF6_ROUTER_BIT_E);
  520. }
  521. else
  522. assert (0);
  523. /* Find existing route */
  524. route = ospf6_route_lookup (&prefix, table);
  525. if (route)
  526. ospf6_route_lock (route);
  527. while (route && ospf6_route_is_prefix (&prefix, route))
  528. {
  529. if (route->path.area_id == oa->area_id &&
  530. route->path.origin.type == lsa->header->type &&
  531. route->path.origin.id == lsa->header->id &&
  532. route->path.origin.adv_router == lsa->header->adv_router &&
  533. ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED))
  534. old = route;
  535. route = ospf6_route_next (route);
  536. }
  537. /* (1) if cost == LSInfinity or if the LSA is MaxAge */
  538. if (cost == LS_INFINITY)
  539. {
  540. if (is_debug)
  541. zlog_debug ("cost is LS_INFINITY, ignore");
  542. if (old)
  543. ospf6_route_remove (old, table);
  544. return;
  545. }
  546. if (OSPF6_LSA_IS_MAXAGE (lsa))
  547. {
  548. if (is_debug)
  549. zlog_debug ("LSA is MaxAge, ignore");
  550. if (old)
  551. ospf6_route_remove (old, table);
  552. return;
  553. }
  554. /* (2) if the LSA is self-originated, ignore */
  555. if (lsa->header->adv_router == oa->ospf6->router_id)
  556. {
  557. if (is_debug)
  558. zlog_debug ("LSA is self-originated, ignore");
  559. if (old)
  560. ospf6_route_remove (old, table);
  561. return;
  562. }
  563. /* (3) if the prefix is equal to an active configured address range */
  564. if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
  565. {
  566. range = ospf6_route_lookup (&prefix, oa->range_table);
  567. if (range)
  568. {
  569. if (is_debug)
  570. zlog_debug ("Prefix is equal to address range, ignore");
  571. if (old)
  572. ospf6_route_remove (old, table);
  573. return;
  574. }
  575. }
  576. /* (4) if the routing table entry for the ABR does not exist */
  577. ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
  578. abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
  579. if (abr_entry == NULL || abr_entry->path.area_id != oa->area_id ||
  580. CHECK_FLAG (abr_entry->flag, OSPF6_ROUTE_REMOVE) ||
  581. ! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B))
  582. {
  583. if (is_debug)
  584. zlog_debug ("ABR router entry does not exist, ignore");
  585. if (old)
  586. ospf6_route_remove (old, table);
  587. return;
  588. }
  589. /* Check import list */
  590. if (IMPORT_NAME (oa))
  591. {
  592. if (IMPORT_LIST (oa) == NULL)
  593. IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa));
  594. if (IMPORT_LIST (oa))
  595. if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY)
  596. {
  597. if (is_debug)
  598. zlog_debug ("Prefix was denied by import-list");
  599. if (old)
  600. ospf6_route_remove (old, table);
  601. return;
  602. }
  603. }
  604. /* Check input prefix-list */
  605. if (PREFIX_NAME_IN (oa))
  606. {
  607. if (PREFIX_LIST_IN (oa) == NULL)
  608. PREFIX_LIST_IN (oa) = prefix_list_lookup (AFI_IP6, PREFIX_NAME_IN (oa));
  609. if (PREFIX_LIST_IN (oa))
  610. if (prefix_list_apply (PREFIX_LIST_IN (oa), &prefix) != PREFIX_PERMIT)
  611. {
  612. if (is_debug)
  613. zlog_debug ("Prefix was denied by prefix-list");
  614. if (old)
  615. ospf6_route_remove (old, table);
  616. return;
  617. }
  618. }
  619. /* (5),(6),(7) the path preference is handled by the sorting
  620. in the routing table. Always install the path by substituting
  621. old route (if any). */
  622. if (old)
  623. route = ospf6_route_copy (old);
  624. else
  625. route = ospf6_route_create ();
  626. route->type = type;
  627. route->prefix = prefix;
  628. route->path.origin.type = lsa->header->type;
  629. route->path.origin.id = lsa->header->id;
  630. route->path.origin.adv_router = lsa->header->adv_router;
  631. route->path.router_bits = router_bits;
  632. route->path.options[0] = options[0];
  633. route->path.options[1] = options[1];
  634. route->path.options[2] = options[2];
  635. route->path.prefix_options = prefix_options;
  636. route->path.area_id = oa->area_id;
  637. route->path.type = OSPF6_PATH_TYPE_INTER;
  638. route->path.cost = abr_entry->path.cost + cost;
  639. for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
  640. route->nexthop[i] = abr_entry->nexthop[i];
  641. if (is_debug)
  642. zlog_debug ("Install route: %s", buf);
  643. ospf6_route_add (route, table);
  644. }
  645. void
  646. ospf6_abr_examin_brouter (u_int32_t router_id)
  647. {
  648. struct ospf6_lsa *lsa;
  649. struct ospf6_area *oa;
  650. struct listnode *node, *nnode;
  651. u_int16_t type;
  652. for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
  653. {
  654. type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  655. for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
  656. lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
  657. ospf6_abr_examin_summary (lsa, oa);
  658. type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  659. for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa;
  660. lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
  661. ospf6_abr_examin_summary (lsa, oa);
  662. }
  663. }
  664. void
  665. ospf6_abr_reimport (struct ospf6_area *oa)
  666. {
  667. struct ospf6_lsa *lsa;
  668. u_int16_t type;
  669. type = htons (OSPF6_LSTYPE_INTER_ROUTER);
  670. for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  671. lsa = ospf6_lsdb_type_next (type, lsa))
  672. ospf6_abr_examin_summary (lsa, oa);
  673. type = htons (OSPF6_LSTYPE_INTER_PREFIX);
  674. for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  675. lsa = ospf6_lsdb_type_next (type, lsa))
  676. ospf6_abr_examin_summary (lsa, oa);
  677. }
  678. /* Display functions */
  679. static int
  680. ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  681. {
  682. struct ospf6_inter_prefix_lsa *prefix_lsa;
  683. struct in6_addr in6;
  684. char buf[64];
  685. prefix_lsa = (struct ospf6_inter_prefix_lsa *)
  686. OSPF6_LSA_HEADER_END (lsa->header);
  687. vty_out (vty, " Metric: %lu%s",
  688. (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa), VNL);
  689. ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options,
  690. buf, sizeof (buf));
  691. vty_out (vty, " Prefix Options: %s%s", buf, VNL);
  692. ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
  693. inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
  694. vty_out (vty, " Prefix: %s/%d%s", buf,
  695. prefix_lsa->prefix.prefix_length, VNL);
  696. return 0;
  697. }
  698. static int
  699. ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  700. {
  701. struct ospf6_inter_router_lsa *router_lsa;
  702. char buf[64];
  703. router_lsa = (struct ospf6_inter_router_lsa *)
  704. OSPF6_LSA_HEADER_END (lsa->header);
  705. ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf));
  706. vty_out (vty, " Options: %s%s", buf, VNL);
  707. vty_out (vty, " Metric: %lu%s",
  708. (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
  709. inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
  710. vty_out (vty, " Destination Router ID: %s%s", buf, VNL);
  711. return 0;
  712. }
  713. /* Debug commands */
  714. DEFUN (debug_ospf6_abr,
  715. debug_ospf6_abr_cmd,
  716. "debug ospf6 abr",
  717. DEBUG_STR
  718. OSPF6_STR
  719. "Debug OSPFv3 ABR function\n"
  720. )
  721. {
  722. OSPF6_DEBUG_ABR_ON ();
  723. return CMD_SUCCESS;
  724. }
  725. DEFUN (no_debug_ospf6_abr,
  726. no_debug_ospf6_abr_cmd,
  727. "no debug ospf6 abr",
  728. NO_STR
  729. DEBUG_STR
  730. OSPF6_STR
  731. "Debug OSPFv3 ABR function\n"
  732. )
  733. {
  734. OSPF6_DEBUG_ABR_OFF ();
  735. return CMD_SUCCESS;
  736. }
  737. int
  738. config_write_ospf6_debug_abr (struct vty *vty)
  739. {
  740. if (IS_OSPF6_DEBUG_ABR)
  741. vty_out (vty, "debug ospf6 abr%s", VNL);
  742. return 0;
  743. }
  744. void
  745. install_element_ospf6_debug_abr (void)
  746. {
  747. install_element (ENABLE_NODE, &debug_ospf6_abr_cmd);
  748. install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd);
  749. install_element (CONFIG_NODE, &debug_ospf6_abr_cmd);
  750. install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
  751. }
  752. struct ospf6_lsa_handler inter_prefix_handler =
  753. {
  754. OSPF6_LSTYPE_INTER_PREFIX,
  755. "Inter-Prefix",
  756. ospf6_inter_area_prefix_lsa_show
  757. };
  758. struct ospf6_lsa_handler inter_router_handler =
  759. {
  760. OSPF6_LSTYPE_INTER_ROUTER,
  761. "Inter-Router",
  762. ospf6_inter_area_router_lsa_show
  763. };
  764. void
  765. ospf6_abr_init (void)
  766. {
  767. ospf6_install_lsa_handler (&inter_prefix_handler);
  768. ospf6_install_lsa_handler (&inter_router_handler);
  769. }