]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/isis_northbound.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / isisd / isis_northbound.c
index 677950185061d1e242e984746734289e44178a25..a4672828260fa0e846b842a82e5857d383f49c40 100644 (file)
@@ -253,31 +253,19 @@ static int isis_instance_dynamic_hostname_modify(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/attached
  */
-static int isis_instance_attached_create(enum nb_event event,
+static int isis_instance_attached_modify(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
        struct isis_area *area;
+       bool attached;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
        area = yang_dnode_get_entry(dnode, true);
-       isis_area_attached_bit_set(area, true);
-
-       return NB_OK;
-}
-
-static int isis_instance_attached_delete(enum nb_event event,
-                                        const struct lyd_node *dnode)
-{
-       struct isis_area *area;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       area = yang_dnode_get_entry(dnode, true);
-       isis_area_attached_bit_set(area, false);
+       attached = yang_dnode_get_bool(dnode, NULL);
+       isis_area_attached_bit_set(area, attached);
 
        return NB_OK;
 }
@@ -285,31 +273,19 @@ static int isis_instance_attached_delete(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/overload
  */
-static int isis_instance_overload_create(enum nb_event event,
+static int isis_instance_overload_modify(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
        struct isis_area *area;
+       bool overload;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
        area = yang_dnode_get_entry(dnode, true);
-       isis_area_overload_bit_set(area, true);
-
-       return NB_OK;
-}
-
-static int isis_instance_overload_delete(enum nb_event event,
-                                        const struct lyd_node *dnode)
-{
-       struct isis_area *area;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       area = yang_dnode_get_entry(dnode, true);
-       isis_area_overload_bit_set(area, false);
+       overload = yang_dnode_get_bool(dnode, NULL);
+       isis_area_overload_bit_set(area, overload);
 
        return NB_OK;
 }
@@ -339,7 +315,7 @@ static int isis_instance_metric_style_modify(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/purge-originator
  */
-static int isis_instance_purge_originator_create(enum nb_event event,
+static int isis_instance_purge_originator_modify(enum nb_event event,
                                                 const struct lyd_node *dnode,
                                                 union nb_resource *resource)
 {
@@ -349,21 +325,7 @@ static int isis_instance_purge_originator_create(enum nb_event event,
                return NB_OK;
 
        area = yang_dnode_get_entry(dnode, true);
-       area->purge_originator = true;
-
-       return NB_OK;
-}
-
-static int isis_instance_purge_originator_delete(enum nb_event event,
-                                                const struct lyd_node *dnode)
-{
-       struct isis_area *area;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       area = yang_dnode_get_entry(dnode, true);
-       area->purge_originator = false;
+       area->purge_originator = yang_dnode_get_bool(dnode, NULL);
 
        return NB_OK;
 }
@@ -854,7 +816,7 @@ static void default_info_origin_apply_finish(const struct lyd_node *dnode,
        struct isis_area *area = yang_dnode_get_entry(dnode, true);
        int level = yang_dnode_get_enum(dnode, "./level");
 
-       if (yang_dnode_exists(dnode, "./always")) {
+       if (yang_dnode_get_bool(dnode, "./always")) {
                originate_type = DEFAULT_ORIGINATE_ALWAYS;
        } else if (family == AF_INET6) {
                zlog_warn(
@@ -908,7 +870,7 @@ static int isis_instance_default_information_originate_ipv4_delete(
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always
  */
-static int isis_instance_default_information_originate_ipv4_always_create(
+static int isis_instance_default_information_originate_ipv4_always_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
@@ -916,13 +878,6 @@ static int isis_instance_default_information_originate_ipv4_always_create(
        return NB_OK;
 }
 
-static int isis_instance_default_information_originate_ipv4_always_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       /* It's all done by default_info_origin_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map
  */
@@ -989,7 +944,7 @@ static int isis_instance_default_information_originate_ipv6_delete(
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always
  */
-static int isis_instance_default_information_originate_ipv6_always_create(
+static int isis_instance_default_information_originate_ipv6_always_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
@@ -997,13 +952,6 @@ static int isis_instance_default_information_originate_ipv6_always_create(
        return NB_OK;
 }
 
-static int isis_instance_default_information_originate_ipv6_always_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       /* It's all done by default_info_origin_apply_finish */
-       return NB_OK;
-}
-
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map
  */
@@ -1241,8 +1189,7 @@ static int isis_multi_topology_common(enum nb_event event,
 
 static int isis_multi_topology_overload_common(enum nb_event event,
                                               const struct lyd_node *dnode,
-                                              const char *topology,
-                                              bool create)
+                                              const char *topology)
 {
        struct isis_area *area;
        struct isis_area_mt_setting *setting;
@@ -1254,7 +1201,7 @@ static int isis_multi_topology_overload_common(enum nb_event event,
 
        area = yang_dnode_get_entry(dnode, true);
        setting = area_get_mt_setting(area, mtid);
-       setting->overload = create;
+       setting->overload = yang_dnode_get_bool(dnode, NULL);
        if (setting->enabled)
                lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
 
@@ -1280,19 +1227,12 @@ isis_instance_multi_topology_ipv4_multicast_delete(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload
  */
-static int isis_instance_multi_topology_ipv4_multicast_overload_create(
+static int isis_instance_multi_topology_ipv4_multicast_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        return isis_multi_topology_overload_common(event, dnode,
-                                                  "ipv4-multicast", true);
-}
-
-static int isis_instance_multi_topology_ipv4_multicast_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode,
-                                                  "ipv4-multicast", false);
+                                                  "ipv4-multicast");
 }
 
 /*
@@ -1314,19 +1254,11 @@ static int isis_instance_multi_topology_ipv4_management_delete(
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload
  */
-static int isis_instance_multi_topology_ipv4_management_overload_create(
+static int isis_instance_multi_topology_ipv4_management_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt",
-                                                  true);
-}
-
-static int isis_instance_multi_topology_ipv4_management_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt",
-                                                  false);
+       return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt");
 }
 
 /*
@@ -1350,19 +1282,12 @@ isis_instance_multi_topology_ipv6_unicast_delete(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload
  */
-static int isis_instance_multi_topology_ipv6_unicast_overload_create(
+static int isis_instance_multi_topology_ipv6_unicast_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-unicast",
-                                                  true);
-}
-
-static int isis_instance_multi_topology_ipv6_unicast_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-unicast",
-                                                  false);
+       return isis_multi_topology_overload_common(event, dnode,
+                                                  "ipv6-unicast");
 }
 
 /*
@@ -1387,19 +1312,12 @@ isis_instance_multi_topology_ipv6_multicast_delete(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload
  */
-static int isis_instance_multi_topology_ipv6_multicast_overload_create(
+static int isis_instance_multi_topology_ipv6_multicast_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        return isis_multi_topology_overload_common(event, dnode,
-                                                  "ipv6-multicast", true);
-}
-
-static int isis_instance_multi_topology_ipv6_multicast_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode,
-                                                  "ipv6-multicast", false);
+                                                  "ipv6-multicast");
 }
 
 /*
@@ -1421,19 +1339,11 @@ static int isis_instance_multi_topology_ipv6_management_delete(
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload
  */
-static int isis_instance_multi_topology_ipv6_management_overload_create(
+static int isis_instance_multi_topology_ipv6_management_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt",
-                                                  true);
-}
-
-static int isis_instance_multi_topology_ipv6_management_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt",
-                                                  false);
+       return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt");
 }
 
 /*
@@ -1457,38 +1367,30 @@ isis_instance_multi_topology_ipv6_dstsrc_delete(enum nb_event event,
 /*
  * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload
  */
-static int isis_instance_multi_topology_ipv6_dstsrc_overload_create(
+static int isis_instance_multi_topology_ipv6_dstsrc_overload_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc",
-                                                  true);
-}
-
-static int isis_instance_multi_topology_ipv6_dstsrc_overload_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc",
-                                                  false);
+       return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc");
 }
 
 /*
  * XPath: /frr-isisd:isis/instance/log-adjacency-changes
  */
 static int
