]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_pdu.c
Merge pull request #5625 from qlyoung/fix-zapi-ipset-name-nullterm
[mirror_frr.git] / isisd / isis_pdu.c
index 8e9302963dabdd6dd7c0d11d0c21adf893342474..cc22aa5ffd8650d7da1b9b99d0afd436c940f470 100644 (file)
@@ -36,7 +36,6 @@
 #include "md5.h"
 #include "lib_errors.h"
 
-#include "isisd/dict.h"
 #include "isisd/isis_constants.h"
 #include "isisd/isis_common.h"
 #include "isisd/isis_flags.h"
@@ -59,6 +58,7 @@
 #include "isisd/fabricd.h"
 #include "isisd/isis_tx_queue.h"
 #include "isisd/isis_pdu_counter.h"
+#include "isisd/isis_nb.h"
 
 static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
                   int level)
@@ -188,7 +188,7 @@ static int process_p2p_hello(struct iih_info *iih)
                adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
        }
 
-       if (tw_adj && adj->threeway_state == ISIS_THREEWAY_DOWN)
+       if (tw_adj)
                adj->ext_circuit_id = tw_adj->local_circuit_id;
 
        /* 8.2.6 Monitoring point-to-point adjacencies */
@@ -200,12 +200,6 @@ static int process_p2p_hello(struct iih_info *iih)
        changed |= tlvs_to_adj_mt_set(iih->tlvs, iih->v4_usable, iih->v6_usable,
                                      adj);
 
-       /* Update MPLS TE Remote IP address parameter if possible */
-       if (IS_MPLS_TE(isisMplsTE) && iih->circuit->mtc
-           && IS_CIRCUIT_TE(iih->circuit->mtc) && adj->ipv4_address_count)
-               set_circuitparams_rmt_ipaddr(iih->circuit->mtc,
-                                            adj->ipv4_addresses[0]);
-
        /* lets take care of the expiry */
        THREAD_TIMER_OFF(adj->t_expire);
        thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
@@ -583,6 +577,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        if (p2p_hello) {
                if (circuit->circ_type != CIRCUIT_T_P2P) {
                        zlog_warn("p2p hello on non p2p circuit");
+                       circuit->rej_adjacencies++;
 #ifndef FABRICD
                        isis_notif_reject_adjacency(
                                circuit, "p2p hello on non p2p circuit",
@@ -593,6 +588,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        } else {
                if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
                        zlog_warn("lan hello on non broadcast circuit");
+                       circuit->rej_adjacencies++;
 #ifndef FABRICD
                        isis_notif_reject_adjacency(
                                circuit, "lan hello on non broadcast circuit",
@@ -605,6 +601,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                        zlog_debug(
                                "level %d LAN Hello received over circuit with externalDomain = true",
                                level);
+                       circuit->rej_adjacencies++;
 #ifndef FABRICD
                        isis_notif_reject_adjacency(
                                circuit,
@@ -621,6 +618,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                                        circuit->area->area_tag,
                                        circuit->interface->name);
                        }
+                       circuit->rej_adjacencies++;
 #ifndef FABRICD
                        isis_notif_reject_adjacency(
                                circuit, "Interface level mismatch", raw_pdu);
@@ -650,6 +648,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                        "ISIS-Adj (%s): Rcvd %s from (%s) with invalid pdu length %" PRIu16,
                        circuit->area->area_tag, pdu_name,
                        circuit->interface->name, iih.pdu_len);
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(circuit, "Invalid PDU length",
                                            raw_pdu);
@@ -661,6 +660,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                flog_err(EC_ISIS_PACKET,
                         "Level %d LAN Hello with Circuit Type %d", level,
                         iih.circ_type);
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(
                        circuit, "LAN Hello with wrong IS-level", raw_pdu);
@@ -674,6 +674,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
        if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream),
                             circuit->rcv_stream, &iih.tlvs, &error_log)) {
                zlog_warn("isis_unpack_tlvs() failed: %s", error_log);
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(circuit, "Failed to unpack TLVs",
                                            raw_pdu);
@@ -692,6 +693,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
 
        if (!iih.tlvs->protocols_supported.count) {
                zlog_warn("No supported protocols TLV in %s", pdu_name);
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(
                        circuit, "No supported protocols TLV", raw_pdu);
@@ -709,11 +711,14 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                /* send northbound notification */
                stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
                                pdu_end - pdu_start);
-               if (auth_code == ISIS_AUTH_FAILURE)
+               if (auth_code == ISIS_AUTH_FAILURE) {
+                       circuit->auth_failures++;
                        isis_notif_authentication_failure(circuit, raw_pdu);
-               else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+               } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                       circuit->auth_type_failures++;
                        isis_notif_authentication_type_failure(circuit,
                                                               raw_pdu);
+               }
 #endif /* ifndef FABRICD */
                goto out;
        }
