isisd: handle lsp confusion (ISO/IEC 10589:2002 7.3.16.2)

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Christian Franke 2015-11-10 18:33:15 +01:00 committed by Donald Sharp
parent 8c8829a620
commit 0250758d15
2 changed files with 40 additions and 6 deletions

View 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)
{

View 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)
{