📄 ospf6_message.c
字号:
! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && ntohl (dbdesc->seqnum) == on->dbdesc_seqnum) { /* execute NegotiationDone */ thread_execute (master, negotiation_done, on, 0); /* Record neighbor options */ memcpy (on->options, dbdesc->options, sizeof (on->options)); } else { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Negotiation failed"); return; } /* fall through to exchange */ case OSPF6_NEIGHBOR_EXCHANGE: if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) { /* Duplicated DatabaseDescription is dropped by master */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Duplicated dbdesc discarded by Master, ignore"); return; } if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Master/Slave bit mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Initialize bit mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (memcmp (on->options, dbdesc->options, sizeof (on->options))) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Option field mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Sequence number mismatch (%#lx expected)", (u_long) on->dbdesc_seqnum); thread_add_event (master, seqnumber_mismatch, on, 0); return; } break; case OSPF6_NEIGHBOR_LOADING: case OSPF6_NEIGHBOR_FULL: if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) { /* Duplicated DatabaseDescription is dropped by master */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Duplicated dbdesc discarded by Master, ignore"); return; } if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Not duplicate dbdesc in state %s", ospf6_neighbor_state_str[on->state]); thread_add_event (master, seqnumber_mismatch, on, 0); return; default: assert (0); break; } /* Process LSA headers */ for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsa_header)) { struct ospf6_lsa *his, *mine; struct ospf6_lsdb *lsdb = NULL; his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("%s", his->name); 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 (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && IS_AREA_STUB (on->ospf6_if->area)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("SeqNumMismatch (E-bit mismatch), discard"); ospf6_lsa_delete (his); thread_add_event (master, seqnumber_mismatch, on, 0); return; } 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 ("Add request (No database copy)"); ospf6_lsdb_add (his, on->request_list); } else if (ospf6_lsa_compare (his, mine) < 0) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Add request (Received MoreRecent)"); ospf6_lsdb_add (his, on->request_list); } else { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Discard (Existing MoreRecent)"); ospf6_lsa_delete (his); } } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); } /* Increment sequence number */ on->dbdesc_seqnum ++; /* schedule send lsreq */ if (on->thread_send_lsreq == NULL) on->thread_send_lsreq = thread_add_event (master, ospf6_lsreq_send, on, 0); THREAD_OFF (on->thread_send_dbdesc); /* More bit check */ if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT)) thread_add_event (master, exchange_done, on, 0); else on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send_newone, on, 0); /* save last received dbdesc */ memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));}static voidospf6_dbdesc_recv_slave (struct ospf6_header *oh, struct ospf6_neighbor *on){ struct ospf6_dbdesc *dbdesc; char *p; dbdesc = (struct ospf6_dbdesc *) ((caddr_t) oh + sizeof (struct ospf6_header)); if (on->state < OSPF6_NEIGHBOR_INIT) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state less than Init, ignore"); return; } switch (on->state) { case OSPF6_NEIGHBOR_TWOWAY: if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state is 2-Way, ignore"); return; case OSPF6_NEIGHBOR_INIT: thread_execute (master, twoway_received, on, 0); if (on->state != OSPF6_NEIGHBOR_EXSTART) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Neighbor state is not ExStart, ignore"); return; } /* else fall through to ExStart */ case OSPF6_NEIGHBOR_EXSTART: /* If the neighbor is Master, act as Slave. Schedule negotiation_done and process LSA Headers. Otherwise, ignore this message */ if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) && ntohs (oh->length) == sizeof (struct ospf6_header) + sizeof (struct ospf6_dbdesc)) { /* set the master/slave bit to slave */ UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); /* set the DD sequence number to one specified by master */ on->dbdesc_seqnum = ntohl (dbdesc->seqnum); /* schedule NegotiationDone */ thread_execute (master, negotiation_done, on, 0); /* Record neighbor options */ memcpy (on->options, dbdesc->options, sizeof (on->options)); } else { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Negotiation failed"); return; } break; case OSPF6_NEIGHBOR_EXCHANGE: if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) { /* Duplicated DatabaseDescription causes slave to retransmit */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Duplicated dbdesc causes retransmit"); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); return; } if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Master/Slave bit mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Initialize bit mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (memcmp (on->options, dbdesc->options, sizeof (on->options))) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Option field mismatch"); thread_add_event (master, seqnumber_mismatch, on, 0); return; } if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Sequence number mismatch (%#lx expected)", (u_long) on->dbdesc_seqnum + 1); thread_add_event (master, seqnumber_mismatch, on, 0); return; } break; case OSPF6_NEIGHBOR_LOADING: case OSPF6_NEIGHBOR_FULL: if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) { /* Duplicated DatabaseDescription causes slave to retransmit */ if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Duplicated dbdesc causes retransmit"); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); return; } if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Not duplicate dbdesc in state %s", ospf6_neighbor_state_str[on->state]); thread_add_event (master, seqnumber_mismatch, on, 0); return; default: assert (0); break; } /* Process LSA headers */ for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); p += sizeof (struct ospf6_lsa_header)) { struct ospf6_lsa *his, *mine; struct ospf6_lsdb *lsdb = NULL; 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 (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS && IS_AREA_STUB (on->ospf6_if->area)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("E-bit mismatch with LSA Headers"); ospf6_lsa_delete (his); thread_add_event (master, seqnumber_mismatch, on, 0); return; } mine = ospf6_lsdb_lookup (his->header->type, his->header->id, his->header->adv_router, lsdb); if (mine == NULL || ospf6_lsa_compare (his, mine) < 0) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Add request-list: %s", his->name); ospf6_lsdb_add (his, on->request_list); } else ospf6_lsa_delete (his); } if (p != OSPF6_MESSAGE_END (oh)) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Trailing garbage ignored"); } /* Set sequence number to Master's */ on->dbdesc_seqnum = ntohl (dbdesc->seqnum); /* schedule send lsreq */ if (on->thread_send_lsreq == NULL) on->thread_send_lsreq = thread_add_event (master, ospf6_lsreq_send, on, 0); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send_newone, on, 0); /* save last received dbdesc */ memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));}voidospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst, struct ospf6_interface *oi, struct ospf6_header *oh){ struct ospf6_neighbor *on; struct ospf6_dbdesc *dbdesc; 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; } dbdesc = (struct ospf6_dbdesc *) ((caddr_t) oh + sizeof (struct ospf6_header)); /* Interface MTU check */ if (ntohs (dbdesc->ifmtu) != oi->ifmtu) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("I/F MTU mismatch"); return; } if (dbdesc->reserved1 || dbdesc->reserved2) { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) zlog_info ("Non-0 reserved field in %s's DbDesc, correct", on->name); dbdesc->reserved1 = 0; dbdesc->reserved2 = 0; } if (ntohl (oh->router_id) < ntohl (ospf6->router_id)) ospf6_dbdesc_recv_master (oh, on); else if (ntohl (ospf6->router_id) < ntohl (oh->router_id)) ospf6_dbdesc_recv_slave (oh, on); else { if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -