ospf6_lsa.c 26 KB

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