summaryrefslogtreecommitdiffstats
path: root/isisd
diff options
context:
space:
mode:
Diffstat (limited to 'isisd')
-rw-r--r--isisd/isis_adjacency.c1
-rw-r--r--isisd/isis_circuit.c49
-rw-r--r--isisd/isis_circuit.h9
-rw-r--r--isisd/isis_cli.c111
-rw-r--r--isisd/isis_main.c2
-rw-r--r--isisd/isis_northbound.c534
-rw-r--r--isisd/isis_pdu.c35
-rw-r--r--isisd/isis_te.c3
-rw-r--r--isisd/isis_zebra.c79
-rw-r--r--isisd/isis_zebra.h2
-rw-r--r--isisd/isisd.c3
-rw-r--r--isisd/isisd.h3
12 files changed, 633 insertions, 198 deletions
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 9b368cc40..d2ec6ff56 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -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);
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 5da8e6ee9..29fb725b0 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -61,6 +61,8 @@
DEFINE_QOBJ_TYPE(isis_circuit)
+DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
+
/*
* Prototypes.
*/
@@ -1389,6 +1391,51 @@ int isis_if_delete_hook(struct interface *ifp)
return 0;
}
+static int isis_ifp_create(struct interface *ifp)
+{
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
+ ifp);
+
+ hook_call(isis_if_new_hook, ifp);
+
+ return 0;
+}
+
+static int isis_ifp_up(struct interface *ifp)
+{
+ isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+
+ return 0;
+}
+
+static int isis_ifp_down(struct interface *ifp)
+{
+ struct isis_circuit *circuit;
+
+ circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
+ circuit_scan_by_ifp(ifp), ifp);
+ if (circuit)
+ SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
+
+ return 0;
+}
+
+static int isis_ifp_destroy(struct interface *ifp)
+{
+ if (if_is_operative(ifp))
+ zlog_warn("Zebra: got delete of %s, but interface is still up",
+ ifp->name);
+
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+
+ /* Cannot call if_delete because we should retain the pseudo interface
+ in case there is configuration info attached to it. */
+ if_delete_retain(ifp);
+
+ return 0;
+}
+
void isis_circuit_init(void)
{
/* Initialize Zebra interface data structure */
@@ -1398,4 +1445,6 @@ void isis_circuit_init(void)
/* Install interface node */
install_node(&interface_node, isis_interface_config_write);
if_cmd_init();
+ if_zapi_callbacks(isis_ifp_create, isis_ifp_up,
+ isis_ifp_down, isis_ifp_destroy);
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index e3541644a..f677d3ade 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -32,6 +32,8 @@
#include "isis_constants.h"
#include "isis_common.h"
+DECLARE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
+
struct isis_lsp;
struct password {
@@ -144,6 +146,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
};
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index bd0628675..37f4dcfab 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -188,14 +188,10 @@ DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
}
/* check if the interface is a loopback and if so set it as passive */
- pthread_rwlock_rdlock(&running_config->lock);
- {
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (ifp && if_is_loopback(ifp))
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
- NB_OP_MODIFY, "true");
- }
- pthread_rwlock_unlock(&running_config->lock);
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ if (ifp && if_is_loopback(ifp))
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
+ NB_OP_MODIFY, "true");
return nb_cli_apply_changes(vty, NULL);
}
@@ -262,14 +258,10 @@ DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
}
/* check if the interface is a loopback and if so set it as passive */
- pthread_rwlock_rdlock(&running_config->lock);
- {
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (ifp && if_is_loopback(ifp))
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
- NB_OP_MODIFY, "true");
- }
- pthread_rwlock_unlock(&running_config->lock);
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ if (ifp && if_is_loopback(ifp))
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
+ NB_OP_MODIFY, "true");
return nb_cli_apply_changes(vty, NULL);
}
@@ -410,26 +402,20 @@ DEFPY(no_is_type, no_is_type_cmd,
"Act as both a station router and an area router\n"
"Act as an area router only\n")
{
- const char *value;
-
- pthread_rwlock_rdlock(&running_config->lock);
- {
- struct isis_area *area;
+ const char *value = NULL;
+ struct isis_area *area;
- area = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
-
- /*
- * Put the is-type back to defaults:
- * - level-1-2 on first area
- * - level-1 for the rest
- */
- if (area && listgetdata(listhead(isis->area_list)) == area)
- value = "level-1-2";
- else
- value = NULL;
- }
- pthread_rwlock_unlock(&running_config->lock);
+ area = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ /*
+ * Put the is-type back to defaults:
+ * - level-1-2 on first area
+ * - level-1 for the rest
+ */
+ if (area && listgetdata(listhead(isis->area_list)) == area)
+ value = "level-1-2";
+ else
+ value = NULL;
nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, value);
return nb_cli_apply_changes(vty, NULL);
@@ -1817,45 +1803,52 @@ DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd,
"Level-1-2 adjacencies are formed\n"
"Level-2 only adjacencies are formed\n")
{
- const char *circ_type = NULL;
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+ int is_type;
+ const char *circ_type;
/*
* Default value depends on whether the circuit is part of an area,
* and the is-type of the area if there is one. So we need to do this
* here.
*/
- pthread_rwlock_rdlock(&running_config->lock);
- {
- struct interface *ifp;
- struct isis_circuit *circuit;
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ if (!ifp)
+ goto def_val;
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (!ifp)
- goto unlock;
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ goto def_val;
- circuit = circuit_scan_by_ifp(ifp);
- if (!circuit || circuit->state != C_STATE_UP)
- goto unlock;
+ if (circuit->state == C_STATE_UP)
+ is_type = circuit->area->is_type;
+ else
+ goto def_val;
- switch (circuit->area->is_type) {
- case IS_LEVEL_1:
- circ_type = "level-1";
- break;
- case IS_LEVEL_2:
- circ_type = "level-2";
- break;
- case IS_LEVEL_1_AND_2:
- circ_type = "level-1-2";
- break;
- }
+ switch (is_type) {
+ case IS_LEVEL_1:
+ circ_type = "level-1";
+ break;
+ case IS_LEVEL_2:
+ circ_type = "level-2";
+ break;
+ case IS_LEVEL_1_AND_2:
+ circ_type = "level-1-2";
+ break;
+ default:
+ return CMD_ERR_NO_MATCH;
}
-unlock:
- pthread_rwlock_unlock(&running_config->lock);
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
NB_OP_MODIFY, circ_type);
return nb_cli_apply_changes(vty, NULL);
+
+def_val:
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
+ NB_OP_MODIFY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
}
void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode,
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 7f49e9d89..718924daf 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -243,7 +243,7 @@ int main(int argc, char **argv, char **envp)
mt_init();
/* create the global 'isis' instance */
- isis_new(1);
+ isis_new(1, VRF_DEFAULT);
isis_zebra_init(master);
isis_bfd_init();
diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c
index bd6191869..97b7ae4f7 100644
--- a/isisd/isis_northbound.c
+++ b/isisd/isis_northbound.c
@@ -49,6 +49,23 @@
#include "lib/vrf.h"
/*
+ * Helper functions.
+ */
+static const char *isis_yang_adj_state(enum isis_adj_state state)
+{
+ switch (state) {
+ case ISIS_ADJ_DOWN:
+ return "down";
+ case ISIS_ADJ_UP:
+ return "up";
+ case ISIS_ADJ_INITIALIZING:
+ return "init";
+ default:
+ return "failed";
+ }
+}
+
+/*
* XPath: /frr-isisd:isis/instance
*/
static int isis_instance_create(enum nb_event event,
@@ -1401,29 +1418,12 @@ static int isis_instance_mpls_te_create(enum nb_event event,
area->mta->status = enable;
}
- /*
- * Following code is intended to handle two cases;
- *
- * 1) MPLS-TE was disabled at startup time, but now become enabled.
- * In this case, we must enable MPLS-TE Circuit regarding interface
- * MPLS_TE flag
- * 2) MPLS-TE was once enabled then disabled, and now enabled again.
- */
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
- if (circuit->ext == NULL)
- continue;
+ /* Update Extended TLVs according to Interface link parameters */
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ isis_link_params_update(circuit, circuit->interface);
- if (!IS_EXT_TE(circuit->ext)
- && HAS_LINK_PARAMS(circuit->interface))
- isis_link_params_update(circuit, circuit->interface);
- else
- continue;
-
- /* Reoriginate STD_TE & GMPLS circuits */
- if (circuit->area)
- lsp_regenerate_schedule(circuit->area, circuit->is_type,
- 0);
- }
+ /* Reoriginate STD_TE & GMPLS circuits */
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -1456,13 +1456,11 @@ static int isis_instance_mpls_te_destroy(enum nb_event event,
circuit->ext->status = EXT_LAN_ADJ_SID;
else
circuit->ext->status = 0;
-
- /* Re-originate circuit without STD_TE & GMPLS parameters */
- if (circuit->area)
- lsp_regenerate_schedule(circuit->area, circuit->is_type,
- 0);
}
+ /* Reoriginate STD_TE & GMPLS circuits */
+ lsp_regenerate_schedule(area, area->is_type, 0);
+
zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
area->area_tag);
@@ -1492,8 +1490,7 @@ static int isis_instance_mpls_te_router_address_modify(enum nb_event event,
area->mta->router_id.s_addr = value.s_addr;
/* And re-schedule LSP update */
- if (listcount(area->area_addrs) > 0)
- lsp_regenerate_schedule(area, area->is_type, 0);
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -1515,8 +1512,7 @@ static int isis_instance_mpls_te_router_address_destroy(enum nb_event event,
area->mta->router_id.s_addr = INADDR_ANY;
/* And re-schedule LSP update */
- if (listcount(area->area_addrs) > 0)
- lsp_regenerate_schedule(area, area->is_type, 0);
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -1542,9 +1538,9 @@ static int lib_interface_isis_create(enum nb_event event,
/* check if interface mtu is sufficient. If the area has not
* been created yet, assume default MTU for the area
*/
- ifp = nb_running_get_entry(dnode, NULL, true);
+ ifp = nb_running_get_entry(dnode, NULL, false);
/* zebra might not know yet about the MTU - nothing we can do */
- if (ifp->mtu == 0)
+ if (!ifp || ifp->mtu == 0)
break;
actual_mtu =
if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
@@ -2304,6 +2300,368 @@ static int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
}
/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency
+ */
+static const void *
+lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry,
+ const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+ struct isis_adjacency *adj, *adj_next = NULL;
+ struct list *list;
+ struct listnode *node, *node_next;
+
+ /* Get first adjacency. */
+ if (list_entry == NULL) {
+ ifp = (struct interface *)parent_list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ switch (circuit->circ_type) {
+ case CIRCUIT_T_BROADCAST:
+ for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS;
+ level++) {
+ adj = listnode_head(
+ circuit->u.bc.adjdb[level - 1]);
+ if (adj)
+ break;
+ }
+ break;
+ case CIRCUIT_T_P2P:
+ adj = circuit->u.p2p.neighbor;
+ break;
+ default:
+ adj = NULL;
+ break;
+ }
+
+ return adj;
+ }
+
+ /* Get next adjacency. */
+ adj = (struct isis_adjacency *)list_entry;
+ circuit = adj->circuit;
+ switch (circuit->circ_type) {
+ case CIRCUIT_T_BROADCAST:
+ list = circuit->u.bc.adjdb[adj->level - 1];
+ node = listnode_lookup(list, adj);
+ node_next = listnextnode(node);
+ if (node_next)
+ adj_next = listgetdata(node_next);
+ else if (adj->level == ISIS_LEVEL1) {
+ /*
+ * Once we finish the L1 adjacencies, move to the L2
+ * adjacencies list.
+ */
+ list = circuit->u.bc.adjdb[ISIS_LEVEL2 - 1];
+ adj_next = listnode_head(list);
+ }
+ break;
+ case CIRCUIT_T_P2P:
+ /* P2P circuits have at most one adjacency. */
+ default:
+ break;
+ }
+
+ return adj_next;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_enum(xpath, adj->level);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_string(xpath, sysid_print(adj->sysid));
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint32(xpath, adj->circuit->circuit_id);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_string(xpath, snpa_print(adj->snpa));
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint16(xpath, adj->hold_time);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-priority
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint8(xpath, adj->prio[adj->level - 1]);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ 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
*/
static void notif_prep_instance_hdr(const char *xpath,
@@ -2545,19 +2903,7 @@ void isis_notif_adj_state_change(const struct isis_adjacency *adj,
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");
- }
+ data = yang_data_new_string(xpath_arg, isis_yang_adj_state(new_state));
listnode_add(arguments, data);
if (new_state == ISIS_ADJ_DOWN) {
snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
@@ -3484,6 +3830,102 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency",
+ .cbs = {
+ .get_next = lib_interface_isis_adjacencies_adjacency_get_next,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-priority",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state",
+ .cbs = {
+ .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,
},
}
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index ecfce392f..a637ff003 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -187,7 +187,7 @@ static int process_p2p_hello(struct iih_info *iih)
adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
}
- if (tw_adj && adj->threeway_state == ISIS_THREEWAY_DOWN)
+ if (tw_adj)
adj->ext_circuit_id = tw_adj->local_circuit_id;
/* 8.2.6 Monitoring point-to-point adjacencies */
@@ -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,
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 44fa45d02..9871d2bcb 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -81,8 +81,7 @@ void isis_link_params_update(struct isis_circuit *circuit,
return;
/* Sanity Check */
- if ((circuit == NULL) || (ifp == NULL)
- || (circuit->state != C_STATE_UP))
+ if ((ifp == NULL) || (circuit->state != C_STATE_UP))
return;
zlog_debug("TE(%s): Update circuit parameters for interface %s",
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 39a2f6ef3..bdf6869f5 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -53,8 +53,6 @@
struct zclient *zclient = NULL;
-DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
-
/* Router-id update message from zebra. */
static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
{
@@ -74,79 +72,6 @@ static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int isis_zebra_if_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (if_is_operative(ifp))
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
- ifp);
-
- hook_call(isis_if_new_hook, ifp);
-
- return 0;
-}
-
-static int isis_zebra_if_del(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (!ifp)
- return 0;
-
- if (if_is_operative(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
-
- /* Cannot call if_delete because we should retain the pseudo interface
- in case there is configuration info attached to it. */
- if_delete_retain(ifp);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
-
- return 0;
-}
-
-static int isis_zebra_if_state_up(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
-
- return 0;
-}
-
-static int isis_zebra_if_state_down(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct isis_circuit *circuit;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
- circuit_scan_by_ifp(ifp), ifp);
- if (circuit)
- SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
-
- return 0;
-}
-
static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
@@ -388,10 +313,6 @@ void isis_zebra_init(struct thread_master *master)
zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
- zclient->interface_add = isis_zebra_if_add;
- zclient->interface_delete = isis_zebra_if_del;
- zclient->interface_up = isis_zebra_if_state_up;
- zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->interface_link_params = isis_zebra_link_params;
diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h
index 83a32108e..d00f348c8 100644
--- a/isisd/isis_zebra.h
+++ b/isisd/isis_zebra.h
@@ -24,8 +24,6 @@
extern struct zclient *zclient;
-DECLARE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
-
void isis_zebra_init(struct thread_master *);
void isis_zebra_stop(void);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 67f557ab5..029a9e068 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -75,12 +75,13 @@ int clear_isis_neighbor_common(struct vty *, const char *id);
int isis_config_write(struct vty *);
-void isis_new(unsigned long process_id)
+void isis_new(unsigned long process_id, vrf_id_t vrf_id)
{
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
/*
* Default values
*/
+ isis->vrf_id = vrf_id;
isis->max_area_addrs = 3;
isis->process_id = process_id;
isis->router_id = 0;
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 308f018c1..f825b6ecb 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -62,6 +62,7 @@ extern struct zebra_privs_t isisd_privs;
struct fabricd;
struct isis {
+ vrf_id_t vrf_id;
unsigned long process_id;
int sysid_set;
uint8_t sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
@@ -189,7 +190,7 @@ struct isis_area {
DECLARE_QOBJ_TYPE(isis_area)
void isis_init(void);
-void isis_new(unsigned long);
+void isis_new(unsigned long process_id, vrf_id_t vrf_id);
struct isis_area *isis_area_create(const char *);
struct isis_area *isis_area_lookup(const char *);
int isis_area_get(struct vty *vty, const char *area_tag);