📄 ospf6_message.c
字号:
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 + -