ospf6_intra.c 45 KB

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