]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_northbound.c
isisd: implement the 'lsp-received' notification
[mirror_frr.git] / isisd / isis_northbound.c
index 150b5755a5740cba0798d96e2c286fdf64f35fc5..bb6b23122dd034e7f11c0afd691339df77029d4e 100644 (file)
@@ -1480,7 +1480,14 @@ isis_instance_log_adjacency_changes_create(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->log_adj_changes = 1;
+
        return NB_OK;
 }
 
@@ -1488,7 +1495,14 @@ static int
 isis_instance_log_adjacency_changes_delete(enum nb_event event,
                                           const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->log_adj_changes = 0;
+
        return NB_OK;
 }
 
@@ -2069,7 +2083,14 @@ lib_interface_isis_priority_level_1_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -2081,7 +2102,14 @@ lib_interface_isis_priority_level_2_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -2092,14 +2120,48 @@ static int lib_interface_isis_network_type_modify(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct isis_circuit *circuit;
+       int net_type = yang_dnode_get_enum(dnode, NULL);
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               circuit = yang_dnode_get_entry(dnode, false);
+               if (!circuit)
+                       break;
+               if (circuit->circ_type == CIRCUIT_T_LOOPBACK
+                   || circuit->circ_type == CIRCUIT_T_UNKNOWN) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Cannot change network type on unknown or loopback interface");
+                       return NB_ERR_VALIDATION;
+               }
+               if (net_type == CIRCUIT_T_BROADCAST
+                   && circuit->state == C_STATE_UP
+                   && !if_is_broadcast(circuit->interface)) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Cannot configure non-broadcast interface for broadcast operation");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               circuit = yang_dnode_get_entry(dnode, true);
+               isis_circuit_circ_type_set(circuit, net_type);
+               break;
+       }
+
        return NB_OK;
 }
 
 static int lib_interface_isis_network_type_delete(enum nb_event event,
                                                  const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* FIXME: This cannot be done in FRR. Not sure what the intended
+        * behavior is.
+        */
        return NB_OK;
 }
 
@@ -2381,6 +2443,350 @@ static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
                                                        ISIS_MT_IPV6_DSTSRC);
 }
 
