ospf6_intra.c 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  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 "linklist.h"
  24. #include "thread.h"
  25. #include "memory.h"
  26. #include "if.h"
  27. #include "prefix.h"
  28. #include "table.h"
  29. #include "vty.h"
  30. #include "command.h"
  31. #include "ospf6_proto.h"
  32. #include "ospf6_message.h"
  33. #include "ospf6_route.h"
  34. #include "ospf6_lsa.h"
  35. #include "ospf6_lsdb.h"
  36. #include "ospf6_top.h"
  37. #include "ospf6_area.h"
  38. #include "ospf6_interface.h"
  39. #include "ospf6_neighbor.h"
  40. #include "ospf6_intra.h"
  41. #include "ospf6_asbr.h"
  42. #include "ospf6_abr.h"
  43. #include "ospf6_flood.h"
  44. #include "ospf6d.h"
  45. unsigned char conf_debug_ospf6_brouter = 0;
  46. u_int32_t conf_debug_ospf6_brouter_specific_router_id;
  47. u_int32_t conf_debug_ospf6_brouter_specific_area_id;
  48. /******************************/
  49. /* RFC2740 3.4.3.1 Router-LSA */
  50. /******************************/
  51. static int
  52. ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  53. {
  54. char *start, *end, *current;
  55. char buf[32], name[32], bits[16], options[32];
  56. struct ospf6_router_lsa *router_lsa;
  57. struct ospf6_router_lsdesc *lsdesc;
  58. router_lsa = (struct ospf6_router_lsa *)
  59. ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
  60. ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
  61. ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
  62. vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL);
  63. start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
  64. end = (char *) lsa->header + ntohs (lsa->header->length);
  65. for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end;
  66. current += sizeof (struct ospf6_router_lsdesc))
  67. {
  68. lsdesc = (struct ospf6_router_lsdesc *) current;
  69. if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT)
  70. snprintf (name, sizeof (name), "Point-To-Point");
  71. else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK)
  72. snprintf (name, sizeof (name), "Transit-Network");
  73. else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK)
  74. snprintf (name, sizeof (name), "Stub-Network");
  75. else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK)
  76. snprintf (name, sizeof (name), "Virtual-Link");
  77. else
  78. snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
  79. vty_out (vty, " Type: %s Metric: %d%s",
  80. name, ntohs (lsdesc->metric), VNL);
  81. vty_out (vty, " Interface ID: %s%s",
  82. inet_ntop (AF_INET, &lsdesc->interface_id,
  83. buf, sizeof (buf)), VNL);
  84. vty_out (vty, " Neighbor Interface ID: %s%s",
  85. inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
  86. buf, sizeof (buf)), VNL);
  87. vty_out (vty, " Neighbor Router ID: %s%s",
  88. inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
  89. buf, sizeof (buf)), VNL);
  90. }
  91. return 0;
  92. }
  93. int
  94. ospf6_router_lsa_originate (struct thread *thread)
  95. {
  96. struct ospf6_area *oa;
  97. char buffer [OSPF6_MAX_LSASIZE];
  98. struct ospf6_lsa_header *lsa_header;
  99. struct ospf6_lsa *lsa;
  100. u_int32_t link_state_id = 0;
  101. struct listnode *node, *nnode;
  102. struct listnode *j;
  103. struct ospf6_interface *oi;
  104. struct ospf6_neighbor *on, *drouter = NULL;
  105. struct ospf6_router_lsa *router_lsa;
  106. struct ospf6_router_lsdesc *lsdesc;
  107. u_int16_t type;
  108. u_int32_t router;
  109. int count;
  110. oa = (struct ospf6_area *) THREAD_ARG (thread);
  111. oa->thread_router_lsa = NULL;
  112. if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
  113. zlog_debug ("Originate Router-LSA for Area %s", oa->name);
  114. memset (buffer, 0, sizeof (buffer));
  115. lsa_header = (struct ospf6_lsa_header *) buffer;
  116. router_lsa = (struct ospf6_router_lsa *)
  117. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  118. OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
  119. OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
  120. OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
  121. OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
  122. OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
  123. OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
  124. if (ospf6_is_router_abr (ospf6))
  125. SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
  126. else
  127. UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
  128. if (ospf6_asbr_is_asbr (ospf6))
  129. SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
  130. else
  131. UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
  132. UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
  133. UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
  134. /* describe links for each interfaces */
  135. lsdesc = (struct ospf6_router_lsdesc *)
  136. ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
  137. for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
  138. {
  139. /* Interfaces in state Down or Loopback are not described */
  140. if (oi->state == OSPF6_INTERFACE_DOWN ||
  141. oi->state == OSPF6_INTERFACE_LOOPBACK)
  142. continue;
  143. /* Nor are interfaces without any full adjacencies described */
  144. count = 0;
  145. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
  146. if (on->state == OSPF6_NEIGHBOR_FULL)
  147. count++;
  148. if (count == 0)
  149. continue;
  150. /* Multiple Router-LSA instance according to size limit setting */
  151. if ( (oa->router_lsa_size_limit != 0)
  152. && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) -
  153. /* XXX warning: comparison between signed and unsigned */
  154. (caddr_t) buffer > oa->router_lsa_size_limit))
  155. {
  156. if ((caddr_t) lsdesc == (caddr_t) router_lsa +
  157. sizeof (struct ospf6_router_lsa))
  158. {
  159. if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
  160. zlog_debug ("Size limit setting for Router-LSA too short");
  161. return 0;
  162. }
  163. /* Fill LSA Header */
  164. lsa_header->age = 0;
  165. lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
  166. lsa_header->id = htonl (link_state_id);
  167. lsa_header->adv_router = oa->ospf6->router_id;
  168. lsa_header->seqnum =
  169. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  170. lsa_header->adv_router, oa->lsdb);
  171. lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
  172. /* LSA checksum */
  173. ospf6_lsa_checksum (lsa_header);
  174. /* create LSA */
  175. lsa = ospf6_lsa_create (lsa_header);
  176. /* Originate */
  177. ospf6_lsa_originate_area (lsa, oa);
  178. /* Reset setting for consecutive origination */
  179. memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
  180. 0, (caddr_t) lsdesc - (caddr_t) router_lsa);
  181. lsdesc = (struct ospf6_router_lsdesc *)
  182. ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
  183. link_state_id ++;
  184. }
  185. /* Point-to-Point interfaces */
  186. if (if_is_pointopoint (oi->interface))
  187. {
  188. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
  189. {
  190. if (on->state != OSPF6_NEIGHBOR_FULL)
  191. continue;
  192. lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
  193. lsdesc->metric = htons (oi->cost);
  194. lsdesc->interface_id = htonl (oi->interface->ifindex);
  195. lsdesc->neighbor_interface_id = htonl (on->ifindex);
  196. lsdesc->neighbor_router_id = on->router_id;
  197. lsdesc++;
  198. }
  199. }
  200. /* Broadcast and NBMA interfaces */
  201. if (if_is_broadcast (oi->interface))
  202. {
  203. /* If this router is not DR,
  204. and If this router not fully adjacent with DR,
  205. this interface is not transit yet: ignore. */
  206. if (oi->state != OSPF6_INTERFACE_DR)
  207. {
  208. drouter = ospf6_neighbor_lookup (oi->drouter, oi);
  209. if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
  210. continue;
  211. }
  212. lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
  213. lsdesc->metric = htons (oi->cost);
  214. lsdesc->interface_id = htonl (oi->interface->ifindex);
  215. if (oi->state != OSPF6_INTERFACE_DR)
  216. {
  217. lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
  218. lsdesc->neighbor_router_id = drouter->router_id;
  219. }
  220. else
  221. {
  222. lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
  223. lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
  224. }
  225. lsdesc++;
  226. }
  227. /* Virtual links */
  228. /* xxx */
  229. /* Point-to-Multipoint interfaces */
  230. /* xxx */
  231. }
  232. if ((caddr_t) lsdesc != (caddr_t) router_lsa +
  233. sizeof (struct ospf6_router_lsa))
  234. {
  235. /* Fill LSA Header */
  236. lsa_header->age = 0;
  237. lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
  238. lsa_header->id = htonl (link_state_id);
  239. lsa_header->adv_router = oa->ospf6->router_id;
  240. lsa_header->seqnum =
  241. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  242. lsa_header->adv_router, oa->lsdb);
  243. lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
  244. /* LSA checksum */
  245. ospf6_lsa_checksum (lsa_header);
  246. /* create LSA */
  247. lsa = ospf6_lsa_create (lsa_header);
  248. /* Originate */
  249. ospf6_lsa_originate_area (lsa, oa);
  250. link_state_id ++;
  251. }
  252. else
  253. {
  254. if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
  255. zlog_debug ("Nothing to describe in Router-LSA, suppress");
  256. }
  257. /* Do premature-aging of rest, undesired Router-LSAs */
  258. type = ntohs (OSPF6_LSTYPE_ROUTER);
  259. router = oa->ospf6->router_id;
  260. for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
  261. lsa = ospf6_lsdb_type_router_next (type, router, lsa))
  262. {
  263. if (ntohl (lsa->header->id) < link_state_id)
  264. continue;
  265. ospf6_lsa_purge (lsa);
  266. }
  267. return 0;
  268. }
  269. /*******************************/
  270. /* RFC2740 3.4.3.2 Network-LSA */
  271. /*******************************/
  272. static int
  273. ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  274. {
  275. char *start, *end, *current;
  276. struct ospf6_network_lsa *network_lsa;
  277. struct ospf6_network_lsdesc *lsdesc;
  278. char buf[128], options[32];
  279. network_lsa = (struct ospf6_network_lsa *)
  280. ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
  281. ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
  282. vty_out (vty, " Options: %s%s", options, VNL);
  283. start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
  284. end = (char *) lsa->header + ntohs (lsa->header->length);
  285. for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
  286. current += sizeof (struct ospf6_network_lsdesc))
  287. {
  288. lsdesc = (struct ospf6_network_lsdesc *) current;
  289. inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
  290. vty_out (vty, " Attached Router: %s%s", buf, VNL);
  291. }
  292. return 0;
  293. }
  294. int
  295. ospf6_network_lsa_originate (struct thread *thread)
  296. {
  297. struct ospf6_interface *oi;
  298. char buffer [OSPF6_MAX_LSASIZE];
  299. struct ospf6_lsa_header *lsa_header;
  300. int count;
  301. struct ospf6_lsa *old, *lsa;
  302. struct ospf6_network_lsa *network_lsa;
  303. struct ospf6_network_lsdesc *lsdesc;
  304. struct ospf6_neighbor *on;
  305. struct ospf6_link_lsa *link_lsa;
  306. struct listnode *i;
  307. u_int16_t type;
  308. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  309. oi->thread_network_lsa = NULL;
  310. /* The interface must be enabled until here. A Network-LSA of a
  311. disabled interface (but was once enabled) should be flushed
  312. by ospf6_lsa_refresh (), and does not come here. */
  313. assert (oi->area);
  314. old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
  315. htonl (oi->interface->ifindex),
  316. oi->area->ospf6->router_id, oi->area->lsdb);
  317. /* Do not originate Network-LSA if not DR */
  318. if (oi->state != OSPF6_INTERFACE_DR)
  319. {
  320. if (old)
  321. ospf6_lsa_purge (old);
  322. return 0;
  323. }
  324. if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
  325. zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
  326. /* If none of neighbor is adjacent to us */
  327. count = 0;
  328. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
  329. if (on->state == OSPF6_NEIGHBOR_FULL)
  330. count++;
  331. if (count == 0)
  332. {
  333. if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
  334. zlog_debug ("Interface stub, ignore");
  335. if (old)
  336. ospf6_lsa_purge (old);
  337. return 0;
  338. }
  339. /* prepare buffer */
  340. memset (buffer, 0, sizeof (buffer));
  341. lsa_header = (struct ospf6_lsa_header *) buffer;
  342. network_lsa = (struct ospf6_network_lsa *)
  343. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  344. /* Collect the interface's Link-LSAs to describe
  345. network's optional capabilities */
  346. type = htons (OSPF6_LSTYPE_LINK);
  347. for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
  348. lsa = ospf6_lsdb_type_next (type, lsa))
  349. {
  350. link_lsa = (struct ospf6_link_lsa *)
  351. ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
  352. network_lsa->options[0] |= link_lsa->options[0];
  353. network_lsa->options[1] |= link_lsa->options[1];
  354. network_lsa->options[2] |= link_lsa->options[2];
  355. }
  356. lsdesc = (struct ospf6_network_lsdesc *)
  357. ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
  358. /* set Link Description to the router itself */
  359. lsdesc->router_id = oi->area->ospf6->router_id;
  360. lsdesc++;
  361. /* Walk through the neighbors */
  362. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
  363. {
  364. if (on->state != OSPF6_NEIGHBOR_FULL)
  365. continue;
  366. /* set this neighbor's Router-ID to LSA */
  367. lsdesc->router_id = on->router_id;
  368. lsdesc++;
  369. }
  370. /* Fill LSA Header */
  371. lsa_header->age = 0;
  372. lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
  373. lsa_header->id = htonl (oi->interface->ifindex);
  374. lsa_header->adv_router = oi->area->ospf6->router_id;
  375. lsa_header->seqnum =
  376. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  377. lsa_header->adv_router, oi->area->lsdb);
  378. lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
  379. /* LSA checksum */
  380. ospf6_lsa_checksum (lsa_header);
  381. /* create LSA */
  382. lsa = ospf6_lsa_create (lsa_header);
  383. /* Originate */
  384. ospf6_lsa_originate_area (lsa, oi->area);
  385. return 0;
  386. }
  387. /****************************/
  388. /* RFC2740 3.4.3.6 Link-LSA */
  389. /****************************/
  390. static int
  391. ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  392. {
  393. char *start, *end, *current;
  394. struct ospf6_link_lsa *link_lsa;
  395. int prefixnum;
  396. char buf[128], options[32];
  397. struct ospf6_prefix *prefix;
  398. const char *p, *mc, *la, *nu;
  399. struct in6_addr in6;
  400. link_lsa = (struct ospf6_link_lsa *)
  401. ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
  402. ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
  403. inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
  404. prefixnum = ntohl (link_lsa->prefix_num);
  405. vty_out (vty, " Priority: %d Options: %s%s",
  406. link_lsa->priority, options, VNL);
  407. vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
  408. vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
  409. start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
  410. end = (char *) lsa->header + ntohs (lsa->header->length);
  411. for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
  412. {
  413. prefix = (struct ospf6_prefix *) current;
  414. if (prefix->prefix_length == 0 ||
  415. current + OSPF6_PREFIX_SIZE (prefix) > end)
  416. break;
  417. p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
  418. "P" : "--");
  419. mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
  420. "MC" : "--");
  421. la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
  422. "LA" : "--");
  423. nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
  424. "NU" : "--");
  425. vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
  426. p, mc, la, nu, VNL);
  427. memset (&in6, 0, sizeof (in6));
  428. memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
  429. OSPF6_PREFIX_SPACE (prefix->prefix_length));
  430. inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
  431. vty_out (vty, " Prefix: %s/%d%s",
  432. buf, prefix->prefix_length, VNL);
  433. }
  434. return 0;
  435. }
  436. int
  437. ospf6_link_lsa_originate (struct thread *thread)
  438. {
  439. struct ospf6_interface *oi;
  440. char buffer[OSPF6_MAX_LSASIZE];
  441. struct ospf6_lsa_header *lsa_header;
  442. struct ospf6_lsa *old, *lsa;
  443. struct ospf6_link_lsa *link_lsa;
  444. struct ospf6_route *route;
  445. struct ospf6_prefix *op;
  446. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  447. oi->thread_link_lsa = NULL;
  448. assert (oi->area);
  449. /* find previous LSA */
  450. old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
  451. htonl (oi->interface->ifindex),
  452. oi->area->ospf6->router_id, oi->lsdb);
  453. if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
  454. {
  455. if (old)
  456. ospf6_lsa_purge (old);
  457. return 0;
  458. }
  459. if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
  460. zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
  461. /* can't make Link-LSA if linklocal address not set */
  462. if (oi->linklocal_addr == NULL)
  463. {
  464. if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
  465. zlog_debug ("No Linklocal address on %s, defer originating",
  466. oi->interface->name);
  467. if (old)
  468. ospf6_lsa_purge (old);
  469. return 0;
  470. }
  471. /* prepare buffer */
  472. memset (buffer, 0, sizeof (buffer));
  473. lsa_header = (struct ospf6_lsa_header *) buffer;
  474. link_lsa = (struct ospf6_link_lsa *)
  475. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  476. /* Fill Link-LSA */
  477. link_lsa->priority = oi->priority;
  478. memcpy (link_lsa->options, oi->area->options, 3);
  479. memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
  480. sizeof (struct in6_addr));
  481. link_lsa->prefix_num = htonl (oi->route_connected->count);
  482. op = (struct ospf6_prefix *)
  483. ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
  484. /* connected prefix to advertise */
  485. for (route = ospf6_route_head (oi->route_connected); route;
  486. route = ospf6_route_next (route))
  487. {
  488. op->prefix_length = route->prefix.prefixlen;
  489. op->prefix_options = route->path.prefix_options;
  490. op->prefix_metric = htons (0);
  491. memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
  492. OSPF6_PREFIX_SPACE (op->prefix_length));
  493. op = OSPF6_PREFIX_NEXT (op);
  494. }
  495. /* Fill LSA Header */
  496. lsa_header->age = 0;
  497. lsa_header->type = htons (OSPF6_LSTYPE_LINK);
  498. lsa_header->id = htonl (oi->interface->ifindex);
  499. lsa_header->adv_router = oi->area->ospf6->router_id;
  500. lsa_header->seqnum =
  501. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  502. lsa_header->adv_router, oi->lsdb);
  503. lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
  504. /* LSA checksum */
  505. ospf6_lsa_checksum (lsa_header);
  506. /* create LSA */
  507. lsa = ospf6_lsa_create (lsa_header);
  508. /* Originate */
  509. ospf6_lsa_originate_interface (lsa, oi);
  510. return 0;
  511. }
  512. /*****************************************/
  513. /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
  514. /*****************************************/
  515. static int
  516. ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  517. {
  518. char *start, *end, *current;
  519. struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  520. int prefixnum;
  521. char buf[128];
  522. struct ospf6_prefix *prefix;
  523. char id[16], adv_router[16];
  524. const char *p, *mc, *la, *nu;
  525. struct in6_addr in6;
  526. intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
  527. ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
  528. prefixnum = ntohs (intra_prefix_lsa->prefix_num);
  529. vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
  530. inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
  531. inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
  532. adv_router, sizeof (adv_router));
  533. vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
  534. ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
  535. VNL);
  536. start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
  537. end = (char *) lsa->header + ntohs (lsa->header->length);
  538. for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
  539. {
  540. prefix = (struct ospf6_prefix *) current;
  541. if (prefix->prefix_length == 0 ||
  542. current + OSPF6_PREFIX_SIZE (prefix) > end)
  543. break;
  544. p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
  545. "P" : "--");
  546. mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
  547. "MC" : "--");
  548. la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
  549. "LA" : "--");
  550. nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
  551. "NU" : "--");
  552. vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
  553. p, mc, la, nu, VNL);
  554. memset (&in6, 0, sizeof (in6));
  555. memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
  556. OSPF6_PREFIX_SPACE (prefix->prefix_length));
  557. inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
  558. vty_out (vty, " Prefix: %s/%d%s",
  559. buf, prefix->prefix_length, VNL);
  560. }
  561. return 0;
  562. }
  563. int
  564. ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
  565. {
  566. struct ospf6_area *oa;
  567. char buffer[OSPF6_MAX_LSASIZE];
  568. struct ospf6_lsa_header *lsa_header;
  569. struct ospf6_lsa *old, *lsa;
  570. struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  571. struct ospf6_interface *oi;
  572. struct ospf6_neighbor *on;
  573. struct ospf6_route *route;
  574. struct ospf6_prefix *op;
  575. struct listnode *i, *j;
  576. int full_count = 0;
  577. unsigned short prefix_num = 0;
  578. char buf[BUFSIZ];
  579. struct ospf6_route_table *route_advertise;
  580. oa = (struct ospf6_area *) THREAD_ARG (thread);
  581. oa->thread_intra_prefix_lsa = NULL;
  582. /* find previous LSA */
  583. old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
  584. htonl (0), oa->ospf6->router_id, oa->lsdb);
  585. if (! IS_AREA_ENABLED (oa))
  586. {
  587. if (old)
  588. ospf6_lsa_purge (old);
  589. return 0;
  590. }
  591. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  592. zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
  593. oa->name);
  594. /* prepare buffer */
  595. memset (buffer, 0, sizeof (buffer));
  596. lsa_header = (struct ospf6_lsa_header *) buffer;
  597. intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
  598. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  599. /* Fill Intra-Area-Prefix-LSA */
  600. intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
  601. intra_prefix_lsa->ref_id = htonl (0);
  602. intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
  603. route_advertise = ospf6_route_table_create (0, 0);
  604. for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
  605. {
  606. if (oi->state == OSPF6_INTERFACE_DOWN)
  607. {
  608. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  609. zlog_debug (" Interface %s is down, ignore", oi->interface->name);
  610. continue;
  611. }
  612. full_count = 0;
  613. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
  614. if (on->state == OSPF6_NEIGHBOR_FULL)
  615. full_count++;
  616. if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
  617. oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
  618. full_count != 0)
  619. {
  620. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  621. zlog_debug (" Interface %s is not stub, ignore",
  622. oi->interface->name);
  623. continue;
  624. }
  625. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  626. zlog_debug (" Interface %s:", oi->interface->name);
  627. /* connected prefix to advertise */
  628. for (route = ospf6_route_head (oi->route_connected); route;
  629. route = ospf6_route_best_next (route))
  630. {
  631. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  632. {
  633. prefix2str (&route->prefix, buf, sizeof (buf));
  634. zlog_debug (" include %s", buf);
  635. }
  636. ospf6_route_add (ospf6_route_copy (route), route_advertise);
  637. }
  638. }
  639. if (route_advertise->count == 0)
  640. {
  641. if (old)
  642. ospf6_lsa_purge (old);
  643. ospf6_route_table_delete (route_advertise);
  644. return 0;
  645. }
  646. /* put prefixes to advertise */
  647. prefix_num = 0;
  648. op = (struct ospf6_prefix *)
  649. ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
  650. for (route = ospf6_route_head (route_advertise); route;
  651. route = ospf6_route_best_next (route))
  652. {
  653. op->prefix_length = route->prefix.prefixlen;
  654. op->prefix_options = route->path.prefix_options;
  655. op->prefix_metric = htons (route->path.cost);
  656. memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
  657. OSPF6_PREFIX_SPACE (op->prefix_length));
  658. op = OSPF6_PREFIX_NEXT (op);
  659. prefix_num++;
  660. }
  661. ospf6_route_table_delete (route_advertise);
  662. if (prefix_num == 0)
  663. {
  664. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  665. zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
  666. return 0;
  667. }
  668. intra_prefix_lsa->prefix_num = htons (prefix_num);
  669. /* Fill LSA Header */
  670. lsa_header->age = 0;
  671. lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  672. lsa_header->id = htonl (0);
  673. lsa_header->adv_router = oa->ospf6->router_id;
  674. lsa_header->seqnum =
  675. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  676. lsa_header->adv_router, oa->lsdb);
  677. lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
  678. /* LSA checksum */
  679. ospf6_lsa_checksum (lsa_header);
  680. /* create LSA */
  681. lsa = ospf6_lsa_create (lsa_header);
  682. /* Originate */
  683. ospf6_lsa_originate_area (lsa, oa);
  684. return 0;
  685. }
  686. int
  687. ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
  688. {
  689. struct ospf6_interface *oi;
  690. char buffer[OSPF6_MAX_LSASIZE];
  691. struct ospf6_lsa_header *lsa_header;
  692. struct ospf6_lsa *old, *lsa;
  693. struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  694. struct ospf6_neighbor *on;
  695. struct ospf6_route *route;
  696. struct ospf6_prefix *op;
  697. struct listnode *i;
  698. int full_count = 0;
  699. unsigned short prefix_num = 0;
  700. struct ospf6_route_table *route_advertise;
  701. struct ospf6_link_lsa *link_lsa;
  702. char *start, *end, *current;
  703. u_int16_t type;
  704. char buf[BUFSIZ];
  705. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  706. oi->thread_intra_prefix_lsa = NULL;
  707. assert (oi->area);
  708. /* find previous LSA */
  709. old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
  710. htonl (oi->interface->ifindex),
  711. oi->area->ospf6->router_id, oi->area->lsdb);
  712. if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
  713. {
  714. if (old)
  715. ospf6_lsa_purge (old);
  716. return 0;
  717. }
  718. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  719. zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
  720. oi->interface->name);
  721. /* prepare buffer */
  722. memset (buffer, 0, sizeof (buffer));
  723. lsa_header = (struct ospf6_lsa_header *) buffer;
  724. intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
  725. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  726. /* Fill Intra-Area-Prefix-LSA */
  727. intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
  728. intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
  729. intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
  730. if (oi->state != OSPF6_INTERFACE_DR)
  731. {
  732. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  733. zlog_debug (" Interface is not DR");
  734. if (old)
  735. ospf6_lsa_purge (old);
  736. return 0;
  737. }
  738. full_count = 0;
  739. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
  740. if (on->state == OSPF6_NEIGHBOR_FULL)
  741. full_count++;
  742. if (full_count == 0)
  743. {
  744. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  745. zlog_debug (" Interface is stub");
  746. if (old)
  747. ospf6_lsa_purge (old);
  748. return 0;
  749. }
  750. /* connected prefix to advertise */
  751. route_advertise = ospf6_route_table_create (0, 0);
  752. type = ntohs (OSPF6_LSTYPE_LINK);
  753. for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
  754. lsa = ospf6_lsdb_type_next (type, lsa))
  755. {
  756. if (OSPF6_LSA_IS_MAXAGE (lsa))
  757. continue;
  758. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  759. zlog_debug (" include prefix from %s", lsa->name);
  760. if (lsa->header->adv_router != oi->area->ospf6->router_id)
  761. {
  762. on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
  763. if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
  764. {
  765. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  766. zlog_debug (" Neighbor not found or not Full, ignore");
  767. continue;
  768. }
  769. }
  770. link_lsa = (struct ospf6_link_lsa *)
  771. ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
  772. prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
  773. start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
  774. end = (char *) lsa->header + ntohs (lsa->header->length);
  775. for (current = start; current < end && prefix_num;
  776. current += OSPF6_PREFIX_SIZE (op))
  777. {
  778. op = (struct ospf6_prefix *) current;
  779. if (op->prefix_length == 0 ||
  780. current + OSPF6_PREFIX_SIZE (op) > end)
  781. break;
  782. route = ospf6_route_create ();
  783. route->type = OSPF6_DEST_TYPE_NETWORK;
  784. route->prefix.family = AF_INET6;
  785. route->prefix.prefixlen = op->prefix_length;
  786. memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
  787. memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
  788. OSPF6_PREFIX_SPACE (op->prefix_length));
  789. route->path.origin.type = lsa->header->type;
  790. route->path.origin.id = lsa->header->id;
  791. route->path.origin.adv_router = lsa->header->adv_router;
  792. route->path.options[0] = link_lsa->options[0];
  793. route->path.options[1] = link_lsa->options[1];
  794. route->path.options[2] = link_lsa->options[2];
  795. route->path.prefix_options = op->prefix_options;
  796. route->path.area_id = oi->area->area_id;
  797. route->path.type = OSPF6_PATH_TYPE_INTRA;
  798. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  799. {
  800. prefix2str (&route->prefix, buf, sizeof (buf));
  801. zlog_debug (" include %s", buf);
  802. }
  803. ospf6_route_add (route, route_advertise);
  804. prefix_num--;
  805. }
  806. if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  807. zlog_debug ("Trailing garbage in %s", lsa->name);
  808. }
  809. op = (struct ospf6_prefix *)
  810. ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
  811. prefix_num = 0;
  812. for (route = ospf6_route_head (route_advertise); route;
  813. route = ospf6_route_best_next (route))
  814. {
  815. op->prefix_length = route->prefix.prefixlen;
  816. op->prefix_options = route->path.prefix_options;
  817. op->prefix_metric = htons (0);
  818. memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
  819. OSPF6_PREFIX_SPACE (op->prefix_length));
  820. op = OSPF6_PREFIX_NEXT (op);
  821. prefix_num++;
  822. }
  823. ospf6_route_table_delete (route_advertise);
  824. if (prefix_num == 0)
  825. {
  826. if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
  827. zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
  828. return 0;
  829. }
  830. intra_prefix_lsa->prefix_num = htons (prefix_num);
  831. /* Fill LSA Header */
  832. lsa_header->age = 0;
  833. lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  834. lsa_header->id = htonl (oi->interface->ifindex);
  835. lsa_header->adv_router = oi->area->ospf6->router_id;
  836. lsa_header->seqnum =
  837. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  838. lsa_header->adv_router, oi->area->lsdb);
  839. lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
  840. /* LSA checksum */
  841. ospf6_lsa_checksum (lsa_header);
  842. /* create LSA */
  843. lsa = ospf6_lsa_create (lsa_header);
  844. /* Originate */
  845. ospf6_lsa_originate_area (lsa, oi->area);
  846. return 0;
  847. }
  848. void
  849. ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
  850. {
  851. struct ospf6_area *oa;
  852. struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  853. struct prefix ls_prefix;
  854. struct ospf6_route *route, *ls_entry;
  855. int i, prefix_num;
  856. struct ospf6_prefix *op;
  857. char *start, *current, *end;
  858. char buf[64];
  859. if (OSPF6_LSA_IS_MAXAGE (lsa))
  860. return;
  861. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  862. zlog_debug ("%s found", lsa->name);
  863. oa = OSPF6_AREA (lsa->lsdb->data);
  864. intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
  865. OSPF6_LSA_HEADER_END (lsa->header);
  866. if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
  867. ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
  868. htonl (0), &ls_prefix);
  869. else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
  870. ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
  871. intra_prefix_lsa->ref_id, &ls_prefix);
  872. else
  873. {
  874. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  875. zlog_debug ("Unknown reference LS-type: %#hx",
  876. ntohs (intra_prefix_lsa->ref_type));
  877. return;
  878. }
  879. ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
  880. if (ls_entry == NULL)
  881. {
  882. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  883. {
  884. ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
  885. zlog_debug ("LS entry does not exist: %s", buf);
  886. }
  887. return;
  888. }
  889. prefix_num = ntohs (intra_prefix_lsa->prefix_num);
  890. start = (caddr_t) intra_prefix_lsa +
  891. sizeof (struct ospf6_intra_prefix_lsa);
  892. end = OSPF6_LSA_END (lsa->header);
  893. for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
  894. {
  895. op = (struct ospf6_prefix *) current;
  896. if (prefix_num == 0)
  897. break;
  898. if (end < current + OSPF6_PREFIX_SIZE (op))
  899. break;
  900. route = ospf6_route_create ();
  901. memset (&route->prefix, 0, sizeof (struct prefix));
  902. route->prefix.family = AF_INET6;
  903. route->prefix.prefixlen = op->prefix_length;
  904. ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
  905. route->type = OSPF6_DEST_TYPE_NETWORK;
  906. route->path.origin.type = lsa->header->type;
  907. route->path.origin.id = lsa->header->id;
  908. route->path.origin.adv_router = lsa->header->adv_router;
  909. route->path.prefix_options = op->prefix_options;
  910. route->path.area_id = oa->area_id;
  911. route->path.type = OSPF6_PATH_TYPE_INTRA;
  912. route->path.metric_type = 1;
  913. route->path.cost = ls_entry->path.cost +
  914. ntohs (op->prefix_metric);
  915. for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) &&
  916. i < OSPF6_MULTI_PATH_LIMIT; i++)
  917. ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
  918. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  919. {
  920. prefix2str (&route->prefix, buf, sizeof (buf));
  921. zlog_debug (" add %s", buf);
  922. }
  923. ospf6_route_add (route, oa->route_table);
  924. prefix_num--;
  925. }
  926. if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  927. zlog_debug ("Trailing garbage ignored");
  928. }
  929. void
  930. ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
  931. {
  932. struct ospf6_area *oa;
  933. struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
  934. struct prefix prefix;
  935. struct ospf6_route *route;
  936. int prefix_num;
  937. struct ospf6_prefix *op;
  938. char *start, *current, *end;
  939. char buf[64];
  940. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  941. zlog_debug ("%s disappearing", lsa->name);
  942. oa = OSPF6_AREA (lsa->lsdb->data);
  943. intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
  944. OSPF6_LSA_HEADER_END (lsa->header);
  945. prefix_num = ntohs (intra_prefix_lsa->prefix_num);
  946. start = (caddr_t) intra_prefix_lsa +
  947. sizeof (struct ospf6_intra_prefix_lsa);
  948. end = OSPF6_LSA_END (lsa->header);
  949. for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
  950. {
  951. op = (struct ospf6_prefix *) current;
  952. if (prefix_num == 0)
  953. break;
  954. if (end < current + OSPF6_PREFIX_SIZE (op))
  955. break;
  956. prefix_num--;
  957. memset (&prefix, 0, sizeof (struct prefix));
  958. prefix.family = AF_INET6;
  959. prefix.prefixlen = op->prefix_length;
  960. ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
  961. route = ospf6_route_lookup (&prefix, oa->route_table);
  962. if (route == NULL)
  963. continue;
  964. for (ospf6_route_lock (route);
  965. route && ospf6_route_is_prefix (&prefix, route);
  966. route = ospf6_route_next (route))
  967. {
  968. if (route->type != OSPF6_DEST_TYPE_NETWORK)
  969. continue;
  970. if (route->path.area_id != oa->area_id)
  971. continue;
  972. if (route->path.type != OSPF6_PATH_TYPE_INTRA)
  973. continue;
  974. if (route->path.origin.type != lsa->header->type ||
  975. route->path.origin.id != lsa->header->id ||
  976. route->path.origin.adv_router != lsa->header->adv_router)
  977. continue;
  978. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  979. {
  980. prefix2str (&route->prefix, buf, sizeof (buf));
  981. zlog_debug ("remove %s", buf);
  982. }
  983. ospf6_route_remove (route, oa->route_table);
  984. }
  985. if (route)
  986. ospf6_route_unlock (route);
  987. }
  988. if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  989. zlog_debug ("Trailing garbage ignored");
  990. }
  991. void
  992. ospf6_intra_route_calculation (struct ospf6_area *oa)
  993. {
  994. struct ospf6_route *route;
  995. u_int16_t type;
  996. struct ospf6_lsa *lsa;
  997. void (*hook_add) (struct ospf6_route *) = NULL;
  998. void (*hook_remove) (struct ospf6_route *) = NULL;
  999. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  1000. zlog_debug ("Re-examin intra-routes for area %s", oa->name);
  1001. hook_add = oa->route_table->hook_add;
  1002. hook_remove = oa->route_table->hook_remove;
  1003. oa->route_table->hook_add = NULL;
  1004. oa->route_table->hook_remove = NULL;
  1005. for (route = ospf6_route_head (oa->route_table); route;
  1006. route = ospf6_route_next (route))
  1007. route->flag = OSPF6_ROUTE_REMOVE;
  1008. type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  1009. for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  1010. lsa = ospf6_lsdb_type_next (type, lsa))
  1011. ospf6_intra_prefix_lsa_add (lsa);
  1012. oa->route_table->hook_add = hook_add;
  1013. oa->route_table->hook_remove = hook_remove;
  1014. for (route = ospf6_route_head (oa->route_table); route;
  1015. route = ospf6_route_next (route))
  1016. {
  1017. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
  1018. CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
  1019. {
  1020. UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
  1021. UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
  1022. }
  1023. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
  1024. ospf6_route_remove (route, oa->route_table);
  1025. else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
  1026. CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
  1027. {
  1028. if (hook_add)
  1029. (*hook_add) (route);
  1030. }
  1031. route->flag = 0;
  1032. }
  1033. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  1034. zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
  1035. }
  1036. static void
  1037. ospf6_brouter_debug_print (struct ospf6_route *brouter)
  1038. {
  1039. u_int32_t brouter_id;
  1040. char brouter_name[16];
  1041. char area_name[16];
  1042. char destination[64];
  1043. char installed[16], changed[16];
  1044. struct timeval now, res;
  1045. char id[16], adv_router[16];
  1046. char capa[16], options[16];
  1047. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1048. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1049. inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
  1050. ospf6_linkstate_prefix2str (&brouter->prefix, destination,
  1051. sizeof (destination));
  1052. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  1053. timersub (&now, &brouter->installed, &res);
  1054. timerstring (&res, installed, sizeof (installed));
  1055. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  1056. timersub (&now, &brouter->changed, &res);
  1057. timerstring (&res, changed, sizeof (changed));
  1058. inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
  1059. inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
  1060. sizeof (adv_router));
  1061. ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
  1062. ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
  1063. zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
  1064. zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
  1065. brouter->prev, brouter, brouter->next, brouter->rnode);
  1066. zlog_info (" type: %d prefix: %s installed: %s changed: %s",
  1067. brouter->type, destination, installed, changed);
  1068. zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
  1069. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
  1070. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
  1071. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
  1072. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
  1073. zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
  1074. OSPF6_PATH_TYPE_NAME (brouter->path.type),
  1075. ospf6_lstype_name (brouter->path.origin.type),
  1076. id, adv_router);
  1077. zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
  1078. options, capa, brouter->path.metric_type,
  1079. brouter->path.cost, brouter->path.cost_e2);
  1080. }
  1081. void
  1082. ospf6_intra_brouter_calculation (struct ospf6_area *oa)
  1083. {
  1084. struct ospf6_route *brouter, *copy;
  1085. void (*hook_add) (struct ospf6_route *) = NULL;
  1086. void (*hook_remove) (struct ospf6_route *) = NULL;
  1087. u_int32_t brouter_id;
  1088. char brouter_name[16];
  1089. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1090. zlog_info ("border-router calculation for area %s", oa->name);
  1091. hook_add = oa->ospf6->brouter_table->hook_add;
  1092. hook_remove = oa->ospf6->brouter_table->hook_remove;
  1093. oa->ospf6->brouter_table->hook_add = NULL;
  1094. oa->ospf6->brouter_table->hook_remove = NULL;
  1095. /* withdraw the previous router entries for the area */
  1096. for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
  1097. brouter = ospf6_route_next (brouter))
  1098. {
  1099. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1100. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1101. if (brouter->path.area_id != oa->area_id)
  1102. continue;
  1103. brouter->flag = OSPF6_ROUTE_REMOVE;
  1104. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1105. IS_OSPF6_DEBUG_ROUTE (MEMORY))
  1106. {
  1107. zlog_info ("%p: mark as removing: area %s brouter %s",
  1108. brouter, oa->name, brouter_name);
  1109. ospf6_brouter_debug_print (brouter);
  1110. }
  1111. }
  1112. for (brouter = ospf6_route_head (oa->spf_table); brouter;
  1113. brouter = ospf6_route_next (brouter))
  1114. {
  1115. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1116. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1117. if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
  1118. continue;
  1119. if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
  1120. continue;
  1121. if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
  1122. ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
  1123. continue;
  1124. copy = ospf6_route_copy (brouter);
  1125. copy->type = OSPF6_DEST_TYPE_ROUTER;
  1126. copy->path.area_id = oa->area_id;
  1127. ospf6_route_add (copy, oa->ospf6->brouter_table);
  1128. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1129. IS_OSPF6_DEBUG_ROUTE (MEMORY))
  1130. {
  1131. zlog_info ("%p: transfer: area %s brouter %s",
  1132. brouter, oa->name, brouter_name);
  1133. ospf6_brouter_debug_print (brouter);
  1134. }
  1135. }
  1136. oa->ospf6->brouter_table->hook_add = hook_add;
  1137. oa->ospf6->brouter_table->hook_remove = hook_remove;
  1138. for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
  1139. brouter = ospf6_route_next (brouter))
  1140. {
  1141. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1142. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1143. if (brouter->path.area_id != oa->area_id)
  1144. continue;
  1145. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
  1146. continue;
  1147. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
  1148. CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
  1149. {
  1150. UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
  1151. UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
  1152. }
  1153. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
  1154. {
  1155. if (IS_OSPF6_DEBUG_BROUTER ||
  1156. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1157. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1158. zlog_info ("brouter %s disappears via area %s",
  1159. brouter_name, oa->name);
  1160. ospf6_route_remove (brouter, oa->ospf6->brouter_table);
  1161. }
  1162. else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
  1163. CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
  1164. {
  1165. if (IS_OSPF6_DEBUG_BROUTER ||
  1166. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1167. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1168. zlog_info ("brouter %s appears via area %s",
  1169. brouter_name, oa->name);
  1170. /* newly added */
  1171. if (hook_add)
  1172. (*hook_add) (brouter);
  1173. }
  1174. else
  1175. {
  1176. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1177. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1178. zlog_info ("brouter %s still exists via area %s",
  1179. brouter_name, oa->name);
  1180. }
  1181. brouter->flag = 0;
  1182. }
  1183. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1184. zlog_info ("border-router calculation for area %s: done", oa->name);
  1185. }
  1186. struct ospf6_lsa_handler router_handler =
  1187. {
  1188. OSPF6_LSTYPE_ROUTER,
  1189. "Router",
  1190. ospf6_router_lsa_show
  1191. };
  1192. struct ospf6_lsa_handler network_handler =
  1193. {
  1194. OSPF6_LSTYPE_NETWORK,
  1195. "Network",
  1196. ospf6_network_lsa_show
  1197. };
  1198. struct ospf6_lsa_handler link_handler =
  1199. {
  1200. OSPF6_LSTYPE_LINK,
  1201. "Link",
  1202. ospf6_link_lsa_show
  1203. };
  1204. struct ospf6_lsa_handler intra_prefix_handler =
  1205. {
  1206. OSPF6_LSTYPE_INTRA_PREFIX,
  1207. "Intra-Prefix",
  1208. ospf6_intra_prefix_lsa_show
  1209. };
  1210. void
  1211. ospf6_intra_init (void)
  1212. {
  1213. ospf6_install_lsa_handler (&router_handler);
  1214. ospf6_install_lsa_handler (&network_handler);
  1215. ospf6_install_lsa_handler (&link_handler);
  1216. ospf6_install_lsa_handler (&intra_prefix_handler);
  1217. }
  1218. DEFUN (debug_ospf6_brouter,
  1219. debug_ospf6_brouter_cmd,
  1220. "debug ospf6 border-routers",
  1221. DEBUG_STR
  1222. OSPF6_STR
  1223. "Debug border router\n"
  1224. )
  1225. {
  1226. OSPF6_DEBUG_BROUTER_ON ();
  1227. return CMD_SUCCESS;
  1228. }
  1229. DEFUN (no_debug_ospf6_brouter,
  1230. no_debug_ospf6_brouter_cmd,
  1231. "no debug ospf6 border-routers",
  1232. NO_STR
  1233. DEBUG_STR
  1234. OSPF6_STR
  1235. "Debug border router\n"
  1236. )
  1237. {
  1238. OSPF6_DEBUG_BROUTER_OFF ();
  1239. return CMD_SUCCESS;
  1240. }
  1241. DEFUN (debug_ospf6_brouter_router,
  1242. debug_ospf6_brouter_router_cmd,
  1243. "debug ospf6 border-routers router-id A.B.C.D",
  1244. DEBUG_STR
  1245. OSPF6_STR
  1246. "Debug border router\n"
  1247. "Debug specific border router\n"
  1248. "Specify border-router's router-id\n"
  1249. )
  1250. {
  1251. u_int32_t router_id;
  1252. inet_pton (AF_INET, argv[0], &router_id);
  1253. OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
  1254. return CMD_SUCCESS;
  1255. }
  1256. DEFUN (no_debug_ospf6_brouter_router,
  1257. no_debug_ospf6_brouter_router_cmd,
  1258. "no debug ospf6 border-routers router-id",
  1259. NO_STR
  1260. DEBUG_STR
  1261. OSPF6_STR
  1262. "Debug border router\n"
  1263. "Debug specific border router\n"
  1264. )
  1265. {
  1266. OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
  1267. return CMD_SUCCESS;
  1268. }
  1269. DEFUN (debug_ospf6_brouter_area,
  1270. debug_ospf6_brouter_area_cmd,
  1271. "debug ospf6 border-routers area-id A.B.C.D",
  1272. DEBUG_STR
  1273. OSPF6_STR
  1274. "Debug border router\n"
  1275. "Debug border routers in specific Area\n"
  1276. "Specify Area-ID\n"
  1277. )
  1278. {
  1279. u_int32_t area_id;
  1280. inet_pton (AF_INET, argv[0], &area_id);
  1281. OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
  1282. return CMD_SUCCESS;
  1283. }
  1284. DEFUN (no_debug_ospf6_brouter_area,
  1285. no_debug_ospf6_brouter_area_cmd,
  1286. "no debug ospf6 border-routers area-id",
  1287. NO_STR
  1288. DEBUG_STR
  1289. OSPF6_STR
  1290. "Debug border router\n"
  1291. "Debug border routers in specific Area\n"
  1292. )
  1293. {
  1294. OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
  1295. return CMD_SUCCESS;
  1296. }
  1297. int
  1298. config_write_ospf6_debug_brouter (struct vty *vty)
  1299. {
  1300. char buf[16];
  1301. if (IS_OSPF6_DEBUG_BROUTER)
  1302. vty_out (vty, "debug ospf6 border-routers%s", VNL);
  1303. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
  1304. {
  1305. inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
  1306. buf, sizeof (buf));
  1307. vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
  1308. }
  1309. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
  1310. {
  1311. inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
  1312. buf, sizeof (buf));
  1313. vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
  1314. }
  1315. return 0;
  1316. }
  1317. void
  1318. install_element_ospf6_debug_brouter (void)
  1319. {
  1320. install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
  1321. install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
  1322. install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
  1323. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
  1324. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
  1325. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
  1326. install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
  1327. install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
  1328. install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
  1329. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
  1330. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
  1331. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
  1332. }