From: Christian Franke <[email protected]>

Signed-off-by: Christian Franke <[email protected]>
---
 isisd/isis_lsp.c | 14 +++++++++++++-
 isisd/isis_pdu.c | 32 +++++++++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index d42aa30..e9eaafa 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -273,7 +273,19 @@ lsp_compare (char *areatag, struct isis_lsp *lsp, 
u_int32_t seq_num,
       return LSP_EQUAL;
     }
 
-  if (ntohl (seq_num) >= ntohl (lsp->lsp_header->seq_num))
+  /*
+   * LSPs with identical checksums should only be treated as newer if:
+   * a) The current LSP has a remaining lifetime != 0 and the other LSP has a
+   *    remaining lifetime == 0. In this case, we should participate in the 
purge
+   *    and should not treat the current LSP with remaining lifetime == 0 as 
older.
+   * b) The LSP has an incorrect checksum. In this case, we need to react as 
given
+   *    in 7.3.16.2.
+   */
+   if (ntohl (seq_num) > ntohl (lsp->lsp_header->seq_num)
+      || (ntohl(seq_num) == ntohl(lsp->lsp_header->seq_num)
+          && (  (lsp->lsp_header->rem_lifetime != 0
+                 && rem_lifetime == 0)
+              || lsp->lsp_header->checksum != checksum)))
     {
       if (isis->debugs & DEBUG_SNP_PACKETS)
        {
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index d2be27b..bbf0d73 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -1309,6 +1309,7 @@ process_lsp (int level, struct isis_circuit *circuit, 
const u_char *ssnpa)
   u_char lspid[ISIS_SYS_ID_LEN + 2];
   struct isis_passwd *passwd;
   uint16_t pdu_len;
+  int lsp_confusion;
 
   if (isis->debugs & DEBUG_UPDATE_PACKETS)
     {
@@ -1483,6 +1484,21 @@ dontcheckadj:
 
   /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented  FIXME: do it 
*/
 
+  /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num but
+   *            wrong checksum, initiate a purge. */
+  if (lsp
+      && (lsp->lsp_header->seq_num == hdr->seq_num)
+      && (lsp->lsp_header->checksum != hdr->checksum))
+    {
+      zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum 
received.",
+                circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+                ntohl(hdr->seq_num));
+      hdr->rem_lifetime = 0;
+      lsp_confusion = 1;
+    }
+  else
+    lsp_confusion = 0;
+
   /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */
   if (hdr->rem_lifetime == 0)
     {
@@ -1505,14 +1521,20 @@ dontcheckadj:
                   lsp_update (lsp, circuit->rcv_stream, circuit->area, level);
                  /* ii */
                   lsp_set_all_srmflags (lsp);
-                 /* iii */
-                 ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
                  /* v */
                  ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags); /* FIXME: OTHER than c 
*/
-                 /* iv */
-                 if (circuit->circ_type != CIRCUIT_T_BROADCAST)
-                   ISIS_SET_FLAG (lsp->SSNflags, circuit);
 
+                 /* For the case of lsp confusion, flood the purge back to its
+                  * originator so that it can react. Otherwise, don't reflood
+                  * through incoming circuit as usual */
+                 if (!lsp_confusion)
+                   {
+                     /* iii */
+                     ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
+                     /* iv */
+                     if (circuit->circ_type != CIRCUIT_T_BROADCAST)
+                       ISIS_SET_FLAG (lsp->SSNflags, circuit);
+                   }
                }               /* 7.3.16.4 b) 2) */
              else if (comp == LSP_EQUAL)
                {
-- 
2.6.1


_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to