summaryrefslogtreecommitdiff
path: root/isisd/isis_csm.c
diff options
context:
space:
mode:
authorPeter Szilagyi <peszilagyi@gmail.com>2011-10-01 17:11:45 +0400
committerDenis Ovsienko <infrastation@yandex.ru>2012-02-14 03:06:00 +0400
commit7fd6cd819ff98f0580b745ba637990df9c20ef0f (patch)
treec95fc6bc290d170cd14a5962609df5baf577999d /isisd/isis_csm.c
parent4c0cf00afc4340a429a9c4830f638b4593d7c3af (diff)
isisd: fix circuit state machine
isisd has a so-called circuit state machine that takes care about the interface state changes, such as initializing, down, up. When an interface was brought down by a link failure, the interface information was deleted and set to NULL. When the link was restored later, the interface was looked up by the old pointer, but since it was cleared, it was never found again, resulting in an interface never entering the up state again. Also, the program regularly crashed because of a deleted pointer in the same context which was later accessed without any further checking. Signed-off-by: Fritz Reichmann <fritz@reichmann.nl>
Diffstat (limited to 'isisd/isis_csm.c')
-rw-r--r--isisd/isis_csm.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c
index 80d0c906..6cdde46a 100644
--- a/isisd/isis_csm.c
+++ b/isisd/isis_csm.c
@@ -112,6 +112,7 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
isis_circuit_configure (circuit, (struct isis_area *) arg);
isis_circuit_up (circuit);
circuit->state = C_STATE_UP;
+ circuit->connected = 1;
isis_event_circuit_state_change (circuit, 1);
listnode_delete (isis->init_circ_list, circuit);
break;
@@ -136,9 +137,12 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
zlog_warn ("circuit already enabled");
break;
case IF_UP_FROM_Z:
- isis_circuit_if_add (circuit, (struct interface *) arg);
- isis_circuit_up (circuit);
+ if (!circuit->connected) {
+ isis_circuit_if_add (circuit, (struct interface *) arg);
+ isis_circuit_up (circuit);
+ }
circuit->state = C_STATE_UP;
+ circuit->connected = 1;
isis_event_circuit_state_change (circuit, 1);
break;
case ISIS_DISABLE:
@@ -167,7 +171,6 @@ isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
isis_event_circuit_state_change (circuit, 0);
break;
case IF_DOWN_FROM_Z:
- isis_circuit_if_del (circuit);
circuit->state = C_STATE_CONF;
isis_event_circuit_state_change (circuit, 0);
break;