XFREE(MTYPE_TMP, peer->notify.data);
memset(&peer->notify, 0, sizeof(struct bgp_notify));
- if (peer->clear_node_queue) {
- work_queue_free(peer->clear_node_queue);
- peer->clear_node_queue = NULL;
- }
+ if (peer->clear_node_queue)
+ work_queue_free_and_null(&peer->clear_node_queue);
bgp_sync_delete(peer);
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG);
- if (bm->process_main_queue) {
- work_queue_free(bm->process_main_queue);
- bm->process_main_queue = NULL;
- }
+ if (bm->process_main_queue)
+ work_queue_free_and_null(&bm->process_main_queue);
if (bm->t_rmap_update)
BGP_TIMER_OFF(bm->t_rmap_update);
h->import_mac = NULL;
}
- work_queue_free(h->deferred_close_q);
+ work_queue_free_and_null(&h->deferred_close_q);
if (h->rfp != NULL)
rfp_stop(h->rfp);
}
}
}
- if (rfd->updated_responses_queue) {
- work_queue_free(rfd->updated_responses_queue);
- rfd->updated_responses_queue = NULL;
- }
+ if (rfd->updated_responses_queue)
+ work_queue_free_and_null(&rfd->updated_responses_queue);
}
/*
return new;
}
-void work_queue_free(struct work_queue *wq)
+void work_queue_free_original(struct work_queue *wq)
{
if (wq->thread != NULL)
thread_cancel(wq->thread);
return;
}
+void work_queue_free_and_null(struct work_queue **wq)
+{
+ work_queue_free_original(*wq);
+ *wq = NULL;
+}
+
bool work_queue_is_scheduled(struct work_queue *wq)
{
return (wq->thread != NULL);
DECLARE_MTYPE(WORK_QUEUE)
/* Hold time for the initial schedule of a queue run, in millisec */
-#define WORK_QUEUE_DEFAULT_HOLD 50
+#define WORK_QUEUE_DEFAULT_HOLD 50
/* action value, for use by item processor and item error handlers */
typedef enum {
* anything to it
*/
extern struct work_queue *work_queue_new(struct thread_master *, const char *);
+
/* destroy work queue */
-extern void work_queue_free(struct work_queue *);
+/*
+ * The usage of work_queue_free is being transitioned to pass
+ * in the double pointer to remove use after free's.
+ */
+#if CONFDATE > 20190205
+CPP_NOTICE("work_queue_free without double pointer is deprecated, please fixup")
+#endif
+extern void work_queue_free_and_null(struct work_queue **);
+extern void work_queue_free_original(struct work_queue *);
+#define work_queue_free(X) \
+ do { \
+ work_queue_free_original((X)); \
+ CPP_WARN("Please use work_queue_free_and_null"); \
+ } while (0)
/* Add the supplied data as an item onto the workqueue */
extern void work_queue_add(struct work_queue *, void *);
SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN);
}
if (zebrad.lsp_process_q)
- work_queue_free(zebrad.lsp_process_q);
+ work_queue_free_and_null(&zebrad.lsp_process_q);
vrf_terminate();
ns_walk_func(zebra_ns_disabled);
route_map_finish();
list_delete_and_null(&zebrad.client_list);
- work_queue_free(zebrad.ribq);
+ work_queue_free_and_null(&zebrad.ribq);
meta_queue_free(zebrad.mq);
frr_fini();