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

📄 ospf6_interface.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1999 Yasuhiro Ohara * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING.  If not, write to the  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  * Boston, MA 02111-1307, USA.   */#include "ospf6d.h"#include "if.h"#include "log.h"#include "command.h"#include "ospf6_lsdb.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"char *ospf6_interface_state_string[] =  {    "None", "Down", "Loopback", "Waiting", "PointToPoint",    "DROther", "BDR", "DR", NULL  };static voidospf6_interface_foreach_neighbor (struct ospf6_interface *o6i,                                  void *arg, int val,                                  void (*func) (void *, int, void *)){  listnode node;  struct ospf6_neighbor *nei;  for (node = listhead (o6i->neighbor_list); node; nextnode (node))    {      nei = (struct ospf6_neighbor *) getdata (node);      (*func) (arg, val, nei);    }}static intospf6_interface_maxage_remover (struct thread *t){  int count;  struct ospf6_interface *o6i = (struct ospf6_interface *) THREAD_ARG (t);  o6i->maxage_remover = (struct thread *) NULL;  count = 0;  o6i->foreach_nei (o6i, &count, NBS_EXCHANGE, ospf6_count_state);  o6i->foreach_nei (o6i, &count, NBS_LOADING, ospf6_count_state);  if (count != 0)    return 0;  ospf6_lsdb_remove_maxage (o6i->lsdb);  return 0;}voidospf6_interface_schedule_maxage_remover (void *arg, int val, void *obj){  struct ospf6_interface *o6i = (struct ospf6_interface *) obj;  if (o6i->maxage_remover != NULL)    return;  o6i->maxage_remover =    thread_add_event (master, ospf6_interface_maxage_remover, o6i, 0);}/* Create new ospf6 interface structure */struct ospf6_interface *ospf6_interface_create (struct interface *ifp){  struct ospf6_interface *o6i;  o6i = (struct ospf6_interface *)    XMALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));  if (o6i)    memset (o6i, 0, sizeof (struct ospf6_interface));  else    {      zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);      return (struct ospf6_interface *) NULL;    }  o6i->instance_id = 0;  o6i->if_id = ifp->ifindex;  o6i->lladdr = (struct in6_addr *) NULL;  o6i->area = (struct ospf6_area *) NULL;  o6i->state = IFS_DOWN;  o6i->flag = 0;  o6i->neighbor_list = list_new ();  o6i->ack_list = ospf6_lsdb_create ();  o6i->lsdb = ospf6_lsdb_create ();  o6i->transdelay = 1;  o6i->priority = 1;  o6i->hello_interval = 10;  o6i->dead_interval = 40;  o6i->rxmt_interval = 5;  o6i->cost = 1;  o6i->ifmtu = 1280;  o6i->foreach_nei = ospf6_interface_foreach_neighbor;  /* link both */  o6i->interface = ifp;  ifp->info = o6i;  CALL_ADD_HOOK (&interface_hook, o6i);  /* Get the interface's link-local if any */  ospf6_interface_address_update(ifp);  return o6i;}voidospf6_interface_delete (struct ospf6_interface *o6i){  listnode n;  struct ospf6_neighbor *o6n;  CALL_REMOVE_HOOK (&interface_hook, o6i);  for (n = listhead (o6i->neighbor_list); n; nextnode (n))    {      o6n = (struct ospf6_neighbor *) getdata (n);      ospf6_neighbor_delete (o6n);    }  list_delete (o6i->neighbor_list);  if (o6i->thread_send_hello)    {      thread_cancel (o6i->thread_send_hello);      o6i->thread_send_hello = NULL;    }  if (o6i->thread_send_lsack_delayed)    {      thread_cancel (o6i->thread_send_lsack_delayed);      o6i->thread_send_lsack_delayed = NULL;    }  ospf6_lsdb_delete (o6i->ack_list);  ospf6_lsdb_remove_all (o6i->lsdb);  ospf6_lsdb_delete (o6i->lsdb);  /* cut link */  o6i->interface->info = NULL;  /* plist_name */  if (o6i->plist_name)    XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name);  XFREE (MTYPE_OSPF6_IF, o6i);}static struct in6_addr *ospf6_interface_update_linklocal_address (struct interface *ifp){  listnode n;  struct connected *c;  struct in6_addr *l = (struct in6_addr *) NULL;  /* for each connected address */  for (n = listhead (ifp->connected); n; nextnode (n))    {      c = (struct connected *) getdata (n);      /* if family not AF_INET6, ignore */      if (c->address->family != AF_INET6)        continue;      /* linklocal scope check */      if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))        l = &c->address->u.prefix6;    }  return l;}voidospf6_interface_if_add (struct interface *ifp){  struct ospf6_interface *o6i;  o6i = (struct ospf6_interface *) ifp->info;  if (!o6i)    return;  o6i->if_id = ifp->ifindex;  ospf6_interface_address_update (ifp);  /* interface start */  if (o6i->area)    thread_add_event (master, interface_up, o6i, 0);}voidospf6_interface_if_del (struct interface *ifp){  struct ospf6_interface *o6i;  o6i = (struct ospf6_interface *) ifp->info;  if (!o6i)    return;  /* interface stop */  if (o6i->area)    thread_execute (master, interface_down, o6i, 0);  listnode_delete (o6i->area->if_list, o6i);  o6i->area = (struct ospf6_area *) NULL;  /* cut link */  o6i->interface = NULL;  ifp->info = NULL;  ospf6_interface_delete (o6i);}voidospf6_interface_state_update (struct interface *ifp){  struct ospf6_interface *o6i;  o6i = (struct ospf6_interface *) ifp->info;  if (! o6i)    return;  if (! o6i->area)    return;  if (if_is_up (ifp))    thread_add_event (master, interface_up, o6i, 0);  else    thread_add_event (master, interface_down, o6i, 0);  return;}voidospf6_interface_address_update (struct interface *ifp){  struct ospf6_interface *o6i;  o6i = (struct ospf6_interface *) ifp->info;  if (! o6i)    return;  /* reset linklocal pointer */  o6i->lladdr = ospf6_interface_update_linklocal_address (ifp);  /* if area is null, can't make link-lsa */  if (! o6i->area)    return;  /* create new Link-LSA */  CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i);  CALL_CHANGE_HOOK (&interface_hook, o6i);}struct ospf6_interface *ospf6_interface_lookup_by_index (int ifindex){  struct ospf6_interface *o6i;  struct interface *ifp;  ifp = if_lookup_by_index (ifindex);  if (! ifp)    return (struct ospf6_interface *) NULL;  o6i = (struct ospf6_interface *) ifp->info;  return o6i;}struct ospf6_interface *ospf6_interface_lookup_by_name (char *ifname){  struct ospf6_interface *o6i;  struct interface *ifp;  ifp = if_lookup_by_name (ifname);  if (! ifp)    return (struct ospf6_interface *) NULL;  o6i = (struct ospf6_interface *) ifp->info;  return o6i;}intospf6_interface_count_neighbor_in_state (u_char state,                                         struct ospf6_interface *o6i){  listnode n;  struct ospf6_neighbor *o6n;  int count = 0;  for (n = listhead (o6i->neighbor_list); n; nextnode (n))    {      o6n = (struct ospf6_neighbor *) getdata (n);      if (o6n->state == state)        count++;    }  return count;}intospf6_interface_count_full_neighbor (struct ospf6_interface *o6i){  listnode n;  struct ospf6_neighbor *o6n;  int count = 0;  for (n = listhead (o6i->neighbor_list); n; nextnode (n))    {      o6n = (struct ospf6_neighbor *) getdata (n);      if (o6n->state == NBS_FULL)        count++;    }  return count;}intospf6_interface_is_enabled (unsigned int ifindex){  struct ospf6_interface *o6i;  o6i = ospf6_interface_lookup_by_index (ifindex);  if (! o6i)    return 0;  if (! o6i->area)    return 0;  if (o6i->state <= IFS_DOWN)    return 0;  return 1;}voidospf6_interface_delayed_ack_add (struct ospf6_lsa *lsa,                                 struct ospf6_interface *o6i){  struct ospf6_lsa *summary;  summary = ospf6_lsa_summary_create (lsa->header);  ospf6_lsdb_add (summary, o6i->ack_list);}voidospf6_interface_delayed_ack_remove (struct ospf6_lsa *lsa,                                    struct ospf6_interface *o6i){  struct ospf6_lsa *summary;  summary = ospf6_lsdb_lookup_lsdb (lsa->header->type, lsa->header->id,                                    lsa->header->adv_router, o6i->ack_list);  ospf6_lsdb_remove (summary, o6i->ack_list);}/* show specified interface structure */intospf6_interface_show (struct vty *vty, struct interface *iface){  struct ospf6_interface *ospf6_interface;  struct connected *c;  struct prefix *p;  listnode i;  char strbuf[64], dr[32], bdr[32];  char *updown[3] = {"down", "up", NULL};  char *type;  /* check physical interface type */  if (if_is_loopback (iface))    type = "LOOPBACK";  else if (if_is_broadcast (iface))    type = "BROADCAST";  else if (if_is_pointopoint (iface))    type = "POINTOPOINT";  else    type = "UNKNOWN";  vty_out (vty, "%s is %s, type %s%s",           iface->name, updown[if_is_up (iface)], type,	   VTY_NEWLINE);  vty_out (vty, "  Interface ID: %d%s", iface->ifindex, VTY_NEWLINE);  if (iface->info == NULL)    {      vty_out (vty, "   OSPF not enabled on this interface%s", VTY_NEWLINE);      return 0;    }  else    ospf6_interface = (struct ospf6_interface *) iface->info;  vty_out (vty, "  Internet Address:%s", VTY_NEWLINE);  for (i = listhead (iface->connected); i; nextnode (i))    {      c = (struct connected *)getdata (i);      p = c->address;      prefix2str (p, strbuf, sizeof (strbuf));      switch (p->family)        {        case AF_INET:          vty_out (vty, "   inet : %s%s", strbuf,		   VTY_NEWLINE);          break;        case AF_INET6:          vty_out (vty, "   inet6: %s%s", strbuf,		   VTY_NEWLINE);          break;        default:          vty_out (vty, "   ???  : %s%s", strbuf,		   VTY_NEWLINE);          break;        }    }  if (ospf6_interface->area)    {      inet_ntop (AF_INET, &ospf6_interface->area->ospf6->router_id,                 strbuf, sizeof (strbuf));      vty_out (vty, "  Instance ID %d, Router ID %s%s",	       ospf6_interface->instance_id, strbuf,	       VTY_NEWLINE);      inet_ntop (AF_INET, &ospf6_interface->area->area_id,                 strbuf, sizeof (strbuf));      vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf,	       ospf6_interface->cost, VTY_NEWLINE);    }  else    vty_out (vty, "  Not Attached to Area%s", VTY_NEWLINE);  vty_out (vty, "  State %s, Transmit Delay %d sec, Priority %d%s",           ospf6_interface_state_string[ospf6_interface->state],           ospf6_interface->transdelay,           ospf6_interface->priority,	   VTY_NEWLINE);  vty_out (vty, "  Timer intervals configured:%s", VTY_NEWLINE);  vty_out (vty, "   Hello %d, Dead %d, Retransmit %d%s",           ospf6_interface->hello_interval,           ospf6_interface->dead_interval,           ospf6_interface->rxmt_interval,	   VTY_NEWLINE);  inet_ntop (AF_INET, &ospf6_interface->dr, dr, sizeof (dr));  inet_ntop (AF_INET, &ospf6_interface->bdr, bdr, sizeof (bdr));  vty_out (vty, "  DR:%s BDR:%s%s", dr, bdr, VTY_NEWLINE);  vty_out (vty, "  Number of I/F scoped LSAs is %u%s",	   ospf6_interface->lsdb->count, VTY_NEWLINE);  vty_out (vty, "  %-16s %5d times, %-16s %5d times%s",	   "DRElection", ospf6_interface->ospf6_stat_dr_election,	   "DelayedLSAck", ospf6_interface->ospf6_stat_delayed_lsack,	   VTY_NEWLINE);  return 0;}voidospf6_interface_statistics_show (struct vty *vty, struct ospf6_interface *o6i){  struct timeval now, uptime;  u_long recv_total, send_total;  u_long bps_total_avg, bps_tx_avg, bps_rx_avg;  int i;  gettimeofday (&now, (struct timezone *) NULL);  ospf6_timeval_sub (&now, &ospf6->starttime, &uptime);  recv_total = send_total = 0;  for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++)    {      recv_total += o6i->message_stat[i].recv_octet;      send_total += o6i->message_stat[i].send_octet;    }  bps_total_avg = (recv_total + send_total) * 8 / uptime.tv_sec;  bps_tx_avg = send_total * 8 / uptime.tv_sec;  bps_rx_avg = recv_total * 8 / uptime.tv_sec;  vty_out (vty, "     Statistics of interface %s%s",           o6i->interface->name, VTY_NEWLINE);  vty_out (vty, "         Number of Neighbor: %d%s",           listcount (o6i->neighbor_list), VTY_NEWLINE);  vty_out (vty, "         %-8s %6s %6s %8s %8s%s",           "Type", "tx", "rx", "tx-byte", "rx-byte", VTY_NEWLINE);  for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++)    {      vty_out (vty, "         %-8s %6d %6d %8d %8d%s",               ospf6_message_type_string[i],               o6i->message_stat[i].send,               o6i->message_stat[i].recv,               o6i->message_stat[i].send_octet,               o6i->message_stat[i].recv_octet,               VTY_NEWLINE);    }  vty_out (vty, "         Average Link bandwidth: %ldbps"

⌨️ 快捷键说明

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