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

📄 ospf6_message.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 5 页
字号:
      case OSPF6_MESSAGE_TYPE_LSREQ:        ospf6_lsreq_recv (&src, &dst, oi, oh);        break;      case OSPF6_MESSAGE_TYPE_LSUPDATE:        ospf6_lsupdate_recv (&src, &dst, oi, oh);        break;      case OSPF6_MESSAGE_TYPE_LSACK:        ospf6_lsack_recv (&src, &dst, oi, oh);        break;      default:        if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))          zlog_info ("Unknown message");        break;    }  return 0;}voidospf6_send (struct in6_addr *src, struct in6_addr *dst,            struct ospf6_interface *oi, struct ospf6_header *oh){  int len;  char srcname[64], dstname[64];  struct iovec iovector[2];  /* initialize */  iovector[0].iov_base = (caddr_t) oh;  iovector[0].iov_len = ntohs (oh->length);  iovector[1].iov_base = NULL;  iovector[1].iov_len = 0;  /* fill OSPF header */  oh->version = OSPFV3_VERSION;  /* message type must be set before */  /* message length must be set before */  oh->router_id = oi->area->ospf6->router_id;  oh->area_id = oi->area->area_id;  /* checksum is calculated by kernel */  oh->instance_id = oi->instance_id;  oh->reserved = 0;  /* Log */  if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))    {      inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));      if (src)        inet_ntop (AF_INET6, src, srcname, sizeof (srcname));      else        memset (srcname, 0, sizeof (srcname));      zlog_info ("%s send on %s",                 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);      zlog_info ("    src: %s", srcname);      zlog_info ("    dst: %s", dstname);      switch (oh->type)        {          case OSPF6_MESSAGE_TYPE_HELLO:            ospf6_hello_print (oh);            break;          case OSPF6_MESSAGE_TYPE_DBDESC:            ospf6_dbdesc_print (oh);            break;          case OSPF6_MESSAGE_TYPE_LSREQ:            ospf6_lsreq_print (oh);            break;          case OSPF6_MESSAGE_TYPE_LSUPDATE:            ospf6_lsupdate_print (oh);            break;          case OSPF6_MESSAGE_TYPE_LSACK:            ospf6_lsack_print (oh);            break;          default:            zlog_info ("Unknown message");            assert (0);            break;        }    }  /* send message */  len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);  if (len != ntohs (oh->length))    zlog_err ("Could not send entire message");}intospf6_hello_send (struct thread *thread){  struct ospf6_interface *oi;  struct ospf6_header *oh;  struct ospf6_hello *hello;  char *p;  listnode node;  struct ospf6_neighbor *on;  oi = (struct ospf6_interface *) THREAD_ARG (thread);  oi->thread_send_hello = (struct thread *) NULL;  if (oi->state <= OSPF6_INTERFACE_DOWN)    {      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))        zlog_info ("Unable to send Hello on down interface %s",                   oi->interface->name);      return 0;    }  /* set next thread */  oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,                                            oi, oi->hello_interval);  memset (sendbuf, 0, iobuflen);  oh = (struct ospf6_header *) sendbuf;  hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));  hello->interface_id = htonl (oi->interface->ifindex);  hello->priority = oi->priority;  hello->options[0] = oi->area->options[0];  hello->options[1] = oi->area->options[1];  hello->options[2] = oi->area->options[2];  hello->hello_interval = htons (oi->hello_interval);  hello->dead_interval = htons (oi->dead_interval);  hello->drouter = oi->drouter;  hello->bdrouter = oi->bdrouter;  p = (char *)((caddr_t) hello + sizeof (struct ospf6_hello));  for (node = listhead (oi->neighbor_list); node; nextnode (node))    {      on = (struct ospf6_neighbor *) getdata (node);      if (on->state < OSPF6_NEIGHBOR_INIT)        continue;      if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu)        {          if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))            zlog_info ("sending Hello message: exceeds I/F MTU");          break;        }      memcpy (p, &on->router_id, sizeof (u_int32_t));      p += sizeof (u_int32_t);    }  oh->type = OSPF6_MESSAGE_TYPE_HELLO;  oh->length = htons (p - sendbuf);  ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);  return 0;}intospf6_dbdesc_send (struct thread *thread){  struct ospf6_neighbor *on;  struct ospf6_header *oh;  struct ospf6_dbdesc *dbdesc;  char *p;  struct ospf6_lsa *lsa;  on = (struct ospf6_neighbor *) THREAD_ARG (thread);  on->thread_send_dbdesc = (struct thread *) NULL;  if (on->state < OSPF6_NEIGHBOR_EXSTART)    {      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))        zlog_info ("Quit to send DbDesc to neighbor %s state %s",                   on->name, ospf6_neighbor_state_str[on->state]);      return 0;    }  /* set next thread if master */  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))    on->thread_send_dbdesc =      thread_add_timer (master, ospf6_dbdesc_send, on,                        on->ospf6_if->rxmt_interval);  memset (sendbuf, 0, iobuflen);  oh = (struct ospf6_header *) sendbuf;  dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +                                   sizeof (struct ospf6_header));  /* if this is initial one, initialize sequence number for DbDesc */  if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))    {      struct timeval tv;      if (gettimeofday (&tv, (struct timezone *) NULL) < 0)        tv.tv_sec = 1;      on->dbdesc_seqnum = tv.tv_sec;    }  dbdesc->options[0] = on->ospf6_if->area->options[0];  dbdesc->options[1] = on->ospf6_if->area->options[1];  dbdesc->options[2] = on->ospf6_if->area->options[2];  dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);  dbdesc->bits = on->dbdesc_bits;  dbdesc->seqnum = htonl (on->dbdesc_seqnum);  /* if this is not initial one, set LSA headers in dbdesc */  p = (char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))    {      for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;           lsa = ospf6_lsdb_next (lsa))        {          ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);          /* MTU check */          if (p - sendbuf + sizeof (struct ospf6_lsa_header) >              on->ospf6_if->ifmtu)            {              ospf6_lsa_unlock (lsa);              break;            }          memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));          p += sizeof (struct ospf6_lsa_header);        }    }  oh->type = OSPF6_MESSAGE_TYPE_DBDESC;  oh->length = htons (p - sendbuf);  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,              on->ospf6_if, oh);  return 0;}intospf6_dbdesc_send_newone (struct thread *thread){  struct ospf6_neighbor *on;  struct ospf6_lsa *lsa;  unsigned int size = 0;  on = (struct ospf6_neighbor *) THREAD_ARG (thread);  ospf6_lsdb_remove_all (on->dbdesc_list);  /* move LSAs from summary_list to dbdesc_list (within neighbor structure)     so that ospf6_send_dbdesc () can send those LSAs */  size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);  for (lsa = ospf6_lsdb_head (on->summary_list); lsa;       lsa = ospf6_lsdb_next (lsa))    {      if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)        {          ospf6_lsa_unlock (lsa);          break;        }      ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);      ospf6_lsdb_remove (lsa, on->summary_list);      size += sizeof (struct ospf6_lsa_header);    }  if (on->summary_list->count == 0)    UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);  /* If slave, More bit check must be done here */  if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */      ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&      ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))    thread_add_event (master, exchange_done, on, 0);  thread_execute (master, ospf6_dbdesc_send, on, 0);  return 0;}intospf6_lsreq_send (struct thread *thread){  struct ospf6_neighbor *on;  struct ospf6_header *oh;  struct ospf6_lsreq_entry *e;  char *p;  struct ospf6_lsa *lsa;  on = (struct ospf6_neighbor *) THREAD_ARG (thread);  on->thread_send_lsreq = (struct thread *) NULL;  /* LSReq will be sent only in ExStart or Loading */  if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&      on->state != OSPF6_NEIGHBOR_LOADING)    {      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))        zlog_info ("Quit to send LSReq to neighbor %s state %s",                   on->name, ospf6_neighbor_state_str[on->state]);      return 0;    }  /* schedule loading_done if request list is empty */  if (on->request_list->count == 0)    {      thread_add_event (master, loading_done, on, 0);      return 0;    }  /* set next thread */  on->thread_send_lsreq =    thread_add_timer (master, ospf6_lsreq_send, on,                      on->ospf6_if->rxmt_interval);  memset (sendbuf, 0, iobuflen);  oh = (struct ospf6_header *) sendbuf;  /* set Request entries in lsreq */  p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));  for (lsa = ospf6_lsdb_head (on->request_list); lsa;       lsa = ospf6_lsdb_next (lsa))    {      /* MTU check */      if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu)        {          ospf6_lsa_unlock (lsa);          break;        }      e = (struct ospf6_lsreq_entry *) p;      e->type = lsa->header->type;      e->id = lsa->header->id;      e->adv_router = lsa->header->adv_router;      p += sizeof (struct ospf6_lsreq_entry);    }  oh->type = OSPF6_MESSAGE_TYPE_LSREQ;  oh->length = htons (p - sendbuf);  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,              on->ospf6_if, oh);  return 0;}intospf6_lsupdate_send_neighbor (struct thread *thread){  struct ospf6_neighbor *on;  struct ospf6_header *oh;  struct ospf6_lsupdate *lsupdate;  char *p;  int num;  struct ospf6_lsa *lsa;  on = (struct ospf6_neighbor *) THREAD_ARG (thread);  on->thread_send_lsupdate = (struct thread *) NULL;  if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))    zlog_info ("LSUpdate to neighbor %s", on->name);  if (on->state < OSPF6_NEIGHBOR_EXCHANGE)    {      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))        zlog_info ("Quit to send (neighbor state %s)",                   ospf6_neighbor_state_str[on->state]);      return 0;    }  /* if we have nothing to send, return */  if (on->lsupdate_list->count == 0 &&      on->retrans_list->count == 0)    {      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))        zlog_info ("Quit to send (nothing to send)");      return 0;    }  memset (sendbuf, 0, iobuflen);  oh = (struct ospf6_header *) sendbuf;  lsupdate = (struct ospf6_lsupdate *)    ((caddr_t) oh + sizeof (struct ospf6_header));  p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));  num = 0;  /* lsupdate_list lists those LSA which doesn't need to be     retransmitted. remove those from the list */  for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;       lsa = ospf6_lsdb_next (lsa))    {      /* MTU check */      if (p - sendbuf + OSPF6_LSA_SIZE (lsa->header) > on->ospf6_if->ifmtu)        {          ospf6_lsa_unlock (lsa);          break;        }      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));      p += OSPF6_LSA_SIZE (lsa->header);      num++;      assert (lsa->lock == 2);      ospf6_lsdb_remove (lsa, on->lsupdate_list);    }  for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;       lsa = ospf6_lsdb_next (lsa))    {      /* MTU check */      if (p - sendbuf + OSPF6_LSA_SIZE (lsa->header) > on->ospf6_if->ifmtu)        {          ospf6_lsa_unlock (lsa);          break;        }      ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);      memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));      p += OSPF6_LSA_SIZE (lsa->header);      num++;    }  lsupdate->lsa_number = htonl (num);  oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;  oh->length = htons (p - sendbuf);  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,              on->ospf6_if, oh);  if (on->lsupdate_list->count != 0 ||      on->retrans_list->count != 0)    {      if (on->lsupdate_list->count != 0)        on->thread_send_lsupdate =          thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);      else        on->thread_send_lsupdate =          thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,                            on->ospf6_if->rxmt_interval);

⌨️ 快捷键说明

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