ospf6_lsa.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:26k
源码类别:

网络

开发平台:

Unix_Linux

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