summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2017-07-30 19:49:19 +0200
committerChristian Franke <chris@opensourcerouting.org>2017-08-03 11:34:04 +0200
commit164066e4d9e3d773ae6f6d291861c2f45d54ed07 (patch)
treed90a1cc0e9573470f87bc2b357712cc5c83f7939
parent39a275aa0fefda85913e454d82bccf536032ddd7 (diff)
isisd: purge LSP correctly on confusion
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
-rw-r--r--isisd/isis_lsp.c19
-rw-r--r--isisd/isis_lsp.h2
-rw-r--r--isisd/isis_pdu.c7
3 files changed, 20 insertions, 8 deletions
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 400e4b5fe4..51fe41a706 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 8b62ed5513..0f9c749949 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 eea5d66ad8..17ef8935d8 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);