ospf6_intra.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  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. }
  986. if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  987. zlog_debug ("Trailing garbage ignored");
  988. }
  989. void
  990. ospf6_intra_route_calculation (struct ospf6_area *oa)
  991. {
  992. struct ospf6_route *route;
  993. u_int16_t type;
  994. struct ospf6_lsa *lsa;
  995. void (*hook_add) (struct ospf6_route *) = NULL;
  996. void (*hook_remove) (struct ospf6_route *) = NULL;
  997. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  998. zlog_debug ("Re-examin intra-routes for area %s", oa->name);
  999. hook_add = oa->route_table->hook_add;
  1000. hook_remove = oa->route_table->hook_remove;
  1001. oa->route_table->hook_add = NULL;
  1002. oa->route_table->hook_remove = NULL;
  1003. for (route = ospf6_route_head (oa->route_table); route;
  1004. route = ospf6_route_next (route))
  1005. route->flag = OSPF6_ROUTE_REMOVE;
  1006. type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
  1007. for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
  1008. lsa = ospf6_lsdb_type_next (type, lsa))
  1009. ospf6_intra_prefix_lsa_add (lsa);
  1010. oa->route_table->hook_add = hook_add;
  1011. oa->route_table->hook_remove = hook_remove;
  1012. for (route = ospf6_route_head (oa->route_table); route;
  1013. route = ospf6_route_next (route))
  1014. {
  1015. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
  1016. CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
  1017. {
  1018. UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
  1019. UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
  1020. }
  1021. if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
  1022. ospf6_route_remove (route, oa->route_table);
  1023. else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
  1024. CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
  1025. {
  1026. if (hook_add)
  1027. (*hook_add) (route);
  1028. }
  1029. route->flag = 0;
  1030. }
  1031. if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
  1032. zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
  1033. }
  1034. static void
  1035. ospf6_brouter_debug_print (struct ospf6_route *brouter)
  1036. {
  1037. u_int32_t brouter_id;
  1038. char brouter_name[16];
  1039. char area_name[16];
  1040. char destination[64];
  1041. char installed[16], changed[16];
  1042. struct timeval now, res;
  1043. char id[16], adv_router[16];
  1044. char capa[16], options[16];
  1045. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1046. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1047. inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
  1048. ospf6_linkstate_prefix2str (&brouter->prefix, destination,
  1049. sizeof (destination));
  1050. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  1051. timersub (&now, &brouter->installed, &res);
  1052. timerstring (&res, installed, sizeof (installed));
  1053. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  1054. timersub (&now, &brouter->changed, &res);
  1055. timerstring (&res, changed, sizeof (changed));
  1056. inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
  1057. inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
  1058. sizeof (adv_router));
  1059. ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
  1060. ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
  1061. zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
  1062. zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
  1063. brouter->prev, brouter, brouter->next, brouter->rnode);
  1064. zlog_info (" type: %d prefix: %s installed: %s changed: %s",
  1065. brouter->type, destination, installed, changed);
  1066. zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
  1067. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
  1068. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
  1069. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
  1070. (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
  1071. zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
  1072. OSPF6_PATH_TYPE_NAME (brouter->path.type),
  1073. ospf6_lstype_name (brouter->path.origin.type),
  1074. id, adv_router);
  1075. zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
  1076. options, capa, brouter->path.metric_type,
  1077. brouter->path.cost, brouter->path.cost_e2);
  1078. }
  1079. void
  1080. ospf6_intra_brouter_calculation (struct ospf6_area *oa)
  1081. {
  1082. struct ospf6_route *brouter, *copy;
  1083. void (*hook_add) (struct ospf6_route *) = NULL;
  1084. void (*hook_remove) (struct ospf6_route *) = NULL;
  1085. u_int32_t brouter_id;
  1086. char brouter_name[16];
  1087. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1088. zlog_info ("border-router calculation for area %s", oa->name);
  1089. hook_add = oa->ospf6->brouter_table->hook_add;
  1090. hook_remove = oa->ospf6->brouter_table->hook_remove;
  1091. oa->ospf6->brouter_table->hook_add = NULL;
  1092. oa->ospf6->brouter_table->hook_remove = NULL;
  1093. /* withdraw the previous router entries for the area */
  1094. for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
  1095. brouter = ospf6_route_next (brouter))
  1096. {
  1097. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1098. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1099. if (brouter->path.area_id != oa->area_id)
  1100. continue;
  1101. brouter->flag = OSPF6_ROUTE_REMOVE;
  1102. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1103. IS_OSPF6_DEBUG_ROUTE (MEMORY))
  1104. {
  1105. zlog_info ("%p: mark as removing: area %s brouter %s",
  1106. brouter, oa->name, brouter_name);
  1107. ospf6_brouter_debug_print (brouter);
  1108. }
  1109. }
  1110. for (brouter = ospf6_route_head (oa->spf_table); brouter;
  1111. brouter = ospf6_route_next (brouter))
  1112. {
  1113. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1114. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1115. if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
  1116. continue;
  1117. if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
  1118. continue;
  1119. if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
  1120. ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
  1121. continue;
  1122. copy = ospf6_route_copy (brouter);
  1123. copy->type = OSPF6_DEST_TYPE_ROUTER;
  1124. copy->path.area_id = oa->area_id;
  1125. ospf6_route_add (copy, oa->ospf6->brouter_table);
  1126. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1127. IS_OSPF6_DEBUG_ROUTE (MEMORY))
  1128. {
  1129. zlog_info ("%p: transfer: area %s brouter %s",
  1130. brouter, oa->name, brouter_name);
  1131. ospf6_brouter_debug_print (brouter);
  1132. }
  1133. }
  1134. oa->ospf6->brouter_table->hook_add = hook_add;
  1135. oa->ospf6->brouter_table->hook_remove = hook_remove;
  1136. for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
  1137. brouter = ospf6_route_next (brouter))
  1138. {
  1139. brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
  1140. inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
  1141. if (brouter->path.area_id != oa->area_id)
  1142. continue;
  1143. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
  1144. continue;
  1145. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
  1146. CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
  1147. {
  1148. UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
  1149. UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
  1150. }
  1151. if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
  1152. {
  1153. if (IS_OSPF6_DEBUG_BROUTER ||
  1154. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1155. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1156. zlog_info ("brouter %s disappears via area %s",
  1157. brouter_name, oa->name);
  1158. ospf6_route_remove (brouter, oa->ospf6->brouter_table);
  1159. }
  1160. else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
  1161. CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
  1162. {
  1163. if (IS_OSPF6_DEBUG_BROUTER ||
  1164. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1165. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1166. zlog_info ("brouter %s appears via area %s",
  1167. brouter_name, oa->name);
  1168. /* newly added */
  1169. if (hook_add)
  1170. (*hook_add) (brouter);
  1171. }
  1172. else
  1173. {
  1174. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
  1175. IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1176. zlog_info ("brouter %s still exists via area %s",
  1177. brouter_name, oa->name);
  1178. }
  1179. brouter->flag = 0;
  1180. }
  1181. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
  1182. zlog_info ("border-router calculation for area %s: done", oa->name);
  1183. }
  1184. struct ospf6_lsa_handler router_handler =
  1185. {
  1186. OSPF6_LSTYPE_ROUTER,
  1187. "Router",
  1188. ospf6_router_lsa_show
  1189. };
  1190. struct ospf6_lsa_handler network_handler =
  1191. {
  1192. OSPF6_LSTYPE_NETWORK,
  1193. "Network",
  1194. ospf6_network_lsa_show
  1195. };
  1196. struct ospf6_lsa_handler link_handler =
  1197. {
  1198. OSPF6_LSTYPE_LINK,
  1199. "Link",
  1200. ospf6_link_lsa_show
  1201. };
  1202. struct ospf6_lsa_handler intra_prefix_handler =
  1203. {
  1204. OSPF6_LSTYPE_INTRA_PREFIX,
  1205. "Intra-Prefix",
  1206. ospf6_intra_prefix_lsa_show
  1207. };
  1208. void
  1209. ospf6_intra_init (void)
  1210. {
  1211. ospf6_install_lsa_handler (&router_handler);
  1212. ospf6_install_lsa_handler (&network_handler);
  1213. ospf6_install_lsa_handler (&link_handler);
  1214. ospf6_install_lsa_handler (&intra_prefix_handler);
  1215. }
  1216. DEFUN (debug_ospf6_brouter,
  1217. debug_ospf6_brouter_cmd,
  1218. "debug ospf6 border-routers",
  1219. DEBUG_STR
  1220. OSPF6_STR
  1221. "Debug border router\n"
  1222. )
  1223. {
  1224. OSPF6_DEBUG_BROUTER_ON ();
  1225. return CMD_SUCCESS;
  1226. }
  1227. DEFUN (no_debug_ospf6_brouter,
  1228. no_debug_ospf6_brouter_cmd,
  1229. "no debug ospf6 border-routers",
  1230. NO_STR
  1231. DEBUG_STR
  1232. OSPF6_STR
  1233. "Debug border router\n"
  1234. )
  1235. {
  1236. OSPF6_DEBUG_BROUTER_OFF ();
  1237. return CMD_SUCCESS;
  1238. }
  1239. DEFUN (debug_ospf6_brouter_router,
  1240. debug_ospf6_brouter_router_cmd,
  1241. "debug ospf6 border-routers router-id A.B.C.D",
  1242. DEBUG_STR
  1243. OSPF6_STR
  1244. "Debug border router\n"
  1245. "Debug specific border router\n"
  1246. "Specify border-router's router-id\n"
  1247. )
  1248. {
  1249. u_int32_t router_id;
  1250. inet_pton (AF_INET, argv[0], &router_id);
  1251. OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
  1252. return CMD_SUCCESS;
  1253. }
  1254. DEFUN (no_debug_ospf6_brouter_router,
  1255. no_debug_ospf6_brouter_router_cmd,
  1256. "no debug ospf6 border-routers router-id",
  1257. NO_STR
  1258. DEBUG_STR
  1259. OSPF6_STR
  1260. "Debug border router\n"
  1261. "Debug specific border router\n"
  1262. )
  1263. {
  1264. OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
  1265. return CMD_SUCCESS;
  1266. }
  1267. DEFUN (debug_ospf6_brouter_area,
  1268. debug_ospf6_brouter_area_cmd,
  1269. "debug ospf6 border-routers area-id A.B.C.D",
  1270. DEBUG_STR
  1271. OSPF6_STR
  1272. "Debug border router\n"
  1273. "Debug border routers in specific Area\n"
  1274. "Specify Area-ID\n"
  1275. )
  1276. {
  1277. u_int32_t area_id;
  1278. inet_pton (AF_INET, argv[0], &area_id);
  1279. OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
  1280. return CMD_SUCCESS;
  1281. }
  1282. DEFUN (no_debug_ospf6_brouter_area,
  1283. no_debug_ospf6_brouter_area_cmd,
  1284. "no debug ospf6 border-routers area-id",
  1285. NO_STR
  1286. DEBUG_STR
  1287. OSPF6_STR
  1288. "Debug border router\n"
  1289. "Debug border routers in specific Area\n"
  1290. )
  1291. {
  1292. OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
  1293. return CMD_SUCCESS;
  1294. }
  1295. int
  1296. config_write_ospf6_debug_brouter (struct vty *vty)
  1297. {
  1298. char buf[16];
  1299. if (IS_OSPF6_DEBUG_BROUTER)
  1300. vty_out (vty, "debug ospf6 border-routers%s", VNL);
  1301. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
  1302. {
  1303. inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
  1304. buf, sizeof (buf));
  1305. vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
  1306. }
  1307. if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
  1308. {
  1309. inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
  1310. buf, sizeof (buf));
  1311. vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
  1312. }
  1313. return 0;
  1314. }
  1315. void
  1316. install_element_ospf6_debug_brouter (void)
  1317. {
  1318. install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
  1319. install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
  1320. install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
  1321. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
  1322. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
  1323. install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
  1324. install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
  1325. install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
  1326. install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
  1327. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
  1328. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
  1329. install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);
  1330. }