-isis_instance_log_adjacency_changes_create(enum nb_event event,
+isis_instance_log_adjacency_changes_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
-}
+       struct isis_area *area;
+       bool log = yang_dnode_get_bool(dnode, NULL);
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       area->log_adj_changes = log ? 1 : 0;
 
-static int
-isis_instance_log_adjacency_changes_delete(enum nb_event event,
-                                          const struct lyd_node *dnode)
-{
-       /* TODO: implement me. */
        return NB_OK;
 }
 
@@ -1768,37 +1670,20 @@ static int lib_interface_isis_circuit_type_modify(enum nb_event event,
 /*
  * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
  */
-static int lib_interface_isis_ipv4_routing_create(enum nb_event event,
+static int lib_interface_isis_ipv4_routing_modify(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       bool ipv6;
+       bool ipv4, ipv6;
        struct isis_circuit *circuit;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
        circuit = yang_dnode_get_entry(dnode, true);
-       ipv6 = yang_dnode_exists(dnode, "../ipv6-routing");
-       isis_circuit_af_set(circuit, true, ipv6);
-
-       return NB_OK;
-}
-
-static int lib_interface_isis_ipv4_routing_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
-{
-       bool ipv6;
-       struct isis_circuit *circuit;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       circuit = yang_dnode_get_entry(dnode, true);
-       if (circuit && circuit->area) {
-               ipv6 = yang_dnode_exists(dnode, "../ipv6-routing");
-               isis_circuit_af_set(circuit, false, ipv6);
-       }
+       ipv4 = yang_dnode_get_bool(dnode, NULL);
+       ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing");
+       isis_circuit_af_set(circuit, ipv4, ipv6);
 
        return NB_OK;
 }
@@ -1806,37 +1691,20 @@ static int lib_interface_isis_ipv4_routing_delete(enum nb_event event,
 /*
  * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing
  */
-static int lib_interface_isis_ipv6_routing_create(enum nb_event event,
+static int lib_interface_isis_ipv6_routing_modify(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       bool ipv4;
-       struct isis_circuit *circuit;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       circuit = yang_dnode_get_entry(dnode, true);
-       ipv4 = yang_dnode_exists(dnode, "../ipv6-routing");
-       isis_circuit_af_set(circuit, ipv4, true);
-
-       return NB_OK;
-}
-
-static int lib_interface_isis_ipv6_routing_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
-{
-       bool ipv4;
+       bool ipv4, ipv6;
        struct isis_circuit *circuit;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
        circuit = yang_dnode_get_entry(dnode, true);
-       if (circuit->area) {
-               ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
-               isis_circuit_af_set(circuit, ipv4, false);
-       }
+       ipv4 = yang_dnode_exists(dnode, "../ipv4-routing");
+       ipv6 = yang_dnode_get_bool(dnode, NULL);
+       isis_circuit_af_set(circuit, ipv4, ipv6);
 
        return NB_OK;
 }
@@ -1849,7 +1717,14 @@ lib_interface_isis_csnp_interval_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->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -1861,7 +1736,14 @@ lib_interface_isis_csnp_interval_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->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -1873,7 +1755,14 @@ lib_interface_isis_psnp_interval_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->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -1885,7 +1774,14 @@ lib_interface_isis_psnp_interval_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->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -1896,7 +1792,14 @@ static int lib_interface_isis_hello_padding_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->pad_hellos = yang_dnode_get_bool(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -2034,7 +1937,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;
 }
 
@@ -2046,7 +1956,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;
 }
 
@@ -2057,78 +1974,80 @@ static int lib_interface_isis_network_type_modify(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
-}
+       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;
+       }
 
-static int lib_interface_isis_network_type_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
-{
-       /* TODO: implement me. */
        return NB_OK;
 }
 
 /*
  * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive
  */
-static int lib_interface_isis_passive_create(enum nb_event event,
+static int lib_interface_isis_passive_modify(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
        struct isis_circuit *circuit;
        struct isis_area *area;
-
-       if (event != NB_EV_APPLY)
-               return NB_OK;
-
-       circuit = yang_dnode_get_entry(dnode, true);
-       if (circuit->state != C_STATE_UP) {
-               circuit->is_passive = true;
-       } else {
-               area = circuit->area;
-               isis_csm_state_change(ISIS_DISABLE, circuit, area);
-               circuit->is_passive = true;
-               isis_csm_state_change(ISIS_ENABLE, circuit, area);
-       }
-
-       return NB_OK;
-}
-
-static int lib_interface_isis_passive_delete(enum nb_event event,
-                                            const struct lyd_node *dnode)
-{
-       struct isis_circuit *circuit;
-       struct isis_area *area;
        struct interface *ifp;
+       bool passive = yang_dnode_get_bool(dnode, NULL);
 
-       switch (event) {
-       case NB_EV_VALIDATE:
+       /* validation only applies if we are setting passive to false */
+       if (!passive && event == NB_EV_VALIDATE) {
                circuit = yang_dnode_get_entry(dnode, false);
                if (!circuit)
-                       break;
+                       return NB_OK;
                ifp = circuit->interface;
                if (!ifp)
-                       break;
+                       return NB_OK;
                if (if_is_loopback(ifp)) {
                        flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
                                  "Loopback is always passive");
                        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);
-               if (circuit->state != C_STATE_UP) {
-                       circuit->is_passive = false;
-               } else {
-                       area = circuit->area;
-                       isis_csm_state_change(ISIS_DISABLE, circuit, area);
-                       circuit->is_passive = false;
-                       isis_csm_state_change(ISIS_ENABLE, circuit, area);
-               }
-               break;
+       }
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       if (circuit->state != C_STATE_UP) {
+               circuit->is_passive = passive;
+       } else {
+               area = circuit->area;
+               isis_csm_state_change(ISIS_DISABLE, circuit, area);
+               circuit->is_passive = passive;
+               isis_csm_state_change(ISIS_ENABLE, circuit, area);
        }
 
        return NB_OK;
@@ -2205,18 +2124,18 @@ lib_interface_isis_password_password_type_modify(enum nb_event event,
  * XPath:
  * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake
  */
-static int lib_interface_isis_disable_three_way_handshake_create(
+static int lib_interface_isis_disable_three_way_handshake_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
-}
+       struct isis_circuit *circuit;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = yang_dnode_get_entry(dnode, true);
+       circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL);
 
-static int lib_interface_isis_disable_three_way_handshake_delete(
-       enum nb_event event, const struct lyd_node *dnode)
-{
-       /* TODO: implement me. */
        return NB_OK;
 }
 
@@ -2224,12 +2143,41 @@ static int lib_interface_isis_disable_three_way_handshake_delete(
  * XPath:
  * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast
  */
+static int lib_interface_isis_multi_topology_common(
+       enum nb_event event, const struct lyd_node *dnode, uint16_t mtid)
+{
+       struct isis_circuit *circuit;
+       bool value;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               circuit = yang_dnode_get_entry(dnode, false);
+               if (circuit && circuit->area && circuit->area->oldmetric) {
+                       flog_warn(
+                               EC_LIB_NB_CB_CONFIG_VALIDATE,
+                               "Multi topology IS-IS can only be used with wide metrics");
+                       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);
+               value = yang_dnode_get_bool(dnode, NULL);
+               isis_circuit_mt_enabled_set(circuit, mtid, value);
+               break;
+       }
+
+       return NB_OK;
+}
+
 static int lib_interface_isis_multi_topology_ipv4_unicast_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_UNICAST);
 }
 
 /*
@@ -2240,8 +2188,8 @@ static int lib_interface_isis_multi_topology_ipv4_multicast_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_MULTICAST);
 }
 
 /*
@@ -2252,8 +2200,8 @@ static int lib_interface_isis_multi_topology_ipv4_management_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV4_MGMT);
 }
 
 /*
@@ -2264,8 +2212,8 @@ static int lib_interface_isis_multi_topology_ipv6_unicast_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_UNICAST);
 }
 
 /*
@@ -2276,8 +2224,8 @@ static int lib_interface_isis_multi_topology_ipv6_multicast_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_MULTICAST);
 }
 
 /*
@@ -2288,8 +2236,8 @@ static int lib_interface_isis_multi_topology_ipv6_management_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       ISIS_MT_IPV6_MGMT);
 }
 
 /*
@@ -2299,8 +2247,500 @@ static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       return lib_interface_isis_multi_topology_common(event, dnode,
+                                                       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);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:lsp-generation
+ */
+void isis_notif_lsp_gen(const struct isis_area *area, const char *lsp_id,
+                       uint32_t seqno, uint32_t timestamp)
+{
+       const char *xpath = "/frr-isisd:lsp-generation";
+       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);
+       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/send-timestamp", xpath);
+       data = yang_data_new_uint32(xpath_arg, timestamp);
+       listnode_add(arguments, data);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:id-len-mismatch
+ */
+void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
+                               uint8_t rcv_id_len, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:id-len-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/pdu-field-len", xpath);
+       data = yang_data_new_uint8(xpath_arg, rcv_id_len);
+       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:version-skew
+ */
+void isis_notif_version_skew(const struct isis_circuit *circuit,
+                            uint8_t version, const char *raw_pdu)
+{
+       const char *xpath = "/frr-isisd:version-skew";
+       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/protocol-version", xpath);
+       data = yang_data_new_uint8(xpath_arg, version);
+       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:lsp-error-detected
+ */
+void isis_notif_lsp_error(const struct isis_circuit *circuit,
+                         const char *lsp_id, const char *raw_pdu,
+                         __attribute__((unused)) uint32_t offset,
+                         __attribute__((unused)) uint8_t tlv_type)
+{
+       const char *xpath = "/frr-isisd:lsp-error-detected";
+       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/raw-pdu", xpath);
+       data = yang_data_new(xpath_arg, raw_pdu);
+       listnode_add(arguments, data);
+       /* ignore offset and tlv_type which cannot be set properly */
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:sequence-number-skipped
+ */
+void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
+                             const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:sequence-number-skipped";
+       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);
+
+       nb_notification_send(xpath, arguments);
+}
+
+/*
+ * XPath:
+ * /frr-isisd:own-lsp-purge
+ */
+void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
+                             const char *lsp_id)
+{
+       const char *xpath = "/frr-isisd:own-lsp-purge";
+       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);
+
+       nb_notification_send(xpath, arguments);
 }
 
 /* clang-format off */
