]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: handle lsp confusion (ISO/IEC 10589:2002 7.3.16.2)
authorChristian Franke <nobody@nowhere.ws>
Tue, 10 Nov 2015 17:33:15 +0000 (18:33 +0100)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 30 Mar 2016 00:26:32 +0000 (20:26 -0400)
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
isisd/isis_lsp.c
isisd/isis_pdu.c

index 291fa20ab65e9d83ab25fd23e846430e6ec19afb..3801eb737b7bad9fede691530bb358f6be47656d 100644 (file)
@@ -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)
        {
index 02d6fffc72670de392206488d6ba5f514ed52107..7f5a57079902f9416686039d0699d05b5e3d8474 100644 (file)
@@ -1281,6 +1281,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)
     {
@@ -1455,6 +1456,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)
     {
@@ -1477,14 +1493,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)
                {