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

网络

开发平台:

Unix_Linux

  1. #include <zebra.h>
  2. #include <math.h>
  3. #include "log.h"
  4. #include "memory.h"
  5. #include "prefix.h"
  6. #include "table.h"
  7. #include "command.h"
  8. #include "vty.h"
  9. #include "thread.h"
  10. #include "linklist.h"
  11. #include "if.h"
  12. #include "ospf6_proto.h"
  13. #include "ospf6_lsa.h"
  14. #include "ospf6_lsdb.h"
  15. #include "ospf6_route.h"
  16. #include "ospf6_spf.h"
  17. #include "ospf6_top.h"
  18. #include "ospf6_area.h"
  19. #include "ospf6_interface.h"
  20. #include "ospf6_intra.h"
  21. extern char *malloc_options;
  22. struct thread_master *master;
  23. #define NUMBER_OF_TRIALS 1000000
  24. int N = 4;
  25. #define ROW(n) ((n) % N)
  26. #define COL(n) ((n) / N)
  27. #define IS_TOPOF(n) (COL(n) > 0)
  28. #define IS_BOTTOMOF(n) (COL(n) < N - 1)
  29. #define IS_LEFTOF(n) (ROW(n) > 0)
  30. #define IS_RIGHTOF(n) (ROW(n) < N - 1)
  31. #define TOPOF(n) (n - N)
  32. #define BOTTOMOF(n) (n + N)
  33. #define LEFTOF(n) (n - 1)
  34. #define RIGHTOF(n) (n + 1)
  35. #define IFINDEX_TOP    0
  36. #define IFINDEX_BOTTOM 1
  37. #define IFINDEX_LEFT   2
  38. #define IFINDEX_RIGHT  3
  39. struct in6_addr topaddr =
  40. {{{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, IFINDEX_TOP }}};
  42. struct in6_addr leftaddr =
  43. {{{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, IFINDEX_LEFT }}};
  45. struct in6_addr rightaddr =
  46. {{{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, IFINDEX_RIGHT }}};
  48. struct in6_addr bottomaddr =
  49. {{{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, IFINDEX_BOTTOM }}};
  51. void
  52. install_router_lsa (u_int32_t router_id, struct ospf6_lsdb *lsdb)
  53. {
  54.   char buffer[OSPF6_MAX_LSASIZE];
  55.   struct ospf6_lsa_header *lsa_header;
  56.   struct ospf6_lsa *lsa;
  57.   struct ospf6_router_lsa *router_lsa;
  58.   struct ospf6_router_lsdesc *lsdesc;
  59.   //printf ("install %dn", router_id);
  60.   lsa_header = (struct ospf6_lsa_header *) buffer;
  61.   router_lsa = (struct ospf6_router_lsa *)
  62.     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  63.   lsdesc = (struct ospf6_router_lsdesc *)
  64.     ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
  65.   if (IS_TOPOF (router_id))
  66.     {
  67.       lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
  68.       lsdesc->metric = htons (1);
  69.       lsdesc->interface_id = htonl (IFINDEX_TOP);
  70.       lsdesc->neighbor_interface_id = htonl (IFINDEX_BOTTOM);
  71.       lsdesc->neighbor_router_id = htonl (TOPOF (router_id));
  72.       lsdesc++;
  73.     }
  74.   if (IS_LEFTOF (router_id))
  75.     {
  76.       lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
  77.       lsdesc->metric = htons (1);
  78.       lsdesc->interface_id = htonl (IFINDEX_LEFT);
  79.       lsdesc->neighbor_interface_id = htonl (IFINDEX_RIGHT);
  80.       lsdesc->neighbor_router_id = htonl (LEFTOF (router_id));
  81.       lsdesc++;
  82.     }
  83.   if (IS_RIGHTOF (router_id))
  84.     {
  85.       lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
  86.       lsdesc->metric = htons (1);
  87.       lsdesc->interface_id = htonl (IFINDEX_RIGHT);
  88.       lsdesc->neighbor_interface_id = htonl (IFINDEX_LEFT);
  89.       lsdesc->neighbor_router_id = htonl (RIGHTOF (router_id));
  90.       lsdesc++;
  91.     }
  92.   if (IS_BOTTOMOF (router_id))
  93.     {
  94.       lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
  95.       lsdesc->metric = htons (1);
  96.       lsdesc->interface_id = htonl (IFINDEX_BOTTOM);
  97.       lsdesc->neighbor_interface_id = htonl (IFINDEX_TOP);
  98.       lsdesc->neighbor_router_id = htonl (BOTTOMOF (router_id));
  99.       lsdesc++;
  100.     }
  101.   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
  102.   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
  103.   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
  104.   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
  105.   OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
  106.   OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
  107.   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
  108.   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
  109.   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
  110.   UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
  111.   lsa_header->age = 0;
  112.   lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
  113.   lsa_header->id = htonl (0);
  114.   lsa_header->adv_router = htonl (router_id);
  115.   lsa_header->seqnum = htonl (INITIAL_SEQUENCE_NUMBER);
  116.   lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
  117.   lsa = ospf6_lsa_create (lsa_header);
  118.   ospf6_lsdb_add (lsa, lsdb);
  119. }
  120. static double
  121. diffsec (struct timeval *end, struct timeval *start)
  122. {
  123.   double time;
  124.   time = (end->tv_sec - start->tv_sec) * 1.0 +
  125.          (end->tv_usec - start->tv_usec) / 1000000.0;
  126.   if (time < 0.0)
  127.     fprintf (stderr, "time: %f end{%010lu,%010lu} start{%010lu,%010lu}n",
  128.              time, end->tv_sec, end->tv_usec, start->tv_sec, start->tv_usec);
  129.   return time;
  130. }
  131. void
  132. lsdb_lookup_try (int ntry, struct ospf6_lsdb *lsdb)
  133. {
  134.   struct ospf6_lsa *lsa;
  135.   struct timeval start, now;
  136.   double time, timesum, timesumsq;
  137.   double max, min, avg, variance, std;
  138.   int rets, retn;
  139.   int i;
  140.   u_int32_t router_id;
  141.   max = 0.0;
  142.   min = 999999999.0;
  143.   timesum = 0.0;
  144.   timesumsq = 0.0;
  145.   for (i = 0; i < ntry; i++)
  146.     {
  147.       router_id = random () % (N * N);
  148.       memset (&start, 0, sizeof (&start));
  149.       memset (&now, 0, sizeof (&now));
  150.       lsa = NULL;
  151.       rets = gettimeofday (&start, NULL);
  152.       lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0),
  153.                                htonl (router_id), lsdb);
  154.       retn = gettimeofday (&now, NULL);
  155.       assert (lsa);
  156.       if (rets != 0 || retn != 0)
  157.         {
  158.           fprintf (stderr, "gettimeofday failed: %sn", strerror (errno));
  159.           i--;
  160.           continue;
  161.         }
  162.       time = diffsec (&now, &start);
  163.       timesum += time;
  164.       timesumsq += time * time;
  165.       max = (time > max ? time : max);
  166.       min = (time < min ? time : min);
  167.     }
  168.   avg = timesum / ntry;
  169.   variance = (timesumsq - ntry * avg * avg) / ntry;
  170.   std = sqrt (variance);
  171.   printf ("test lsdb: #LSAs: %d #lookup: %d min: %.3f avg: %.3f max: %.3f stddev: %.3f (ms)n",
  172.           N * N, ntry, min * 1000.0, avg * 1000.0, max * 1000.0, std * 1000.0);
  173. }
  174. void
  175. install_link_lsdb (u_int32_t router_id, int ifindex)
  176. {
  177.   struct interface *ifp;
  178.   struct ospf6_interface *oi;
  179.   char *ifname = NULL;
  180.   u_int32_t peer = 0;
  181.   int peer_ifindex = 0;
  182.   char buffer[OSPF6_MAX_LSASIZE];
  183.   struct ospf6_lsa_header *lsa_header;
  184.   struct ospf6_link_lsa *link_lsa;
  185.   struct ospf6_lsa *lsa;
  186.   char *p;
  187.   if (ifindex == IFINDEX_TOP && IS_TOPOF (router_id))
  188.     {
  189.       ifname = "top";
  190.       peer = TOPOF (router_id);
  191.       peer_ifindex = IFINDEX_BOTTOM;
  192.     }
  193.   else if (ifindex == IFINDEX_LEFT && IS_LEFTOF (router_id))
  194.     {
  195.       ifname = "left";
  196.       peer = LEFTOF (router_id);
  197.       peer_ifindex = IFINDEX_RIGHT;
  198.     }
  199.   else if (ifindex == IFINDEX_RIGHT && IS_RIGHTOF (router_id))
  200.     {
  201.       ifname = "right";
  202.       peer = RIGHTOF (router_id);
  203.       peer_ifindex = IFINDEX_LEFT;
  204.     }
  205.   else if (ifindex == IFINDEX_BOTTOM && IS_BOTTOMOF (router_id))
  206.     {
  207.       ifname = "bottom";
  208.       peer = BOTTOMOF (router_id);
  209.       peer_ifindex = IFINDEX_TOP;
  210.     }
  211.   else
  212.     assert (0);
  213.   ifp = if_get_by_name (ifname);
  214.   ifp->ifindex = ifindex;
  215.   oi = malloc (sizeof (struct ospf6_interface));
  216.   oi->interface = ifp;
  217.   ifp->info = oi;
  218.   oi->lsdb = ospf6_lsdb_create (oi);
  219.   memset (buffer, 0, sizeof (buffer));
  220.   lsa_header = (struct ospf6_lsa_header *) buffer;
  221.   link_lsa = (struct ospf6_link_lsa *)
  222.     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  223.   p = ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
  224.   link_lsa->priority = 1;
  225.   link_lsa->options[0] = 0;
  226.   link_lsa->options[1] = 0;
  227.   link_lsa->options[2] = 0;
  228.   if (ifindex == IFINDEX_TOP)
  229.     link_lsa->linklocal_addr = topaddr;
  230.   else if (ifindex == IFINDEX_LEFT)
  231.     link_lsa->linklocal_addr = leftaddr;
  232.   else if (ifindex == IFINDEX_RIGHT)
  233.     link_lsa->linklocal_addr = rightaddr;
  234.   else
  235.     link_lsa->linklocal_addr = bottomaddr;
  236.   link_lsa->prefix_num = htonl (0);
  237.   lsa_header->age = 0;
  238.   lsa_header->type = htons (OSPF6_LSTYPE_LINK);
  239.   lsa_header->id = htonl (ifindex);
  240.   lsa_header->adv_router = htonl (router_id);
  241.   lsa_header->seqnum = htonl (INITIAL_SEQUENCE_NUMBER);
  242.   lsa_header->length = htons ((caddr_t) p - (caddr_t) buffer);
  243.   lsa = ospf6_lsa_create (lsa_header);
  244.   ospf6_lsdb_add (lsa, oi->lsdb);
  245.   /* peer's */
  246.   memset (buffer, 0, sizeof (buffer));
  247.   lsa_header = (struct ospf6_lsa_header *) buffer;
  248.   link_lsa = (struct ospf6_link_lsa *)
  249.     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  250.   p = ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
  251.   link_lsa->priority = 1;
  252.   link_lsa->options[0] = 0;
  253.   link_lsa->options[1] = 0;
  254.   link_lsa->options[2] = 0;
  255.   if (peer_ifindex == IFINDEX_TOP)
  256.     link_lsa->linklocal_addr = topaddr;
  257.   else if (peer_ifindex == IFINDEX_LEFT)
  258.     link_lsa->linklocal_addr = leftaddr;
  259.   else if (peer_ifindex == IFINDEX_RIGHT)
  260.     link_lsa->linklocal_addr = rightaddr;
  261.   else
  262.     link_lsa->linklocal_addr = bottomaddr;
  263.   link_lsa->prefix_num = htonl (0);
  264.   lsa_header->age = 0;
  265.   lsa_header->type = htons (OSPF6_LSTYPE_LINK);
  266.   lsa_header->id = htonl (peer_ifindex);
  267.   lsa_header->adv_router = htonl (peer);
  268.   lsa_header->seqnum = htonl (INITIAL_SEQUENCE_NUMBER);
  269.   lsa_header->length = htons ((caddr_t) p - (caddr_t) buffer);
  270.   lsa = ospf6_lsa_create (lsa_header);
  271.   ospf6_lsdb_add (lsa, oi->lsdb);
  272.   return;
  273. }
  274. void
  275. spf_try (u_int32_t router_id, struct ospf6_lsdb *lsdb)
  276. {
  277.   struct ospf6_area *oa;
  278.   struct ospf6_interface *oi;
  279.   struct timeval start, end;
  280.   double time;
  281.   int rets, rete;
  282.   listnode node;
  283.   oa = malloc (sizeof (struct ospf6_area));
  284.   snprintf (oa->name, sizeof (oa->name), "spf_test");
  285.   oa->lsdb = lsdb;
  286.   oa->spf_table = ospf6_route_table_create (); 
  287.   oa->if_list = list_new ();
  288.   if (IS_TOPOF (router_id))
  289.     {
  290.       install_link_lsdb (router_id, IFINDEX_TOP);
  291.       oi = ospf6_interface_lookup_by_ifindex (IFINDEX_TOP);
  292.       listnode_add (oa->if_list, oi);
  293.     }
  294.   if (IS_LEFTOF (router_id))
  295.     {
  296.       install_link_lsdb (router_id, IFINDEX_LEFT);
  297.       oi = ospf6_interface_lookup_by_ifindex (IFINDEX_LEFT);
  298.       listnode_add (oa->if_list, oi);
  299.     }
  300.   if (IS_RIGHTOF (router_id))
  301.     {
  302.       install_link_lsdb (router_id, IFINDEX_RIGHT);
  303.       oi = ospf6_interface_lookup_by_ifindex (IFINDEX_RIGHT);
  304.       listnode_add (oa->if_list, oi);
  305.     }
  306.   if (IS_BOTTOMOF (router_id))
  307.     {
  308.       install_link_lsdb (router_id, IFINDEX_BOTTOM);
  309.       oi = ospf6_interface_lookup_by_ifindex (IFINDEX_BOTTOM);
  310.       listnode_add (oa->if_list, oi);
  311.     }
  312.   rets = gettimeofday (&start, (struct timezone *) NULL);
  313.   ospf6_spf_calculation (htonl (router_id), oa->spf_table, oa);
  314.   rete = gettimeofday (&end, (struct timezone *) NULL);
  315.   if (rets != 0 || rete != 0)
  316.     fprintf (stderr, "gettimeofday failed: %sn", strerror (errno));
  317.   time = diffsec (&end, &start);
  318.   printf ("test spf: root: %lu #LSAs: %d #routes: %d time: %.3f (ms)n",
  319.           (unsigned long) router_id, N * N, oa->spf_table->count,
  320.           time * 1000.0);
  321.   for (node = listhead (oa->if_list); node; nextnode (node))
  322.     {
  323.       oi = (struct ospf6_interface *) getdata (node);
  324.       ospf6_lsdb_delete (oi->lsdb);
  325.       oi->interface->info = NULL;
  326.       free (oi);
  327.     }
  328.   list_delete (oa->if_list);
  329.   ospf6_route_table_delete (oa->spf_table);
  330.   free (oa);
  331. }
  332. int
  333. main (int argc, char **argv)
  334. {
  335.   struct ospf6_lsdb *lsdb;
  336.   u_int32_t router_id;
  337.   struct timeval start, now;
  338.   double timeadd;
  339. #if 0
  340.   malloc_options = "X";
  341. #endif
  342.   if (argc > 1)
  343.     N = atoi (argv[1]);
  344.   lsdb = ospf6_lsdb_create (NULL);
  345.   fprintf (stderr, "Installing %d virtual Router-LSA ... ", N * N);
  346.   fflush (stdout);
  347.   gettimeofday (&start, NULL);
  348.   for (router_id = 0; router_id < N * N; router_id++)
  349.     install_router_lsa (router_id, lsdb);
  350.   gettimeofday (&now, NULL);
  351.   timeadd = diffsec (&now, &start);
  352.   fprintf (stderr, "done (%.3f ms) n", timeadd * 1000.0);
  353.   gettimeofday (&now, NULL);
  354.   srandom (now.tv_sec);
  355.   //lsdb_lookup_try (NUMBER_OF_TRIALS, lsdb);
  356.   cmd_init (0);
  357.   vty_init ();
  358.   if_init ();
  359.   zlog_default = openzlog ("ospf6_test", ZLOG_STDERR, ZLOG_OSPF6,
  360.                            LOG_CONS|LOG_NDELAY|LOG_PERROR|LOG_PID,
  361.                            LOG_DAEMON);
  362.   OSPF6_DEBUG_SPF_OFF (OSPF6_DEBUG_SPF_PROCESS);
  363.   spf_try (0, lsdb);
  364.   spf_try ((N / 2) * (N + 1), lsdb);
  365.   return 0;
  366. }