]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: always link fragments to fragment #0, even when learned by CSNP 961/head
authorChristian Franke <chris@opensourcerouting.org>
Fri, 11 Aug 2017 13:28:58 +0000 (15:28 +0200)
committerChristian Franke <chris@opensourcerouting.org>
Fri, 11 Aug 2017 13:53:07 +0000 (15:53 +0200)
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
isisd/isis_lsp.c
isisd/isis_lsp.h
isisd/isis_pdu.c

index 51fe41a706473e13833a963d1e113b8782a48d0f..6bf6e45d9239b6253236ab8f4a3760701bca9dab 100644 (file)
@@ -473,6 +473,19 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
        lsp_insert(lsp, area->lspdb[level - 1]);
 }
 
+static void lsp_link_fragment(struct isis_lsp *lsp, struct isis_lsp *lsp0)
+{
+       if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) {
+               /* zero lsp -> create list to store fragments */
+               lsp->lspu.frags = list_new();
+       } else {
+               /* fragment -> set backpointer and add to zero lsps list */
+               assert(lsp0);
+               lsp->lspu.zero_lsp = lsp0;
+               listnode_add(lsp0->lspu.frags, lsp);
+       }
+}
+
 /* creation of LSP directly from what we received */
 struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
                                   struct isis_tlvs *tlvs,
@@ -483,27 +496,15 @@ struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
 
        lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp));
        lsp_update_data(lsp, hdr, tlvs, stream, area, level);
-
-       if (lsp0 == NULL) {
-               /*
-                * zero lsp -> create the list for fragments
-                */
-               lsp->lspu.frags = list_new();
-       } else {
-               /*
-                * a fragment -> set the backpointer and add this to zero lsps
-                * frag list
-                */
-               lsp->lspu.zero_lsp = lsp0;
-               listnode_add(lsp0->lspu.frags, lsp);
-       }
+       lsp_link_fragment(lsp, lsp0);
 
        return lsp;
 }
 
 struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
                         uint16_t rem_lifetime, uint32_t seqno,
-                        uint8_t lsp_bits, uint16_t checksum, int level)
+                        uint8_t lsp_bits, uint16_t checksum,
+                        struct isis_lsp *lsp0, int level)
 {
        struct isis_lsp *lsp;
 
@@ -511,8 +512,6 @@ struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
        lsp->area = area;
 
        lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu);
-       if (LSP_FRAGMENT(lsp_id) == 0)
-               lsp->lspu.frags = list_new();
 
        /* Minimal LSP PDU size */
        lsp->hdr.pdu_len = ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN;
@@ -523,6 +522,7 @@ struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
        lsp->hdr.lsp_bits = lsp_bits;
        lsp->level = level;
        lsp->age_out = ZERO_AGE_LIFETIME;
+       lsp_link_fragment(lsp, lsp0);
        put_lsp_hdr(lsp, NULL);
 
        if (isis->debugs & DEBUG_EVENTS)
@@ -808,11 +808,9 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
        lsp = lsp_new(area, frag_id, lsp0->hdr.rem_lifetime, 0,
                      lsp_bits_generate(level, area->overload_bit,
                                        area->attached_bit),
-                     0, level);
+                     0, lsp0, level);
        lsp->own_lsp = 1;
        lsp_insert(lsp, area->lspdb[level - 1]);
-       listnode_add(lsp0->lspu.frags, lsp);
-       lsp->lspu.zero_lsp = lsp0;
        return lsp;
 }
 
@@ -1158,7 +1156,7 @@ int lsp_generate(struct isis_area *area, int level)
        newlsp =
                lsp_new(area, lspid, rem_lifetime, seq_num,
                        area->is_type | area->overload_bit | area->attached_bit,
-                       0, level);
+                       0, NULL, level);
        newlsp->area = area;
        newlsp->own_lsp = 1;
 
@@ -1532,7 +1530,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
        /* RFC3787  section 4 SHOULD not set overload bit in pseudo LSPs */
        lsp = lsp_new(circuit->area, lsp_id, rem_lifetime, 1,
                      circuit->area->is_type | circuit->area->attached_bit, 0,
-                     level);
+                     NULL, level);
        lsp->area = circuit->area;
 
        lsp_build_pseudo(lsp, circuit, level);
index 0f9c749949710402cde9ab4da6466c5f6e009dac..550e7a0645af7f97ec04bfe931c4344eff9a77e2 100644 (file)
@@ -61,7 +61,8 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
 
 struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
                         uint16_t rem_lifetime, uint32_t seq_num,
-                        uint8_t lsp_bits, uint16_t checksum, int level);
+                        uint8_t lsp_bits, uint16_t checksum,
+                        struct isis_lsp *lsp0, int level);
 struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
                                   struct isis_tlvs *tlvs,
                                   struct stream *stream, struct isis_lsp *lsp0,
index 17ef8935d8d4e3fe5815f1bd12a4824af35073a2..a20051f8c366f7b4152f689bb554e0086cb1b6be 100644 (file)
@@ -1235,10 +1235,26 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                        if (entry->rem_lifetime && entry->checksum
                            && entry->seqno && memcmp(entry->id, isis->sysid,
                                                      ISIS_SYS_ID_LEN)) {
+                               struct isis_lsp *lsp0 = NULL;
+
+                               if (LSP_FRAGMENT(entry->id)) {
+                                       uint8_t lspid[ISIS_SYS_ID_LEN + 2];
+
+                                       memcpy(lspid, entry->id,
+                                              ISIS_SYS_ID_LEN + 1);
+                                       LSP_FRAGMENT(lspid) = 0;
+                                       lsp0 = lsp_search(
+                                                 lspid,
+                                                 circuit->area->lspdb[level - 1]);
+                                       if (!lsp0) {
+                                               zlog_debug("Got lsp frag in snp, while zero not in database");
+                                               continue;
+                                       }
+                               }
                                struct isis_lsp *lsp =
                                        lsp_new(circuit->area, entry->id,
                                                entry->rem_lifetime, 0, 0,
-                                               entry->checksum, level);
+                                               entry->checksum, lsp0, level);
                                lsp_insert(lsp,
                                           circuit->area->lspdb[level - 1]);
                                ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);