summaryrefslogtreecommitdiff
path: root/isisd/isis_circuit.c
diff options
context:
space:
mode:
Diffstat (limited to 'isisd/isis_circuit.c')
-rw-r--r--isisd/isis_circuit.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 4aac3f8880..62822cbf89 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -71,6 +71,48 @@ DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
int isis_if_new_hook(struct interface *);
int isis_if_delete_hook(struct interface *);
+static int isis_circuit_smmp_id_gen(struct isis_circuit *circuit)
+{
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ struct isis *isis = NULL;
+ uint32_t id;
+ uint32_t i;
+
+ isis = isis_lookup_by_vrfid(vrf->vrf_id);
+ if (isis == NULL)
+ return 0;
+
+ id = isis->snmp_circuit_id_last;
+ id++;
+
+ /* find next unused entry */
+ for (i = 0; i < SNMP_CIRCUITS_MAX; i++) {
+ if (id >= SNMP_CIRCUITS_MAX) {
+ id = 0;
+ continue;
+ }
+
+ if (id == 0)
+ continue;
+
+ if (isis->snmp_circuits[id] == NULL)
+ break;
+
+ id++;
+ }
+
+ if (i == SNMP_CIRCUITS_MAX) {
+ zlog_warn("Could not allocate a smmp-circuit-id");
+ return 0;
+ }
+
+ isis->snmp_circuits[id] = circuit;
+ isis->snmp_circuit_id_last = id;
+ circuit->snmp_id = id;
+
+ return 1;
+}
+
struct isis_circuit *isis_circuit_new(struct isis *isis)
{
struct isis_circuit *circuit;
@@ -80,6 +122,12 @@ struct isis_circuit *isis_circuit_new(struct isis *isis)
circuit->isis = isis;
/*
+ * Note: if snmp-id generation failed circuit will fail
+ * up operation
+ */
+ isis_circuit_smmp_id_gen(circuit);
+
+ /*
* Default values
*/
#ifndef FABRICD
@@ -150,11 +198,18 @@ struct isis_circuit *isis_circuit_new(struct isis *isis)
void isis_circuit_del(struct isis_circuit *circuit)
{
+ struct isis *isis = NULL;
+
if (!circuit)
return;
QOBJ_UNREG(circuit);
+ if (circuit->interface) {
+ isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
+ isis->snmp_circuits[circuit->snmp_id] = NULL;
+ }
+
isis_circuit_if_unbind(circuit, circuit->interface);
circuit_mt_finish(circuit);
@@ -609,6 +664,7 @@ int isis_circuit_up(struct isis_circuit *circuit)
return ISIS_OK;
if (circuit->is_passive) {
+ circuit->last_uptime = time(NULL);
/* make sure the union fields are initialized, else we
* could end with garbage values from a previous circuit
* type, which would then cause a segfault when building
@@ -623,6 +679,13 @@ int isis_circuit_up(struct isis_circuit *circuit)
return ISIS_OK;
}
+ if (circuit->snmp_id == 0) {
+ /* We cannot bring circuit up if does not have snmp-id */
+ flog_err(EC_ISIS_CONFIG,
+ "No snnmp-id: there are too many circuits:");
+ return ISIS_ERROR;
+ }
+
if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) {
flog_err(
EC_ISIS_CONFIG,
@@ -722,6 +785,8 @@ int isis_circuit_up(struct isis_circuit *circuit)
circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp);
+ circuit->last_uptime = time(NULL);
+
#ifndef FABRICD
/* send northbound notification */
isis_notif_if_state_change(circuit, false);
@@ -828,6 +893,15 @@ void isis_circuit_down(struct isis_circuit *circuit)
thread_cancel(&circuit->u.p2p.t_send_p2p_hello);
}
+ /*
+ * All adjacencies have to be gone, delete snmp list
+ * and reset snmpd idx generator
+ */
+ if (circuit->snmp_adj_list != NULL)
+ list_delete(&circuit->snmp_adj_list);
+
+ circuit->snmp_adj_idx_gen = 0;
+
/* Cancel all active threads */
thread_cancel(&circuit->t_send_csnp[0]);
thread_cancel(&circuit->t_send_csnp[1]);