ospf6_lsa.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  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 other stuffs */
  23. #include "log.h"
  24. #include "linklist.h"
  25. #include "vector.h"
  26. #include "vty.h"
  27. #include "command.h"
  28. #include "memory.h"
  29. #include "thread.h"
  30. #include "ospf6_proto.h"
  31. #include "ospf6_lsa.h"
  32. #include "ospf6_lsdb.h"
  33. #include "ospf6_message.h"
  34. #include "ospf6_top.h"
  35. #include "ospf6_area.h"
  36. #include "ospf6_interface.h"
  37. #include "ospf6_neighbor.h"
  38. #include "ospf6_flood.h"
  39. #include "ospf6d.h"
  40. vector ospf6_lsa_handler_vector;
  41. static int
  42. ospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  43. {
  44. u_char *start, *end, *current;
  45. char byte[4];
  46. start = (u_char *) lsa->header + sizeof (struct ospf6_lsa_header);
  47. end = (u_char *) lsa->header + ntohs (lsa->header->length);
  48. vty_out (vty, " Unknown contents:%s", VNL);
  49. for (current = start; current < end; current ++)
  50. {
  51. if ((current - start) % 16 == 0)
  52. vty_out (vty, "%s ", VNL);
  53. else if ((current - start) % 4 == 0)
  54. vty_out (vty, " ");
  55. snprintf (byte, sizeof (byte), "%02x", *current);
  56. vty_out (vty, "%s", byte);
  57. }
  58. vty_out (vty, "%s%s", VNL, VNL);
  59. return 0;
  60. }
  61. struct ospf6_lsa_handler unknown_handler =
  62. {
  63. OSPF6_LSTYPE_UNKNOWN,
  64. "Unknown",
  65. ospf6_unknown_lsa_show,
  66. OSPF6_LSA_DEBUG,
  67. };
  68. void
  69. ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler)
  70. {
  71. /* type in handler is host byte order */
  72. int index = handler->type & OSPF6_LSTYPE_FCODE_MASK;
  73. vector_set_index (ospf6_lsa_handler_vector, index, handler);
  74. }
  75. struct ospf6_lsa_handler *
  76. ospf6_get_lsa_handler (u_int16_t type)
  77. {
  78. struct ospf6_lsa_handler *handler = NULL;
  79. unsigned int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
  80. if (index >= vector_active (ospf6_lsa_handler_vector))
  81. handler = &unknown_handler;
  82. else
  83. handler = vector_slot (ospf6_lsa_handler_vector, index);
  84. if (handler == NULL)
  85. handler = &unknown_handler;
  86. return handler;
  87. }
  88. const char *
  89. ospf6_lstype_name (u_int16_t type)
  90. {
  91. static char buf[8];
  92. struct ospf6_lsa_handler *handler;
  93. handler = ospf6_get_lsa_handler (type);
  94. if (handler && handler != &unknown_handler)
  95. return handler->name;
  96. snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
  97. return buf;
  98. }
  99. u_char
  100. ospf6_lstype_debug (u_int16_t type)
  101. {
  102. struct ospf6_lsa_handler *handler;
  103. handler = ospf6_get_lsa_handler (type);
  104. return handler->debug;
  105. }
  106. /* RFC2328: Section 13.2 */
  107. int
  108. ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
  109. struct ospf6_lsa *lsa2)
  110. {
  111. int len;
  112. assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));
  113. /* XXX, Options ??? */
  114. ospf6_lsa_age_current (lsa1);
  115. ospf6_lsa_age_current (lsa2);
  116. if (ntohs (lsa1->header->age) == MAXAGE &&
  117. ntohs (lsa2->header->age) != MAXAGE)
  118. return 1;
  119. if (ntohs (lsa1->header->age) != MAXAGE &&
  120. ntohs (lsa2->header->age) == MAXAGE)
  121. return 1;
  122. /* compare body */
  123. if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
  124. return 1;
  125. len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
  126. return memcmp (lsa1->header + 1, lsa2->header + 1, len);
  127. }
  128. int
  129. ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
  130. struct ospf6_lsa *lsa2)
  131. {
  132. int length;
  133. if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
  134. return 1;
  135. if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
  136. return 1;
  137. length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
  138. assert (length > 0);
  139. return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
  140. OSPF6_LSA_HEADER_END (lsa2->header), length);
  141. }
  142. /* ospf6 age functions */
  143. /* calculate birth */
  144. static void
  145. ospf6_lsa_age_set (struct ospf6_lsa *lsa)
  146. {
  147. struct timeval now;
  148. assert (lsa && lsa->header);
  149. if (gettimeofday (&now, (struct timezone *)NULL) < 0)
  150. zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
  151. safe_strerror (errno));
  152. lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);
  153. lsa->birth.tv_usec = now.tv_usec;
  154. return;
  155. }
  156. /* this function calculates current age from its birth,
  157. then update age field of LSA header. return value is current age */
  158. u_int16_t
  159. ospf6_lsa_age_current (struct ospf6_lsa *lsa)
  160. {
  161. struct timeval now;
  162. u_int32_t ulage;
  163. u_int16_t age;
  164. assert (lsa);
  165. assert (lsa->header);
  166. /* current time */
  167. if (gettimeofday (&now, (struct timezone *)NULL) < 0)
  168. zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
  169. safe_strerror (errno));
  170. /* calculate age */
  171. ulage = now.tv_sec - lsa->birth.tv_sec;
  172. /* if over MAXAGE, set to it */
  173. age = (ulage > MAXAGE ? MAXAGE : ulage);
  174. lsa->header->age = htons (age);
  175. return age;
  176. }
  177. /* update age field of LSA header with adding InfTransDelay */
  178. void
  179. ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay)
  180. {
  181. unsigned short age;
  182. age = ospf6_lsa_age_current (lsa) + transdelay;
  183. if (age > MAXAGE)
  184. age = MAXAGE;
  185. lsa->header->age = htons (age);
  186. }
  187. void
  188. ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
  189. {
  190. /* log */
  191. if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
  192. zlog_debug ("LSA: Premature aging: %s", lsa->name);
  193. THREAD_OFF (lsa->expire);
  194. THREAD_OFF (lsa->refresh);
  195. memset (&lsa->birth, 0, sizeof (struct timeval));
  196. thread_execute (master, ospf6_lsa_expire, lsa, 0);
  197. }
  198. /* check which is more recent. if a is more recent, return -1;
  199. if the same, return 0; otherwise(b is more recent), return 1 */
  200. int
  201. ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
  202. {
  203. signed long seqnuma, seqnumb;
  204. u_int16_t cksuma, cksumb;
  205. u_int16_t agea, ageb;
  206. assert (a && a->header);
  207. assert (b && b->header);
  208. assert (OSPF6_LSA_IS_SAME (a, b));
  209. seqnuma = ((signed long) ntohl (a->header->seqnum))
  210. - (signed long) INITIAL_SEQUENCE_NUMBER;
  211. seqnumb = ((signed long) ntohl (b->header->seqnum))
  212. - (signed long) INITIAL_SEQUENCE_NUMBER;
  213. /* compare by sequence number */
  214. /* XXX, LS sequence number wrapping */
  215. if (seqnuma > seqnumb)
  216. return -1;
  217. else if (seqnuma < seqnumb)
  218. return 1;
  219. /* Checksum */
  220. cksuma = ntohs (a->header->checksum);
  221. cksumb = ntohs (b->header->checksum);
  222. if (cksuma > cksumb)
  223. return -1;
  224. if (cksuma < cksumb)
  225. return 0;
  226. /* Update Age */
  227. agea = ospf6_lsa_age_current (a);
  228. ageb = ospf6_lsa_age_current (b);
  229. /* MaxAge check */
  230. if (agea == MAXAGE && ageb != MAXAGE)
  231. return -1;
  232. else if (agea != MAXAGE && ageb == MAXAGE)
  233. return 1;
  234. /* Age check */
  235. if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)
  236. return 1;
  237. else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)
  238. return -1;
  239. /* neither recent */
  240. return 0;
  241. }
  242. char *
  243. ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
  244. {
  245. char id[16], adv_router[16];
  246. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  247. inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
  248. sizeof (adv_router));
  249. snprintf (buf, size, "[%s Id:%s Adv:%s]",
  250. ospf6_lstype_name (lsa->header->type), id, adv_router);
  251. return buf;
  252. }
  253. void
  254. ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header)
  255. {
  256. char id[16], adv_router[16];
  257. inet_ntop (AF_INET, &header->id, id, sizeof (id));
  258. inet_ntop (AF_INET, &header->adv_router, adv_router,
  259. sizeof (adv_router));
  260. zlog_debug (" [%s Id:%s Adv:%s]",
  261. ospf6_lstype_name (header->type), id, adv_router);
  262. zlog_debug (" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",
  263. ntohs (header->age), (u_long) ntohl (header->seqnum),
  264. ntohs (header->checksum), ntohs (header->length));
  265. }
  266. void
  267. ospf6_lsa_header_print (struct ospf6_lsa *lsa)
  268. {
  269. ospf6_lsa_age_current (lsa);
  270. ospf6_lsa_header_print_raw (lsa->header);
  271. }
  272. void
  273. ospf6_lsa_show_summary_header (struct vty *vty)
  274. {
  275. vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
  276. "Type", "LSId", "AdvRouter", "Age", "SeqNum",
  277. "Cksm", "Len", "Duration", VNL);
  278. }
  279. void
  280. ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
  281. {
  282. char adv_router[16], id[16];
  283. struct timeval now, res;
  284. char duration[16];
  285. assert (lsa);
  286. assert (lsa->header);
  287. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  288. inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
  289. sizeof (adv_router));
  290. gettimeofday (&now, NULL);
  291. timersub (&now, &lsa->installed, &res);
  292. timerstring (&res, duration, sizeof (duration));
  293. vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
  294. ospf6_lstype_name (lsa->header->type),
  295. id, adv_router, ospf6_lsa_age_current (lsa),
  296. (u_long) ntohl (lsa->header->seqnum),
  297. ntohs (lsa->header->checksum), ntohs (lsa->header->length),
  298. duration, VNL);
  299. }
  300. void
  301. ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
  302. {
  303. u_char *start, *end, *current;
  304. char byte[4];
  305. start = (u_char *) lsa->header;
  306. end = (u_char *) lsa->header + ntohs (lsa->header->length);
  307. vty_out (vty, "%s", VNL);
  308. vty_out (vty, "%s:%s", lsa->name, VNL);
  309. for (current = start; current < end; current ++)
  310. {
  311. if ((current - start) % 16 == 0)
  312. vty_out (vty, "%s ", VNL);
  313. else if ((current - start) % 4 == 0)
  314. vty_out (vty, " ");
  315. snprintf (byte, sizeof (byte), "%02x", *current);
  316. vty_out (vty, "%s", byte);
  317. }
  318. vty_out (vty, "%s%s", VNL, VNL);
  319. return;
  320. }
  321. void
  322. ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
  323. {
  324. char adv_router[64], id[64];
  325. assert (lsa && lsa->header);
  326. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  327. inet_ntop (AF_INET, &lsa->header->adv_router,
  328. adv_router, sizeof (adv_router));
  329. vty_out (vty, "%s", VNL);
  330. vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  331. ospf6_lstype_name (lsa->header->type), VNL);
  332. vty_out (vty, "Link State ID: %s%s", id, VNL);
  333. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  334. vty_out (vty, "LS Sequence Number: %#010lx%s",
  335. (u_long) ntohl (lsa->header->seqnum), VNL);
  336. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  337. ntohs (lsa->header->checksum),
  338. ntohs (lsa->header->length), VNL);
  339. vty_out (vty, " Prev: %p This: %p Next: %p%s",
  340. lsa->prev, lsa, lsa->next, VNL);
  341. vty_out (vty, "%s", VNL);
  342. return;
  343. }
  344. void
  345. ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  346. {
  347. char adv_router[64], id[64];
  348. struct ospf6_lsa_handler *handler;
  349. assert (lsa && lsa->header);
  350. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  351. inet_ntop (AF_INET, &lsa->header->adv_router,
  352. adv_router, sizeof (adv_router));
  353. vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  354. ospf6_lstype_name (lsa->header->type), VNL);
  355. vty_out (vty, "Link State ID: %s%s", id, VNL);
  356. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  357. vty_out (vty, "LS Sequence Number: %#010lx%s",
  358. (u_long) ntohl (lsa->header->seqnum), VNL);
  359. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  360. ntohs (lsa->header->checksum),
  361. ntohs (lsa->header->length), VNL);
  362. handler = ospf6_get_lsa_handler (lsa->header->type);
  363. if (handler->show == NULL)
  364. handler = &unknown_handler;
  365. (*handler->show) (vty, lsa);
  366. vty_out (vty, "%s", VNL);
  367. }
  368. /* OSPFv3 LSA creation/deletion function */
  369. struct ospf6_lsa *
  370. ospf6_lsa_create (struct ospf6_lsa_header *header)
  371. {
  372. struct ospf6_lsa *lsa = NULL;
  373. struct ospf6_lsa_header *new_header = NULL;
  374. u_int16_t lsa_size = 0;
  375. /* size of the entire LSA */
  376. lsa_size = ntohs (header->length); /* XXX vulnerable */
  377. /* allocate memory for this LSA */
  378. new_header = (struct ospf6_lsa_header *)
  379. XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
  380. /* copy LSA from original header */
  381. memcpy (new_header, header, lsa_size);
  382. /* LSA information structure */
  383. /* allocate memory */
  384. lsa = (struct ospf6_lsa *)
  385. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  386. memset (lsa, 0, sizeof (struct ospf6_lsa));
  387. lsa->header = (struct ospf6_lsa_header *) new_header;
  388. /* dump string */
  389. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  390. /* calculate birth of this lsa */
  391. ospf6_lsa_age_set (lsa);
  392. return lsa;
  393. }
  394. struct ospf6_lsa *
  395. ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
  396. {
  397. struct ospf6_lsa *lsa = NULL;
  398. struct ospf6_lsa_header *new_header = NULL;
  399. /* allocate memory for this LSA */
  400. new_header = (struct ospf6_lsa_header *)
  401. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
  402. /* copy LSA from original header */
  403. memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
  404. /* LSA information structure */
  405. /* allocate memory */
  406. lsa = (struct ospf6_lsa *)
  407. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  408. memset (lsa, 0, sizeof (struct ospf6_lsa));
  409. lsa->header = (struct ospf6_lsa_header *) new_header;
  410. SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY);
  411. /* dump string */
  412. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  413. /* calculate birth of this lsa */
  414. ospf6_lsa_age_set (lsa);
  415. return lsa;
  416. }
  417. void
  418. ospf6_lsa_delete (struct ospf6_lsa *lsa)
  419. {
  420. assert (lsa->lock == 0);
  421. /* cancel threads */
  422. THREAD_OFF (lsa->expire);
  423. THREAD_OFF (lsa->refresh);
  424. /* do free */
  425. XFREE (MTYPE_OSPF6_LSA, lsa->header);
  426. XFREE (MTYPE_OSPF6_LSA, lsa);
  427. }
  428. struct ospf6_lsa *
  429. ospf6_lsa_copy (struct ospf6_lsa *lsa)
  430. {
  431. struct ospf6_lsa *copy = NULL;
  432. ospf6_lsa_age_current (lsa);
  433. if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
  434. copy = ospf6_lsa_create_headeronly (lsa->header);
  435. else
  436. copy = ospf6_lsa_create (lsa->header);
  437. assert (copy->lock == 0);
  438. copy->birth = lsa->birth;
  439. copy->originated = lsa->originated;
  440. copy->received = lsa->received;
  441. copy->installed = lsa->installed;
  442. copy->lsdb = lsa->lsdb;
  443. return copy;
  444. }
  445. /* increment reference counter of struct ospf6_lsa */
  446. void
  447. ospf6_lsa_lock (struct ospf6_lsa *lsa)
  448. {
  449. lsa->lock++;
  450. return;
  451. }
  452. /* decrement reference counter of struct ospf6_lsa */
  453. void
  454. ospf6_lsa_unlock (struct ospf6_lsa *lsa)
  455. {
  456. /* decrement reference counter */
  457. assert (lsa->lock > 0);
  458. lsa->lock--;
  459. if (lsa->lock != 0)
  460. return;
  461. ospf6_lsa_delete (lsa);
  462. }
  463. /* ospf6 lsa expiry */
  464. int
  465. ospf6_lsa_expire (struct thread *thread)
  466. {
  467. struct ospf6_lsa *lsa;
  468. lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
  469. assert (lsa && lsa->header);
  470. assert (OSPF6_LSA_IS_MAXAGE (lsa));
  471. assert (! lsa->refresh);
  472. lsa->expire = (struct thread *) NULL;
  473. if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
  474. {
  475. zlog_debug ("LSA Expire:");
  476. ospf6_lsa_header_print (lsa);
  477. }
  478. if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
  479. return 0; /* dbexchange will do something ... */
  480. /* reflood lsa */
  481. ospf6_flood (NULL, lsa);
  482. /* reinstall lsa */
  483. ospf6_install_lsa (lsa);
  484. /* schedule maxage remover */
  485. ospf6_maxage_remove (ospf6);
  486. return 0;
  487. }
  488. int
  489. ospf6_lsa_refresh (struct thread *thread)
  490. {
  491. struct ospf6_lsa *old, *self, *new;
  492. struct ospf6_lsdb *lsdb_self;
  493. assert (thread);
  494. old = (struct ospf6_lsa *) THREAD_ARG (thread);
  495. assert (old && old->header);
  496. old->refresh = (struct thread *) NULL;
  497. lsdb_self = ospf6_get_scoped_lsdb_self (old);
  498. self = ospf6_lsdb_lookup (old->header->type, old->header->id,
  499. old->header->adv_router, lsdb_self);
  500. if (self == NULL)
  501. {
  502. if (IS_OSPF6_DEBUG_LSA_TYPE (old->header->type))
  503. zlog_debug ("Refresh: could not find self LSA, flush %s", old->name);
  504. ospf6_lsa_premature_aging (old);
  505. return 0;
  506. }
  507. /* Reset age, increment LS sequence number. */
  508. self->header->age = htons (0);
  509. self->header->seqnum =
  510. ospf6_new_ls_seqnum (self->header->type, self->header->id,
  511. self->header->adv_router, old->lsdb);
  512. ospf6_lsa_checksum (self->header);
  513. new = ospf6_lsa_create (self->header);
  514. new->lsdb = old->lsdb;
  515. new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new,
  516. LS_REFRESH_TIME);
  517. /* store it in the LSDB for self-originated LSAs */
  518. ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self);
  519. if (IS_OSPF6_DEBUG_LSA_TYPE (new->header->type))
  520. {
  521. zlog_debug ("LSA Refresh:");
  522. ospf6_lsa_header_print (new);
  523. }
  524. ospf6_flood_clear (old);
  525. ospf6_flood (NULL, new);
  526. ospf6_install_lsa (new);
  527. return 0;
  528. }
  529. /* enhanced Fletcher checksum algorithm, RFC1008 7.2 */
  530. #define MODX 4102
  531. #define LSA_CHECKSUM_OFFSET 15
  532. unsigned short
  533. ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
  534. {
  535. u_char *sp, *ep, *p, *q;
  536. int c0 = 0, c1 = 0;
  537. int x, y;
  538. u_int16_t length;
  539. lsa_header->checksum = 0;
  540. length = ntohs (lsa_header->length) - 2;
  541. sp = (u_char *) &lsa_header->type;
  542. for (ep = sp + length; sp < ep; sp = q)
  543. {
  544. q = sp + MODX;
  545. if (q > ep)
  546. q = ep;
  547. for (p = sp; p < q; p++)
  548. {
  549. c0 += *p;
  550. c1 += c0;
  551. }
  552. c0 %= 255;
  553. c1 %= 255;
  554. }
  555. /* r = (c1 << 8) + c0; */
  556. x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
  557. if (x <= 0)
  558. x += 255;
  559. y = 510 - c0 - x;
  560. if (y > 255)
  561. y -= 255;
  562. lsa_header->checksum = htons ((x << 8) + y);
  563. return (lsa_header->checksum);
  564. }
  565. void
  566. ospf6_lsa_init (void)
  567. {
  568. ospf6_lsa_handler_vector = vector_init (0);
  569. ospf6_install_lsa_handler (&unknown_handler);
  570. }
  571. static char *
  572. ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
  573. {
  574. static char buf[64];
  575. unsigned int i;
  576. unsigned int size = strlen (h->name);
  577. if (!strcmp(h->name, "Unknown") &&
  578. h->type != OSPF6_LSTYPE_UNKNOWN)
  579. {
  580. snprintf (buf, sizeof (buf), "%#04hx", h->type);
  581. return buf;
  582. }
  583. for (i = 0; i < MIN (size, sizeof (buf)); i++)
  584. {
  585. if (! islower (h->name[i]))
  586. buf[i] = tolower (h->name[i]);
  587. else
  588. buf[i] = h->name[i];
  589. }
  590. buf[size] = '\0';
  591. return buf;
  592. }
  593. DEFUN (debug_ospf6_lsa_type,
  594. debug_ospf6_lsa_hex_cmd,
  595. "debug ospf6 lsa XXXX/0xXXXX",
  596. DEBUG_STR
  597. OSPF6_STR
  598. "Debug Link State Advertisements (LSAs)\n"
  599. "Specify LS type as Hexadecimal\n"
  600. )
  601. {
  602. unsigned int i;
  603. struct ospf6_lsa_handler *handler = NULL;
  604. unsigned long val;
  605. char *endptr = NULL;
  606. u_int16_t type = 0;
  607. assert (argc);
  608. if ((strlen (argv[0]) == 6 && ! strncmp (argv[0], "0x", 2)) ||
  609. (strlen (argv[0]) == 4))
  610. {
  611. val = strtoul (argv[0], &endptr, 16);
  612. if (*endptr == '\0')
  613. type = val;
  614. }
  615. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  616. {
  617. handler = vector_slot (ospf6_lsa_handler_vector, i);
  618. if (handler == NULL)
  619. continue;
  620. if (type && handler->type == type)
  621. break;
  622. if (! strcasecmp (argv[0], handler->name))
  623. break;
  624. handler = NULL;
  625. }
  626. if (type && handler == NULL)
  627. {
  628. handler = (struct ospf6_lsa_handler *)
  629. malloc (sizeof (struct ospf6_lsa_handler));
  630. memset (handler, 0, sizeof (struct ospf6_lsa_handler));
  631. handler->type = type;
  632. handler->name = "Unknown";
  633. handler->show = ospf6_unknown_lsa_show;
  634. vector_set_index (ospf6_lsa_handler_vector,
  635. handler->type & OSPF6_LSTYPE_FCODE_MASK, handler);
  636. }
  637. if (handler == NULL)
  638. handler = &unknown_handler;
  639. if (argc >= 2)
  640. {
  641. if (! strcmp (argv[1], "originate"))
  642. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
  643. if (! strcmp (argv[1], "examin"))
  644. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
  645. if (! strcmp (argv[1], "flooding"))
  646. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
  647. }
  648. else
  649. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG);
  650. return CMD_SUCCESS;
  651. }
  652. DEFUN (no_debug_ospf6_lsa_type,
  653. no_debug_ospf6_lsa_hex_cmd,
  654. "no debug ospf6 lsa XXXX/0xXXXX",
  655. NO_STR
  656. DEBUG_STR
  657. OSPF6_STR
  658. "Debug Link State Advertisements (LSAs)\n"
  659. "Specify LS type as Hexadecimal\n"
  660. )
  661. {
  662. u_int i;
  663. struct ospf6_lsa_handler *handler = NULL;
  664. unsigned long val;
  665. char *endptr = NULL;
  666. u_int16_t type = 0;
  667. assert (argc);
  668. if ((strlen (argv[0]) == 6 && ! strncmp (argv[0], "0x", 2)) ||
  669. (strlen (argv[0]) == 4))
  670. {
  671. val = strtoul (argv[0], &endptr, 16);
  672. if (*endptr == '\0')
  673. type = val;
  674. }
  675. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  676. {
  677. handler = vector_slot (ospf6_lsa_handler_vector, i);
  678. if (handler == NULL)
  679. continue;
  680. if (type && handler->type == type)
  681. break;
  682. if (! strcasecmp (argv[0], handler->name))
  683. break;
  684. }
  685. if (handler == NULL)
  686. return CMD_SUCCESS;
  687. if (argc >= 2)
  688. {
  689. if (! strcmp (argv[1], "originate"))
  690. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
  691. if (! strcmp (argv[1], "examin"))
  692. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
  693. if (! strcmp (argv[1], "flooding"))
  694. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
  695. }
  696. else
  697. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG);
  698. if (handler->debug == 0 &&
  699. !strcmp(handler->name, "Unknown") && type != OSPF6_LSTYPE_UNKNOWN)
  700. {
  701. free (handler);
  702. vector_slot (ospf6_lsa_handler_vector, i) = NULL;
  703. }
  704. return CMD_SUCCESS;
  705. }
  706. struct cmd_element debug_ospf6_lsa_type_cmd;
  707. struct cmd_element debug_ospf6_lsa_type_detail_cmd;
  708. struct cmd_element no_debug_ospf6_lsa_type_cmd;
  709. struct cmd_element no_debug_ospf6_lsa_type_detail_cmd;
  710. void
  711. install_element_ospf6_debug_lsa (void)
  712. {
  713. u_int i;
  714. struct ospf6_lsa_handler *handler;
  715. #define STRSIZE 256
  716. #define DOCSIZE 1024
  717. static char strbuf[STRSIZE];
  718. static char docbuf[DOCSIZE];
  719. static char detail_strbuf[STRSIZE];
  720. static char detail_docbuf[DOCSIZE];
  721. char *str, *no_str;
  722. char *doc, *no_doc;
  723. strbuf[0] = '\0';
  724. no_str = &strbuf[strlen (strbuf)];
  725. strncat (strbuf, "no ", STRSIZE - strlen (strbuf));
  726. str = &strbuf[strlen (strbuf)];
  727. strncat (strbuf, "debug ospf6 lsa (", STRSIZE - strlen (strbuf));
  728. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  729. {
  730. handler = vector_slot (ospf6_lsa_handler_vector, i);
  731. if (handler == NULL)
  732. continue;
  733. strncat (strbuf, ospf6_lsa_handler_name (handler),
  734. STRSIZE - strlen (strbuf));
  735. strncat (strbuf, "|", STRSIZE - strlen (strbuf));
  736. }
  737. strbuf[strlen (strbuf) - 1] = ')';
  738. strbuf[strlen (strbuf)] = '\0';
  739. docbuf[0] = '\0';
  740. no_doc = &docbuf[strlen (docbuf)];
  741. strncat (docbuf, NO_STR, DOCSIZE - strlen (docbuf));
  742. doc = &docbuf[strlen (docbuf)];
  743. strncat (docbuf, DEBUG_STR, DOCSIZE - strlen (docbuf));
  744. strncat (docbuf, OSPF6_STR, DOCSIZE - strlen (docbuf));
  745. strncat (docbuf, "Debug Link State Advertisements (LSAs)\n",
  746. DOCSIZE - strlen (docbuf));
  747. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  748. {
  749. handler = vector_slot (ospf6_lsa_handler_vector, i);
  750. if (handler == NULL)
  751. continue;
  752. strncat (docbuf, "Debug ", DOCSIZE - strlen (docbuf));
  753. strncat (docbuf, handler->name, DOCSIZE - strlen (docbuf));
  754. strncat (docbuf, "-LSA\n", DOCSIZE - strlen (docbuf));
  755. }
  756. docbuf[strlen (docbuf)] = '\0';
  757. debug_ospf6_lsa_type_cmd.string = str;
  758. debug_ospf6_lsa_type_cmd.func = debug_ospf6_lsa_type;
  759. debug_ospf6_lsa_type_cmd.doc = doc;
  760. no_debug_ospf6_lsa_type_cmd.string = no_str;
  761. no_debug_ospf6_lsa_type_cmd.func = no_debug_ospf6_lsa_type;
  762. no_debug_ospf6_lsa_type_cmd.doc = no_doc;
  763. strncpy (detail_strbuf, strbuf, STRSIZE);
  764. strncat (detail_strbuf, " (originate|examin|flooding)",
  765. STRSIZE - strlen (detail_strbuf));
  766. detail_strbuf[strlen (detail_strbuf)] = '\0';
  767. no_str = &detail_strbuf[0];
  768. str = &detail_strbuf[strlen ("no ")];
  769. strncpy (detail_docbuf, docbuf, DOCSIZE);
  770. strncat (detail_docbuf, "Debug Originating LSA\n",
  771. DOCSIZE - strlen (detail_docbuf));
  772. strncat (detail_docbuf, "Debug Examining LSA\n",
  773. DOCSIZE - strlen (detail_docbuf));
  774. strncat (detail_docbuf, "Debug Flooding LSA\n",
  775. DOCSIZE - strlen (detail_docbuf));
  776. detail_docbuf[strlen (detail_docbuf)] = '\0';
  777. no_doc = &detail_docbuf[0];
  778. doc = &detail_docbuf[strlen (NO_STR)];
  779. debug_ospf6_lsa_type_detail_cmd.string = str;
  780. debug_ospf6_lsa_type_detail_cmd.func = debug_ospf6_lsa_type;
  781. debug_ospf6_lsa_type_detail_cmd.doc = doc;
  782. no_debug_ospf6_lsa_type_detail_cmd.string = no_str;
  783. no_debug_ospf6_lsa_type_detail_cmd.func = no_debug_ospf6_lsa_type;
  784. no_debug_ospf6_lsa_type_detail_cmd.doc = no_doc;
  785. install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_cmd);
  786. install_element (ENABLE_NODE, &debug_ospf6_lsa_type_cmd);
  787. install_element (ENABLE_NODE, &debug_ospf6_lsa_type_detail_cmd);
  788. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd);
  789. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_type_cmd);
  790. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_type_detail_cmd);
  791. install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_cmd);
  792. install_element (CONFIG_NODE, &debug_ospf6_lsa_type_cmd);
  793. install_element (CONFIG_NODE, &debug_ospf6_lsa_type_detail_cmd);
  794. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd);
  795. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_type_cmd);
  796. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_type_detail_cmd);
  797. }
  798. int
  799. config_write_ospf6_debug_lsa (struct vty *vty)
  800. {
  801. u_int i;
  802. struct ospf6_lsa_handler *handler;
  803. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  804. {
  805. handler = vector_slot (ospf6_lsa_handler_vector, i);
  806. if (handler == NULL)
  807. continue;
  808. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG))
  809. vty_out (vty, "debug ospf6 lsa %s%s",
  810. ospf6_lsa_handler_name (handler), VNL);
  811. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE))
  812. vty_out (vty, "debug ospf6 lsa %s originate%s",
  813. ospf6_lsa_handler_name (handler), VNL);
  814. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN))
  815. vty_out (vty, "debug ospf6 lsa %s examin%s",
  816. ospf6_lsa_handler_name (handler), VNL);
  817. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD))
  818. vty_out (vty, "debug ospf6 lsa %s flooding%s",
  819. ospf6_lsa_handler_name (handler), VNL);
  820. }
  821. return 0;
  822. }