@@ -722,6 +727,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                zlog_warn(
                        "ISIS-Adj (%s): Received IIH with own sysid - discard",
                        circuit->area->area_tag);
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(
                        circuit, "Received IIH with our own sysid", raw_pdu);
@@ -759,6 +765,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                                "ISIS-Adj (%s): Neither IPv4 nor IPv6 considered usable. Ignoring IIH",
                                circuit->area->area_tag);
                }
+               circuit->rej_adjacencies++;
 #ifndef FABRICD
                isis_notif_reject_adjacency(
                        circuit, "Neither IPv4 not IPv6 considered usable",
@@ -947,11 +954,14 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
                                        hdr.lsp_id);
 #ifndef FABRICD
                /* send northbound notification */
-               if (auth_code == ISIS_AUTH_FAILURE)
+               if (auth_code == ISIS_AUTH_FAILURE) {
+                       circuit->auth_failures++;
                        isis_notif_authentication_failure(circuit, raw_pdu);
-               else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+               } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                       circuit->auth_type_failures++;
                        isis_notif_authentication_type_failure(circuit,
                                                               raw_pdu);
+               }
 #endif /* ifndef FABRICD */
                goto out;
        }
@@ -959,7 +969,7 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
        /* Find the LSP in our database and compare it to this Link State header
         */
        struct isis_lsp *lsp =
-               lsp_search(hdr.lsp_id, circuit->area->lspdb[level - 1]);
+               lsp_search(&circuit->area->lspdb[level - 1], hdr.lsp_id);
        int comp = 0;
        if (lsp)
                comp = lsp_compare(circuit->area->area_tag, lsp, hdr.seqno,
@@ -1044,6 +1054,8 @@ dontcheckadj:
                                                   circuit->rcv_stream,
                                                   circuit->area, level,
                                                   lsp_confusion);
+                                       if (lsp_confusion)
+                                               isis_free_tlvs(tlvs);
                                        tlvs = NULL;
                                        /* ii */
                                        lsp_flood_or_update(lsp, NULL,
@@ -1186,7 +1198,7 @@ dontcheckadj:
                                memcpy(lspid, hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
                                LSP_FRAGMENT(lspid) = 0;
                                lsp0 = lsp_search(
-                                       lspid, circuit->area->lspdb[level - 1]);
+                                       &circuit->area->lspdb[level - 1], lspid);
                                if (!lsp0) {
                                        zlog_debug(
                                                "Got lsp frag, while zero lsp not in database");
@@ -1199,8 +1211,8 @@ dontcheckadj:
                                        &hdr, tlvs, circuit->rcv_stream, lsp0,
                                        circuit->area, level);
                                tlvs = NULL;
-                               lsp_insert(lsp,
-                                          circuit->area->lspdb[level - 1]);
+                               lsp_insert(&circuit->area->lspdb[level - 1],
+                                          lsp);
                        } else /* exists, so we overwrite */
                        {
                                lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
@@ -1380,12 +1392,15 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                        /* send northbound notification */
                        stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
                                        pdu_end - pdu_start);
-                       if (auth_code == ISIS_AUTH_FAILURE)
+                       if (auth_code == ISIS_AUTH_FAILURE) {
+                               circuit->auth_failures++;
                                isis_notif_authentication_failure(circuit,
                                                                  raw_pdu);
-                       else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                       } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+                               circuit->auth_type_failures++;
                                isis_notif_authentication_type_failure(circuit,
                                                                       raw_pdu);
+                       }
 #endif /* ifndef FABRICD */
                        goto out;
                }
