summaryrefslogtreecommitdiffstats
path: root/isisd/isis_pdu.c
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2018-08-09 22:07:20 +0200
committerChristian Franke <chris@opensourcerouting.org>2018-09-05 11:38:13 +0200
commit1cbd5b37b7c0fc7bb1a075f2f232f5251ef1a106 (patch)
treed49be4fc66189ed29fd3418b680f1456f3f909b4 /isisd/isis_pdu.c
parentfabricd: reimplement LSP transmission logic (diff)
downloadfrr-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.c49
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