forked from Mirror/frr
isisd: fix crash on "no router isis" (BZ#536)
The crash is due to threads accessing data that gets destroyed during the removal of the configuration. * isis_circuit.c: Destroy adjacencies to stop adjacency expiry thread. Stop PSNP threads. * isisd.c: Change state of circuit back to INIT and reassign the circuit structure to isis->init_circ_list rather than destroying the circuit data structure. Stop SPF threads. Stop LSP generation threads. * isisd.h: Add pointers to LSP threads into area structure in order to stop them in isisd.c * isis_lsp.c: Store pointer to LSP thread in area structure. * isis_pdu.c: Stop PDU generation for a circuit with a removed area. * isis_pfpacket.c: Stop processing received PDUs for a circuit with a removed area.
This commit is contained in:
parent
b69442d456
commit
5574999e59
|
@ -142,6 +142,11 @@ isis_circuit_deconfigure (struct isis_circuit *circuit,
|
|||
struct isis_area *area)
|
||||
{
|
||||
|
||||
/* destroy adjacencies */
|
||||
if (circuit->u.bc.adjdb[0])
|
||||
isis_adjdb_iterate (circuit->u.bc.adjdb[0], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[0]);
|
||||
if (circuit->u.bc.adjdb[1])
|
||||
isis_adjdb_iterate (circuit->u.bc.adjdb[1], (void(*) (struct isis_adjacency *, void *)) isis_delete_adj, circuit->u.bc.adjdb[1]);
|
||||
/* Remove circuit from area */
|
||||
listnode_delete (area->circuit_list, circuit);
|
||||
/* Free the index of SRM and SSN flags */
|
||||
|
@ -602,6 +607,13 @@ isis_circuit_down (struct isis_circuit *circuit)
|
|||
{
|
||||
THREAD_TIMER_OFF (circuit->u.p2p.t_send_p2p_hello);
|
||||
}
|
||||
|
||||
if (circuit->t_send_psnp[0]) {
|
||||
THREAD_TIMER_OFF (circuit->t_send_psnp[0]);
|
||||
}
|
||||
if (circuit->t_send_psnp[1]) {
|
||||
THREAD_TIMER_OFF (circuit->t_send_psnp[1]);
|
||||
}
|
||||
/* close the socket */
|
||||
close (circuit->fd);
|
||||
|
||||
|
|
|
@ -1640,7 +1640,7 @@ lsp_regenerate_schedule (struct isis_area *area)
|
|||
if (diff < MIN_LSP_GEN_INTERVAL)
|
||||
{
|
||||
area->lsp_regenerate_pending[0] = 1;
|
||||
thread_add_timer (master, lsp_l1_regenerate, area,
|
||||
area->t_lsp_l1_regenerate=thread_add_timer (master, lsp_l1_regenerate, area,
|
||||
MIN_LSP_GEN_INTERVAL - diff);
|
||||
goto L2;
|
||||
}
|
||||
|
@ -1663,7 +1663,7 @@ L2:
|
|||
if (diff < MIN_LSP_GEN_INTERVAL)
|
||||
{
|
||||
area->lsp_regenerate_pending[1] = 1;
|
||||
thread_add_timer (master, lsp_l2_regenerate, area,
|
||||
area->t_lsp_l2_regenerate=thread_add_timer (master, lsp_l2_regenerate, area,
|
||||
MIN_LSP_GEN_INTERVAL - diff);
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
|
|
@ -1781,6 +1781,9 @@ isis_receive (struct thread *thread)
|
|||
circuit = THREAD_ARG (thread);
|
||||
assert (circuit);
|
||||
|
||||
if (!circuit->area)
|
||||
return ISIS_OK;
|
||||
|
||||
if (circuit->rcv_stream == NULL)
|
||||
circuit->rcv_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
|
@ -2088,6 +2091,11 @@ send_lan_l2_hello (struct thread *thread)
|
|||
|
||||
circuit = THREAD_ARG (thread);
|
||||
assert (circuit);
|
||||
|
||||
if (!circuit->area) {
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
circuit->u.bc.t_send_lan_hello[1] = NULL;
|
||||
|
||||
if (circuit->u.bc.run_dr_elect[1])
|
||||
|
|
|
@ -232,6 +232,10 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
|
|||
LLC_LEN, MSG_PEEK,
|
||||
(struct sockaddr *) &s_addr, (socklen_t *) &addr_len);
|
||||
|
||||
if (!circuit->area) {
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
if (bytesread < 0)
|
||||
{
|
||||
zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "isisd/isis_route.h"
|
||||
#include "isisd/isis_zebra.h"
|
||||
#include "isisd/isis_events.h"
|
||||
#include "isisd/isis_csm.h"
|
||||
|
||||
#ifdef TOPOLOGY_GENERATE
|
||||
#include "spgrid.h"
|
||||
|
@ -217,21 +218,31 @@ isis_area_destroy (struct vty *vty, const char *area_tag)
|
|||
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
|
||||
{
|
||||
/* The fact that it's in circuit_list means that it was configured */
|
||||
isis_csm_state_change (ISIS_DISABLE, circuit, area);
|
||||
isis_circuit_down (circuit);
|
||||
isis_circuit_deconfigure (circuit, area);
|
||||
isis_circuit_del (circuit);
|
||||
}
|
||||
|
||||
list_delete (area->circuit_list);
|
||||
}
|
||||
listnode_delete (isis->area_list, area);
|
||||
|
||||
THREAD_TIMER_OFF (area->t_tick);
|
||||
if (area->t_remove_aged)
|
||||
thread_cancel (area->t_remove_aged);
|
||||
THREAD_TIMER_OFF (area->t_lsp_refresh[0]);
|
||||
THREAD_TIMER_OFF (area->t_lsp_refresh[1]);
|
||||
|
||||
THREAD_TIMER_OFF (area->spftree[0]->t_spf);
|
||||
THREAD_TIMER_OFF (area->spftree[1]->t_spf);
|
||||
|
||||
THREAD_TIMER_OFF (area->t_lsp_l1_regenerate);
|
||||
THREAD_TIMER_OFF (area->t_lsp_l2_regenerate);
|
||||
|
||||
XFREE (MTYPE_ISIS_AREA, area);
|
||||
|
||||
isis->sysid_set=0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ struct isis_area
|
|||
struct flags flags;
|
||||
struct thread *t_tick; /* LSP walker */
|
||||
struct thread *t_remove_aged;
|
||||
struct thread *t_lsp_l1_regenerate;
|
||||
struct thread *t_lsp_l2_regenerate;
|
||||
int lsp_regenerate_pending[ISIS_LEVELS];
|
||||
struct thread *t_lsp_refresh[ISIS_LEVELS];
|
||||
|
||||
|
|
Loading…
Reference in a new issue