📄 ospf6_message.c
字号:
zlog_info ("Can't decide which is master, ignore"); }}voidospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ struct ospf6_neighbor *on; char *p; struct ospf6_lsreq_entry *e; struct ospf6_lsdb *lsdb = NULL; struct ospf6_lsa *lsa; if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) return; on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor not found, ignore"); return; } if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr))) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Seems to be from Secondary I/F of the neighbor, ignore"); return; } if (on->state != OSPF6_NEIGHBOR_EXCHANGE && on->state != OSPF6_NEIGHBOR_LOADING && on->state != OSPF6_NEIGHBOR_FULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state less than Exchange, ignore"); return; } /* Process each request */ for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsreq_entry)) { e = (struct ospf6_lsreq_entry *) p; switch (OSPF6_LSA_SCOPE (e->type)) { case OSPF6_SCOPE_LINKLOCAL: lsdb = on->ospf6_if->lsdb; break; case OSPF6_SCOPE_AREA: lsdb = on->ospf6_if->area->lsdb; break; case OSPF6_SCOPE_AS: lsdb = on->ospf6_if->area->ospf6->lsdb; break; default: if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Ignoring LSA of reserved scope"); continue; break; } /* Find database copy */ lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb); if (lsa == NULL) { char id[16], adv_router[16]; if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) { inet_ntop (AF_INET, &e->id, id, sizeof (id)); inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router)); zlog_info ("Can't find requested [%s Id:%s Adv:%s]", ospf6_lstype_name (e->type), id, adv_router); } thread_add_event (master, bad_lsreq, on, 0); return; } ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list); } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); } /* schedule send lsupdate */ THREAD_OFF (on->thread_send_lsupdate); on->thread_send_lsupdate = thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);}voidospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ struct ospf6_neighbor *on; struct ospf6_lsupdate *lsupdate; unsigned long num; char *p; if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) return; on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor not found, ignore"); return; } if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr))) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Seems to be from Secondary I/F of the neighbor, ignore"); return; } if (on->state != OSPF6_NEIGHBOR_EXCHANGE && on->state != OSPF6_NEIGHBOR_LOADING && on->state != OSPF6_NEIGHBOR_FULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state less than Exchange, ignore"); return; } lsupdate = (struct ospf6_lsupdate *) ((caddr_t) oh + sizeof (struct ospf6_header)); num = ntohl (lsupdate->lsa_number); /* Process LSAs */ for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); p < OSPF6_MESSAGE_END (oh) && p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); p += OSPF6_LSA_SIZE (p)) { if (num == 0) break; if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Malformed LSA length, quit processing"); break; } ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p); num--; } if (num != 0) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Malformed LSA number or LSA length"); } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); } /* RFC2328 Section 10.9: When the neighbor responds to these requests with the proper Link State Update packet(s), the Link state request list is truncated and a new Link State Request packet is sent. */ /* send new Link State Request packet if this LS Update packet can be recognized as a response to our previous LS Request */ if (! IN6_IS_ADDR_MULTICAST (dst) && (on->state == OSPF6_NEIGHBOR_EXCHANGE || on->state == OSPF6_NEIGHBOR_LOADING)) { THREAD_OFF (on->thread_send_lsreq); on->thread_send_lsreq = thread_add_event (master, ospf6_lsreq_send, on, 0); }}voidospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ struct ospf6_neighbor *on; char *p; struct ospf6_lsa *his, *mine; struct ospf6_lsdb *lsdb = NULL; assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK) return; on = ospf6_neighbor_lookup (oh->router_id, oi); if (on == NULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor not found, ignore"); return; } if (memcmp (src, &on->linklocal_addr, sizeof (struct in6_addr))) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Seems to be from Secondary I/F of the neighbor, ignore"); return; } if (on->state != OSPF6_NEIGHBOR_EXCHANGE && on->state != OSPF6_NEIGHBOR_LOADING && on->state != OSPF6_NEIGHBOR_FULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state less than Exchange, ignore"); return; } for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsa_header)) { his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); switch (OSPF6_LSA_SCOPE (his->header->type)) { case OSPF6_SCOPE_LINKLOCAL: lsdb = on->ospf6_if->lsdb; break; case OSPF6_SCOPE_AREA: lsdb = on->ospf6_if->area->lsdb; break; case OSPF6_SCOPE_AS: lsdb = on->ospf6_if->area->ospf6->lsdb; break; case OSPF6_SCOPE_RESERVED: if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Ignoring LSA of reserved scope"); ospf6_lsa_delete (his); continue; break; } if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("%s acknowledged by %s", his->name, on->name); /* Find database copy */ mine = ospf6_lsdb_lookup (his->header->type, his->header->id, his->header->adv_router, lsdb); if (mine == NULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("No database copy"); ospf6_lsa_delete (his); continue; } /* Check if the LSA is on his retrans-list */ mine = ospf6_lsdb_lookup (his->header->type, his->header->id, his->header->adv_router, on->retrans_list); if (mine == NULL) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Not on %s's retrans-list", on->name); ospf6_lsa_delete (his); continue; } if (ospf6_lsa_compare (his, mine) != 0) { /* Log this questionable acknowledgement, and examine the next one. */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Questionable acknowledgement"); ospf6_lsa_delete (his); continue; } if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Acknowledged, remove from %s's retrans-list", on->name); if (OSPF6_LSA_IS_MAXAGE (mine)) ospf6_maxage_remove (on->ospf6_if->area->ospf6); ospf6_decrement_retrans_count (mine); ospf6_lsdb_remove (mine, on->retrans_list); ospf6_lsa_delete (his); } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); }}char *recvbuf = NULL;char *sendbuf = NULL;int iobuflen = 0;intospf6_iobuf_size (int size){ char *recvnew, *sendnew; if (size <= iobuflen) return iobuflen; recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); if (recvnew == NULL || sendnew == NULL) { if (recvnew) XFREE (MTYPE_OSPF6_MESSAGE, recvnew); if (sendnew) XFREE (MTYPE_OSPF6_MESSAGE, sendnew); zlog_info ("Could not allocate I/O buffer of size %d.", size); return iobuflen; } if (recvbuf) XFREE (MTYPE_OSPF6_MESSAGE, recvbuf); if (sendbuf) XFREE (MTYPE_OSPF6_MESSAGE, sendbuf); recvbuf = recvnew; sendbuf = sendnew; iobuflen = size; return iobuflen;}intospf6_receive (struct thread *thread){ int sockfd, len; char srcname[64], dstname[64]; struct in6_addr src, dst; unsigned int ifindex; struct iovec iovector[2]; struct ospf6_interface *oi; struct ospf6_header *oh; /* add next read thread */ sockfd = THREAD_FD (thread); thread_add_read (master, ospf6_receive, NULL, sockfd); /* initialize */ memset (recvbuf, 0, iobuflen); iovector[0].iov_base = recvbuf; iovector[0].iov_len = iobuflen; iovector[1].iov_base = NULL; iovector[1].iov_len = 0; /* receive message */ len = ospf6_recvmsg (&src, &dst, &ifindex, iovector); if (len > iobuflen) { zlog_err ("Excess message read"); return 0; } else if (len < sizeof (struct ospf6_header)) { zlog_err ("Deficient message read"); return 0; } oi = ospf6_interface_lookup_by_ifindex (ifindex); if (oi == NULL || oi->area == NULL) { zlog_info ("Message received on disabled interface"); return 0; } oh = (struct ospf6_header *) recvbuf; /* Log */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) { inet_ntop (AF_INET6, &src, srcname, sizeof (srcname)); inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname)); zlog_info ("%s received on %s", OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name); zlog_info (" src: %s", srcname); zlog_info (" dst: %s", dstname); if (len != ntohs (oh->length)) zlog_info ("Message length does not match actually received: %d", len); 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"); break; } } if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Ignore message on passive interface %s", oi->interface->name); return 0; } switch (oh->type) { case OSPF6_MESSAGE_TYPE_HELLO: ospf6_hello_recv (&src, &dst, oi, oh); break; case OSPF6_MESSAGE_TYPE_DBDESC: ospf6_dbdesc_recv (&src, &dst, oi, oh); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -