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

📄 ospf6_asbr.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
      info->prev = route->info_tail;      if (route->info_tail)        route->info_tail->next = info;      else        route->info_head = info;      route->info_tail = info;      info->id = link_state_id++;    }  /* copy result of route-map */  info->metric_type = tinfo.metric_type;  info->metric = tinfo.metric;  memcpy (&info->forwarding, &tinfo.forwarding,          sizeof (struct in6_addr));  info->type = type;  info->ifindex = ifindex;  if (nexthop_num && nexthop)    {      info->nexthop_num = nexthop_num;      if (info->nexthop)        XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info->nexthop);      info->nexthop = (struct in6_addr *)        XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,                 nexthop_num * sizeof (struct in6_addr));      memcpy (info->nexthop, nexthop,              nexthop_num * sizeof (struct in6_addr));    }  info->is_removed = 0;  //if (IS_OSPF6_DUMP_ASBR)    {      char pbuf[64];      struct timeval now;      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));      gettimeofday (&now, NULL);      zlog_info ("ASBR: start redistributing %s as LS-ID %ld: %ld.%06ld",                 pbuf, (u_long) info->id, now.tv_sec, now.tv_usec);    }#ifdef HAVE_OSPF6_DAMP  ospf6_damp_event_up (OSPF6_DAMP_TYPE_ROUTE, prefix,                       ospf6_asbr_schedule_external, info);#else /*HAVE_OSPF6_DAMP*/  ospf6_asbr_schedule_external (info);#endif /*HAVE_OSPF6_DAMP*/}voidospf6_asbr_route_remove (int type, int ifindex, struct prefix *prefix){  struct route_node *node;  struct ospf6_external_route *route;  struct ospf6_external_info *info;  struct ospf6_lsa *lsa;  node = route_node_get (external_table, prefix);  route = node->info;  if (! route)    return;  for (info = route->info_head; info; info = info->next)    {      if (info->type == type && info->ifindex == ifindex)        break;    }  if (! info)    return;  //if (IS_OSPF6_DUMP_ASBR)    {      char pbuf[64];      struct timeval now;      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));      gettimeofday (&now, NULL);      zlog_info ("ASBR: quit redistributing %s as LS-ID %ld: %ld.%06ld",                 pbuf, (u_long) info->id, now.tv_sec, now.tv_usec);    }  if (info->thread_originate)    thread_cancel (info->thread_originate);  info->thread_originate = NULL;  lsa = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),                           htonl (info->id), ospf6->router_id, ospf6);#ifdef HAVE_OSPF6_DAMP  ospf6_damp_event_down (OSPF6_DAMP_TYPE_ROUTE, &info->route->prefix,                         ospf6_asbr_external_lsa_flush, lsa);#else /*HAVE_OSPF6_DAMP*/  ospf6_asbr_external_lsa_flush (lsa);#endif /*HAVE_OSPF6_DAMP*/#if 1  info->is_removed = 1;#else  /* remove from route */  if (info->prev)    info->prev->next = info->next;  else    info->route->info_head = info->next;  if (info->next)    info->next->prev = info->prev;  else    info->route->info_tail = info->prev;  /* if no info, free route */  if (! info->route->info_head && ! info->route->info_tail)    {      info->route->node->info = NULL;      free (info->route);    }  if (info->nexthop)    free (info->nexthop);  free (info);#endif /*0*/}voidospf6_asbr_external_lsa_add (struct ospf6_lsa *lsa){  struct ospf6_lsa_as_external *external;  struct prefix_ls asbr_id;  struct ospf6_route_req asbr_entry;  struct ospf6_route_req request;  external = OSPF6_LSA_HEADER_END (lsa->header);  if (IS_LSA_MAXAGE (lsa))    {      if (IS_OSPF6_DUMP_ASBR)        zlog_info ("ASBR: maxage external lsa: %s seq: %lx",                   lsa->str, (u_long)ntohl (lsa->header->seqnum));      ospf6_asbr_external_lsa_remove (lsa);      return;    }  if (IS_OSPF6_DUMP_ASBR)    zlog_info ("ASBR: new external lsa: %s seq: %lx",               lsa->str, (u_long)ntohl (lsa->header->seqnum));  if (lsa->header->adv_router == ospf6->router_id)    {      if (IS_OSPF6_DUMP_ASBR)        zlog_info ("ASBR: my external LSA, ignore");      return;    }  if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)    {      if (IS_OSPF6_DUMP_ASBR)        zlog_info ("ASBR: metric is infinity, ignore");      return;    }  memset (&asbr_id, 0, sizeof (asbr_id));  asbr_id.family = AF_UNSPEC;  asbr_id.prefixlen = 64; /* xxx */  asbr_id.adv_router.s_addr = lsa->header->adv_router;  ospf6_route_lookup (&asbr_entry, (struct prefix *) &asbr_id,                      ospf6->topology_table);  if (ospf6_route_end (&asbr_entry))    {      if (IS_OSPF6_DUMP_ASBR)        {          char buf[64];          inet_ntop (AF_INET, &asbr_id.adv_router, buf, sizeof (buf));          zlog_info ("ASBR: router %s not found, ignore", buf);        }      return;    }  memset (&request, 0, sizeof (request));  request.route.type = OSPF6_DEST_TYPE_NETWORK;  request.route.prefix.family = AF_INET6;  request.route.prefix.prefixlen = external->prefix.prefix_length;  memcpy (&request.route.prefix.u.prefix6, (char *)(external + 1),          OSPF6_PREFIX_SPACE (request.route.prefix.prefixlen));  request.path.area_id = asbr_entry.path.area_id;  request.path.origin.type = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);  request.path.origin.id = lsa->header->id;  request.path.origin.adv_router = lsa->header->adv_router;  if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))    {      request.path.type = OSPF6_PATH_TYPE_EXTERNAL2;      request.path.metric_type = 2;      request.path.cost = asbr_entry.path.cost;      request.path.cost_e2 = OSPF6_ASBR_METRIC (external);    }  else    {      request.path.type = OSPF6_PATH_TYPE_EXTERNAL1;      request.path.metric_type = 1;      request.path.cost = asbr_entry.path.cost                          + OSPF6_ASBR_METRIC (external);      request.path.cost_e2 = 0;    }  request.path.prefix_options = external->prefix.prefix_options;  while (((struct prefix_ls *)&asbr_entry.route.prefix)->adv_router.s_addr ==         asbr_id.adv_router.s_addr &&         asbr_entry.route.type == OSPF6_DEST_TYPE_ROUTER)    {      memcpy (&request.nexthop, &asbr_entry.nexthop,              sizeof (struct ospf6_nexthop));      if (IS_OSPF6_DUMP_ASBR)        {          char buf[64], nhop[64], ifname[IFNAMSIZ];          prefix2str (&request.route.prefix, buf, sizeof (buf));          inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop));          if_indextoname (request.nexthop.ifindex, ifname);          zlog_info ("ASBR: add route: %s %s%%%s", buf, nhop, ifname);        }      ospf6_route_add (&request, ospf6->route_table);      ospf6_route_next (&asbr_entry);    }}voidospf6_asbr_external_lsa_remove (struct ospf6_lsa *lsa){  struct ospf6_lsa_as_external *external;  struct prefix dest;  char buf[64];  struct ospf6_route_req request;  if (IS_OSPF6_DUMP_ASBR)    zlog_info ("ASBR: withdraw external lsa: %s seq: %lx",               lsa->str, (u_long)ntohl (lsa->header->seqnum));  if (lsa->header->adv_router == ospf6->router_id)    {      if (IS_OSPF6_DUMP_ASBR)        zlog_info ("ASBR: my external LSA, ignore");      return;    }  external = OSPF6_LSA_HEADER_END (lsa->header);  memset (&dest, 0, sizeof (dest));  dest.family = AF_INET6;  dest.prefixlen = external->prefix.prefix_length;  memcpy (&dest.u.prefix6, (char *)(external + 1),          OSPF6_PREFIX_SPACE (dest.prefixlen));  ospf6_route_lookup (&request, &dest, ospf6->route_table);  if (ospf6_route_end (&request))    {      if (IS_OSPF6_DUMP_ASBR)        {          prefix2str (&dest, buf, sizeof (buf));          zlog_info ("ASBR: %s not found", buf);        }      return;    }  while (request.path.origin.id != lsa->header->id ||         request.path.origin.adv_router != lsa->header->adv_router)    {      if (prefix_same (&request.route.prefix, &dest) != 1)        {          if (IS_OSPF6_DUMP_ASBR)            zlog_info ("ASBR:   Can't find the entry matches the origin");          return;        }      ospf6_route_next (&request);    }  assert (request.path.origin.id == lsa->header->id);  assert (request.path.origin.adv_router == request.path.origin.adv_router);  while (request.path.origin.id == lsa->header->id &&         request.path.origin.adv_router == lsa->header->adv_router &&         prefix_same (&request.route.prefix, &dest) == 1)    {      if (IS_OSPF6_DUMP_ASBR)        {          char nhop[64], ifname[IFNAMSIZ];          prefix2str (&dest, buf, sizeof (buf));          inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop));          if_indextoname (request.nexthop.ifindex, ifname);          zlog_info ("ASBR: remove route: %s %s%%%s", buf, nhop, ifname);        }      ospf6_route_remove (&request, ospf6->route_table);      ospf6_route_next (&request);    }}voidospf6_asbr_external_lsa_change (struct ospf6_lsa *old, struct ospf6_lsa *new){  assert (old || new);  if (old == NULL)    ospf6_asbr_external_lsa_add (new);  else if (new == NULL)    ospf6_asbr_external_lsa_remove (old);  else    {      ospf6_route_table_freeze (ospf6->route_table);      ospf6_asbr_external_lsa_remove (old);      ospf6_asbr_external_lsa_add (new);      ospf6_route_table_thaw (ospf6->route_table);    }}voidospf6_asbr_asbr_entry_add (struct ospf6_route_req *topo_entry){  struct ospf6_lsdb_node node;  struct prefix_ls *inter_router;  u_int32_t id, adv_router;  inter_router = (struct prefix_ls *) &topo_entry->route.prefix;  id = inter_router->id.s_addr;  adv_router = inter_router->adv_router.s_addr;  if (IS_OSPF6_DUMP_ASBR)    {      char buf[64];      inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf));      zlog_info ("ASBR: new router found: %s", buf);    }  if (ntohl (id) != 0 ||      ! OSPF6_OPT_ISSET (topo_entry->path.capability, OSPF6_OPT_E))    {      zlog_warn ("ASBR: Inter topology table malformed");      return;    }  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_AS_EXTERNAL),                               adv_router, ospf6->lsdb);       ! ospf6_lsdb_is_end (&node);       ospf6_lsdb_next (&node))    ospf6_asbr_external_lsa_add (node.lsa);}voidospf6_asbr_asbr_entry_remove (struct ospf6_route_req *topo_entry){  struct prefix_ls *inter_router;  u_int32_t id, adv_router;  struct ospf6_route_req request;  inter_router = (struct prefix_ls *) &topo_entry->route.prefix;  id = inter_router->id.s_addr;  adv_router = inter_router->adv_router.s_addr;  if (IS_OSPF6_DUMP_ASBR)    {      char buf[64];      inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf));      zlog_info ("ASBR: router disappearing: %s", buf);    }  if (ntohl (id) != 0 ||      ! OSPF6_OPT_ISSET (topo_entry->path.capability, OSPF6_OPT_E))    {      zlog_warn ("ASBR: Inter topology table malformed");    }  for (ospf6_route_head (&request, ospf6->route_table);       ! ospf6_route_end (&request);       ospf6_route_next (&request))    {      if (request.path.type != OSPF6_PATH_TYPE_EXTERNAL1 &&          request.path.type != OSPF6_PATH_TYPE_EXTERNAL2)        continue;      if (request.path.area_id != topo_entry->path.area_id)        continue;      if (request.path.origin.adv_router != topo_entry->path.origin.adv_router)        continue;      if (memcmp (&topo_entry->nexthop, &request.nexthop,                  sizeof (struct ospf6_nexthop)))        continue;      ospf6_route_remove (&request, ospf6->route_table);    }}intospf6_asbr_external_show (struct vty *vty, struct ospf6_lsa *lsa){  struct ospf6_lsa_as_external *external;  char buf[128], *ptr;  struct in6_addr in6;  assert (lsa->header);  external = (struct ospf6_lsa_as_external *)(lsa->header + 1);    /* bits */  snprintf (buf, sizeof (buf), "%s%s%s",            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ?             "E" : "-"),            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ?             "F" : "-"),            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ?             "T" : "-"));  vty_out (vty, "     Bits: %s%s", buf, VTY_NEWLINE);  vty_out (vty, "     Metric: %5lu%s", (u_long)OSPF6_ASBR_METRIC (external),           VTY_NEWLINE);  ospf6_prefix_options_str (external->prefix.prefix_options,                            buf, sizeof (buf));  vty_out (vty, "     Prefix Options: %s%s", buf, VTY_NEWLINE);  vty_out (vty, "     Referenced LSType: %d%s",           ntohs (external->prefix.prefix_refer_lstype), VTY_NEWLINE);  ospf6_prefix_in6_addr (&external->prefix, &in6);  inet_ntop (AF_INET6, &in6, buf, sizeof (buf));  vty_out (vty, "     Prefix: %s/%d%s",           buf, external->prefix.prefix_length, VTY_NEWLINE);  /* Forwarding-Address */  if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))    {      ptr = ((char *)(external + 1))            + OSPF6_PREFIX_SPACE (external->prefix.prefix_length);      inet_ntop (AF_INET6, (struct in6_addr *) ptr, buf, sizeof (buf));      vty_out (vty, "     Forwarding-Address: %s%s", buf, VTY_NEWLINE);    }  return 0;}voidospf6_asbr_database_hook (struct ospf6_lsa *old, struct ospf6_lsa *new){  if (old)    ospf6_asbr_external_lsa_remove (old);  if (new && ! IS_LSA_MAXAGE (new))    ospf6_asbr_external_lsa_add (new);}voidospf6_asbr_register_as_external (){  struct ospf6_lsa_slot slot;  memset (&slot, 0, sizeof (slot));  slot.type              = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);  slot.name              = "AS-External";  slot.func_show         = ospf6_asbr_external_show;  slot.func_refresh      = ospf6_asbr_external_lsa_refresh;  ospf6_lsa_slot_register (&slot);  ospf6_lsdb_hook[OSPF6_LSA_TYPE_AS_EXTERNAL & OSPF6_LSTYPE_CODE_MASK].hook =     ospf6_asbr_database_hook;}voidospf6_asbr_external_info_show (struct vty *vty,                               struct ospf6_external_info *info){  char prefix_buf[64], id_buf[16];  struct in_addr id;  if (info->is_removed)    return;  id.s_addr = ntohl (info->id);  inet_ntop (AF_INET, &id, id_buf, sizeof (id_buf));  prefix2str (&info->route->prefix, prefix_buf, sizeof (prefix_buf));  vty_out (vty, "%s %-32s %3d %-15s %3d %lu(type-%d)%s",           ZROUTE_ABNAME(info->type), prefix_buf, info->ifindex, id_buf,           info->nexthop_num, (u_long) info->metric, info->metric_type,           VTY_NEWLINE);}voidospf6_asbr_external_route_show (struct vty *vty,                                struct ospf6_external_route *route){  struct ospf6_external_info *info;  for (info = route->info_head; info; info = info->next)    ospf6_asbr_external_info_show (vty, info);}DEFUN (show_ipv6_route_ospf6_external,       show_ipv6_route_ospf6_external_cmd,       "show ipv6 ospf6 route redistribute",       SHOW_STR       IP6_STR       ROUTE_STR       OSPF6_STR       "redistributing External information\n"       ){  struct route_node *node;  struct ospf6_external_route *route;  vty_out (vty, "%s %-32s %3s %-15s %3s %s%s",           " ", "Prefix", "I/F", "LS-Id", "#NH", "Metric",           VTY_NEWLINE);  for (node = route_top (external_table); node; node = route_next (node))    {      route = node->info;      if (route)        ospf6_asbr_external_route_show (vty, route);    }  return CMD_SUCCESS;}voidospf6_asbr_init (){  external_table = route_table_init ();  link_state_id = 0;  ospf6_asbr_register_as_external ();  install_element (VIEW_NODE, &show_ipv6_route_ospf6_external_cmd);  install_element (ENABLE_NODE, &show_ipv6_route_ospf6_external_cmd);  install_element (OSPF6_NODE, &ospf6_redistribute_cmd);  install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);  install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);}

⌨️ 快捷键说明

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