@@ -2332,14 +2772,12 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/attached",
-                       .cbs.create = isis_instance_attached_create,
-                       .cbs.delete = isis_instance_attached_delete,
+                       .cbs.modify = isis_instance_attached_modify,
                        .cbs.cli_show = cli_show_isis_attached,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/overload",
-                       .cbs.create = isis_instance_overload_create,
-                       .cbs.delete = isis_instance_overload_delete,
+                       .cbs.modify = isis_instance_overload_modify,
                        .cbs.cli_show = cli_show_isis_overload,
                },
                {
@@ -2349,8 +2787,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/purge-originator",
-                       .cbs.create = isis_instance_purge_originator_create,
-                       .cbs.delete = isis_instance_purge_originator_delete,
+                       .cbs.modify = isis_instance_purge_originator_modify,
                        .cbs.cli_show = cli_show_isis_purge_origin,
                },
                {
@@ -2480,8 +2917,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
-                       .cbs.create = isis_instance_default_information_originate_ipv4_always_create,
-                       .cbs.delete = isis_instance_default_information_originate_ipv4_always_delete,
+                       .cbs.modify = isis_instance_default_information_originate_ipv4_always_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/route-map",
@@ -2502,8 +2938,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
-                       .cbs.create = isis_instance_default_information_originate_ipv6_always_create,
-                       .cbs.delete = isis_instance_default_information_originate_ipv6_always_delete,
+                       .cbs.modify = isis_instance_default_information_originate_ipv6_always_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/route-map",
@@ -2557,8 +2992,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv4_multicast_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv4_multicast_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv4_multicast_overload_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management",
@@ -2568,8 +3002,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv4-management/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv4_management_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv4_management_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv4_management_overload_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast",
@@ -2579,8 +3012,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv6_unicast_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv6_unicast_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv6_unicast_overload_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast",
@@ -2590,8 +3022,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv6_multicast_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv6_multicast_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv6_multicast_overload_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management",
@@ -2601,8 +3032,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-management/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv6_management_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv6_management_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv6_management_overload_modify,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc",
@@ -2612,13 +3042,12 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload",
-                       .cbs.create = isis_instance_multi_topology_ipv6_dstsrc_overload_create,
-                       .cbs.delete = isis_instance_multi_topology_ipv6_dstsrc_overload_delete,
+                       .cbs.modify = isis_instance_multi_topology_ipv6_dstsrc_overload_modify,
                },
                {
                        .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.modify = isis_instance_log_adjacency_changes_modify,
+                       .cbs.cli_show = cli_show_isis_log_adjacency,
                },
                {
                        .xpath = "/frr-isisd:isis/mpls-te",
@@ -2644,19 +3073,22 @@ 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",
-                       .cbs.create = lib_interface_isis_ipv4_routing_create,
-                       .cbs.delete = lib_interface_isis_ipv4_routing_delete,
+                       .cbs.modify = lib_interface_isis_ipv4_routing_modify,
                        .cbs.cli_show = cli_show_ip_isis_ipv4,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/ipv6-routing",
-                       .cbs.create = lib_interface_isis_ipv6_routing_create,
-                       .cbs.delete = lib_interface_isis_ipv6_routing_delete,
+                       .cbs.modify = lib_interface_isis_ipv6_routing_modify,
                        .cbs.cli_show = cli_show_ip_isis_ipv6,
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval",
+                       .cbs.cli_show = cli_show_ip_isis_csnp_interval,
+               },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1",
                        .cbs.modify = lib_interface_isis_csnp_interval_level_1_modify,
