ospf6_lsa.c 25 KB

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