]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd, yang: implement interface counters 5039/head
authorRenato Westphal <renato@opensourcerouting.org>
Mon, 23 Sep 2019 12:38:02 +0000 (09:38 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Mon, 23 Sep 2019 12:38:05 +0000 (09:38 -0300)
The new "event-counters" grouping is almost a 1:1 copy of the same
grouping from the IETF IS-IS module, except for the "lan-dis-changes"
leaf which was skipped (more work needs to be done to support it).

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
isisd/isis_adjacency.c
isisd/isis_circuit.h
isisd/isis_northbound.c
isisd/isis_pdu.c
yang/frr-isisd.yang

index 9b368cc4042675ca768a75f9b2c6ad70a6c279b0..d2ec6ff5665f8cbe2e598dc9e9b6376bf69e052f 100644 (file)
@@ -254,6 +254,7 @@ void isis_adj_state_change(struct isis_adjacency *adj,
                        reason ? reason : "unspecified");
        }
 
+       circuit->adj_state_changes++;
 #ifndef FABRICD
        /* send northbound notification */
        isis_notif_adj_state_change(adj, new_state, reason);
index e3541644aa9052ec5d4a86f8da37406b7edb6840..b77c8ce35214a49160834d10c288366429d36a57 100644 (file)
@@ -144,6 +144,13 @@ struct isis_circuit {
        uint32_t
                desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges */
        uint32_t rej_adjacencies; /* rejectedAdjacencies */
+       /*
+        * Counters as in ietf-isis@2019-09-09.yang
+        */
+       uint32_t id_len_mismatches; /* id-len-mismatch */
+       uint32_t max_area_addr_mismatches; /* max-area-addresses-mismatch */
+       uint32_t auth_type_failures; /*authentication-type-fails */
+       uint32_t auth_failures; /* authentication-fails */
 
        QOBJ_FIELDS
 };
index 7eba4791aff5632c8a580eec9820b3433d550780..ccd4cfbd1c8c1526122fb81b6de7fa311c54d553 100644 (file)
@@ -2483,6 +2483,205 @@ lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath,
        return yang_data_new_string(xpath, isis_yang_adj_state(adj->adj_state));
 }
 
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_changes_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->adj_state_changes);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_number_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+       struct isis_adjacency *adj;
+       struct listnode *node;
+       uint32_t total = 0;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       /*
+        * TODO: keep track of the number of adjacencies instead of calculating
+        * it on demand.
+        */
+       switch (circuit->circ_type) {
+       case CIRCUIT_T_BROADCAST:
+               for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
+                       for (ALL_LIST_ELEMENTS_RO(
+                                    circuit->u.bc.adjdb[level - 1], node, adj))
+                               total++;
+               }
+               break;
+       case CIRCUIT_T_P2P:
+               adj = circuit->u.p2p.neighbor;
+               if (adj)
+                       total = 1;
+               break;
+       default:
+               break;
+       }
+
+       return yang_data_new_uint32(xpath, total);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath,
+                                                     const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->init_failures);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_rejects_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->rej_adjacencies);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_id_len_mismatch_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->id_len_mismatches);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/max-area-addresses-mismatch
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->max_area_addr_mismatches);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-type-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_authentication_type_fails_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->auth_type_failures);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_authentication_fails_get_elem(
+       const char *xpath, const void *list_entry)
+{
+       struct interface *ifp;
+       struct isis_circuit *circuit;
+
+       ifp = (struct interface *)list_entry;
+       if (!ifp)
+               return NULL;
+
+       circuit = circuit_scan_by_ifp(ifp);
+       if (!circuit)
+               return NULL;
+
+       return yang_data_new_uint32(xpath, circuit->auth_failures);
+}
+
 /*
  * NOTIFICATIONS
  */
@@ -3699,6 +3898,54 @@ const struct frr_yang_module_info frr_isisd_info = {
                                .get_elem = lib_interface_isis_adjacencies_adjacency_state_get_elem,
                        }
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_adjacency_changes_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_adjacency_number_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_init_fails_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_adjacency_rejects_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_id_len_mismatch_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/max-area-addresses-mismatch",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-type-fails",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_authentication_type_fails_get_elem,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-fails",
+                       .cbs = {
+                               .get_elem = lib_interface_isis_event_counters_authentication_fails_get_elem,
+                       }
+               },
                {
                        .xpath = NULL,
                },
index ecfce392ff5f61e55d858847d62b2776cde621b0..46b013ddd0c78bcd382121ce88d668642d1129a8 100644 (file)
@@ -576,6 +576,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",
@@ -586,6 +587,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",
@@ -598,6 +600,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,
@@ -614,6 +617,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);
@@ -643,6 +647,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);
@@ -654,6 +659,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);
@@ -667,6 +673,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);
@@ -685,6 +692,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);
@@ -702,11 +710,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;
        }
@@ -715,6 +726,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);
@@ -752,6 +764,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",
@@ -940,11 +953,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;
        }
@@ -1373,12 +1389,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;
                }
@@ -1614,6 +1633,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);
@@ -1666,6 +1686,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,
index c724e1089badc3061cbe32db2d9921eced9b5a40..faa880eff4479648f74757a820dce46735f32466 100644 (file)
@@ -623,10 +623,70 @@ module frr-isisd {
       "Adjacency state";
   }
 
+  grouping event-counters {
+    container event-counters {
+      config false;
+      leaf adjacency-changes {
+        type uint32;
+        description
+          "The number of times an adjacency state change has
+           occurred on this interface.";
+      }
+      leaf adjacency-number {
+        type uint32;
+        description
+          "The number of adjacencies on this interface.";
+      }
+      leaf init-fails {
+        type uint32;
+        description
+          "The number of times initialization of this
+           interface has failed. This counts events such
+           as PPP NCP failures. Failures to form an
+           adjacency are counted by adjacency-rejects.";
+      }
+      leaf adjacency-rejects {
+        type uint32;
+        description
+          "The number of times an adjacency has been
+           rejected on this interface.";
+      }
+      leaf id-len-mismatch {
+        type uint32;
+        description
+          "The number of times an IS-IS PDU with an ID
+           field length different from that for this
+           system has been received on this interface.";
+      }
+      leaf max-area-addresses-mismatch {
+        type uint32;
+        description
+          "The number of times an IS-IS PDU has been
+           received on this interface with the
+           max area address field differing from that of
+           this system.";
+      }
+      leaf authentication-type-fails {
+        type uint32;
+        description
+          "Number of authentication type mismatches.";
+      }
+      leaf authentication-fails {
+        type uint32;
+        description
+          "Number of authentication key failures.";
+      }
+      description "IS-IS interface event counters.";
+    }
+    description
+      "Grouping for IS-IS interface event counters";
+  }
+
   grouping interface-state {
     description
       "IS-IS interface operational state.";
     uses adjacency-state;
+    uses event-counters;
   }
 
   grouping notification-instance-hdr {