diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 44dca18..86fe4a2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1051,31 +1051,23 @@ #endif /* HAVE_OPAQUE_LSA */ } } - /* Master */ - if (IS_SET_DD_MS (nbr->dd_flags)) - { - nbr->dd_seqnum++; - /* Entire DD packet sent. */ - if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags)) - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone); - else - /* Send new DD packet. */ - ospf_db_desc_send (nbr); - } - /* Slave */ + /* Update DD Sequence number */ + if (IS_SET_DD_MS (nbr->dd_flags)) /* Master */ + nbr->dd_seqnum++; + else /* Slave */ + nbr->dd_seqnum = ntohl (dd->dd_seqnum); + + /* Any more DB-summaries to exchange? */ + if (IS_SET_DD_M (dd->flags) || IS_SET_DD_M (nbr->dd_flags)) + ospf_db_desc_send (nbr); else { - nbr->dd_seqnum = ntohl (dd->dd_seqnum); - - /* When master's more flags is not set. */ - if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr)) - { - nbr->dd_flags &= ~(OSPF_DD_FLAG_M); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone); - } - - /* Send DD packet in reply. */ - ospf_db_desc_send (nbr); + /* Both sides have sent with More-bit clear: Exchange is done */ + OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone); + + /* Slave must still send a DB-Desc, to acknowledge the masters packet */ + if (!IS_SET_DD_MS (nbr->dd_flags)) + ospf_db_desc_send (nbr); } /* Save received neighbor values from DD. */ @@ -1200,7 +1192,9 @@ #endif /* HAVE_OPAQUE_LSA */ zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).", inet_ntoa(nbr->router_id)); nbr->dd_seqnum = ntohl (dd->dd_seqnum); - nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */ + + /* Reset I/MS */ + UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I)); } else { @@ -1217,7 +1211,8 @@ #endif /* HAVE_OPAQUE_LSA */ { zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).", inet_ntoa(nbr->router_id)); - nbr->dd_flags &= ~OSPF_DD_FLAG_I; + /* Reset I, leaving MS */ + UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I); } else { @@ -2676,7 +2671,7 @@ #ifdef HAVE_OPAQUE_LSA #endif /* HAVE_OPAQUE_LSA */ stream_putc (s, options); - /* Keep pointer to flags. */ + /* DD flags */ pp = stream_get_endp (s); stream_putc (s, nbr->dd_flags); @@ -2685,12 +2680,21 @@ #endif /* HAVE_OPAQUE_LSA */ if (ospf_db_summary_isempty (nbr)) { + /* Sanity check: + * + * Must be here either: + * - Initial DBD (ospf_nsm.c) + * - M must be set + * or + * - finishing Exchange, and DB-Summary list empty + * - from ospf_db_desc_proc() + * - M must not be set + */ if (nbr->state >= NSM_Exchange) - { - nbr->dd_flags &= ~OSPF_DD_FLAG_M; - /* Set DD flags again */ - stream_putc_at (s, pp, nbr->dd_flags); - } + assert (!IS_SET_DD_M(nbr->dd_flags)); + else + assert (IS_SET_DD_M(nbr->dd_flags)); + return length; } @@ -2743,7 +2747,14 @@ #endif /* HAVE_OPAQUE_LSA */ ospf_lsdb_delete (lsdb, lsa); } } - + + /* Update 'More' bit */ + if (ospf_db_summary_isempty (nbr)) + { + UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M); + /* Rewrite DD flags */ + stream_putc_at (s, pp, nbr->dd_flags); + } return length; }