ospf6_lsa.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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 "ospf6_proto.h"
  29. #include "ospf6_lsa.h"
  30. #include "ospf6_lsdb.h"
  31. #include "ospf6_message.h"
  32. #include "ospf6_top.h"
  33. #include "ospf6_area.h"
  34. #include "ospf6_interface.h"
  35. #include "ospf6_neighbor.h"
  36. #include "ospf6_flood.h"
  37. #include "ospf6d.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, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  235. OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
  236. vty_out (vty, "Link State ID: %s%s", id, VNL);
  237. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  238. vty_out (vty, "LS Sequence Number: %#010lx%s",
  239. (u_long) ntohl (lsa->header->seqnum), VNL);
  240. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  241. ntohs (lsa->header->checksum),
  242. ntohs (lsa->header->length), VNL);
  243. index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
  244. if (ospf6_lstype[index].show)
  245. (*ospf6_lstype[index].show) (vty, lsa);
  246. else
  247. vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
  248. vty_out (vty, "%s", VNL);
  249. }
  250. void
  251. ospf6_lsa_show_summary_header (struct vty *vty)
  252. {
  253. vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
  254. "Type", "LSId", "AdvRouter", "Age", "SeqNum",
  255. "Cksm", "Len", "Duration", VNL);
  256. }
  257. void
  258. ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
  259. {
  260. char adv_router[16], id[16];
  261. struct timeval now, res;
  262. char duration[16];
  263. assert (lsa);
  264. assert (lsa->header);
  265. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  266. inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
  267. sizeof (adv_router));
  268. gettimeofday (&now, NULL);
  269. timersub (&now, &lsa->installed, &res);
  270. timerstring (&res, duration, sizeof (duration));
  271. vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
  272. OSPF6_LSTYPE_NAME (lsa->header->type),
  273. id, adv_router, ospf6_lsa_age_current (lsa),
  274. (u_long) ntohl (lsa->header->seqnum),
  275. ntohs (lsa->header->checksum), ntohs (lsa->header->length),
  276. duration, VNL);
  277. }
  278. void
  279. ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
  280. {
  281. u_char *start, *end, *current;
  282. char byte[4];
  283. start = (char *) lsa->header;
  284. end = (char *) lsa->header + ntohs (lsa->header->length);
  285. vty_out (vty, "%s", VNL);
  286. vty_out (vty, "%s:%s", lsa->name, VNL);
  287. for (current = start; current < end; current ++)
  288. {
  289. if ((current - start) % 16 == 0)
  290. vty_out (vty, "%s ", VNL);
  291. else if ((current - start) % 4 == 0)
  292. vty_out (vty, " ");
  293. snprintf (byte, sizeof (byte), "%02x", *current);
  294. vty_out (vty, "%s", byte);
  295. }
  296. vty_out (vty, "%s%s", VNL, VNL);
  297. }
  298. void
  299. ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
  300. {
  301. char adv_router[64], id[64];
  302. assert (lsa && lsa->header);
  303. inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
  304. inet_ntop (AF_INET, &lsa->header->adv_router,
  305. adv_router, sizeof (adv_router));
  306. vty_out (vty, "%s", VNL);
  307. vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
  308. OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
  309. vty_out (vty, "Link State ID: %s%s", id, VNL);
  310. vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
  311. vty_out (vty, "LS Sequence Number: %#010lx%s",
  312. (u_long) ntohl (lsa->header->seqnum), VNL);
  313. vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
  314. ntohs (lsa->header->checksum),
  315. ntohs (lsa->header->length), VNL);
  316. vty_out (vty, " Prev: %p This: %p Next: %p%s",
  317. lsa->prev, lsa, lsa->next, VNL);
  318. vty_out (vty, "%s", VNL);
  319. }
  320. /* OSPFv3 LSA creation/deletion function */
  321. struct ospf6_lsa *
  322. ospf6_lsa_create (struct ospf6_lsa_header *header)
  323. {
  324. struct ospf6_lsa *lsa = NULL;
  325. struct ospf6_lsa_header *new_header = NULL;
  326. u_int16_t lsa_size = 0;
  327. /* size of the entire LSA */
  328. lsa_size = ntohs (header->length); /* XXX vulnerable */
  329. /* allocate memory for this LSA */
  330. new_header = (struct ospf6_lsa_header *)
  331. XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
  332. /* copy LSA from original header */
  333. memcpy (new_header, header, lsa_size);
  334. /* LSA information structure */
  335. /* allocate memory */
  336. lsa = (struct ospf6_lsa *)
  337. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  338. memset (lsa, 0, sizeof (struct ospf6_lsa));
  339. lsa->header = (struct ospf6_lsa_header *) new_header;
  340. lsa->headeronly = 0; /* this is not header only */
  341. /* dump string */
  342. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  343. /* calculate birth, expire and refresh of this lsa */
  344. ospf6_lsa_age_set (lsa);
  345. if (IS_OSPF6_DEBUG_LSA (MEMORY))
  346. zlog_info ("Create LSA Memory: %s (%p/%p)",
  347. lsa->name, lsa, lsa->header);
  348. return lsa;
  349. }
  350. struct ospf6_lsa *
  351. ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
  352. {
  353. struct ospf6_lsa *lsa = NULL;
  354. struct ospf6_lsa_header *new_header = NULL;
  355. /* allocate memory for this LSA */
  356. new_header = (struct ospf6_lsa_header *)
  357. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
  358. /* copy LSA from original header */
  359. memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
  360. /* LSA information structure */
  361. /* allocate memory */
  362. lsa = (struct ospf6_lsa *)
  363. XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
  364. memset (lsa, 0, sizeof (struct ospf6_lsa));
  365. lsa->header = (struct ospf6_lsa_header *) new_header;
  366. lsa->headeronly = 1; /* this is header only */
  367. /* dump string */
  368. ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
  369. /* calculate birth, expire and refresh of this lsa */
  370. ospf6_lsa_age_set (lsa);
  371. if (IS_OSPF6_DEBUG_LSA (MEMORY))
  372. zlog_info ("Create LSA (Header-only) Memory: %s (%p/%p)",
  373. lsa->name, lsa, lsa->header);
  374. return lsa;
  375. }
  376. void
  377. ospf6_lsa_delete (struct ospf6_lsa *lsa)
  378. {
  379. assert (lsa->lock == 0);
  380. /* cancel threads */
  381. THREAD_OFF (lsa->expire);
  382. THREAD_OFF (lsa->refresh);
  383. if (IS_OSPF6_DEBUG_LSA (MEMORY))
  384. zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
  385. (lsa->headeronly ? "(Header-only) " : ""),
  386. lsa->name, lsa, lsa->header);
  387. /* do free */
  388. XFREE (MTYPE_OSPF6_LSA, lsa->header);
  389. XFREE (MTYPE_OSPF6_LSA, lsa);
  390. }
  391. struct ospf6_lsa *
  392. ospf6_lsa_copy (struct ospf6_lsa *lsa)
  393. {
  394. struct ospf6_lsa *copy = NULL;
  395. if (IS_OSPF6_DEBUG_LSA (MEMORY))
  396. zlog_info ("Create LSA Copy from %s", lsa->name);
  397. ospf6_lsa_age_current (lsa);
  398. if (lsa->headeronly)
  399. copy = ospf6_lsa_create_headeronly (lsa->header);
  400. else
  401. copy = ospf6_lsa_create (lsa->header);
  402. assert (copy->lock == 0);
  403. copy->installed = lsa->installed;
  404. copy->originated = lsa->originated;
  405. copy->scope = lsa->scope;
  406. return copy;
  407. }
  408. /* increment reference counter of struct ospf6_lsa */
  409. void
  410. ospf6_lsa_lock (struct ospf6_lsa *lsa)
  411. {
  412. lsa->lock++;
  413. return;
  414. }
  415. /* decrement reference counter of struct ospf6_lsa */
  416. void
  417. ospf6_lsa_unlock (struct ospf6_lsa *lsa)
  418. {
  419. /* decrement reference counter */
  420. assert (lsa->lock > 0);
  421. lsa->lock--;
  422. if (lsa->lock != 0)
  423. return;
  424. ospf6_lsa_delete (lsa);
  425. }
  426. void
  427. ospf6_lsa_originate (struct ospf6_lsa *lsa)
  428. {
  429. struct ospf6_lsa *old;
  430. struct ospf6_lsdb *lsdb = NULL;
  431. /* find previous LSA */
  432. lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
  433. if (lsdb == NULL)
  434. {
  435. zlog_warn ("Can't decide scoped LSDB");
  436. ospf6_lsa_delete (lsa);
  437. return;
  438. }
  439. old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
  440. lsa->header->adv_router, lsdb);
  441. if (old)
  442. {
  443. /* If this origination is neither different instance nor refresh,
  444. suppress this origination */
  445. if (! CHECK_FLAG (old->flag, OSPF6_LSA_REFRESH) &&
  446. ! OSPF6_LSA_IS_DIFFER (lsa, old))
  447. {
  448. if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
  449. zlog_info ("Suppress updating LSA: %s", lsa->name);
  450. ospf6_lsa_delete (lsa);
  451. return;
  452. }
  453. }
  454. lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
  455. LS_REFRESH_TIME);
  456. if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
  457. {
  458. zlog_info ("LSA Originate:");
  459. ospf6_lsa_header_print (lsa);
  460. }
  461. if (old)
  462. ospf6_flood_clear (old);
  463. ospf6_flood_lsa (lsa, NULL);
  464. ospf6_install_lsa (lsa, lsdb);
  465. }
  466. void
  467. ospf6_lsa_re_originate (struct ospf6_lsa *lsa)
  468. {
  469. u_int16_t index;
  470. if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
  471. {
  472. zlog_info ("LSA Reoriginate:");
  473. ospf6_lsa_header_print (lsa);
  474. }
  475. index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
  476. if (ospf6_lstype[index].reoriginate)
  477. (*ospf6_lstype[index].reoriginate) (lsa);
  478. else
  479. ospf6_lsa_premature_aging (lsa);
  480. }
  481. /* ospf6 lsa expiry */
  482. int
  483. ospf6_lsa_expire (struct thread *thread)
  484. {
  485. struct ospf6_lsa *lsa;
  486. struct ospf6_lsdb *lsdb = NULL;
  487. lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
  488. assert (lsa && lsa->header);
  489. assert (OSPF6_LSA_IS_MAXAGE (lsa));
  490. assert (! lsa->refresh);
  491. lsa->expire = (struct thread *) NULL;
  492. if (IS_OSPF6_DEBUG_LSA (TIMER))
  493. {
  494. zlog_info ("LSA Expire:");
  495. ospf6_lsa_header_print (lsa);
  496. }
  497. if (lsa->headeronly)
  498. return 0; /* dbexchange will do something ... */
  499. /* reflood lsa */
  500. ospf6_flood_lsa (lsa, NULL);
  501. /* reinstall lsa */
  502. lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
  503. if (lsdb == NULL)
  504. {
  505. zlog_warn ("Can't decide scoped LSDB: %s", lsa->name);
  506. return 0;
  507. }
  508. if (IS_OSPF6_DEBUG_LSA (DATABASE))
  509. zlog_info ("Reinstall MaxAge %s", lsa->name);
  510. ospf6_lsdb_add (lsa, lsdb);
  511. /* schedule maxage remover */
  512. ospf6_maxage_remove (ospf6);
  513. return 0;
  514. }
  515. /* Below will become dummy thread.
  516. refresh function must be set individually per each LSAs */
  517. int
  518. ospf6_lsa_refresh (struct thread *thread)
  519. {
  520. struct ospf6_lsa *lsa;
  521. assert (thread);
  522. lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
  523. assert (lsa && lsa->header);
  524. lsa->refresh = (struct thread *) NULL;
  525. /* this will be used later to decide really originate or not */
  526. SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
  527. if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
  528. {
  529. zlog_info ("LSA Refresh:");
  530. ospf6_lsa_header_print (lsa);
  531. }
  532. ospf6_lsa_re_originate (lsa);
  533. return 0;
  534. }
  535. /* enhanced Fletcher checksum algorithm, RFC1008 7.2 */
  536. #define MODX 4102
  537. #define LSA_CHECKSUM_OFFSET 15
  538. unsigned short
  539. ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
  540. {
  541. u_char *sp, *ep, *p, *q;
  542. int c0 = 0, c1 = 0;
  543. int x, y;
  544. u_int16_t length;
  545. lsa_header->checksum = 0;
  546. length = ntohs (lsa_header->length) - 2;
  547. sp = (char *) &lsa_header->type;
  548. for (ep = sp + length; sp < ep; sp = q)
  549. {
  550. q = sp + MODX;
  551. if (q > ep)
  552. q = ep;
  553. for (p = sp; p < q; p++)
  554. {
  555. c0 += *p;
  556. c1 += c0;
  557. }
  558. c0 %= 255;
  559. c1 %= 255;
  560. }
  561. /* r = (c1 << 8) + c0; */
  562. x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
  563. if (x <= 0)
  564. x += 255;
  565. y = 510 - c0 - x;
  566. if (y > 255)
  567. y -= 255;
  568. lsa_header->checksum = htons ((x << 8) + y);
  569. return (lsa_header->checksum);
  570. }
  571. int
  572. ospf6_unknown_reoriginate (struct ospf6_lsa *lsa)
  573. {
  574. ospf6_lsa_premature_aging (lsa);
  575. return 0;
  576. }
  577. int
  578. ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
  579. {
  580. u_char *start, *end, *current;
  581. char byte[4];
  582. start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
  583. end = (char *) lsa->header + ntohs (lsa->header->length);
  584. vty_out (vty, " Unknown contents:%s", VNL);
  585. for (current = start; current < end; current ++)
  586. {
  587. if ((current - start) % 16 == 0)
  588. vty_out (vty, "%s ", VNL);
  589. else if ((current - start) % 4 == 0)
  590. vty_out (vty, " ");
  591. snprintf (byte, sizeof (byte), "%02x", *current);
  592. vty_out (vty, "%s", byte);
  593. }
  594. vty_out (vty, "%s%s", VNL, VNL);
  595. return 0;
  596. }
  597. void
  598. ospf6_lsa_init ()
  599. {
  600. memset (ospf6_lstype, 0, sizeof (ospf6_lstype));
  601. ospf6_lstype[0].name = "Unknown";
  602. ospf6_lstype[0].reoriginate = ospf6_unknown_reoriginate;
  603. ospf6_lstype[0].show = ospf6_unknown_show;
  604. }
  605. DEFUN (debug_ospf6_lsa_sendrecv,
  606. debug_ospf6_lsa_sendrecv_cmd,
  607. "debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
  608. DEBUG_STR
  609. OSPF6_STR
  610. "Debug Link State Advertisements (LSAs)\n"
  611. "Debug Sending LSAs\n"
  612. "Debug Receiving LSAs\n"
  613. "Debug Originating LSAs\n"
  614. "Debug Timer Event of LSAs\n"
  615. "Debug LSA Database\n"
  616. "Debug Memory of LSAs\n"
  617. "Debug LSAs all\n"
  618. )
  619. {
  620. unsigned char level = 0;
  621. if (argc)
  622. {
  623. if (! strncmp (argv[0], "s", 1))
  624. level = OSPF6_DEBUG_LSA_SEND;
  625. else if (! strncmp (argv[0], "r", 1))
  626. level = OSPF6_DEBUG_LSA_RECV;
  627. else if (! strncmp (argv[0], "o", 1))
  628. level = OSPF6_DEBUG_LSA_ORIGINATE;
  629. else if (! strncmp (argv[0], "t", 1))
  630. level = OSPF6_DEBUG_LSA_TIMER;
  631. else if (! strncmp (argv[0], "d", 1))
  632. level = OSPF6_DEBUG_LSA_DATABASE;
  633. else if (! strncmp (argv[0], "m", 1))
  634. level = OSPF6_DEBUG_LSA_MEMORY;
  635. else if (! strncmp (argv[0], "a", 1))
  636. {
  637. level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
  638. OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
  639. OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
  640. }
  641. }
  642. else
  643. {
  644. level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
  645. OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
  646. }
  647. OSPF6_DEBUG_LSA_ON (level);
  648. return CMD_SUCCESS;
  649. }
  650. ALIAS (debug_ospf6_lsa_sendrecv,
  651. debug_ospf6_lsa_cmd,
  652. "debug ospf6 lsa",
  653. NO_STR
  654. DEBUG_STR
  655. OSPF6_STR
  656. "Debug Link State Advertisements (LSAs)\n"
  657. );
  658. DEFUN (no_debug_ospf6_lsa_sendrecv,
  659. no_debug_ospf6_lsa_sendrecv_cmd,
  660. "no debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
  661. NO_STR
  662. DEBUG_STR
  663. OSPF6_STR
  664. "Debug Link State Advertisements (LSAs)\n"
  665. "Debug Sending LSAs\n"
  666. "Debug Receiving LSAs\n"
  667. "Debug Originating LSAs\n"
  668. "Debug Timer Event of LSAs\n"
  669. "Debug LSA Database\n"
  670. "Debug Memory of LSAs\n"
  671. "Debug LSAs all\n"
  672. )
  673. {
  674. unsigned char level = 0;
  675. if (argc)
  676. {
  677. if (! strncmp (argv[0], "s", 1))
  678. level = OSPF6_DEBUG_LSA_SEND;
  679. else if (! strncmp (argv[0], "r", 1))
  680. level = OSPF6_DEBUG_LSA_RECV;
  681. else if (! strncmp (argv[0], "o", 1))
  682. level = OSPF6_DEBUG_LSA_ORIGINATE;
  683. else if (! strncmp (argv[0], "t", 1))
  684. level = OSPF6_DEBUG_LSA_TIMER;
  685. else if (! strncmp (argv[0], "d", 1))
  686. level = OSPF6_DEBUG_LSA_DATABASE;
  687. else if (! strncmp (argv[0], "m", 1))
  688. level = OSPF6_DEBUG_LSA_MEMORY;
  689. else if (! strncmp (argv[0], "a", 1))
  690. {
  691. level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
  692. OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
  693. OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
  694. }
  695. }
  696. else
  697. {
  698. level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
  699. OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
  700. }
  701. OSPF6_DEBUG_LSA_OFF (level);
  702. return CMD_SUCCESS;
  703. }
  704. ALIAS (no_debug_ospf6_lsa_sendrecv,
  705. no_debug_ospf6_lsa_cmd,
  706. "no debug ospf6 lsa",
  707. NO_STR
  708. DEBUG_STR
  709. OSPF6_STR
  710. "Debug Link State Advertisements (LSAs)\n"
  711. );
  712. int
  713. config_write_ospf6_debug_lsa (struct vty *vty)
  714. {
  715. if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_ALL)
  716. vty_out (vty, "debug ospf6 lsa all%s", VNL);
  717. else
  718. {
  719. if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
  720. vty_out (vty, "debug ospf6 lsa%s", VNL);
  721. else
  722. {
  723. if (IS_OSPF6_DEBUG_LSA (SEND))
  724. vty_out (vty, "debug ospf6 lsa send%s", VNL);
  725. if (IS_OSPF6_DEBUG_LSA (RECV))
  726. vty_out (vty, "debug ospf6 lsa recv%s", VNL);
  727. if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
  728. vty_out (vty, "debug ospf6 lsa originate%s", VNL);
  729. if (IS_OSPF6_DEBUG_LSA (TIMER))
  730. vty_out (vty, "debug ospf6 lsa timer%s", VNL);
  731. }
  732. if (IS_OSPF6_DEBUG_LSA (DATABASE))
  733. vty_out (vty, "debug ospf6 lsa database%s", VNL);
  734. if (IS_OSPF6_DEBUG_LSA (MEMORY))
  735. vty_out (vty, "debug ospf6 lsa memory%s", VNL);
  736. }
  737. return 0;
  738. }
  739. void
  740. install_element_ospf6_debug_lsa ()
  741. {
  742. install_element (ENABLE_NODE, &debug_ospf6_lsa_cmd);
  743. install_element (ENABLE_NODE, &debug_ospf6_lsa_sendrecv_cmd);
  744. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_cmd);
  745. install_element (ENABLE_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
  746. install_element (CONFIG_NODE, &debug_ospf6_lsa_cmd);
  747. install_element (CONFIG_NODE, &debug_ospf6_lsa_sendrecv_cmd);
  748. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_cmd);
  749. install_element (CONFIG_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
  750. }