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

📄 ospf6_flood.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 3 页
字号:
    ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);  else    ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);}/* RFC2328 section 13 (4):   if MaxAge LSA and if we have no instance, and no neighbor   is in states Exchange or Loading   returns 1 if match this case, else returns 0 */static intospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from){  struct ospf6_neighbor *on;  struct ospf6_interface *oi;  struct ospf6_area *oa;  struct ospf6 *process = NULL;  listnode i, j, k;  int count = 0;  if (! OSPF6_LSA_IS_MAXAGE (lsa))    return 0;  if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,                         lsa->header->adv_router, lsa->lsdb))    return 0;  process = from->ospf6_if->area->ospf6;  for (i = listhead (process->area_list); i; nextnode (i))    {      oa = OSPF6_AREA (getdata (i));      for (j = listhead (oa->if_list); j; nextnode (j))        {          oi = OSPF6_INTERFACE (getdata (j));          for (k = listhead (oi->neighbor_list); k; nextnode (k))            {              on = OSPF6_NEIGHBOR (getdata (k));              if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||                  on->state == OSPF6_NEIGHBOR_LOADING)                count++;            }        }    }  if (count == 0)    return 1;  return 0;}/* RFC2328 section 13 The Flooding Procedure */voidospf6_receive_lsa (struct ospf6_neighbor *from,                   struct ospf6_lsa_header *lsa_header){  struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;  int ismore_recent;  unsigned short cksum;  int is_debug = 0;  ismore_recent = 1;  assert (from);  /* make lsa structure for received lsa */  new = ospf6_lsa_create (lsa_header);  if (IS_OSPF6_DEBUG_FLOODING ||      IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))    {      is_debug++;      zlog_info ("LSA Receive from %s", from->name);      ospf6_lsa_header_print (new);    }  /* (1) LSA Checksum */  cksum = ntohs (new->header->checksum);  if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)    {      if (is_debug)        zlog_info ("Wrong LSA Checksum, discard");      ospf6_lsa_delete (new);      return;    }  /* (2) Examine the LSA's LS type.      RFC2470 3.5.1. Receiving Link State Update packets  */  if (IS_AREA_STUB (from->ospf6_if->area) &&      OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)    {      if (is_debug)        zlog_info ("AS-External-LSA (or AS-scope LSA) in stub area, discard");      ospf6_lsa_delete (new);      return;    }  /* (3) LSA which have reserved scope is discarded     RFC2470 3.5.1. Receiving Link State Update packets  */  /* Flooding scope check. LSAs with unknown scope are discarded here.     Set appropriate LSDB for the LSA */  switch (OSPF6_LSA_SCOPE (new->header->type))    {    case OSPF6_SCOPE_LINKLOCAL:      new->lsdb = from->ospf6_if->lsdb;      break;    case OSPF6_SCOPE_AREA:      new->lsdb = from->ospf6_if->area->lsdb;      break;    case OSPF6_SCOPE_AS:      new->lsdb = from->ospf6_if->area->ospf6->lsdb;      break;    default:      if (is_debug)        zlog_info ("LSA has reserved scope, discard");      ospf6_lsa_delete (new);      return;    }  /* (4) if MaxAge LSA and if we have no instance, and no neighbor         is in states Exchange or Loading */  if (ospf6_is_maxage_lsa_drop (new, from))    {      /* log */      if (is_debug)        zlog_info ("Drop MaxAge LSA with direct acknowledgement.");      /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */      ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);      if (from->thread_send_lsack == NULL)        from->thread_send_lsack =          thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);      /* b) Discard */      ospf6_lsa_delete (new);      return;    }  /* (5) */  /* lookup the same database copy in lsdb */  old = ospf6_lsdb_lookup (new->header->type, new->header->id,                           new->header->adv_router, new->lsdb);  if (old)    {      ismore_recent = ospf6_lsa_compare (new, old);      if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))        {          if (is_debug)            zlog_info ("Received is duplicated LSA");          SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);        }    }  /* if no database copy or received is more recent */  if (old == NULL || ismore_recent < 0)    {      /* in case we have no database copy */      ismore_recent = -1;      /* (a) MinLSArrival check */      if (old)        {          struct timeval now, res;          gettimeofday (&now, (struct timezone *) NULL);          timersub (&now, &old->installed, &res);          if (res.tv_sec < MIN_LS_ARRIVAL)            {              if (is_debug)                zlog_info ("LSA can't be updated within MinLSArrival, discard");              ospf6_lsa_delete (new);              return;   /* examin next lsa */            }        }      gettimeofday (&new->received, (struct timezone *) NULL);      if (is_debug)        zlog_info ("Flood, Install, Possibly acknowledge the received LSA");      /* (b) immediately flood and (c) remove from all retrans-list */      /* Prevent self-originated LSA to be flooded. this is to make      reoriginated instance of the LSA not to be rejected by other routers      due to MinLSArrival. */      if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)        ospf6_flood (from, new);      /* (c) Remove the current database copy from all neighbors' Link             state retransmission lists. */      /* XXX, flood_clear ? */      /* (d), installing lsdb, which may cause routing              table calculation (replacing database copy) */      ospf6_install_lsa (new);      /* (e) possibly acknowledge */      ospf6_acknowledge_lsa (new, ismore_recent, from);      /* (f) Self Originated LSA, section 13.4 */      if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)        {          /* Self-originated LSA (newer than ours) is received from             another router. We have to make a new instance of the LSA             or have to flush this LSA. */          if (is_debug)            {              zlog_info ("Newer instance of the self-originated LSA");              zlog_info ("Schedule reorigination");            }          new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);        }      return;    }  /* (6) if there is instance on sending neighbor's request list */  if (ospf6_lsdb_lookup (new->header->type, new->header->id,                         new->header->adv_router, from->request_list))    {      /* if no database copy, should go above state (5) */      assert (old);      if (is_debug)        {          zlog_info ("Received is not newer, on the neighbor's request-list");          zlog_info ("BadLSReq, discard the received LSA");        }      /* BadLSReq */      thread_add_event (master, bad_lsreq, from, 0);      ospf6_lsa_delete (new);      return;    }  /* (7) if neither one is more recent */  if (ismore_recent == 0)    {      if (is_debug)        zlog_info ("The same instance as database copy (neither recent)");      /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */      rem = ospf6_lsdb_lookup (new->header->type, new->header->id,                               new->header->adv_router, from->retrans_list);      if (rem)        {          if (is_debug)            {              zlog_info ("It is on the neighbor's retrans-list.");              zlog_info ("Treat as an Implied acknowledgement");            }          SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);          ospf6_decrement_retrans_count (rem);          ospf6_lsdb_remove (rem, from->retrans_list);        }      if (is_debug)        zlog_info ("Possibly acknowledge and then discard");      /* (b) possibly acknowledge */      ospf6_acknowledge_lsa (new, ismore_recent, from);      ospf6_lsa_delete (new);      return;    }  /* (8) previous database copy is more recent */    {      assert (old);      /* If database copy is in 'Seqnumber Wrapping',         simply discard the received LSA */      if (OSPF6_LSA_IS_MAXAGE (old) &&          old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))        {          if (is_debug)            {              zlog_info ("The LSA is in Seqnumber Wrapping");              zlog_info ("MaxAge & MaxSeqNum, discard");            }          ospf6_lsa_delete (new);          return;        }      /* Otherwise, Send database copy of this LSA to this neighbor */        {          if (is_debug)            {              zlog_info ("Database copy is more recent.");              zlog_info ("Send back directly and then discard");            }          /* XXX, MinLSArrival check !? RFC 2328 13 (8) */          ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);          if (from->thread_send_lsupdate == NULL)            from->thread_send_lsupdate =              thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);          ospf6_lsa_delete (new);          return;        }      return;    }}DEFUN (debug_ospf6_flooding,       debug_ospf6_flooding_cmd,       "debug ospf6 flooding",       DEBUG_STR       OSPF6_STR       "Debug OSPFv3 flooding function\n"      ){  OSPF6_DEBUG_FLOODING_ON ();  return CMD_SUCCESS;}DEFUN (no_debug_ospf6_flooding,       no_debug_ospf6_flooding_cmd,       "no debug ospf6 flooding",       NO_STR       DEBUG_STR       OSPF6_STR       "Debug OSPFv3 flooding function\n"      ){  OSPF6_DEBUG_FLOODING_OFF ();  return CMD_SUCCESS;}intconfig_write_ospf6_debug_flood (struct vty *vty){  if (IS_OSPF6_DEBUG_FLOODING)    vty_out (vty, "debug ospf6 flooding%s", VNL);  return 0;}voidinstall_element_ospf6_debug_flood (){  install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);  install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);  install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);  install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);}

⌨️ 快捷键说明

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