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

📄 ospf6_dbex.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (acktype == DIRECT_ACK)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Direct Ack to %s", from->str);          ospf6_dbex_acknowledge_direct (received, from);        }      else if (acktype == DELAYED_ACK)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Delayed Ack to %s", from->str);          ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);        }      else        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: No Ack to %s", from->str);        }      /* (f) */      /* Self Originated LSA, section 13.4 */      if (received->lsa_hdr->lsh_advrtr == ospf6->router_id          && (! have || ismore_recent < 0))        {          /* we're going to make new lsa or to flush this LSA. */          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Self-originated LSA %s from %s:%s",                       received->str, from->str,                       from->ospf6_interface->interface->name);          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: %s: Make new one/Flush", received->str);          SET_FLAG (received->flag, OSPF6_LSA_FLAG_REFRESH);          slot = ospf6_lsa_slot_get (received->header->type);          if (slot && slot->func_refresh)            {              (*slot->func_refresh) (received);              return;            }          zlog_warn ("Can't Refresh LSA: Unknown type: %#x, Flush",                     ntohs (received->header->type));          ospf6_lsa_premature_aging (received);          return;        }    }  else if (ospf6_lsdb_lookup_lsdb (received->header->type,                                   received->header->id,                                   received->header->adv_router,                                   from->request_list))    /* (6) if there is instance on sending neighbor's request list */    {      /* if no database copy, should go above state (5) */      assert (have);      zlog_warn ("DBEX: [%s:%s] received LSA %s is not newer,"                 " and is on his requestlist: Generate BadLSReq",                 from->str, from->ospf6_interface->interface->name,                 received->str);      /* BadLSReq */      thread_add_event (master, bad_lsreq, from, 0);      ospf6_lsa_delete (received);    }  else if (ismore_recent == 0) /* (7) if neither is more recent */    {      /* (a) if on retranslist, Treat this LSA as an Ack: Implied Ack */      rem = ospf6_lsdb_lookup_lsdb (received->header->type,                                    received->header->id,                                    received->header->adv_router,                                    from->retrans_list);      if (rem)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Implied Ack from %s, (remove retrans)",                       from->str);          SET_FLAG (received->flag, OSPF6_LSA_FLAG_IMPLIEDACK);          ospf6_neighbor_retrans_remove (rem, from);        }      /* (b) possibly acknowledge */      acktype = ack_type (received, ismore_recent, from);      if (acktype == DIRECT_ACK)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Direct Ack to %s", from->str);          ospf6_dbex_acknowledge_direct (received, from);        }      else if (acktype == DELAYED_ACK)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: Delayed Ack to %s", from->str);          ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface);        }      else        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: No Ack to %s", from->str);        }      ospf6_lsa_delete (received);    }  else /* (8) previous database copy is more recent */    {      /* If Seqnumber Wrapping, simply discard         Otherwise, Send database copy of this LSA to this neighbor */      if (! IS_LSA_MAXAGE (received) ||          received->lsa_hdr->lsh_seqnum != MAX_SEQUENCE_NUMBER)        {          if (IS_OSPF6_DUMP_DBEX)            zlog_info ("DBEX: database is more recent: send back to %s",                       from->str);          ospf6_send_lsupdate_direct (have, from);        }      ospf6_lsa_delete (received);    }}/* RFC2328: Table 19: Sending link state acknowledgements. */int ack_type (struct ospf6_lsa *newp, int ismore_recent,          struct ospf6_neighbor *from){  struct ospf6_interface *ospf6_interface;  struct ospf6_lsa *have;  int count;  assert (from && from->ospf6_interface);  ospf6_interface = from->ospf6_interface;  if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_FLOODBACK))    return NO_ACK;  if (ismore_recent < 0)    {      if (ospf6_interface->state != IFS_BDR)        return DELAYED_ACK;      if (ospf6_interface->dr == from->router_id)        return DELAYED_ACK;      return NO_ACK;    }  if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&      CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))    {      if (ospf6_interface->state != IFS_BDR)        return NO_ACK;      if (ospf6_interface->dr == from->router_id)        return DELAYED_ACK;      return NO_ACK;    }  if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) &&      ! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK))    return DIRECT_ACK;  have = ospf6_lsdb_lookup (newp->header->type, newp->header->id,                            newp->header->adv_router,                            ospf6_lsa_get_scope (newp->header->type,                                                 from->ospf6_interface));  count = 0;  ospf6->foreach_nei (ospf6, &count, NBS_EXCHANGE, ospf6_count_state);  ospf6->foreach_nei (ospf6, &count, NBS_LOADING, ospf6_count_state);  if (IS_LSA_MAXAGE (newp) && have == NULL && count == 0)    return DIRECT_ACK;   return NO_ACK;}static voidospf6_dbex_flood_linklocal (struct ospf6_lsa *lsa, struct ospf6_interface *o6i,                            struct ospf6_neighbor *from){  struct ospf6_neighbor *o6n = (struct ospf6_neighbor *) NULL;  int ismore_recent, addretrans = 0;  listnode n;  struct ospf6_lsa *req;  /* (1) for each neighbor */  for (n = listhead (o6i->neighbor_list); n; nextnode (n))    {      o6n = (struct ospf6_neighbor *) getdata (n);      /* (a) */      if (o6n->state < NBS_EXCHANGE)        continue;  /* examin next neighbor */      /* (b) */      if (o6n->state == NBS_EXCHANGE          || o6n->state == NBS_LOADING)        {          req = ospf6_lsdb_lookup_lsdb (lsa->header->type,                                        lsa->header->id,                                        lsa->header->adv_router,                                        o6n->request_list);          if (req)            {              ismore_recent = ospf6_lsa_check_recent (lsa, req);              if (ismore_recent > 0)                {                  continue; /* examin next neighbor */                }              else if (ismore_recent == 0)                {                  ospf6_neighbor_request_remove (req, o6n);                  continue; /* examin next neighbor */                }              else /* ismore_recent < 0 (the new LSA is more recent) */                {                  ospf6_neighbor_request_remove (req, o6n);                }            }        }      /* (c) */      if (from && from->router_id == o6n->router_id)        continue; /* examin next neighbor */      /* (d) add retranslist */      if (IS_OSPF6_DUMP_DBEX)        zlog_info ("DBEX: schedule flooding [%s:%s]: %s",                   o6n->str, o6n->ospf6_interface->interface->name,                   lsa->str);      ospf6_neighbor_retrans_add (lsa, o6n);      addretrans++;      if (o6n->send_update == (struct thread *) NULL)        o6n->send_update =          thread_add_timer (master, ospf6_send_lsupdate_rxmt, o6n,                            o6n->ospf6_interface->rxmt_interval);    }  /* (2) */  if (addretrans == 0)    return; /* examin next interface */  if (from && from->ospf6_interface == o6i)    {      if (IS_OSPF6_DUMP_DBEX)        zlog_info ("DBEX: flood back %s to %s",                   lsa->str, o6i->interface->name);      /* note occurence of floodback */      SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_FLOODBACK);    }  /* (3) */  if (from && from->ospf6_interface == o6i)    {      /* if from DR or BDR, don't need to flood this interface */      if (from->router_id == from->ospf6_interface->dr ||          from->router_id == from->ospf6_interface->bdr)        return; /* examin next interface */    }  /* (4) if I'm BDR, DR will flood this interface */  if (from && from->ospf6_interface == o6i      && o6i->state == IFS_BDR)    return; /* examin next interface */  if (IS_OSPF6_DUMP_DBEX)    zlog_info ("Flood to interface %s", o6i->interface->name);  /* (5) send LinkState Update */  ospf6_send_lsupdate_flood (lsa, o6i);  return;}/* RFC2328 section 13.3 */static voidospf6_dbex_flood_area (struct ospf6_lsa *lsa, struct ospf6_area *area,                       struct ospf6_neighbor *from){  listnode n;  struct ospf6_interface *ospf6_interface;  assert (lsa && lsa->lsa_hdr && area);  /* for each eligible ospf_ifs */  for (n = listhead (area->if_list); n; nextnode (n))    {      ospf6_interface = (struct ospf6_interface *) getdata (n);      ospf6_dbex_flood_linklocal (lsa, ospf6_interface, from);    }}static voidospf6_dbex_flood_as (struct ospf6_lsa *lsa, struct ospf6 *ospf6,                     struct ospf6_neighbor *from){  listnode n;  struct ospf6_area *o6a;  assert (lsa && lsa->lsa_hdr && ospf6);  /* for each attached area */  for (n = listhead (ospf6->area_list); n; nextnode (n))    {      o6a = (struct ospf6_area *) getdata (n);      ospf6_dbex_flood_area (lsa, o6a, from);    }}/* flood ospf6_lsa within appropriate scope */voidospf6_dbex_flood (struct ospf6_lsa *lsa, struct ospf6_neighbor *from){  struct ospf6_area *o6a;  struct ospf6_interface *o6i;  struct ospf6 *o6;  struct ospf6_lsa_header *lsa_header;  lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr;  if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa_header->type)))    {      o6i = (struct ospf6_interface *) lsa->scope;      assert (o6i);      if (IS_OSPF6_DUMP_DBEX)        zlog_info ("Flood Linklocal: %s", o6i->interface->name);      ospf6_dbex_flood_linklocal (lsa, o6i, from);    }  else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa_header->type)))    {      o6a = (struct ospf6_area *) lsa->scope;      assert (o6a);      if (IS_OSPF6_DUMP_DBEX)        zlog_info ("Flood Area: %s", o6a->str);      ospf6_dbex_flood_area (lsa, o6a, from);    }  else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa_header->type)))    {      o6 = (struct ospf6 *) lsa->scope;      assert (o6);      if (IS_OSPF6_DUMP_DBEX)        zlog_info ("Flood AS");      ospf6_dbex_flood_as (lsa, o6, from);    }  else    {      zlog_warn ("Can't Flood %s: scope unknown", lsa->str);    }}

⌨️ 快捷键说明

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