@@ -1416,7 +1431,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
        for (struct isis_lsp_entry *entry = entry_head; entry;
             entry = entry->next) {
                struct isis_lsp *lsp =
-                       lsp_search(entry->id, circuit->area->lspdb[level - 1]);
+                       lsp_search(&circuit->area->lspdb[level - 1], entry->id);
                bool own_lsp = !memcmp(entry->id, isis->sysid, ISIS_SYS_ID_LEN);
                if (lsp) {
                        /* 7.3.15.2 b) 1) is this LSP newer */
@@ -1467,8 +1482,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                                               ISIS_SYS_ID_LEN + 1);
                                        LSP_FRAGMENT(lspid) = 0;
                                        lsp0 = lsp_search(
-                                                 lspid,
-                                                 circuit->area->lspdb[level - 1]);
+                                                 &circuit->area->lspdb[level - 1],
+                                                 lspid);
                                        if (!lsp0) {
                                                zlog_debug("Got lsp frag in snp, while zero not in database");
                                                continue;
@@ -1477,8 +1492,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                                lsp = lsp_new(circuit->area, entry->id,
                                                entry->rem_lifetime, 0, 0,
                                                entry->checksum, lsp0, level);
-                               lsp_insert(lsp,
-                                          circuit->area->lspdb[level - 1]);
+                               lsp_insert(&circuit->area->lspdb[level - 1],
+                                          lsp);
 
                                lsp_set_all_srmflags(lsp, false);
                                ISIS_SET_FLAG(lsp->SSNflags, circuit);
@@ -1495,8 +1510,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                 * start_lsp_id and stop_lsp_id
                 */
                struct list *lsp_list = list_new();
-               lsp_build_list_nonzero_ht(start_lsp_id, stop_lsp_id, lsp_list,
-                                         circuit->area->lspdb[level - 1]);
+               lsp_build_list_nonzero_ht(&circuit->area->lspdb[level - 1],
+                                         start_lsp_id, stop_lsp_id, lsp_list);
 
                /* Fixme: Find a better solution */
                struct listnode *node, *nnode;
@@ -1621,6 +1636,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
                        "IDFieldLengthMismatch: ID Length field in a received PDU  %" PRIu8
                        ", while the parameter for this IS is %u",
                        id_len, ISIS_SYS_ID_LEN);
+               circuit->id_len_mismatches++;
 #ifndef FABRICD
                /* send northbound notification */
                isis_notif_id_len_mismatch(circuit, id_len, raw_pdu);
@@ -1673,6 +1689,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
                        "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
                        " while the parameter for this IS is %u",
                        max_area_addrs, isis->max_area_addrs);
+               circuit->max_area_addr_mismatches++;
 #ifndef FABRICD
                /* send northbound notification */
                isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
@@ -2040,8 +2057,7 @@ static uint16_t get_max_lsp_count(uint16_t size)
 
 int send_csnp(struct isis_circuit *circuit, int level)
 {
-       if (circuit->area->lspdb[level - 1] == NULL
-           || dict_count(circuit->area->lspdb[level - 1]) == 0)
+       if (lspdb_count(&circuit->area->lspdb[level - 1]) == 0)
                return ISIS_OK;
 
        uint8_t pdu_type = (level == ISIS_LEVEL1) ? L1_COMPLETE_SEQ_NUM
@@ -2094,7 +2110,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
 
                struct isis_lsp *last_lsp;
                isis_tlvs_add_csnp_entries(tlvs, start, stop, num_lsps,
-                                          circuit->area->lspdb[level - 1],
+                                          &circuit->area->lspdb[level - 1],
                                           &last_lsp);
                /*
                 * Update the stop lsp_id before encoding this CSNP.
@@ -2215,8 +2231,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
            && circuit->u.bc.is_dr[level - 1])
                return ISIS_OK;
 
-       if (circuit->area->lspdb[level - 1] == NULL
-           || dict_count(circuit->area->lspdb[level - 1]) == 0)
+       if (lspdb_count(&circuit->area->lspdb[level - 1]) == 0)
                return ISIS_OK;
 
        if (!circuit->snd_stream)
@@ -2254,16 +2269,13 @@ static int send_psnp(int level, struct isis_circuit *circuit)
                get_max_lsp_count(STREAM_WRITEABLE(circuit->snd_stream));
 
        while (1) {
+               struct isis_lsp *lsp;
+
                tlvs = isis_alloc_tlvs();
                if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND))
                        isis_tlvs_add_auth(tlvs, passwd);
 
-               for (dnode_t *dnode =
-                            dict_first(circuit->area->lspdb[level - 1]);
-                    dnode; dnode = dict_next(circuit->area->lspdb[level - 1],
-                                             dnode)) {
-                       struct isis_lsp *lsp = dnode_get(dnode);
-
+               frr_each (lspdb, &circuit->area->lspdb[level - 1], lsp) {
                        if (ISIS_CHECK_FLAG(lsp->SSNflags, circuit))
                                isis_tlvs_add_lsp_entry(tlvs, lsp);