From 164066e4d9e3d773ae6f6d291861c2f45d54ed07 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sun, 30 Jul 2017 19:49:19 +0200 Subject: [PATCH] isisd: purge LSP correctly on confusion Signed-off-by: Christian Franke --- isisd/isis_lsp.c | 19 +++++++++++++++---- isisd/isis_lsp.h | 2 +- isisd/isis_pdu.c | 7 ++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 400e4b5fe..51fe41a70 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -436,13 +436,15 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, struct isis_tlvs *tlvs, struct stream *stream, - struct isis_area *area, int level) + struct isis_area *area, int level, bool confusion) { dnode_t *dnode = NULL; /* Remove old LSP from database. This is required since the * lsp_update_data will free the lsp->pdu (which has the key, lsp_id) - * and will update it with the new data in the stream. */ + * and will update it with the new data in the stream. + * XXX: This doesn't hold true anymore since the header is now a copy. + * keeping the LSP in the dict if it is already present should be possible */ dnode = dict_lookup(area->lspdb[level - 1], lsp->hdr.lsp_id); if (dnode) dnode_destroy(dict_delete(area->lspdb[level - 1], dnode)); @@ -455,8 +457,17 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp->own_lsp = 0; } - /* rebuild the lsp data */ - lsp_update_data(lsp, hdr, tlvs, stream, area, level); + if (confusion) { + lsp_clear_data(lsp); + if (lsp->pdu != NULL) + stream_free(lsp->pdu); + lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu); + lsp->age_out = ZERO_AGE_LIFETIME; + lsp->hdr.rem_lifetime = 0; + lsp_pack_pdu(lsp); + } else { + lsp_update_data(lsp, hdr, tlvs, stream, area, level); + } /* insert the lsp back into the database */ lsp_insert(lsp, area->lspdb[level - 1]); diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 8b62ed551..0f9c74994 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -93,7 +93,7 @@ int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno, uint16_t checksum, uint16_t rem_lifetime); void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, struct isis_tlvs *tlvs, struct stream *stream, - struct isis_area *area, int level); + struct isis_area *area, int level, bool confusion); void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno); void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost); void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost); diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index eea5d66ad..17ef8935d 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -880,7 +880,8 @@ dontcheckadj: if (comp == LSP_NEWER) { lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream, - circuit->area, level); + circuit->area, level, + lsp_confusion); tlvs = NULL; /* ii */ lsp_set_all_srmflags(lsp); @@ -1005,7 +1006,7 @@ dontcheckadj: } else /* exists, so we overwrite */ { lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream, - circuit->area, level); + circuit->area, level, false); tlvs = NULL; } /* ii */ @@ -1022,7 +1023,7 @@ dontcheckadj: else if (comp == LSP_EQUAL) { ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream, - circuit->area, level); + circuit->area, level, false); tlvs = NULL; if (circuit->circ_type != CIRCUIT_T_BROADCAST) ISIS_SET_FLAG(lsp->SSNflags, circuit); -- 2.39.5