]> git.proxmox.com Git - mirror_frr.git/commitdiff
fabricd: support transmission/reception of circuit-scoped LSPs
authorChristian Franke <chris@opensourcerouting.org>
Thu, 9 Aug 2018 20:07:20 +0000 (22:07 +0200)
committerChristian Franke <chris@opensourcerouting.org>
Wed, 5 Sep 2018 09:38:13 +0000 (11:38 +0200)
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>
isisd/isis_pdu.c
isisd/isis_pdu.h

index c1523a268d17487b00566b7878fe07ace4a03394..ce050a0c93811cb23ff1ecb3a3c21befed231e11 100644 (file)
@@ -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
index ea19de259121d9f2294040684ece7c95c5c7a154..3d2420eb036abf340f7459c8e93b2215fd5ad509 100644 (file)
@@ -127,6 +127,8 @@ struct isis_p2p_hello_hdr {
 
 #define L1_LINK_STATE        18
 #define L2_LINK_STATE        20
+#define FS_LINK_STATE        10
+#define L2_CIRCUIT_FLOODING_SCOPE 2
 struct isis_lsp_hdr {
        uint16_t pdu_len;
        uint16_t rem_lifetime;