@@ -2665,6 +3097,10 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2",
                        .cbs.modify = lib_interface_isis_csnp_interval_level_2_modify,
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval",
+                       .cbs.cli_show = cli_show_ip_isis_psnp_interval,
+               },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1",
                        .cbs.modify = lib_interface_isis_psnp_interval_level_1_modify,
@@ -2676,6 +3112,7 @@ const struct frr_yang_module_info frr_isisd_info = {
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/padding",
                        .cbs.modify = lib_interface_isis_hello_padding_modify,
+                       .cbs.cli_show = cli_show_ip_isis_hello_padding,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/hello/interval",
@@ -2713,6 +3150,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,
@@ -2724,12 +3165,11 @@ 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",
-                       .cbs.create = lib_interface_isis_passive_create,
-                       .cbs.delete = lib_interface_isis_passive_delete,
+                       .cbs.modify = lib_interface_isis_passive_modify,
                        .cbs.cli_show = cli_show_ip_isis_passive,
                },
                {
@@ -2748,36 +3188,43 @@ const struct frr_yang_module_info frr_isisd_info = {
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake",
-                       .cbs.create = lib_interface_isis_disable_three_way_handshake_create,
-                       .cbs.delete = lib_interface_isis_disable_three_way_handshake_delete,
+                       .cbs.modify = lib_interface_isis_disable_three_way_handshake_modify,
+                       .cbs.cli_show = cli_show_ip_isis_threeway_shake,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-unicast",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv4_unicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_unicast,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv4_multicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_multicast,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv4_management_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv4_mgmt,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv6_unicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_unicast,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv6_multicast_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_multicast,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv6_management_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_mgmt,
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc",
                        .cbs.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
+                       .cbs.cli_show = cli_show_ip_isis_mt_ipv6_dstsrc,
                },
                {
                        .xpath = NULL,