⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ospf6_spf.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 3 页
字号:
          if (stat_candidate_max < ospf6_spf_candidate_count ())            stat_candidate_max = ospf6_spf_candidate_count ();          listnode_add (candidate_list, W);          ospf6_spf_candidate_enqueue (W);        }    }  assert (listcount (candidate_list) == 0);  list_free (candidate_list);  assert (ospf6_spf_candidate_count () == 0);  /* Clear thread timer */  o6a->spf_tree->t_spf_calculation = (struct thread *) NULL;  if (IS_OSPF6_DUMP_SPF)    {      zlog_info ("SPF: Calculation for area %s done", o6a->str);      zlog_info ("SPF:   Statistics: %luth", (u_long)stat_spf);      zlog_info ("SPF:   Node Number: %lu", (u_long)stat_node);      zlog_info ("SPF:   Candidate Number: %lu Max: %lu",                 (u_long) stat_candidate, (u_long) stat_candidate_max);    }  ospf6_route_table_thaw (o6a->table_topology);  return 0;}intospf6_spf_calculation_thread (struct thread *t){  struct ospf6_area *o6a;  struct timeval start, end, runtime, interval;  o6a = (struct ospf6_area *) THREAD_ARG (t);  if (! o6a)    {      zlog_err ("SPF: Thread error");      return -1;    }  if (! o6a->spf_tree)    {      zlog_err ("SPF: Can't find SPF Tree for area: %s", o6a->str);      return -1;    }  /* execute SPF calculation */  gettimeofday (&start, (struct timezone *) NULL);  ospf6_spf_calculation (o6a);  gettimeofday (&end, (struct timezone *) NULL);  /* update statistics */  o6a->spf_tree->timerun ++;  ospf6_timeval_sub (&end, &start, &runtime);  ospf6_timeval_add_equal (&runtime, &o6a->spf_tree->runtime_total);  if (o6a->spf_tree->timerun == 1)    {      o6a->spf_tree->runtime_min.tv_sec = runtime.tv_sec;      o6a->spf_tree->runtime_min.tv_usec = runtime.tv_usec;      o6a->spf_tree->runtime_max.tv_sec = runtime.tv_sec;      o6a->spf_tree->runtime_max.tv_usec = runtime.tv_usec;    }  if (ospf6_timeval_cmp (o6a->spf_tree->runtime_min, runtime) > 0)    {      o6a->spf_tree->runtime_min.tv_sec = runtime.tv_sec;      o6a->spf_tree->runtime_min.tv_usec = runtime.tv_usec;    }  if (ospf6_timeval_cmp (runtime, o6a->spf_tree->runtime_max) > 0)    {      o6a->spf_tree->runtime_max.tv_sec = runtime.tv_sec;      o6a->spf_tree->runtime_max.tv_usec = runtime.tv_usec;    }  if (o6a->spf_tree->timerun == 1)    {      ospf6_timeval_sub (&start, &ospf6->starttime, &interval);      ospf6_timeval_add_equal (&interval, &o6a->spf_tree->interval_total);      o6a->spf_tree->interval_min.tv_sec = interval.tv_sec;      o6a->spf_tree->interval_min.tv_usec = interval.tv_usec;      o6a->spf_tree->interval_max.tv_sec = interval.tv_sec;      o6a->spf_tree->interval_max.tv_usec = interval.tv_usec;    }  else    {      ospf6_timeval_sub (&start, &o6a->spf_tree->updated_time, &interval);      ospf6_timeval_add_equal (&interval, &o6a->spf_tree->interval_total);      if (ospf6_timeval_cmp (o6a->spf_tree->interval_min, interval) > 0)        {          o6a->spf_tree->interval_min.tv_sec = interval.tv_sec;          o6a->spf_tree->interval_min.tv_usec = interval.tv_usec;        }      if (ospf6_timeval_cmp (interval, o6a->spf_tree->interval_max) > 0)        {          o6a->spf_tree->interval_max.tv_sec = interval.tv_sec;          o6a->spf_tree->interval_max.tv_usec = interval.tv_usec;        }    }  o6a->spf_tree->updated_time.tv_sec = end.tv_sec;  o6a->spf_tree->updated_time.tv_usec = end.tv_usec;  /* clear thread */  o6a->spf_tree->t_spf_calculation = (struct thread *) NULL;  return 0;}voidospf6_spf_database_hook (struct ospf6_lsa *old, struct ospf6_lsa *new){  struct ospf6_area *o6a = NULL;  struct ospf6_interface *o6i = NULL;  if (new->header->type == htons (OSPF6_LSA_TYPE_ROUTER) ||      new->header->type == htons (OSPF6_LSA_TYPE_NETWORK))    o6a = new->scope;  else if (new->header->type == htons (OSPF6_LSA_TYPE_LINK))    {      o6i = new->scope;      o6a = o6i->area;    }  if (o6a)    ospf6_spf_calculation_schedule (o6a->area_id);}voidospf6_spf_calculation_schedule (u_int32_t area_id){  struct ospf6_area *o6a;  char buf[64];  o6a = ospf6_area_lookup (area_id, ospf6);  if (! o6a)    {      inet_ntop (AF_INET, &area_id, buf, sizeof (buf));      zlog_err ("SPF: Can't find area: %s", buf);      return;    }  if (! o6a->spf_tree)    {      zlog_err ("SPF: Can't find SPF Tree for area: %s", o6a->str);      return;    }  if (o6a->spf_tree->t_spf_calculation)    return;  o6a->spf_tree->t_spf_calculation =    thread_add_event (master, ospf6_spf_calculation_thread, o6a, 0);}struct ospf6_spftree *ospf6_spftree_create (){  struct ospf6_spftree *spf_tree;  spf_tree = (struct ospf6_spftree *) XMALLOC (MTYPE_OSPF6_SPFTREE,                                               sizeof (struct ospf6_spftree));  if (! spf_tree)    {      zlog_err ("SPF: Can't allocate memory for SPF tree");      return (struct ospf6_spftree *) NULL;    }  memset (spf_tree, 0, sizeof (spf_tree));  spf_tree->list = list_new ();  return spf_tree;}voidospf6_spftree_delete (struct ospf6_spftree *spf_tree){  listnode node;  struct ospf6_vertex *v;  /* Delete spf tree */  for (node = listhead (spf_tree->list); node; nextnode (node))    {      v = (struct ospf6_vertex *) getdata (node);      ospf6_spf_vertex_delete (v);    }  list_delete_all_node (spf_tree->list);  XFREE (MTYPE_OSPF6_SPFTREE, spf_tree);}voidospf6_nexthop_show (struct vty *vty, struct ospf6_nexthop *nexthop){  char buf[128], *ifname;  struct ospf6_interface *o6i;  ifname = NULL;  o6i = ospf6_interface_lookup_by_index (nexthop->ifindex);  if (! o6i)    {      zlog_err ("Spf: invalid ifindex %d in nexthop", nexthop->ifindex);    }  else    ifname = o6i->interface->name;  inet_ntop (AF_INET6, &nexthop->address, buf, sizeof (buf));  vty_out (vty, "    %s%%%s(%d)%s", buf, ifname,           nexthop->ifindex, VTY_NEWLINE);}voidospf6_vertex_show (struct vty *vty, struct ospf6_vertex *vertex){  listnode node;  struct ospf6_vertex *v;  struct linklist_node lnode;  vty_out (vty, "SPF node %s%s", vertex->string, VTY_NEWLINE);  vty_out (vty, "  cost to this node: %d%s", vertex->distance, VTY_NEWLINE);  vty_out (vty, "  hops to this node: %d%s", vertex->depth, VTY_NEWLINE);  vty_out (vty, "  nexthops reachable to this node:%s", VTY_NEWLINE);  for (linklist_head (vertex->nexthop_list, &lnode);       ! linklist_end (&lnode);       linklist_next (&lnode))    ospf6_nexthop_show (vty, (struct ospf6_nexthop *) lnode.data);  vty_out (vty, "  parent nodes to this node:%s", VTY_NEWLINE);  if (! list_isempty (vertex->parent_list))    vty_out (vty, "    ");  for (node = listhead (vertex->parent_list); node; nextnode (node))    {      v = (struct ospf6_vertex *) getdata (node);      vty_out (vty, "%s ", v->string);    }  if (! list_isempty (vertex->parent_list))    vty_out (vty, "%s", VTY_NEWLINE);  vty_out (vty, "  child nodes to this node:%s", VTY_NEWLINE);  if (! list_isempty (vertex->path_list))    vty_out (vty, "    ");  for (node = listhead (vertex->path_list); node; nextnode (node))    {      v = (struct ospf6_vertex *) getdata (node);      vty_out (vty, "%s ", v->string);    }  if (! list_isempty (vertex->path_list))    vty_out (vty, "%s", VTY_NEWLINE);  vty_out (vty, "%s", VTY_NEWLINE);}voidospf6_spf_statistics_show (struct vty *vty, struct ospf6_spftree *spf_tree){  listnode node;  struct ospf6_vertex *vertex;  u_int router_count, network_count, maxdepth;  struct timeval runtime_avg, interval_avg, last_updated, now;  char rmin[64], rmax[64], ravg[64];  char imin[64], imax[64], iavg[64];  char last_updated_string[64];  maxdepth = router_count = network_count = 0;  for (node = listhead (spf_tree->list); node; nextnode (node))    {      vertex = (struct ospf6_vertex *) getdata (node);      if (vertex->vertex_id.id.s_addr)        network_count++;      else        router_count++;      if (maxdepth < vertex->depth)        maxdepth = vertex->depth;    }  ospf6_timeval_div (&spf_tree->runtime_total, spf_tree->timerun,                     &runtime_avg);  ospf6_timeval_string (&spf_tree->runtime_min, rmin, sizeof (rmin));  ospf6_timeval_string (&spf_tree->runtime_max, rmax, sizeof (rmax));  ospf6_timeval_string (&runtime_avg, ravg, sizeof (ravg));  ospf6_timeval_div (&spf_tree->interval_total, spf_tree->timerun,                     &interval_avg);  ospf6_timeval_string (&spf_tree->interval_min, imin, sizeof (imin));  ospf6_timeval_string (&spf_tree->interval_max, imax, sizeof (imax));  ospf6_timeval_string (&interval_avg, iavg, sizeof (iavg));  gettimeofday (&now, (struct timezone *) NULL);  ospf6_timeval_sub (&now, &spf_tree->updated_time, &last_updated);  ospf6_timeval_string (&last_updated, last_updated_string,                        sizeof (last_updated_string));  vty_out (vty, "     SPF algorithm executed %d times%s",            spf_tree->timerun, VTY_NEWLINE);  vty_out (vty, "     Average time to run SPF: %s%s",           ravg, VTY_NEWLINE);  vty_out (vty, "     Maximum time to run SPF: %s%s",           rmax, VTY_NEWLINE);  vty_out (vty, "     Average interval of SPF: %s%s",           iavg, VTY_NEWLINE);  vty_out (vty, "     SPF last updated: %s ago%s",           last_updated_string, VTY_NEWLINE);  vty_out (vty, "     Current SPF node count: %d%s",           listcount (spf_tree->list), VTY_NEWLINE);  vty_out (vty, "       Router: %d Network: %d%s",           router_count, network_count, VTY_NEWLINE);  vty_out (vty, "       Maximum of Hop count to nodes: %d%s",           maxdepth, VTY_NEWLINE);}DEFUN (show_ipv6_ospf6_area_spf_node,       show_ipv6_ospf6_area_spf_node_cmd,       "show ipv6 ospf6 area A.B.C.D spf node",       SHOW_STR       IP6_STR       OSPF6_STR       OSPF6_AREA_STR       OSPF6_AREA_ID_STR       "Shortest Path First caculation\n"       "vertex infomation\n"       ){  listnode i;  u_int32_t area_id;  struct ospf6_area *o6a;  struct ospf6_vertex *vertex;  OSPF6_CMD_CHECK_RUNNING ();  inet_pton (AF_INET, argv[0], &area_id);  o6a = ospf6_area_lookup (area_id, ospf6);  if (! o6a)    return CMD_SUCCESS;  for (i = listhead (o6a->spf_tree->list); i; nextnode (i))    {      vertex = (struct ospf6_vertex *) getdata (i);      ospf6_vertex_show (vty, vertex);    }  return CMD_SUCCESS;}static voidospf6_spftree_show (struct vty *vty, char *prefix, int current_rest,                    struct ospf6_vertex *v){  char *p;  int psize;  int restnum;  listnode node;  vty_out (vty, "%s+-%s%s", prefix, v->string, VTY_NEWLINE);  if (listcount (v->path_list) == 0)    return;  psize = strlen (prefix) + 3;  p = malloc (psize);  if (!p)    {      vty_out (vty, "depth too long ...%s", VTY_NEWLINE);      return;    }  restnum = listcount (v->path_list);  for (node = listhead (v->path_list); node; nextnode (node))    {      --restnum;      snprintf (p, psize, "%s%s", prefix, (current_rest ? "| " : "  "));      ospf6_spftree_show (vty, p, restnum,                          (struct ospf6_vertex *) getdata (node));    }  free (p);}DEFUN (show_ipv6_ospf6_area_spf_tree,       show_ipv6_ospf6_area_spf_tree_cmd,       "show ipv6 ospf6 area A.B.C.D spf tree",       SHOW_STR       IP6_STR       OSPF6_STR       OSPF6_AREA_STR       OSPF6_AREA_ID_STR       "Shortest Path First caculation\n"       "Displays spf tree\n"){  u_int32_t area_id;  struct ospf6_area *o6a;  OSPF6_CMD_CHECK_RUNNING ();  inet_pton (AF_INET, argv[0], &area_id);  o6a = ospf6_area_lookup (area_id, ospf6);  if (! o6a)    return CMD_SUCCESS;  vty_out (vty, "%s        SPF tree for Area %s%s%s",           VTY_NEWLINE, o6a->str, VTY_NEWLINE, VTY_NEWLINE);  if (! o6a->spf_tree->root)    return CMD_SUCCESS;  ospf6_spftree_show (vty, "", 0, o6a->spf_tree->root);  return CMD_SUCCESS;}DEFUN (show_ipv6_ospf6_area_topology,       show_ipv6_ospf6_area_topology_cmd,       "show ipv6 ospf6 area A.B.C.D topology",       SHOW_STR       IP6_STR       OSPF6_STR       OSPF6_AREA_STR       OSPF6_AREA_ID_STR       OSPF6_SPF_STR       "Displays SPF topology table\n"){  struct ospf6_area *o6a;  u_int32_t area_id;  OSPF6_CMD_CHECK_RUNNING ();  inet_pton (AF_INET, argv[0], &area_id);  o6a = ospf6_area_lookup (area_id, ospf6);  if (! o6a)    return CMD_SUCCESS;  argc -= 1;  argv += 1;  return ospf6_route_table_show (vty, argc, argv, o6a->table_topology);}ALIAS (show_ipv6_ospf6_area_topology,       show_ipv6_ospf6_area_topology_router_cmd,       "show ipv6 ospf6 area A.B.C.D topology (A.B.C.D|<0-4294967295>|detail)",       SHOW_STR       IP6_STR       OSPF6_STR       OSPF6_AREA_STR       OSPF6_AREA_ID_STR       OSPF6_SPF_STR       "Displays SPF topology table\n"       OSPF6_ROUTER_ID_STR       OSPF6_ROUTER_ID_STR       );ALIAS (show_ipv6_ospf6_area_topology,       show_ipv6_ospf6_area_topology_router_lsid_cmd,       "show ipv6 ospf6 area A.B.C.D topology (A.B.C.D|<0-4294967295>) (A.B.C.D|<0-4294967295>)",       SHOW_STR       IP6_STR       OSPF6_STR       OSPF6_AREA_STR       OSPF6_AREA_ID_STR       OSPF6_SPF_STR       "Displays SPF topology table\n"       OSPF6_ROUTER_ID_STR       OSPF6_ROUTER_ID_STR       OSPF6_LS_ID_STR       OSPF6_LS_ID_STR       );voidospf6_spf_init (){  nexthop_list = linklist_create ();  ospf6_spf_candidate_init ();  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_node_cmd);  install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);  install_element (VIEW_NODE, &show_ipv6_ospf6_area_topology_cmd);  install_element (VIEW_NODE, &show_ipv6_ospf6_area_topology_router_cmd);  install_element (VIEW_NODE, &show_ipv6_ospf6_area_topology_router_lsid_cmd);  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_node_cmd);  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_topology_cmd);  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_topology_router_cmd);  install_element (ENABLE_NODE, &show_ipv6_ospf6_area_topology_router_lsid_cmd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -