ospf6_lsa.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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 "checksum.h"
  31. #include "ospf6_proto.h"
  32. #include "ospf6_lsa.h"
  33. #include "ospf6_lsdb.h"
  34. #include "ospf6_message.h"
  35. #include "ospf6_top.h"
  36. #include "ospf6_area.h"
  37. #include "ospf6_interface.h"
  38. #include "ospf6_neighbor.h"
  39. #include "ospf6_flood.h"
  40. #include "ospf6d.h"
  41. vector ospf6_lsa_handler_vector;
  42. static int
  43. ospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  44. {
  45. u_char *start, *end, *current;
  46. char byte[4];
  47. start = (u_char *) lsa->header + sizeof (struct ospf6_lsa_header);
  48. end = (u_char *) lsa->header + ntohs (lsa->header->length);
  49. vty_out (vty, " Unknown contents:%s", VNL);
  50. for (current = start; current < end; current ++)
  51. {
  52. if ((current - start) % 16 == 0)
  53. vty_out (vty, "%s ", VNL);
  54. else if ((current - start) % 4 == 0)
  55. vty_out (vty, " ");
  56. snprintf (byte, sizeof (byte), "%02x", *current);
  57. vty_out (vty, "%s", byte);
  58. }
  59. vty_out (vty, "%s%s", VNL, VNL);
  60. return 0;
  61. }
  62. struct ospf6_lsa_handler unknown_handler =
  63. {
  64. OSPF6_LSTYPE_UNKNOWN,
  65. "unknown",
  66. ospf6_unknown_lsa_show,
  67. OSPF6_LSA_DEBUG,
  68. };
  69. void
  70. ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler)
  71. {
  72. /* type in handler is host byte order */
  73. int index = handler->type & OSPF6_LSTYPE_FCODE_MASK;
  74. vector_set_index (ospf6_lsa_handler_vector, index, handler);
  75. }
  76. struct ospf6_lsa_handler *
  77. ospf6_get_lsa_handler (u_int16_t type)
  78. {
  79. struct ospf6_lsa_handler *handler = NULL;
  80. unsigned int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
  81. if (index >= vector_active (ospf6_lsa_handler_vector))
  82. handler = &unknown_handler;
  83. else
  84. handler = vector_slot (ospf6_lsa_handler_vector, index);
  85. if (handler == NULL)
  86. handler = &unknown_handler;
  87. return handler;
  88. }
  89. const char *
  90. ospf6_lstype_name (u_int16_t type)
  91. {
  92. static char buf[8];
  93. struct ospf6_lsa_handler *handler;
  94. handler = ospf6_get_lsa_handler (type);
  95. if (handler && handler != &unknown_handler)
  96. return handler->name;
  97. snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
  98. return buf;
  99. }
  100. u_char
  101. ospf6_lstype_debug (u_int16_t type)
  102. {
  103. struct ospf6_lsa_handler *handler;
  104. handler = ospf6_get_lsa_handler (type);
  105. return handler->debug;
  106. }
  107. /* RFC2328: Section 13.2 */
  108. int
  109. ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
  110. struct ospf6_lsa *lsa2)
  111. {
  112. int len;
  113. assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));
  114. /* XXX, Options ??? */
  115. ospf6_lsa_age_current (lsa1);
  116. ospf6_lsa_age_current (lsa2);
  117. if (ntohs (lsa1->header->age) == OSPF_LSA_MAXAGE &&
  118. ntohs (lsa2->header->age) != OSPF_LSA_MAXAGE)
  119. return 1;
  120. if (ntohs (lsa1->header->age) != OSPF_LSA_MAXAGE &&
  121. ntohs (lsa2->header->age) == OSPF_LSA_MAXAGE)
  122. return 1;
  123. /* compare body */
  124. if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
  125. return 1;
  126. len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
  127. return memcmp (lsa1->header + 1, lsa2->header + 1, len);
  128. }
  129. int
  130. ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
  131. struct ospf6_lsa *lsa2)
  132. {
  133. int length;
  134. if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
  135. return 1;
  136. if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
  137. return 1;
  138. /* Going beyond LSA headers to compare the payload only makes sense, when both LSAs aren't header-only. */
  139. if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY) != CHECK_FLAG (lsa2->flag, OSPF6_LSA_HEADERONLY))
  140. {
  141. zlog_warn ("%s: only one of two (%s, %s) LSAs compared is header-only", __func__, lsa1->name, lsa2->name);
  142. return 1;
  143. }
  144. if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY))
  145. return 0;
  146. length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
  147. /* Once upper layer verifies LSAs received, length underrun should become a warning. */
  148. if (length <= 0)
  149. return 0;
  150. return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
  151. OSPF6_LSA_HEADER_END (lsa2->header), length);
  152. }
  153. /* ospf6 age functions */
  154. /* calculate birth */
  155. static void
  156. ospf6_lsa_age_set (struct ospf6_lsa *lsa)
  157. {
  158. struct timeval now;
  159. assert (lsa && lsa->header);
  160. if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0)
  161. zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s",
  162. safe_strerror (errno));
  163. lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);
  164. lsa->birth.tv_usec = now.tv_usec;
  165. return;
  166. }
  167. /* this function calculates current age from its birth,
  168. then update age field of LSA header. return value is current age */
  169. u_int16_t
  170. ospf6_lsa_age_current (struct ospf6_lsa *lsa)
  171. {
  172. struct timeval now;
  173. u_int32_t ulage;
  174. u_int16_t age;
  175. assert (lsa);
  176. assert (lsa->header);
  177. /* current time */
  178. if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &now) < 0)
  179. zlog_warn ("LSA: quagga_gettime failed, may fail LSA AGEs: %s",
  180. safe_strerror (errno));
  181. if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE)
  182. {
  183. /* ospf6_lsa_premature_aging () sets age to MAXAGE; when using
  184. relative time, we cannot compare against lsa birth time, so
  185. we catch this special case here. */
  186. lsa->header->age = htons (OSPF_LSA_MAXAGE);
  187. return OSPF_LSA_MAXAGE;
  188. }
  189. /* calculate age */
  190. ulage = now.tv_sec - lsa->birth.tv_sec;
  191. /* if over MAXAGE, set to it */
  192. age = (ulage > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : ulage);
  193. lsa->header->age = htons (age);
  194. return age;
  195. }
  196. /* update age field of LSA header with adding InfTransDelay */
  197. void
  198. ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay)
  199. {
  200. unsigned short age;
  201. age = ospf6_lsa_age_current (lsa) + transdelay;
  202. if (age > OSPF_LSA_MAXAGE)
  203. age = OSPF_LSA_MAXAGE;
  204. lsa->header->age = htons (age);
  205. }
  206. void
  207. ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
  208. {
  209. /* log */
  210. if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
  211. zlog_debug ("LSA: Premature aging: %s", lsa->name);
  212. THREAD_OFF (lsa->expire);
  213. THREAD_OFF (lsa->refresh);
  214. /*
  215. * We clear the LSA from the neighbor retx lists now because it
  216. * will not get deleted later. Essentially, changing the age to
  217. * MaxAge will prevent this LSA from being matched with its
  218. * existing entries in the retx list thereby causing those entries
  219. * to be silently replaced with its MaxAged version, but with ever
  220. * increasing retx count causing this LSA to remain forever and
  221. * for the MaxAge remover thread to be called forever too.
  222. *
  223. * The reason the previous entry silently disappears is that when
  224. * entry is added to a neighbor's retx list, it replaces the existing
  225. * entry. But since the ospf6_lsdb_add() routine is generic and not aware
  226. * of the special semantics of retx count, the retx count is not
  227. * decremented when its replaced. Attempting to add the incr and decr
  228. * retx count routines as the hook_add and hook_remove for the retx lists
  229. * have a problem because the hook_remove routine is called for MaxAge
  230. * entries (as will be the case in a traditional LSDB, unlike in this case
  231. * where an LSDB is used as an efficient tree structure to store all kinds
  232. * of data) that are added instead of calling the hook_add routine.
  233. */
  234. ospf6_flood_clear (lsa);
  235. lsa->header->age = htons (OSPF_LSA_MAXAGE);
  236. thread_execute (master, ospf6_lsa_expire, lsa, 0);
  237. }
  238. /* check which is more recent. if a is more recent, return -1;
  239. if the same, return 0; otherwise(b is more recent), return 1 */
  240. int
  241. ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
  242. {
  243. int seqnuma, seqnumb;
  244. u_int16_t cksuma, cksumb;
  245. u_int16_t agea, ageb;
  246. assert (a && a->header);
  247. assert (b && b->header);
  248. assert (OSPF6_LSA_IS_SAME (a, b));
  249. seqnuma = (int) ntohl (a->header->seqnum);
  250. seqnumb = (int) ntohl (b->header->seqnum);
  251. /* compare by sequence number */
  252. if (seqnuma > seqnumb)
  253. return -1;
  254. if (seqnuma < seqnumb)
  255. return 1;
  256. /* Checksum */
  257. cksuma = ntohs (a->header->checksum);
  258. cksumb = ntohs (b->header->checksum);
  259. if (cksuma > cksumb)
  260. return -1;
  261. if (cksuma < cksumb)
  262. return 0;
  263. /* Update Age */
  264. agea = ospf6_lsa_age_current (a);
  265. ageb = ospf6_lsa_age_current (b);
  266. /* MaxAge check */
  267. if (agea == OSPF_LSA_MAXAGE && ageb != OSPF_LSA_MAXAGE)
  268. return -1;
  269. else if (agea != OSPF_LSA_MAXAGE && ageb == OSPF_LSA_MAXAGE)
  270. return 1;
  271. /* Age check */
  272. if (agea > ageb && agea - ageb >= OSPF_LSA_MAXAGE_DIFF)
  273. return 1;
  274. else if (agea < ageb && ageb - agea >= OSPF_LSA_MAXAGE_DIFF)
  275. return -1;
  276. /* neither recent */
  277. return 0;
  278. }
  279. char *
  280. ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
  281. {
  282. char id[16], adv_router[16];
  283. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  284. inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
  285. sizeof (adv_router));
  286. snprintf (buf, size, "[%s Id:%s Adv:%s]",
  287. ospf6_lstype_name (lsa->header->type), id, adv_router);
  288. return buf;
  289. }
  290. void
  291. ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header)
  292. {
  293. char id[16], adv_router[16];
  294. inet_ntop (AF_INET, &header->id, id, sizeof (id));
  295. inet_ntop (AF_INET, &header->adv_router, adv_router,
  296. sizeof (adv_router));
  297. zlog_debug (" [%s Id:%s Adv:%s]",
  298. ospf6_lstype_name (header->type), id, adv_router);
  299. zlog_debug (" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",
  300. ntohs (header->age), (u_long) ntohl (header->seqnum),
  301. ntohs (header->checksum), ntohs (header->length));
  302. }
  303. void
  304. ospf6_lsa_header_print (struct ospf6_lsa *lsa)
  305. {
  306. ospf6_lsa_age_current (lsa);
  307. ospf6_lsa_header_print_raw (lsa->header);
  308. }
  309. void
  310. ospf6_lsa_show_summary_header (struct vty *vty)
  311. {
  312. vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
  313. "Type", "LSId", "AdvRouter", "Age", "SeqNum",
  314. "Cksm", "Len", "Duration", VNL);
  315. }
  316. void
  317. ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
  318. {
  319. char adv_router[16], id[16];
  320. struct timeval now, res;
  321. char duration[16];
  322. assert (lsa);
  323. assert (lsa->header);
  324. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  325. inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
  326. sizeof (adv_router));
  327. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  328. timersub (&now, &lsa->installed, &res);
  329. timerstring (&res, duration, sizeof (duration));
  330. vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
  331. ospf6_lstype_name (lsa->header->type),
  332. id, adv_router, ospf6_lsa_age_current (lsa),
  333. (u_long) ntohl (lsa->header->seqnum),
  334. ntohs (lsa->header->checksum), ntohs (lsa->header->length),
  335. duration, VNL);
  336. }
  337. void
  338. ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
  339. {
  340. u_char *start, *end, *current;
  341. char byte[4];
  342. start = (u_char *) lsa->header;
  343. end = (u_char *) lsa->header + ntohs (lsa->header->length);
  344. vty_out (vty, "%s", VNL);
  345. vty_out (vty, "%s:%s", lsa->name, VNL);
  346. for (current = start; current < end; current ++)
  347. {
  348. if ((current - start) % 16 == 0)
  349. vty_out (vty, "%s ", VNL);
  350. else if ((current - start) % 4 == 0)
  351. vty_out (vty, " ");
  352. snprintf (byte, sizeof (byte), "%02x", *current);
  353. vty_out (vty, "%s", byte);
  354. }
  355. vty_out (vty, "%s%s", VNL, VNL);
  356. return;
  357. }
  358. void
  359. ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
  360. {
  361. char adv_router[64], id[64];
  362. assert (lsa && lsa->header);
  363. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  364. inet_ntop (AF_INET, &lsa->header->adv_router,
  365. adv_router, sizeof (adv_router));
  366. vty_out (vty, "%s", VNL);
  367. vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  368. ospf6_lstype_name (lsa->header->type), VNL);
  369. vty_out (vty, "Link State ID: %s%s", id, VNL);
  370. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  371. vty_out (vty, "LS Sequence Number: %#010lx%s",
  372. (u_long) ntohl (lsa->header->seqnum), VNL);
  373. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  374. ntohs (lsa->header->checksum),
  375. ntohs (lsa->header->length), VNL);
  376. vty_out (vty, " Prev: %p This: %p Next: %p%s",
  377. lsa->prev, lsa, lsa->next, VNL);
  378. vty_out (vty, "Flag: %x %s", lsa->flag, VNL);
  379. vty_out (vty, "Lock: %d %s", lsa->lock, VNL);
  380. vty_out (vty, "ReTx Count: %d%s", lsa->retrans_count, VNL);
  381. vty_out (vty, "Threads: Expire: %x, Refresh: %x %s",
  382. lsa->expire, lsa->refresh, VNL);
  383. vty_out (vty, "%s", VNL);
  384. return;
  385. }
  386. void
  387. ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  388. {
  389. char adv_router[64], id[64];
  390. struct ospf6_lsa_handler *handler;
  391. assert (lsa && lsa->header);
  392. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  393. inet_ntop (AF_INET, &lsa->header->adv_router,
  394. adv_router, sizeof (adv_router));
  395. vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  396. ospf6_lstype_name (lsa->header->type), VNL);
  397. vty_out (vty, "Link State ID: %s%s", id, VNL);
  398. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  399. vty_out (vty, "LS Sequence Number: %#010lx%s",
  400. (u_long) ntohl (lsa->header->seqnum), VNL);
  401. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  402. ntohs (lsa->header->checksum),
  403. ntohs (lsa->header->length), VNL);
  404. handler = ospf6_get_lsa_handler (lsa->header->type);
  405. if (handler->show == NULL)
  406. handler = &unknown_handler;
  407. (*handler->show) (vty, lsa);
  408. vty_out (vty, "%s", VNL);
  409. }
  410. /* OSPFv3 LSA creation/deletion function */
  411. struct ospf6_lsa *
  412. ospf6_lsa_create (struct ospf6_lsa_header *header)
  413. {
  414. struct ospf6_lsa *lsa = NULL;
  415. struct ospf6_lsa_header *new_header = NULL;
  416. u_int16_t lsa_size = 0;
  417. /* size of the entire LSA */
  418. lsa_size = ntohs (header->length); /* XXX vulnerable */
  419. /* allocate memory for this LSA */
  420. new_header = (struct ospf6_lsa_header *)
  421. XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
  422. /* copy LSA from original header */
  423. memcpy (new_header, header, lsa_size);
  424. /* LSA information structure */
  425. /* allocate memory */
  426. lsa = (struct ospf6_lsa *)
  427. XCALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  428. lsa->header = (struct ospf6_lsa_header *) new_header;
  429. /* dump string */
  430. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  431. /* calculate birth of this lsa */
  432. ospf6_lsa_age_set (lsa);
  433. return lsa;
  434. }
  435. struct ospf6_lsa *
  436. ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
  437. {
  438. struct ospf6_lsa *lsa = NULL;
  439. struct ospf6_lsa_header *new_header = NULL;
  440. /* allocate memory for this LSA */
  441. new_header = (struct ospf6_lsa_header *)
  442. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
  443. /* copy LSA from original header */
  444. memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
  445. /* LSA information structure */
  446. /* allocate memory */
  447. lsa = (struct ospf6_lsa *)
  448. XCALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  449. lsa->header = (struct ospf6_lsa_header *) new_header;
  450. SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY);
  451. /* dump string */
  452. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  453. /* calculate birth of this lsa */
  454. ospf6_lsa_age_set (lsa);
  455. return lsa;
  456. }
  457. void
  458. ospf6_lsa_delete (struct ospf6_lsa *lsa)
  459. {
  460. assert (lsa->lock == 0);
  461. /* cancel threads */
  462. THREAD_OFF (lsa->expire);
  463. THREAD_OFF (lsa->refresh);
  464. /* do free */
  465. XFREE (MTYPE_OSPF6_LSA, lsa->header);
  466. XFREE (MTYPE_OSPF6_LSA, lsa);
  467. }
  468. struct ospf6_lsa *
  469. ospf6_lsa_copy (struct ospf6_lsa *lsa)
  470. {
  471. struct ospf6_lsa *copy = NULL;
  472. ospf6_lsa_age_current (lsa);
  473. if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
  474. copy = ospf6_lsa_create_headeronly (lsa->header);
  475. else
  476. copy = ospf6_lsa_create (lsa->header);
  477. assert (copy->lock == 0);
  478. copy->birth = lsa->birth;
  479. copy->originated = lsa->originated;
  480. copy->received = lsa->received;
  481. copy->installed = lsa->installed;
  482. copy->lsdb = lsa->lsdb;
  483. return copy;
  484. }
  485. /* increment reference counter of struct ospf6_lsa */
  486. void
  487. ospf6_lsa_lock (struct ospf6_lsa *lsa)
  488. {
  489. lsa->lock++;
  490. return;
  491. }
  492. /* decrement reference counter of struct ospf6_lsa */
  493. void
  494. ospf6_lsa_unlock (struct ospf6_lsa *lsa)
  495. {
  496. /* decrement reference counter */
  497. assert (lsa->lock > 0);
  498. lsa->lock--;
  499. if (lsa->lock != 0)
  500. return;
  501. ospf6_lsa_delete (lsa);
  502. }
  503. /* ospf6 lsa expiry */
  504. int
  505. ospf6_lsa_expire (struct thread *thread)
  506. {
  507. struct ospf6_lsa *lsa;
  508. lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
  509. assert (lsa && lsa->header);
  510. assert (OSPF6_LSA_IS_MAXAGE (lsa));
  511. assert (! lsa->refresh);
  512. lsa->expire = (struct thread *) NULL;
  513. if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
  514. {
  515. zlog_debug ("LSA Expire:");
  516. ospf6_lsa_header_print (lsa);
  517. }
  518. if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
  519. return 0; /* dbexchange will do something ... */
  520. /* reinstall lsa */
  521. ospf6_install_lsa (lsa);
  522. /* reflood lsa */
  523. ospf6_flood (NULL, lsa);
  524. /* schedule maxage remover */
  525. ospf6_maxage_remove (ospf6);
  526. return 0;
  527. }
  528. int
  529. ospf6_lsa_refresh (struct thread *thread)
  530. {
  531. struct ospf6_lsa *old, *self, *new;
  532. struct ospf6_lsdb *lsdb_self;
  533. assert (thread);
  534. old = (struct ospf6_lsa *) THREAD_ARG (thread);
  535. assert (old && old->header);
  536. old->refresh = (struct thread *) NULL;
  537. lsdb_self = ospf6_get_scoped_lsdb_self (old);
  538. self = ospf6_lsdb_lookup (old->header->type, old->header->id,
  539. old->header->adv_router, lsdb_self);
  540. if (self == NULL)
  541. {
  542. if (IS_OSPF6_DEBUG_LSA_TYPE (old->header->type))
  543. zlog_debug ("Refresh: could not find self LSA, flush %s", old->name);
  544. ospf6_lsa_premature_aging (old);
  545. return 0;
  546. }
  547. /* Reset age, increment LS sequence number. */
  548. self->header->age = htons (0);
  549. self->header->seqnum =
  550. ospf6_new_ls_seqnum (self->header->type, self->header->id,
  551. self->header->adv_router, old->lsdb);
  552. ospf6_lsa_checksum (self->header);
  553. new = ospf6_lsa_create (self->header);
  554. new->lsdb = old->lsdb;
  555. new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new,
  556. OSPF_LS_REFRESH_TIME);
  557. /* store it in the LSDB for self-originated LSAs */
  558. ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self);
  559. if (IS_OSPF6_DEBUG_LSA_TYPE (new->header->type))
  560. {
  561. zlog_debug ("LSA Refresh:");
  562. ospf6_lsa_header_print (new);
  563. }
  564. ospf6_install_lsa (new);
  565. ospf6_flood (NULL, new);
  566. return 0;
  567. }
  568. /* Fletcher Checksum -- Refer to RFC1008. */
  569. /* All the offsets are zero-based. The offsets in the RFC1008 are
  570. one-based. */
  571. unsigned short
  572. ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
  573. {
  574. u_char *buffer = (u_char *) &lsa_header->type;
  575. int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */
  576. /* Skip the AGE field */
  577. u_int16_t len = ntohs(lsa_header->length) - type_offset;
  578. /* Checksum offset starts from "type" field, not the beginning of the
  579. lsa_header struct. The offset is 14, rather than 16. */
  580. int checksum_offset = (u_char *) &lsa_header->checksum - buffer;
  581. return (unsigned short)fletcher_checksum(buffer, len, checksum_offset);
  582. }
  583. int
  584. ospf6_lsa_checksum_valid (struct ospf6_lsa_header *lsa_header)
  585. {
  586. u_char *buffer = (u_char *) &lsa_header->type;
  587. int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */
  588. /* Skip the AGE field */
  589. u_int16_t len = ntohs(lsa_header->length) - type_offset;
  590. return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
  591. }
  592. void
  593. ospf6_lsa_init (void)
  594. {
  595. ospf6_lsa_handler_vector = vector_init (0);
  596. ospf6_install_lsa_handler (&unknown_handler);
  597. }
  598. void
  599. ospf6_lsa_terminate (void)
  600. {
  601. vector_free (ospf6_lsa_handler_vector);
  602. }
  603. static char *
  604. ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
  605. {
  606. static char buf[64];
  607. unsigned int i;
  608. unsigned int size = strlen (h->name);
  609. if (!strcmp(h->name, "unknown") &&
  610. h->type != OSPF6_LSTYPE_UNKNOWN)
  611. {
  612. snprintf (buf, sizeof (buf), "%#04hx", h->type);
  613. return buf;
  614. }
  615. for (i = 0; i < MIN (size, sizeof (buf)); i++)
  616. {
  617. if (! islower (h->name[i]))
  618. buf[i] = tolower (h->name[i]);
  619. else
  620. buf[i] = h->name[i];
  621. }
  622. buf[size] = '\0';
  623. return buf;
  624. }
  625. DEFUN (debug_ospf6_lsa_type,
  626. debug_ospf6_lsa_hex_cmd,
  627. "debug ospf6 lsa (router|network|inter-prefix|inter-router|as-ext|grp-mbr|type7|link|intra-prefix|unknown)",
  628. DEBUG_STR
  629. OSPF6_STR
  630. "Debug Link State Advertisements (LSAs)\n"
  631. "Specify LS type as Hexadecimal\n"
  632. )
  633. {
  634. unsigned int i;
  635. struct ospf6_lsa_handler *handler = NULL;
  636. assert (argc);
  637. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  638. {
  639. handler = vector_slot (ospf6_lsa_handler_vector, i);
  640. if (handler == NULL)
  641. continue;
  642. if (strncmp (argv[0], ospf6_lsa_handler_name(handler), strlen(argv[0])) == 0)
  643. break;
  644. if (! strcasecmp (argv[0], handler->name))
  645. break;
  646. handler = NULL;
  647. }
  648. if (handler == NULL)
  649. handler = &unknown_handler;
  650. if (argc >= 2)
  651. {
  652. if (! strcmp (argv[1], "originate"))
  653. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
  654. if (! strcmp (argv[1], "examine"))
  655. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
  656. if (! strcmp (argv[1], "flooding"))
  657. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
  658. }
  659. else
  660. SET_FLAG (handler->debug, OSPF6_LSA_DEBUG);
  661. return CMD_SUCCESS;
  662. }
  663. ALIAS (debug_ospf6_lsa_type,
  664. debug_ospf6_lsa_hex_detail_cmd,
  665. "debug ospf6 lsa (router|network|inter-prefix|inter-router|as-ext|grp-mbr|type7|link|intra-prefix|unknown) (originate|examine|flooding)",
  666. DEBUG_STR
  667. OSPF6_STR
  668. "Debug Link State Advertisements (LSAs)\n"
  669. "Specify LS type as Hexadecimal\n"
  670. )
  671. DEFUN (no_debug_ospf6_lsa_type,
  672. no_debug_ospf6_lsa_hex_cmd,
  673. "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-ext|grp-mbr|type7|link|intra-prefix|unknown)",
  674. NO_STR
  675. DEBUG_STR
  676. OSPF6_STR
  677. "Debug Link State Advertisements (LSAs)\n"
  678. "Specify LS type as Hexadecimal\n"
  679. )
  680. {
  681. u_int i;
  682. struct ospf6_lsa_handler *handler = NULL;
  683. assert (argc);
  684. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  685. {
  686. handler = vector_slot (ospf6_lsa_handler_vector, i);
  687. if (handler == NULL)
  688. continue;
  689. if (strncmp (argv[0], ospf6_lsa_handler_name(handler), strlen(argv[0])) == 0)
  690. break;
  691. if (! strcasecmp (argv[0], handler->name))
  692. break;
  693. }
  694. if (handler == NULL)
  695. return CMD_SUCCESS;
  696. if (argc >= 2)
  697. {
  698. if (! strcmp (argv[1], "originate"))
  699. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE);
  700. if (! strcmp (argv[1], "examine"))
  701. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN);
  702. if (! strcmp (argv[1], "flooding"))
  703. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD);
  704. }
  705. else
  706. UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG);
  707. return CMD_SUCCESS;
  708. }
  709. ALIAS (no_debug_ospf6_lsa_type,
  710. no_debug_ospf6_lsa_hex_detail_cmd,
  711. "no debug ospf6 lsa (router|network|inter-prefix|inter-router|as-ext|grp-mbr|type7|link|intra-prefix) (originate|examine|flooding)",
  712. NO_STR
  713. DEBUG_STR
  714. OSPF6_STR
  715. "Debug Link State Advertisements (LSAs)\n"
  716. "Specify LS type as Hexadecimal\n"
  717. )
  718. void
  719. install_element_ospf6_debug_lsa (void)
  720. {
  721. install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_cmd);
  722. install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_detail_cmd);
  723. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd);
  724. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_detail_cmd);
  725. install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_cmd);
  726. install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_detail_cmd);
  727. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd);
  728. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_detail_cmd);
  729. }
  730. int
  731. config_write_ospf6_debug_lsa (struct vty *vty)
  732. {
  733. u_int i;
  734. struct ospf6_lsa_handler *handler;
  735. for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++)
  736. {
  737. handler = vector_slot (ospf6_lsa_handler_vector, i);
  738. if (handler == NULL)
  739. continue;
  740. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG))
  741. vty_out (vty, "debug ospf6 lsa %s%s",
  742. ospf6_lsa_handler_name (handler), VNL);
  743. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE))
  744. vty_out (vty, "debug ospf6 lsa %s originate%s",
  745. ospf6_lsa_handler_name (handler), VNL);
  746. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN))
  747. vty_out (vty, "debug ospf6 lsa %s examine%s",
  748. ospf6_lsa_handler_name (handler), VNL);
  749. if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD))
  750. vty_out (vty, "debug ospf6 lsa %s flooding%s",
  751. ospf6_lsa_handler_name (handler), VNL);
  752. }
  753. return 0;
  754. }