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

📄 ospf6_message.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
      o6n = (struct ospf6_neighbor *) getdata (n);      if (o6n->state < NBS_INIT)        continue;      if (router_size + sizeof (o6n->router_id) > sizeof (router_buffer))        {          zlog_warn ("Send HELLO: Buffer shortage on %s",                     o6i->interface->name);          break;        }      /* Copy Router-ID to Buffer */      memcpy (router_buffer + router_size, &o6n->router_id,              sizeof (o6n->router_id));      router_size += sizeof (o6n->router_id);    }  OSPF6_MESSAGE_ATTACH (message, router_buffer, router_size);  /* set destionation */  inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);  /* send hello */  ospf6_message_send (OSPF6_MESSAGE_TYPE_HELLO, message, &dst,                      o6i->interface->ifindex);  /* set next timer thread */  o6i->thread_send_hello = thread_add_timer (master, ospf6_send_hello,                                             o6i, o6i->hello_interval);  return 0;}voidospf6_dbdesc_seqnum_init (struct ospf6_neighbor *o6n){  struct timeval tv;  if (gettimeofday (&tv, (struct timezone *) NULL) < 0)    tv.tv_sec = 1;  o6n->dbdesc_seqnum = tv.tv_sec;  if (IS_OSPF6_DUMP_DBDESC)    zlog_info ("set dbdesc seqnum %d for %s", o6n->dbdesc_seqnum, o6n->str);}intospf6_send_dbdesc_rxmt (struct thread *thread){  struct ospf6_lsdb_node node;  struct ospf6_neighbor *o6n;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsa *lsa;  struct ospf6_lsa_header *lsa_header;  struct ospf6_dbdesc dbdesc;  o6n = (struct ospf6_neighbor *) THREAD_ARG (thread);  assert (o6n);  /* clear thread */  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;  /* if state less than ExStart, do nothing */  if (o6n->state < NBS_EXSTART)    return 0;  OSPF6_MESSAGE_CLEAR (message);  /* set dbdesc */  memcpy (dbdesc.options, o6n->ospf6_interface->area->options,          sizeof (dbdesc.options));  dbdesc.ifmtu = htons (o6n->ospf6_interface->interface->mtu);  dbdesc.bits = o6n->dbdesc_bits;  dbdesc.seqnum = htonl (o6n->dbdesc_seqnum);  OSPF6_MESSAGE_ATTACH (message, &dbdesc, sizeof (struct ospf6_dbdesc));  /* if this is not initial, set LSA summary to dbdesc */  if (! DD_IS_IBIT_SET (o6n->dbdesc_bits))    {      for (ospf6_lsdb_head (&node, o6n->dbdesc_list);           ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node))        {          lsa = node.lsa;          /* xxx, no MTU check: no support for Dynamic MTU change */          /* set age and add InfTransDelay */          ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);          /* set LSA summary to send buffer */          lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr;          OSPF6_MESSAGE_ATTACH (message, lsa_header,                                sizeof (struct ospf6_lsa_header));        }    }  /* send dbdesc */  ospf6_message_send (OSPF6_MESSAGE_TYPE_DBDESC, message, &o6n->hisaddr,                      o6n->ospf6_interface->interface->ifindex);  /* if master, set futher retransmission */  if (DD_IS_MSBIT_SET (o6n->dbdesc_bits))    o6n->thread_rxmt_dbdesc =      thread_add_timer (master, ospf6_send_dbdesc_rxmt,                        o6n, o6n->ospf6_interface->rxmt_interval);  /* statistics */  o6n->ospf6_stat_retrans_dbdesc++;  return 0;}intospf6_send_dbdesc (struct thread *thread){  struct ospf6_neighbor *o6n;  struct ospf6_lsa *lsa;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_dbdesc dbdesc;  struct ospf6_lsdb_node node;  o6n = (struct ospf6_neighbor *) THREAD_ARG (thread);  assert (o6n);  /* clear thread */  o6n->thread_send_dbdesc = (struct thread *) NULL;  if (o6n->thread_rxmt_dbdesc)    thread_cancel (o6n->thread_rxmt_dbdesc);  o6n->thread_rxmt_dbdesc = (struct thread *) NULL;  /* if state less than ExStart, do nothing */  if (o6n->state < NBS_EXSTART)    return 0;  OSPF6_MESSAGE_CLEAR (message);  OSPF6_MESSAGE_ATTACH (message, &dbdesc, sizeof (struct ospf6_dbdesc));  /* clear previous LSA summary sent */  ospf6_lsdb_remove_all (o6n->dbdesc_list);  assert (o6n->dbdesc_list->count == 0);  /* if this is not initial, set LSA summary to dbdesc */  if (! DD_IS_IBIT_SET (o6n->dbdesc_bits))    {      for (ospf6_lsdb_head (&node, o6n->summary_list);           ! ospf6_lsdb_is_end (&node);           ospf6_lsdb_next (&node))        {          lsa = node.lsa;          /* MTU check */          if (OSPF6_MESSAGE_LENGTH (message)              + sizeof (struct ospf6_lsa_header)              + sizeof (struct ospf6_header)              > o6n->ospf6_interface->ifmtu)            break;          /* debug */          if (IS_OSPF6_DUMP_DBDESC)            zlog_info ("Include DbDesc: %s", lsa->str);          /* attach to dbdesclist */          ospf6_neighbor_dbdesc_add (lsa, o6n);          /* detach from summarylist */          ospf6_neighbor_summary_remove (lsa, o6n);          /* set age and add InfTransDelay */          ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);          /* set LSA summary to send buffer */          OSPF6_MESSAGE_ATTACH (message, lsa->header,                                sizeof (struct ospf6_lsa_header));        }      if (o6n->summary_list->count == 0)        {          /* Clear more bit */          DD_MBIT_CLEAR (o6n->dbdesc_bits);          /* slave must schedule ExchangeDone on sending, here */          if (! DD_IS_MSBIT_SET (o6n->dbdesc_bits))            {              if (! DD_IS_MBIT_SET (o6n->dbdesc_bits) &&                  ! DD_IS_MBIT_SET (o6n->last_dd.bits))                thread_add_event (master, exchange_done, o6n, 0);            }        }    }  /* if this is initial, set seqnum */  if (DDBIT_IS_INITIAL (o6n->dbdesc_bits))    ospf6_dbdesc_seqnum_init (o6n);  /* set dbdesc */  memcpy (dbdesc.options, o6n->ospf6_interface->area->options,          sizeof (dbdesc.options));  dbdesc.ifmtu = htons (o6n->ospf6_interface->interface->mtu);  dbdesc.bits = o6n->dbdesc_bits;  dbdesc.seqnum = htonl (o6n->dbdesc_seqnum);  /* send dbdesc */  ospf6_message_send (OSPF6_MESSAGE_TYPE_DBDESC, message, &o6n->hisaddr,                      o6n->ospf6_interface->interface->ifindex);  /* if master, set retransmission */  if (DD_IS_MSBIT_SET (o6n->dbdesc_bits))    o6n->thread_rxmt_dbdesc =      thread_add_timer (master, ospf6_send_dbdesc_rxmt,                          o6n, o6n->ospf6_interface->rxmt_interval);  /* statistics */  o6n->lsa_send[OSPF6_MESSAGE_TYPE_DBDESC] += o6n->dbdesc_list->count;  return 0;}intospf6_send_lsreq_rxmt (struct thread *thread){  struct ospf6_neighbor *o6n;  o6n = (struct ospf6_neighbor *) THREAD_ARG (thread);  assert (o6n);  o6n->thread_rxmt_lsreq = (struct thread *) NULL;  o6n->thread_send_lsreq = thread_add_event (master, ospf6_send_lsreq, o6n, 0);  return 0;}intospf6_send_lsreq (struct thread *thread){  struct ospf6_neighbor *o6n;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsreq lsreq[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsa *lsa;  struct ospf6_lsdb_node node;  int i;  o6n = (struct ospf6_neighbor *) THREAD_ARG (thread);  assert (o6n);  /* LSReq will be send only in ExStart or Loading */  if (o6n->state != NBS_EXCHANGE && o6n->state != NBS_LOADING)    return 0;  /* clear thread */  o6n->thread_send_lsreq = (struct thread *) NULL;  if (o6n->thread_rxmt_lsreq)    thread_cancel (o6n->thread_rxmt_lsreq);  o6n->thread_rxmt_lsreq = (struct thread *) NULL;  /* schedule loading_done if request list is empty */  if (o6n->request_list->count == 0)    {      thread_add_event (master, loading_done, o6n, 0);      return 0;    }  /* clear message buffer */  OSPF6_MESSAGE_CLEAR (message);  i = 0;  for (ospf6_lsdb_head (&node, o6n->request_list);       ! ospf6_lsdb_is_end (&node); ospf6_lsdb_next (&node))    {      lsa = node.lsa;      /* Buffer Overflow */      if (i >= OSPF6_MESSAGE_IOVEC_SIZE)        break;      /* I/F MTU check */      if (OSPF6_MESSAGE_LENGTH (message)          + sizeof (struct ospf6_lsreq)          + sizeof (struct ospf6_header)          > o6n->ospf6_interface->ifmtu)        break;      lsreq[i].mbz = 0;      lsreq[i].type = lsa->header->type;      lsreq[i].id = lsa->header->id;      lsreq[i].adv_router = lsa->header->adv_router;      OSPF6_MESSAGE_ATTACH (message, &lsreq[i], sizeof (struct ospf6_lsreq));      i++;    }  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSREQ, message, &o6n->hisaddr,                      o6n->ospf6_interface->interface->ifindex);  /* set retransmit thread */  o6n->thread_rxmt_lsreq =    thread_add_timer (master, ospf6_send_lsreq_rxmt,                      o6n, o6n->ospf6_interface->rxmt_interval);  /* statistics */  o6n->lsa_send[OSPF6_MESSAGE_TYPE_LSREQ] += i;  return 0;}/* Send LSUpdate directly to the neighbor, from his retransmission list */intospf6_send_lsupdate_rxmt (struct thread *thread){  struct ospf6_neighbor *o6n;  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsupdate lsupdate;  struct ospf6_lsa *lsa;  struct ospf6_lsdb_node node;  o6n = (struct ospf6_neighbor *) THREAD_ARG (thread);  assert (o6n);  o6n->send_update = (struct thread *) NULL;  if (o6n->ospf6_interface->state <= IFS_WAITING)    return -1;  /* clear message buffer */  OSPF6_MESSAGE_CLEAR (message);  /* set lsupdate header */  lsupdate.lsupdate_num = 0; /* set gradually */  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));  /* for each LSA listed on retransmission-list */  for (ospf6_lsdb_head (&node, o6n->retrans_list);       ! ospf6_lsdb_is_end (&node);       ospf6_lsdb_next (&node))    {      lsa = node.lsa;      /* I/F MTU check */      if (OSPF6_MESSAGE_LENGTH (message)          + sizeof (struct ospf6_lsupdate)          + sizeof (struct ospf6_header)          + ntohs (lsa->header->length)          > o6n->ospf6_interface->ifmtu)        break;      ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);      OSPF6_MESSAGE_ATTACH (message, lsa->header, ntohs (lsa->header->length));      lsupdate.lsupdate_num++;    }  /* check and correct lsupdate */  if (lsupdate.lsupdate_num == 0)    return 0;  lsupdate.lsupdate_num = htonl (lsupdate.lsupdate_num);  if (IS_OSPF6_DUMP_LSUPDATE)    zlog_info ("MESSAGE: retrsnsmit LSUpdate to %s", o6n->str);  /* statistics */  o6n->ospf6_stat_retrans_lsupdate++;  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message,                      &o6n->hisaddr, o6n->ospf6_interface->if_id);  o6n->send_update = thread_add_timer (master, ospf6_send_lsupdate_rxmt, o6n,                                       o6n->ospf6_interface->rxmt_interval);  return 0;}/* Send LSUpdate containing one LSA directly to the neighbor.   This is "implied acknowledgement" */voidospf6_send_lsupdate_direct (struct ospf6_lsa *lsa, struct ospf6_neighbor *o6n){  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsupdate lsupdate;  int lsa_len;  /* clear message buffer */  OSPF6_MESSAGE_CLEAR (message);  /* set lsupdate header */  lsupdate.lsupdate_num = ntohl (1);  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));  /* set one LSA */  lsa_len = ntohs (lsa->lsa_hdr->lsh_len);  ospf6_lsa_age_update_to_send (lsa, o6n->ospf6_interface->transdelay);  OSPF6_MESSAGE_ATTACH (message, lsa->lsa_hdr, lsa_len);  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message, &o6n->hisaddr,                      o6n->ospf6_interface->if_id);}/* Send LSUpdate containing one LSA by multicast.   On non-broadcast link, send it to each neighbor by unicast.   This is ordinary flooding */voidospf6_send_lsupdate_flood (struct ospf6_lsa *lsa, struct ospf6_interface *o6i){  struct iovec message[OSPF6_MESSAGE_IOVEC_SIZE];  struct ospf6_lsupdate lsupdate;  struct in6_addr dst;  int lsa_len;  /* clear message buffer */  OSPF6_MESSAGE_CLEAR (message);  /* set lsupdate header */  lsupdate.lsupdate_num = ntohl (1);  OSPF6_MESSAGE_ATTACH (message, &lsupdate, sizeof (struct ospf6_lsupdate));  /* set one LSA */  lsa_len = ntohs (lsa->lsa_hdr->lsh_len);  ospf6_lsa_age_update_to_send (lsa, o6i->transdelay);  OSPF6_MESSAGE_ATTACH (message, lsa->lsa_hdr, lsa_len);  if (if_is_broadcast (o6i->interface))    {      /* set destination */      if (o6i->state == IFS_DR || o6i->state == IFS_BDR)        inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);      else        inet_pton (AF_INET6, ALLDROUTERS6, &dst);    }  else    {      /* IPv6 relies on link local multicast */      inet_pton (AF_INET6, ALLSPFROUTERS6, &dst);    }  ospf6_message_send (OSPF6_MESSAGE_TYPE_LSUPDATE, message, &dst,                      o6i->if_id);}intospf6_send_lsack_delayed (struct thread *thread){  struct ospf6_interface *o6i;  struct iovec message[MAXIOVLIST];  struct ospf6_lsa *lsa;  struct ospf6_lsdb_node node;  o6i = THREAD_ARG (thread);  assert (o6i);  if (IS_OSPF6_DUMP_LSACK)    zlog_info ("LSACK: Delayed LSAck for %s\n", o6i->interface->name);  o6i->thread_send_lsack_delayed = (struct thread *) NULL;  if (o6i->state <= IFS_WAITING)    return 0;  if (o6i->ack_list->count == 0)    return 0;  iov_clear (message, MAXIOVLIST);  for (ospf6_lsdb_head (&node, o6i->ack_list);       ! ospf6_lsdb_is_end (&node);       ospf6_lsdb_next (&node))    {      lsa = node.lsa;      if (IS_OVER_MTU (message, o6i->ifmtu, sizeof (struct ospf6_lsa_hdr)))        break;      OSPF6_MESSAGE_ATTACH (message, lsa->header,                            sizeof (struct ospf6_lsa_header));      ospf6_interface_delayed_ack_remove (lsa, o6i);    }  /* statistics */  o6i->ospf6_stat_delayed_lsack++;  switch (o6i->state)    {    case IFS_DR:    case IFS_BDR:      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, message,                          &allspfrouters6.sin6_addr, o6i->if_id);      break;    default:      ospf6_message_send (OSPF6_MESSAGE_TYPE_LSACK, message,                          &alldrouters6.sin6_addr, o6i->if_id);      break;    }  iov_clear (message, MAXIOVLIST);  return 0;}

⌨️ 快捷键说明

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