+/*
+ * NOTIFICATIONS
+ */
+static void notif_prep_instance_hdr(const char *xpath,
+                                   const struct isis_area *area,
+                                   const char *routing_instance,
+                                   struct list *args)
+{
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-instance", xpath);
+       data = yang_data_new_string(xpath_arg, routing_instance);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/routing-protocol-name",
+                xpath);
+       data = yang_data_new_string(xpath_arg, area->area_tag);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/isis-level", xpath);
+       data = yang_data_new_enum(xpath_arg, area->is_type);
+       listnode_add(args, data);
+}
+
+static void notif_prepr_iface_hdr(const char *xpath,
+                                 const struct isis_circuit *circuit,
+                                 struct list *args)
+{
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
+       data = yang_data_new_string(xpath_arg, circuit->interface->name);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-level", xpath);
+       data = yang_data_new_enum(xpath_arg, circuit->is_type);
+       listnode_add(args, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/extended-circuit-id", xpath);
+       /* we do not seem to have the extended version of the circuit_id */
+       data = yang_data_new_uint32(xpath_arg, (uint32_t)circuit->circuit_id);
+       listnode_add(args, data);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:database-overload
+ */
+void isis_notif_db_overload(const struct isis_area *area, bool overload)
+{
+       const char *xpath = "/frr-isisd:database-overload";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/overload", xpath);
+       data = yang_data_new_enum(xpath_arg, !!overload);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-too-large
+ */
+void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
+                             uint32_t pdu_size, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:lsp-too-large";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/pdu-size", xpath);
+       data = yang_data_new_uint32(xpath_arg, pdu_size);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:if-state-change
+ */
+void isis_notif_if_state_change(const struct isis_circuit *circuit, bool down)
+{
+       const char *xpath = "/frr-isisd:if-state-change";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
+       data = yang_data_new_enum(xpath_arg, !!down);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:corrupted-lsp-detected
+ */
+void isis_notif_corrupted_lsp(const struct isis_area *area, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:corrupted-lsp-detected";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:attempt-to-exceed-max-sequence
+ */
+void isis_notif_lsp_exceed_max(const struct isis_area *area, const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:attempt-to-exceed-max-sequence";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:max-area-addresses-mismatch
+ */
+void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
+                                      uint8_t max_area_addrs,
+                                      const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:max-area-addresses-mismatch";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/max-area-addresses", xpath);
+       data = yang_data_new_uint8(xpath_arg, max_area_addrs);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:authentication-type-failure
+ */
+void isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
+                                           const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:authentication-type-failure";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:authentication-failure
+ */
+void isis_notif_authentication_failure(const struct isis_circuit *circuit,
+                                      const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:authentication-failure";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:adjacency-state-change
+ */
+void isis_notif_adj_state_change(const struct isis_adjacency *adj,
+                                int new_state, const char *reason)
+{
+       const char *xpath = "/frr-isisd:adjacency-state-change";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_circuit *circuit = adj->circuit;
+       struct isis_area *area = circuit->area;
+       struct isis_dynhn *dyn = dynhn_find_by_id(adj->sysid);
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       if (dyn) {
+               snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor", xpath);
+               data = yang_data_new_string(xpath_arg, dyn->hostname);
+               listnode_add(arguments, data);
+       }
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
+       data = yang_data_new_string(xpath_arg, sysid_print(adj->sysid));
+       listnode_add(arguments, data);
+
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
+       switch (new_state) {
+       case ISIS_ADJ_DOWN:
+               data = yang_data_new_string(xpath_arg, "down");
+               break;
+       case ISIS_ADJ_UP:
+               data = yang_data_new_string(xpath_arg, "up");
+               break;
+       case ISIS_ADJ_INITIALIZING:
+               data = yang_data_new_string(xpath_arg, "init");
+               break;
+       default:
+               data = yang_data_new_string(xpath_arg, "failed");
+       }
+       listnode_add(arguments, data);
+       if (new_state == ISIS_ADJ_DOWN) {
+               snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
+               data = yang_data_new_string(xpath_arg, reason);
+               listnode_add(arguments, data);
+       }
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:rejected-adjacency
+ */
+void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
+                                const char *reason, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:rejected-adjacency";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
+       data = yang_data_new_string(xpath_arg, reason);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:area-mismatch
+ */
+void isis_notif_area_mismatch(const struct isis_circuit *circuit,
+                             const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:area-mismatch";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-received
+ */
+void isis_notif_lsp_received(const struct isis_circuit *circuit,
+                            const char *lsp_id, uint32_t seqno,
+                            uint32_t timestamp, const char *sys_id)
+{
+       const char *xpath = "/frr-isisd:lsp-received";
+       struct list *arguments = yang_data_list_new();
+       char xpath_arg[XPATH_MAXLEN];
+       struct yang_data *data;
+       struct isis_area *area = circuit->area;
+
+       notif_prep_instance_hdr(xpath, area, "default", arguments);
+       notif_prepr_iface_hdr(xpath, circuit, arguments);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
+       data = yang_data_new_string(xpath_arg, lsp_id);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
+       data = yang_data_new_uint32(xpath_arg, seqno);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/received-timestamp", xpath);
+       data = yang_data_new_uint32(xpath_arg, timestamp);
+       listnode_add(arguments, data);
+       snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
+       data = yang_data_new_string(xpath_arg, sys_id);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
 /* clang-format off */
 const struct frr_yang_module_info frr_isisd_info = {
        .name = "frr-isisd",
@@ -2697,6 +3103,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-isisd:isis/instance/log-adjacency-changes",
                        .cbs.create = isis_instance_log_adjacency_changes_create,
                        .cbs.delete = isis_instance_log_adjacency_changes_delete,
+                       .cbs.cli_show = cli_show_isis_log_adjacency,
                },
                {
                        .xpath = "/frr-isisd:isis/mpls-te",
@@ -2722,6 +3129,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type",
                        .cbs.modify = lib_interface_isis_circuit_type_modify,
+                       .cbs.cli_show = cli_show_ip_isis_circ_type,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv4-routing",
@@ -2800,6 +3208,10 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/metric/level-2",
                        .cbs.modify = lib_interface_isis_metric_level_2_modify,
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority",
+                       .cbs.cli_show = cli_show_ip_isis_priority,
+               },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/priority/level-1",
                        .cbs.modify = lib_interface_isis_priority_level_1_modify,
@@ -2812,6 +3224,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/network-type",
                        .cbs.modify = lib_interface_isis_network_type_modify,
                        .cbs.delete = lib_interface_isis_network_type_delete,
+                       .cbs.cli_show = cli_show_ip_isis_network_type,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/passive",