diff options
author | Christian Franke <chris@opensourcerouting.org> | 2018-08-09 22:07:20 +0200 |
---|---|---|
committer | Christian Franke <chris@opensourcerouting.org> | 2018-09-05 11:38:13 +0200 |
commit | 1cbd5b37b7c0fc7bb1a075f2f232f5251ef1a106 (patch) | |
tree | d49be4fc66189ed29fd3418b680f1456f3f909b4 /isisd/isis_pdu.c | |
parent | fabricd: reimplement LSP transmission logic (diff) | |
download | frr-1cbd5b37b7c0fc7bb1a075f2f232f5251ef1a106.tar.xz frr-1cbd5b37b7c0fc7bb1a075f2f232f5251ef1a106.zip |
fabricd: support transmission/reception of circuit-scoped LSPs
OpenFabric makes use of flooding scope LSPs to reduce the amount of
reflooding caused by the update process. Implement transmission and
reception of such PDUs.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'isisd/isis_pdu.c')
-rw-r--r-- | isisd/isis_pdu.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index c1523a268..ce050a0c9 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -710,12 +710,35 @@ out: static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit, const uint8_t *ssnpa, uint8_t max_area_addrs) { - int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2; + int level; + bool circuit_scoped; + + if (pdu_type == FS_LINK_STATE) { + if (!fabricd) + return ISIS_ERROR; + if (max_area_addrs != L2_CIRCUIT_FLOODING_SCOPE) + return ISIS_ERROR; + level = ISIS_LEVEL2; + circuit_scoped = true; + + /* The stream is used verbatim for sending out new LSPDUs. + * So make sure we store it as an L2 LSPDU internally. + * (compare for the reverse in `send_lsp`) */ + stream_putc_at(circuit->rcv_stream, 4, L2_LINK_STATE); + stream_putc_at(circuit->rcv_stream, 7, 0); + } else { + if (pdu_type == L1_LINK_STATE) + level = ISIS_LEVEL1; + else + level = ISIS_LEVEL2; + circuit_scoped = false; + } if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug( - "ISIS-Upd (%s): Rcvd L%d LSP on %s, cirType %s, cirID %u", - circuit->area->area_tag, level, + "ISIS-Upd (%s): Rcvd %sL%d LSP on %s, cirType %s, cirID %u", + circuit->area->area_tag, + circuit_scoped ? "Circuit scoped " : "", level, circuit->interface->name, circuit_t2string(circuit->is_type), circuit->circuit_id); @@ -907,7 +930,8 @@ dontcheckadj: lsp_confusion); tlvs = NULL; /* ii */ - lsp_flood(lsp, NULL); + if (!circuit_scoped) + lsp_flood(lsp, NULL); /* v */ ISIS_FLAGS_CLEAR_ALL( lsp->SSNflags); /* FIXME: @@ -952,7 +976,8 @@ dontcheckadj: /* our own LSP -> 7.3.16.4 c) */ if (comp == LSP_NEWER) { lsp_inc_seqno(lsp, hdr.seqno); - lsp_flood(lsp, NULL); + if (!circuit_scoped) + lsp_flood(lsp, NULL); } else { isis_tx_queue_add(circuit->tx_queue, lsp, TX_LSP_NORMAL); @@ -1035,7 +1060,8 @@ dontcheckadj: circuit->area, level, false); tlvs = NULL; } - lsp_flood(lsp, circuit); + if (!circuit_scoped) + lsp_flood(lsp, circuit); /* iv */ if (circuit->circ_type != CIRCUIT_T_BROADCAST) @@ -1342,6 +1368,7 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size) break; case L1_LINK_STATE: case L2_LINK_STATE: + case FS_LINK_STATE: *size = ISIS_LSP_HDR_LEN; break; case L1_COMPLETE_SEQ_NUM: @@ -1442,7 +1469,9 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) } /* either 3 or 0 */ - if (max_area_addrs != 0 && max_area_addrs != isis->max_area_addrs) { + if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */ + && max_area_addrs != 0 + && max_area_addrs != isis->max_area_addrs) { flog_err( ISIS_ERR_PACKET, "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8 @@ -1459,6 +1488,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) break; case L1_LINK_STATE: case L2_LINK_STATE: + case FS_LINK_STATE: retval = process_lsp(pdu_type, circuit, ssnpa, max_area_addrs); break; case L1_COMPLETE_SEQ_NUM: @@ -2155,6 +2185,11 @@ void send_lsp(void *arg, struct isis_lsp *lsp, enum isis_tx_type tx_type) /* copy our lsp to the send buffer */ stream_copy(circuit->snd_stream, lsp->pdu); + if (tx_type == TX_LSP_CIRCUIT_SCOPED) { + stream_putc_at(circuit->snd_stream, 4, FS_LINK_STATE); + stream_putc_at(circuit->snd_stream, 7, L2_CIRCUIT_FLOODING_SCOPE); + } + if (isis->debugs & DEBUG_UPDATE_PACKETS) { zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 |